use driver::session::Session;
use std::cell::Cell;
-use std::vec_ng::Vec;
/// This is a list of all known features since the beginning of time. This list
/// can never shrink, it may only be expanded (in order to prevent old programs
("macro_registrar", Active),
("log_syntax", Active),
("trace_macros", Active),
+ ("concat_idents", Active),
+
("simd", Active),
("default_type_params", Active),
("quote", Active),
+ ("linkage", Active),
// These are used to test this portion of the compiler, they don't actually
// mean anything
/// A set of features to be used by later passes.
pub struct Features {
- default_type_params: Cell<bool>
+ pub default_type_params: Cell<bool>
}
impl Features {
}
}
-struct Context {
- features: Vec<&'static str> ,
- sess: Session,
+struct Context<'a> {
+ features: Vec<&'static str>,
+ sess: &'a Session,
}
-impl Context {
+impl<'a> Context<'a> {
fn gate_feature(&self, feature: &str, span: Span, explain: &str) {
if !self.has_feature(feature) {
self.sess.span_err(span, explain);
- self.sess.span_note(span, format!("add \\#[feature({})] to the \
+ self.sess.span_note(span, format!("add \\#![feature({})] to the \
crate attributes to enable",
feature));
}
}
}
-impl Visitor<()> for Context {
+impl<'a> Visitor<()> for Context<'a> {
fn visit_ident(&mut self, sp: Span, id: ast::Ident, _: ()) {
if !token::get_ident(id).get().is_ascii() {
self.gate_feature("non_ascii_idents", sp,
stable enough for use and is subject to change");
}
+ else if id == token::str_to_ident("concat_idents") {
+ self.gate_feature("concat_idents", path.span, "`concat_idents` is not \
+ stable enough for use and is subject to change");
+ }
+
else {
for "e in quotes.iter() {
if id == token::str_to_ident(quote) {
}
}
+ 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")
+ }
+ }
+ }
+ visit::walk_foreign_item(self, i, ())
+ }
+
fn visit_ty(&mut self, t: &ast::Ty, _: ()) {
match t.node {
- ast::TyClosure(closure) if closure.onceness == ast::Once &&
- closure.sigil != ast::OwnedSigil => {
+ ast::TyClosure(closure, _) if closure.onceness == ast::Once => {
self.gate_feature("once_fns", t.span,
"once functions are \
experimental and likely to be removed");
}
}
-pub fn check_crate(sess: Session, krate: &ast::Crate) {
+pub fn check_crate(sess: &Session, krate: &ast::Crate) {
let mut cx = Context {
features: Vec::new(),
sess: sess,
sess.add_lint(lint::UnknownFeatures,
ast::CRATE_NODE_ID,
mi.span,
- ~"unknown feature");
+ "unknown feature".to_owned());
}
}
}