move feature_gate to libsyntax

This commit is contained in:
Nick Cameron 2014-09-11 12:55:42 +12:00
parent 375c95b7ad
commit 74db87b99d
8 changed files with 69 additions and 65 deletions

View File

@ -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,

View File

@ -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<NodeMap<Vec<(lint::LintId, codemap::Span, String)>>>,
pub crate_types: RefCell<Vec<config::CrateType>>,
pub crate_metadata: RefCell<Vec<String>>,
pub features: front::feature_gate::Features,
pub features: RefCell<feature_gate::Features>,
/// 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),
};

View File

@ -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;

View File

@ -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
}

View File

@ -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,

View File

@ -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,

View File

@ -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<bool>,
pub overloaded_calls: Cell<bool>,
pub rustc_diagnostic_macros: Cell<bool>,
pub import_shadowing: Cell<bool>,
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<Span>) {
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)
}

View File

@ -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;