diff options
| author | bors <bors@rust-lang.org> | 2016-09-26 17:44:25 -0700 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2016-09-26 17:44:25 -0700 |
| commit | d0623cf7bda44849ab5df78a06b22f9108cf821a (patch) | |
| tree | 9cdc98941940328cb7208f074f8529b81c88d3e4 /src/libsyntax | |
| parent | 388c3f25f95c55add63d436a8e8bb207d003c63b (diff) | |
| parent | f0e1738e5188b53d6af809481bea58f578bfdbe2 (diff) | |
| download | rust-d0623cf7bda44849ab5df78a06b22f9108cf821a.tar.gz rust-d0623cf7bda44849ab5df78a06b22f9108cf821a.zip | |
Auto merge of #36678 - TimNN:fix-dist, r=alexcrichton
emit feature help in cheat mode (fix nightlies) This should fix the `distcheck` failure in the latest nightly. cc #36539 It's probably not ideal to check the environment that often and the code ist duplicated from `librustc/session/config.rs` but this was the easiest fix I could think of. A cleaner solution would probably be to move the `unstable_features` from `Options` to `ParseSess` and change the `diag` parameter of `emit_feature_err` to take `ParseSess` instead of a `Handler`.
Diffstat (limited to 'src/libsyntax')
| -rw-r--r-- | src/libsyntax/config.rs | 2 | ||||
| -rw-r--r-- | src/libsyntax/ext/expand.rs | 2 | ||||
| -rw-r--r-- | src/libsyntax/feature_gate.rs | 60 | ||||
| -rw-r--r-- | src/libsyntax/parse/mod.rs | 3 |
4 files changed, 48 insertions, 19 deletions
diff --git a/src/libsyntax/config.rs b/src/libsyntax/config.rs index abbbbe1e3d1..78d047c7651 100644 --- a/src/libsyntax/config.rs +++ b/src/libsyntax/config.rs @@ -157,7 +157,7 @@ impl<'a> StripUnconfigured<'a> { // flag the offending attributes for attr in attrs.iter() { if !self.features.map(|features| features.stmt_expr_attributes).unwrap_or(true) { - emit_feature_err(&self.sess.span_diagnostic, + emit_feature_err(&self.sess, "stmt_expr_attributes", attr.span, GateIssue::Language, diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index 7359c21eccc..43c62218963 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -344,7 +344,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> { // Detect use of feature-gated or invalid attributes on macro invoations // since they will not be detected after macro expansion. for attr in attrs.iter() { - feature_gate::check_attribute(&attr, &self.cx.parse_sess.span_diagnostic, + feature_gate::check_attribute(&attr, &self.cx.parse_sess, &self.cx.parse_sess.codemap(), &self.cx.ecfg.features.unwrap()); } diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index 75cfa587ab1..b687e4f92be 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -36,6 +36,7 @@ use parse::ParseSess; use parse::token::InternedString; use std::ascii::AsciiExt; +use std::env; macro_rules! setter { ($field: ident) => {{ @@ -679,16 +680,15 @@ impl GatedCfg { pub fn check_and_emit(&self, sess: &ParseSess, features: &Features) { let (cfg, feature, has_feature) = GATED_CFGS[self.index]; if !has_feature(features) && !sess.codemap().span_allows_unstable(self.span) { - let diagnostic = &sess.span_diagnostic; let explain = format!("`cfg({})` is experimental and subject to change", cfg); - emit_feature_err(diagnostic, feature, self.span, GateIssue::Language, &explain); + emit_feature_err(sess, feature, self.span, GateIssue::Language, &explain); } } } struct Context<'a> { features: &'a Features, - span_handler: &'a Handler, + parse_sess: &'a ParseSess, cm: &'a CodeMap, plugin_attributes: &'a [(String, AttributeType)], } @@ -699,7 +699,7 @@ macro_rules! gate_feature_fn { let has_feature: bool = has_feature(&$cx.features); debug!("gate_feature(feature = {:?}, span = {:?}); has? {}", name, span, has_feature); if !has_feature && !cx.cm.span_allows_unstable(span) { - emit_feature_err(cx.span_handler, name, span, GateIssue::Language, explain); + emit_feature_err(cx.parse_sess, name, span, GateIssue::Language, explain); } }} } @@ -756,10 +756,10 @@ impl<'a> Context<'a> { } } -pub fn check_attribute(attr: &ast::Attribute, handler: &Handler, +pub fn check_attribute(attr: &ast::Attribute, parse_sess: &ParseSess, cm: &CodeMap, features: &Features) { let cx = Context { - features: features, span_handler: handler, + features: features, parse_sess: parse_sess, cm: cm, plugin_attributes: &[] }; cx.check_attribute(attr, true); @@ -788,8 +788,10 @@ pub enum GateIssue { Library(Option<u32>) } -pub fn emit_feature_err(diag: &Handler, feature: &str, span: Span, issue: GateIssue, +pub fn emit_feature_err(sess: &ParseSess, feature: &str, span: Span, issue: GateIssue, explain: &str) { + let diag = &sess.span_diagnostic; + let issue = match issue { GateIssue::Language => find_lang_feature_issue(feature), GateIssue::Library(lib) => lib, @@ -802,13 +804,12 @@ pub fn emit_feature_err(diag: &Handler, feature: &str, span: Span, issue: GateIs }; // #23973: do not suggest `#![feature(...)]` if we are in beta/stable - if option_env!("CFG_DISABLE_UNSTABLE_FEATURES").is_some() { - err.emit(); - return; + if sess.unstable_features.is_nightly_build() { + err.help(&format!("add #![feature({})] to the \ + crate attributes to enable", + feature)); } - err.help(&format!("add #![feature({})] to the \ - crate attributes to enable", - feature)); + err.emit(); } @@ -962,9 +963,10 @@ impl<'a> Visitor for PostExpansionVisitor<'a> { if attr::contains_name(&i.attrs[..], "simd") { gate_feature_post!(&self, simd, i.span, "SIMD types are experimental and possibly buggy"); - self.context.span_handler.span_warn(i.span, - "the `#[simd]` attribute is deprecated, \ - use `#[repr(simd)]` instead"); + self.context.parse_sess.span_diagnostic.span_warn(i.span, + "the `#[simd]` attribute \ + is deprecated, use \ + `#[repr(simd)]` instead"); } for attr in &i.attrs { if attr.name() == "repr" { @@ -1273,7 +1275,7 @@ pub fn check_crate(krate: &ast::Crate, maybe_stage_features(&sess.span_diagnostic, krate, unstable); let ctx = Context { features: features, - span_handler: &sess.span_diagnostic, + parse_sess: sess, cm: sess.codemap(), plugin_attributes: plugin_attributes, }; @@ -1294,6 +1296,30 @@ pub enum UnstableFeatures { Cheat } +impl UnstableFeatures { + pub fn from_environment() -> UnstableFeatures { + // Whether this is a feature-staged build, i.e. on the beta or stable channel + let disable_unstable_features = option_env!("CFG_DISABLE_UNSTABLE_FEATURES").is_some(); + // The secret key needed to get through the rustc build itself by + // subverting the unstable features lints + let bootstrap_secret_key = option_env!("CFG_BOOTSTRAP_KEY"); + // The matching key to the above, only known by the build system + let bootstrap_provided_key = env::var("RUSTC_BOOTSTRAP_KEY").ok(); + match (disable_unstable_features, bootstrap_secret_key, bootstrap_provided_key) { + (_, Some(ref s), Some(ref p)) if s == p => UnstableFeatures::Cheat, + (true, _, _) => UnstableFeatures::Disallow, + (false, _, _) => UnstableFeatures::Allow + } + } + + pub fn is_nightly_build(&self) -> bool { + match *self { + UnstableFeatures::Allow | UnstableFeatures::Cheat => true, + _ => false, + } + } +} + fn maybe_stage_features(span_handler: &Handler, krate: &ast::Crate, unstable: UnstableFeatures) { let allow_features = match unstable { diff --git a/src/libsyntax/parse/mod.rs b/src/libsyntax/parse/mod.rs index 5aa0efdec11..1e286c143de 100644 --- a/src/libsyntax/parse/mod.rs +++ b/src/libsyntax/parse/mod.rs @@ -14,6 +14,7 @@ use ast; use codemap::CodeMap; use syntax_pos::{self, Span, FileMap}; use errors::{Handler, ColorConfig, DiagnosticBuilder}; +use feature_gate::UnstableFeatures; use parse::parser::Parser; use parse::token::InternedString; use ptr::P; @@ -42,6 +43,7 @@ pub mod obsolete; /// Info about a parsing session. pub struct ParseSess { pub span_diagnostic: Handler, // better be the same as the one in the reader! + pub unstable_features: UnstableFeatures, /// Used to determine and report recursive mod inclusions included_mod_stack: RefCell<Vec<PathBuf>>, code_map: Rc<CodeMap>, @@ -60,6 +62,7 @@ impl ParseSess { pub fn with_span_handler(handler: Handler, code_map: Rc<CodeMap>) -> ParseSess { ParseSess { span_diagnostic: handler, + unstable_features: UnstableFeatures::from_environment(), included_mod_stack: RefCell::new(vec![]), code_map: code_map } |
