Permalink
Browse files

librustc: Feature gate lang items and intrinsics.

If you define lang items in your crate, add `#[feature(lang_items)]`.

If you define intrinsics (`extern "rust-intrinsic"`), add
`#[feature(intrinsics)]`.

Closes #12858.

[breaking-change]
  • Loading branch information...
pcwalton committed Jun 20, 2014
1 parent 7689213 commit 5466d13d4320252f57d276c566dbee44617b63b2
View
@@ -451,6 +451,7 @@ in the same format as a C:
```
#![no_std]
+#![feature(lang_items)]
// Pull in the system libc library for what crt0.o likely requires
extern crate libc;
@@ -477,6 +478,7 @@ compiler's name mangling too:
```ignore
#![no_std]
#![no_main]
+#![feature(lang_items)]
extern crate libc;
@@ -528,6 +530,7 @@ vectors provided from C, using idiomatic Rust practices.
```
#![no_std]
#![feature(globs)]
+#![feature(lang_items)]
# extern crate libc;
extern crate core;
@@ -619,6 +622,9 @@ perform efficient pointer arithmetic, one would import those functions
via a declaration like
```
+# #![feature(intrinsics)]
+# fn main() {}
+
extern "rust-intrinsic" {
fn transmute<T, U>(x: T) -> U;
@@ -647,6 +653,7 @@ sugar for dynamic allocations via `malloc` and `free`:
```
#![no_std]
+#![feature(lang_items)]
extern crate libc;
View
@@ -69,7 +69,8 @@
html_root_url = "http://doc.rust-lang.org/")]
#![no_std]
-#![feature(phase, unsafe_destructor)]
+#![feature(lang_items, phase, unsafe_destructor)]
+#![allow(unknown_features)] // NOTE: remove after a stage0 snap
#[phase(plugin, link)]
extern crate core;
View
@@ -55,8 +55,10 @@
html_playground_url = "http://play.rust-lang.org/")]
#![no_std]
-#![feature(globs, macro_rules, managed_boxes, phase, simd, unsafe_destructor)]
+#![feature(globs, intrinsics, lang_items, macro_rules, managed_boxes, phase)]
+#![feature(simd, unsafe_destructor)]
#![deny(missing_doc)]
+#![allow(unknown_features)] // NOTE: remove after stage0 snapshot
#[cfg(test)] extern crate realcore = "core";
#[cfg(test)] extern crate libc;
View
@@ -55,6 +55,8 @@
#![deny(unused_result, unused_must_use)]
#![allow(non_camel_case_types, deprecated)]
+#![allow(unknown_features)] // NOTE: remove after a stage0 snap
+#![feature(default_type_params, lang_items)]
// NB this crate explicitly does *not* allow glob imports, please seriously
// consider whether they're needed before adding that feature here (the
View
@@ -26,6 +26,8 @@
#![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
html_favicon_url = "http://www.rust-lang.org/favicon.ico",
html_root_url = "http://doc.rust-lang.org/")]
+#![feature(intrinsics)]
+#![allow(unknown_features)] // NOTE: remove after stage0 snapshot
#![no_std]
#![experimental]
@@ -20,6 +20,8 @@
use middle::lint;
+use syntax::abi::RustIntrinsic;
+use syntax::ast::NodeId;
use syntax::ast;
use syntax::attr;
use syntax::attr::AttrMetaMethods;
@@ -51,6 +53,8 @@ static KNOWN_FEATURES: &'static [(&'static str, Status)] = &[
("trace_macros", Active),
("concat_idents", Active),
("unsafe_destructor", Active),
+ ("intrinsics", Active),
+ ("lang_items", Active),
("simd", Active),
("default_type_params", Active),
@@ -187,13 +191,18 @@ impl<'a> Visitor<()> for Context<'a> {
}
}
- ast::ItemForeignMod(..) => {
+ ast::ItemForeignMod(ref foreign_module) => {
if attr::contains_name(i.attrs.as_slice(), "link_args") {
self.gate_feature("link_args", i.span,
"the `link_args` attribute is not portable \
across platforms, it is recommended to \
use `#[link(name = \"foo\")]` instead")
}
+ if foreign_module.abi == RustIntrinsic {
+ self.gate_feature("intrinsics",
+ i.span,
+ "intrinsics are subject to change")
+ }
}
ast::ItemFn(..) => {
@@ -283,14 +292,10 @@ impl<'a> Visitor<()> for Context<'a> {
}
fn visit_foreign_item(&mut self, i: &ast::ForeignItem, _: ()) {
- match i.node {
- ast::ForeignItemFn(..) | ast::ForeignItemStatic(..) => {
- if attr::contains_name(i.attrs.as_slice(), "linkage") {
- self.gate_feature("linkage", i.span,
- "the `linkage` attribute is experimental \
- and not portable across platforms")
- }
- }
+ if attr::contains_name(i.attrs.as_slice(), "linkage") {
+ self.gate_feature("linkage", i.span,
+ "the `linkage` attribute is experimental \
+ and not portable across platforms")
}
visit::walk_foreign_item(self, i, ())
}
@@ -338,6 +343,32 @@ impl<'a> Visitor<()> for Context<'a> {
}
visit::walk_generics(self, generics, ());
}
+
+ fn visit_attribute(&mut self, attr: &ast::Attribute, _: ()) {
+ if attr::contains_name([*attr], "lang") {
+ self.gate_feature("lang_items",
+ attr.span,
+ "language items are subject to change");
+ }
+ }
+
+ fn visit_fn(&mut self,
+ fn_kind: &visit::FnKind,
+ fn_decl: &ast::FnDecl,
+ block: &ast::Block,
+ span: Span,
+ _: NodeId,
+ (): ()) {
+ match *fn_kind {
+ visit::FkItemFn(_, _, _, ref abi) if *abi == RustIntrinsic => {
+ self.gate_feature("intrinsics",
+ span,
+ "intrinsics are subject to change")
+ }
+ _ => {}
+ }
+ visit::walk_fn(self, fn_kind, fn_decl, block, span, ());
+ }
}
pub fn check_crate(sess: &Session, krate: &ast::Crate) {
View
@@ -17,7 +17,8 @@
html_root_url = "http://doc.rust-lang.org/")]
#![feature(macro_rules, phase, globs, thread_local, managed_boxes, asm)]
-#![feature(linkage, unsafe_destructor)]
+#![feature(linkage, lang_items, unsafe_destructor)]
+#![allow(unknown_features)] // NOTE: remove after stage0 snapshot
#![no_std]
#![experimental]
View
@@ -104,13 +104,14 @@
html_root_url = "http://doc.rust-lang.org/",
html_playground_url = "http://play.rust-lang.org/")]
-#![feature(macro_rules, globs, managed_boxes)]
-#![feature(linkage, default_type_params, phase, unsafe_destructor)]
+#![feature(macro_rules, globs, managed_boxes, linkage)]
+#![feature(default_type_params, phase, lang_items, unsafe_destructor)]
// Don't link to std. We are std.
#![no_std]
#![allow(deprecated)]
+#![allow(unknown_features)] // NOTE: remove after stage0 snapshot
#![deny(missing_doc)]
// When testing libstd, bring in libuv as the I/O backend so tests can print
@@ -8,6 +8,8 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
+#![feature(intrinsics)]
+
pub mod rusti {
extern "rust-intrinsic" {
pub fn atomic_xchg<T>(dst: *mut T, src: T) -> T;
@@ -9,6 +9,7 @@
// except according to those terms.
#![no_std]
+#![feature(lang_items)]
#[lang="fail_"]
fn fail(_: &'static str, _: &'static str, _: uint) -> ! { loop {} }
@@ -8,6 +8,8 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
+#![feature(lang_items)]
+
fn main() {}
#![lang(foo)] //~ ERROR an inner attribute is not permitted in this context
@@ -11,6 +11,7 @@
// ignore-tidy-linelength
#![no_std]
+#![feature(lang_items)]
#[lang="sized"]
pub trait Sized {}
@@ -0,0 +1,23 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#[lang="foo"] //~ ERROR language items are subject to change
+trait Foo {}
+
+extern "rust-intrinsic" { //~ ERROR intrinsics are subject to change
+ fn bar();
+}
+
+extern "rust-intrinsic" fn baz() { //~ ERROR intrinsics are subject to change
+}
+
+fn main() {
+}
+
@@ -13,6 +13,7 @@
#![allow(non_camel_case_types)]
#![allow(visible_private_types)]
#![deny(dead_code)]
+#![feature(lang_items)]
#![crate_type="lib"]
@@ -8,7 +8,7 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![feature(globs)]
+#![feature(globs, lang_items)]
#![no_std] // makes debugging this test *a lot* easier (during resolve)
#[lang="sized"]
@@ -8,6 +8,7 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
+#![feature(intrinsics)]
mod rusti {
extern "rust-intrinsic" {
@@ -8,6 +8,8 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
+#![feature(intrinsics)]
+
mod rusti {
extern "rust-intrinsic" {
pub fn atomic_cxchg<T>(dst: *mut T, old: T, src: T) -> T;
@@ -8,6 +8,8 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
+#![feature(intrinsics)]
+
use std::mem::transmute;
mod rusti {
@@ -8,6 +8,8 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
+#![feature(intrinsics)]
+
mod rusti {
extern "rust-intrinsic" {
pub fn uninit<T>() -> T;
@@ -8,7 +8,7 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![feature(globs)]
+#![feature(globs, intrinsics)]
mod rusti {
extern "rust-intrinsic" {
@@ -9,7 +9,7 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![feature(globs, macro_rules)]
+#![feature(globs, macro_rules, intrinsics)]
macro_rules! assert_approx_eq(
($a:expr, $b:expr) => ({
@@ -10,6 +10,8 @@
// Issue #2303
+#![feature(intrinsics)]
+
extern crate debug;
use std::mem;
@@ -10,6 +10,8 @@
// Issue #2303
+#![feature(intrinsics)]
+
extern crate debug;
use std::mem;
@@ -13,6 +13,7 @@
// Smallest "hello world" with a libc runtime
#![no_std]
+#![feature(intrinsics, lang_items)]
extern crate libc;