diff --git a/src/librustc/driver/driver.rs b/src/librustc/driver/driver.rs index 4c6bb2de180..20371f63a34 100644 --- a/src/librustc/driver/driver.rs +++ b/src/librustc/driver/driver.rs @@ -13,7 +13,6 @@ use back::link; use back::write; use driver::session::Session; use driver::config; -use front; use lint; use llvm::{ContextRef, ModuleRef}; use metadata::common::LinkMeta; @@ -194,8 +193,20 @@ pub fn phase_2_configure_and_expand(sess: &Session, *sess.crate_metadata.borrow_mut() = collect_crate_metadata(sess, krate.attrs.as_slice()); - time(time_passes, "gated feature checking", (), |_| - front::feature_gate::check_crate(sess, &krate)); + time(time_passes, "gated feature checking", (), |_| { + let (features, unknown_features) = + syntax::feature_gate::check_crate(&sess.parse_sess.span_diagnostic, &krate); + + for uf in unknown_features.iter() { + sess.add_lint(lint::builtin::UNKNOWN_FEATURES, + ast::CRATE_NODE_ID, + *uf, + "unknown feature".to_string()); + } + + sess.abort_if_errors(); + *sess.features.borrow_mut() = features; + }); let any_exe = sess.crate_types.borrow().iter().any(|ty| { *ty == config::CrateTypeExecutable @@ -225,7 +236,7 @@ pub fn phase_2_configure_and_expand(sess: &Session, let mut registry = Registry::new(&krate); time(time_passes, "plugin registration", (), |_| { - if sess.features.rustc_diagnostic_macros.get() { + if sess.features.borrow().rustc_diagnostic_macros { registry.register_macro("__diagnostic_used", diagnostics::plugin::expand_diagnostic_used); registry.register_macro("__register_diagnostic", @@ -277,7 +288,7 @@ pub fn phase_2_configure_and_expand(sess: &Session, os::setenv("PATH", os::join_paths(new_path.as_slice()).unwrap()); } let cfg = syntax::ext::expand::ExpansionConfig { - deriving_hash_type_parameter: sess.features.default_type_params.get(), + deriving_hash_type_parameter: sess.features.borrow().default_type_params, crate_name: crate_name.to_string(), }; let ret = syntax::ext::expand::expand_crate(&sess.parse_sess, diff --git a/src/librustc/driver/session.rs b/src/librustc/driver/session.rs index 2d28a9294e4..d7ed5d3e1ff 100644 --- a/src/librustc/driver/session.rs +++ b/src/librustc/driver/session.rs @@ -11,7 +11,6 @@ use driver::config; use driver::driver; -use front; use metadata::cstore::CStore; use metadata::filesearch; use lint; @@ -21,6 +20,7 @@ use syntax::ast::NodeId; use syntax::codemap::Span; use syntax::diagnostic; use syntax::diagnostics; +use syntax::feature_gate; use syntax::parse; use syntax::parse::token; use syntax::parse::ParseSess; @@ -49,7 +49,7 @@ pub struct Session { pub lints: RefCell>>, pub crate_types: RefCell>, pub crate_metadata: RefCell>, - pub features: front::feature_gate::Features, + pub features: RefCell, /// The maximum recursion limit for potentially infinitely recursive /// operations such as auto-dereference and monomorphization. @@ -245,7 +245,7 @@ pub fn build_session_(sopts: config::Options, lints: RefCell::new(NodeMap::new()), crate_types: RefCell::new(Vec::new()), crate_metadata: RefCell::new(Vec::new()), - features: front::feature_gate::Features::new(), + features: RefCell::new(feature_gate::Features::new()), recursion_limit: Cell::new(64), }; diff --git a/src/librustc/lib.rs b/src/librustc/lib.rs index e1a82d1db7c..81234f36ade 100644 --- a/src/librustc/lib.rs +++ b/src/librustc/lib.rs @@ -116,10 +116,6 @@ pub mod middle { pub mod weak_lang_items; } -pub mod front { - pub mod feature_gate; -} - pub mod metadata; pub mod driver; diff --git a/src/librustc/middle/resolve.rs b/src/librustc/middle/resolve.rs index ded4883350f..d4fe3c265f5 100644 --- a/src/librustc/middle/resolve.rs +++ b/src/librustc/middle/resolve.rs @@ -2811,7 +2811,7 @@ impl<'a> Resolver<'a> { import_span: Span, name: Name, namespace: Namespace) { - if self.session.features.import_shadowing.get() { + if self.session.features.borrow().import_shadowing { return } @@ -2837,7 +2837,7 @@ impl<'a> Resolver<'a> { &mut ImportResolution, import_span: Span, name: Name) { - if self.session.features.import_shadowing.get() { + if self.session.features.borrow().import_shadowing { return } @@ -2919,7 +2919,7 @@ impl<'a> Resolver<'a> { module: &Module, name: Name, span: Span) { - if self.session.features.import_shadowing.get() { + if self.session.features.borrow().import_shadowing { return } @@ -2937,7 +2937,7 @@ impl<'a> Resolver<'a> { module: &Module, name: Name, span: Span) { - if self.session.features.import_shadowing.get() { + if self.session.features.borrow().import_shadowing { return } diff --git a/src/librustc/middle/typeck/astconv.rs b/src/librustc/middle/typeck/astconv.rs index cb449f80ed4..c46e95cf045 100644 --- a/src/librustc/middle/typeck/astconv.rs +++ b/src/librustc/middle/typeck/astconv.rs @@ -235,7 +235,7 @@ fn ast_path_substs<'tcx, AC: AstConv<'tcx>, RS: RegionScope>( } if supplied_ty_param_count > required_ty_param_count - && !this.tcx().sess.features.default_type_params.get() { + && !this.tcx().sess.features.borrow().default_type_params { span_err!(this.tcx().sess, path.span, E0108, "default type parameters are experimental and possibly buggy"); span_note!(this.tcx().sess, path.span, diff --git a/src/librustc/middle/typeck/check/mod.rs b/src/librustc/middle/typeck/check/mod.rs index 20fe8186adf..12905763f52 100644 --- a/src/librustc/middle/typeck/check/mod.rs +++ b/src/librustc/middle/typeck/check/mod.rs @@ -2131,7 +2131,7 @@ fn try_overloaded_call(fcx: &FnCtxt, fcx.inh.method_map.borrow_mut().insert(method_call, method_callee); write_call(fcx, call_expression, output_type); - if !fcx.tcx().sess.features.overloaded_calls.get() { + if !fcx.tcx().sess.features.borrow().overloaded_calls { span_err!(fcx.tcx().sess, call_expression.span, E0056, "overloaded calls are experimental"); span_note!(fcx.tcx().sess, call_expression.span, diff --git a/src/librustc/front/feature_gate.rs b/src/libsyntax/feature_gate.rs similarity index 87% rename from src/librustc/front/feature_gate.rs rename to src/libsyntax/feature_gate.rs index 13a40aba930..e22e55193fc 100644 --- a/src/librustc/front/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -18,21 +18,17 @@ //! Features are enabled in programs via the crate-level attributes of //! `#![feature(...)]` with a comma-separated list of features. -use lint; +use abi::RustIntrinsic; +use ast::NodeId; +use ast; +use attr; +use attr::AttrMetaMethods; +use codemap::Span; +use diagnostic::SpanHandler; +use visit; +use visit::Visitor; +use parse::token; -use syntax::abi::RustIntrinsic; -use syntax::ast::NodeId; -use syntax::ast; -use syntax::attr; -use syntax::attr::AttrMetaMethods; -use syntax::codemap::Span; -use syntax::visit; -use syntax::visit::Visitor; -use syntax::parse::token; - -use driver::session::Session; - -use std::cell::Cell; use std::slice; /// This is a list of all known features since the beginning of time. This list @@ -99,35 +95,35 @@ enum Status { /// A set of features to be used by later passes. pub struct Features { - pub default_type_params: Cell, - pub overloaded_calls: Cell, - pub rustc_diagnostic_macros: Cell, - pub import_shadowing: Cell, + pub default_type_params: bool, + pub overloaded_calls: bool, + pub rustc_diagnostic_macros: bool, + pub import_shadowing: bool, } impl Features { pub fn new() -> Features { Features { - default_type_params: Cell::new(false), - overloaded_calls: Cell::new(false), - rustc_diagnostic_macros: Cell::new(false), - import_shadowing: Cell::new(false), + default_type_params: false, + overloaded_calls: false, + rustc_diagnostic_macros: false, + import_shadowing: false, } } } struct Context<'a> { features: Vec<&'static str>, - sess: &'a Session, + span_handler: &'a SpanHandler, } 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 \ - crate attributes to enable", - feature).as_slice()); + self.span_handler.span_err(span, explain); + self.span_handler.span_note(span, format!("add #![feature({})] to the \ + crate attributes to enable", + feature).as_slice()); } } @@ -404,12 +400,14 @@ impl<'a, 'v> Visitor<'v> for Context<'a> { } } -pub fn check_crate(sess: &Session, krate: &ast::Crate) { +pub fn check_crate(span_handler: &SpanHandler, krate: &ast::Crate) -> (Features, Vec) { let mut cx = Context { features: Vec::new(), - sess: sess, + span_handler: span_handler, }; + let mut unknown_features = Vec::new(); + for attr in krate.attrs.iter() { if !attr.check_name("feature") { continue @@ -417,17 +415,17 @@ pub fn check_crate(sess: &Session, krate: &ast::Crate) { match attr.meta_item_list() { None => { - sess.span_err(attr.span, "malformed feature attribute, \ - expected #![feature(...)]"); + span_handler.span_err(attr.span, "malformed feature attribute, \ + expected #![feature(...)]"); } Some(list) => { for mi in list.iter() { let name = match mi.node { ast::MetaWord(ref word) => (*word).clone(), _ => { - sess.span_err(mi.span, - "malformed feature, expected just \ - one word"); + span_handler.span_err(mi.span, + "malformed feature, expected just \ + one word"); continue } }; @@ -435,17 +433,14 @@ pub fn check_crate(sess: &Session, krate: &ast::Crate) { .find(|& &(n, _)| name.equiv(&n)) { Some(&(name, Active)) => { cx.features.push(name); } Some(&(_, Removed)) => { - sess.span_err(mi.span, "feature has been removed"); + span_handler.span_err(mi.span, "feature has been removed"); } Some(&(_, Accepted)) => { - sess.span_warn(mi.span, "feature has been added to Rust, \ - directive not necessary"); + span_handler.span_warn(mi.span, "feature has been added to Rust, \ + directive not necessary"); } None => { - sess.add_lint(lint::builtin::UNKNOWN_FEATURES, - ast::CRATE_NODE_ID, - mi.span, - "unknown feature".to_string()); + unknown_features.push(mi.span); } } } @@ -455,11 +450,12 @@ pub fn check_crate(sess: &Session, krate: &ast::Crate) { visit::walk_crate(&mut cx, krate); - sess.abort_if_errors(); - - sess.features.default_type_params.set(cx.has_feature("default_type_params")); - sess.features.overloaded_calls.set(cx.has_feature("overloaded_calls")); - sess.features.rustc_diagnostic_macros.set(cx.has_feature("rustc_diagnostic_macros")); - sess.features.import_shadowing.set(cx.has_feature("import_shadowing")); + (Features { + default_type_params: cx.has_feature("default_type_params"), + overloaded_calls: cx.has_feature("overloaded_calls"), + rustc_diagnostic_macros: cx.has_feature("rustc_diagnostic_macros"), + import_shadowing: cx.has_feature("import_shadowing"), + }, + unknown_features) } diff --git a/src/libsyntax/lib.rs b/src/libsyntax/lib.rs index 8122aa1dcc2..457d77efb70 100644 --- a/src/libsyntax/lib.rs +++ b/src/libsyntax/lib.rs @@ -62,6 +62,7 @@ pub mod codemap; pub mod config; pub mod crateid; pub mod diagnostic; +pub mod feature_gate; pub mod fold; pub mod owned_slice; pub mod parse;