//! Features are enabled in programs via the crate-level attributes of
//! `#![feature(...)]` with a comma-separated list of features.
-use middle::lint;
+use lint;
+use syntax::abi::RustIntrinsic;
+use syntax::ast::NodeId;
use syntax::ast;
use syntax::attr;
use syntax::attr::AttrMetaMethods;
("trace_macros", Active),
("concat_idents", Active),
("unsafe_destructor", Active),
+ ("intrinsics", Active),
+ ("lang_items", Active),
("simd", Active),
("default_type_params", Active),
("overloaded_calls", Active),
("unboxed_closure_sugar", Active),
- ("quad_precision_float", Active),
+ ("quad_precision_float", Removed),
+
+ ("rustc_diagnostic_macros", Active),
+ ("unboxed_closures", Active),
+
+ // if you change this list without updating src/doc/rust.md, cmr will be sad
// A temporary feature gate used to enable parser extensions needed
// to bootstrap fix for #5723.
/// A set of features to be used by later passes.
pub struct Features {
pub default_type_params: Cell<bool>,
- pub quad_precision_float: Cell<bool>,
pub issue_5723_bootstrap: Cell<bool>,
pub overloaded_calls: Cell<bool>,
+ pub rustc_diagnostic_macros: Cell<bool>
}
impl Features {
pub fn new() -> Features {
Features {
default_type_params: Cell::new(false),
- quad_precision_float: Cell::new(false),
issue_5723_bootstrap: Cell::new(false),
overloaded_calls: Cell::new(false),
+ rustc_diagnostic_macros: Cell::new(false)
}
}
}
}
}
- 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(..) => {
}
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, ())
}
ast::ExprUnary(ast::UnBox, _) => {
self.gate_box(e.span);
}
+ ast::ExprUnboxedFn(..) => {
+ self.gate_feature("unboxed_closures",
+ e.span,
+ "unboxed closures are a work-in-progress \
+ feature with known bugs");
+ }
_ => {}
}
visit::walk_expr(self, e, ());
}
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) {
directive not necessary");
}
None => {
- sess.add_lint(lint::UnknownFeatures,
+ sess.add_lint(lint::builtin::UNKNOWN_FEATURES,
ast::CRATE_NODE_ID,
mi.span,
"unknown feature".to_string());
sess.abort_if_errors();
sess.features.default_type_params.set(cx.has_feature("default_type_params"));
- sess.features.quad_precision_float.set(cx.has_feature("quad_precision_float"));
sess.features.issue_5723_bootstrap.set(cx.has_feature("issue_5723_bootstrap"));
sess.features.overloaded_calls.set(cx.has_feature("overloaded_calls"));
+ sess.features.rustc_diagnostic_macros.set(cx.has_feature("rustc_diagnostic_macros"));
}