Auto merge of #26417 - brson:feature-err, r=steveklabnik
It now says '#[feature] may not be used on the stable release channel'. I had to convert this error from a lint to a normal compiler error. I left the lint previously-used for this in place since removing it is a breaking change. It will just go unused until the end of time. Fixes #24125
This commit is contained in:
commit
74a7e8b03e
8 changed files with 50 additions and 70 deletions
|
@ -28,9 +28,8 @@ use self::TargetLint::*;
|
||||||
use middle::privacy::ExportedItems;
|
use middle::privacy::ExportedItems;
|
||||||
use middle::ty::{self, Ty};
|
use middle::ty::{self, Ty};
|
||||||
use session::{early_error, Session};
|
use session::{early_error, Session};
|
||||||
use session::config::UnstableFeatures;
|
|
||||||
use lint::{Level, LevelSource, Lint, LintId, LintArray, LintPass, LintPassObject};
|
use lint::{Level, LevelSource, Lint, LintId, LintArray, LintPass, LintPassObject};
|
||||||
use lint::{Default, CommandLine, Node, Allow, Warn, Deny, Forbid, ReleaseChannel};
|
use lint::{Default, CommandLine, Node, Allow, Warn, Deny, Forbid};
|
||||||
use lint::builtin;
|
use lint::builtin;
|
||||||
use util::nodemap::FnvHashMap;
|
use util::nodemap::FnvHashMap;
|
||||||
|
|
||||||
|
@ -208,23 +207,6 @@ impl LintStore {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn maybe_stage_features(&mut self, sess: &Session) {
|
|
||||||
let lvl = match sess.opts.unstable_features {
|
|
||||||
UnstableFeatures::Default => return,
|
|
||||||
UnstableFeatures::Disallow => Forbid,
|
|
||||||
UnstableFeatures::Cheat => Allow
|
|
||||||
};
|
|
||||||
match self.by_name.get("unstable_features") {
|
|
||||||
Some(&Id(lint_id)) => if self.get_level_source(lint_id).0 != Forbid {
|
|
||||||
self.set_level(lint_id, (lvl, ReleaseChannel))
|
|
||||||
},
|
|
||||||
Some(&Renamed(_, lint_id)) => if self.get_level_source(lint_id).0 != Forbid {
|
|
||||||
self.set_level(lint_id, (lvl, ReleaseChannel))
|
|
||||||
},
|
|
||||||
None => unreachable!()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Context for lint checking.
|
/// Context for lint checking.
|
||||||
|
@ -308,7 +290,6 @@ pub fn raw_emit_lint(sess: &Session, lint: &'static Lint,
|
||||||
|
|
||||||
let name = lint.name_lower();
|
let name = lint.name_lower();
|
||||||
let mut def = None;
|
let mut def = None;
|
||||||
let mut note = None;
|
|
||||||
let msg = match source {
|
let msg = match source {
|
||||||
Default => {
|
Default => {
|
||||||
format!("{}, #[{}({})] on by default", msg,
|
format!("{}, #[{}({})] on by default", msg,
|
||||||
|
@ -325,12 +306,6 @@ pub fn raw_emit_lint(sess: &Session, lint: &'static Lint,
|
||||||
def = Some(src);
|
def = Some(src);
|
||||||
msg.to_string()
|
msg.to_string()
|
||||||
}
|
}
|
||||||
ReleaseChannel => {
|
|
||||||
let release_channel = option_env!("CFG_RELEASE_CHANNEL").unwrap_or("(unknown)");
|
|
||||||
note = Some(format!("this feature may not be used in the {} release channel",
|
|
||||||
release_channel));
|
|
||||||
msg.to_string()
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// For purposes of printing, we can treat forbid as deny.
|
// For purposes of printing, we can treat forbid as deny.
|
||||||
|
@ -344,10 +319,6 @@ pub fn raw_emit_lint(sess: &Session, lint: &'static Lint,
|
||||||
_ => sess.bug("impossible level in raw_emit_lint"),
|
_ => sess.bug("impossible level in raw_emit_lint"),
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(note) = note {
|
|
||||||
sess.note(¬e[..]);
|
|
||||||
}
|
|
||||||
|
|
||||||
if let Some(span) = def {
|
if let Some(span) = def {
|
||||||
sess.span_note(span, "lint level defined here");
|
sess.span_note(span, "lint level defined here");
|
||||||
}
|
}
|
||||||
|
@ -689,9 +660,6 @@ impl LintPass for GatherNodeLevels {
|
||||||
pub fn check_crate(tcx: &ty::ctxt,
|
pub fn check_crate(tcx: &ty::ctxt,
|
||||||
exported_items: &ExportedItems) {
|
exported_items: &ExportedItems) {
|
||||||
|
|
||||||
// If this is a feature-staged build of rustc then flip several lints to 'forbid'
|
|
||||||
tcx.sess.lint_store.borrow_mut().maybe_stage_features(&tcx.sess);
|
|
||||||
|
|
||||||
let krate = tcx.map.krate();
|
let krate = tcx.map.krate();
|
||||||
let mut cx = Context::new(tcx, krate, exported_items);
|
let mut cx = Context::new(tcx, krate, exported_items);
|
||||||
|
|
||||||
|
|
|
@ -247,9 +247,6 @@ pub enum LintSource {
|
||||||
|
|
||||||
/// Lint level was set by a command-line flag.
|
/// Lint level was set by a command-line flag.
|
||||||
CommandLine,
|
CommandLine,
|
||||||
|
|
||||||
/// Lint level was set by the release channel.
|
|
||||||
ReleaseChannel
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub type LevelSource = (Level, LintSource);
|
pub type LevelSource = (Level, LintSource);
|
||||||
|
|
|
@ -32,6 +32,7 @@ use syntax::attr::AttrMetaMethods;
|
||||||
use syntax::diagnostic::{ColorConfig, Auto, Always, Never, SpanHandler};
|
use syntax::diagnostic::{ColorConfig, Auto, Always, Never, SpanHandler};
|
||||||
use syntax::parse;
|
use syntax::parse;
|
||||||
use syntax::parse::token::InternedString;
|
use syntax::parse::token::InternedString;
|
||||||
|
use syntax::feature_gate::UnstableFeatures;
|
||||||
|
|
||||||
use getopts;
|
use getopts;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
@ -119,21 +120,6 @@ pub struct Options {
|
||||||
pub unstable_features: UnstableFeatures
|
pub unstable_features: UnstableFeatures
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Copy)]
|
|
||||||
pub enum UnstableFeatures {
|
|
||||||
/// Hard errors for unstable features are active, as on
|
|
||||||
/// beta/stable channels.
|
|
||||||
Disallow,
|
|
||||||
/// Use the default lint levels
|
|
||||||
Default,
|
|
||||||
/// Errors are bypassed for bootstrapping. This is required any time
|
|
||||||
/// during the build that feature-related lints are set to warn or above
|
|
||||||
/// because the build turns on warnings-as-errors and uses lots of unstable
|
|
||||||
/// features. As a result, this this is always required for building Rust
|
|
||||||
/// itself.
|
|
||||||
Cheat
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone, PartialEq, Eq)]
|
#[derive(Clone, PartialEq, Eq)]
|
||||||
pub enum PrintRequest {
|
pub enum PrintRequest {
|
||||||
FileNames,
|
FileNames,
|
||||||
|
@ -1074,7 +1060,7 @@ pub fn get_unstable_features_setting() -> UnstableFeatures {
|
||||||
match (disable_unstable_features, bootstrap_secret_key, bootstrap_provided_key) {
|
match (disable_unstable_features, bootstrap_secret_key, bootstrap_provided_key) {
|
||||||
(_, Some(ref s), Some(ref p)) if s == p => UnstableFeatures::Cheat,
|
(_, Some(ref s), Some(ref p)) if s == p => UnstableFeatures::Cheat,
|
||||||
(true, _, _) => UnstableFeatures::Disallow,
|
(true, _, _) => UnstableFeatures::Disallow,
|
||||||
(false, _, _) => UnstableFeatures::Default
|
(false, _, _) => UnstableFeatures::Allow
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -528,7 +528,8 @@ pub fn phase_2_configure_and_expand(sess: &Session,
|
||||||
let features =
|
let features =
|
||||||
syntax::feature_gate::check_crate(sess.codemap(),
|
syntax::feature_gate::check_crate(sess.codemap(),
|
||||||
&sess.parse_sess.span_diagnostic,
|
&sess.parse_sess.span_diagnostic,
|
||||||
&krate, &attributes);
|
&krate, &attributes,
|
||||||
|
sess.opts.unstable_features);
|
||||||
*sess.features.borrow_mut() = features;
|
*sess.features.borrow_mut() = features;
|
||||||
sess.abort_if_errors();
|
sess.abort_if_errors();
|
||||||
});
|
});
|
||||||
|
@ -558,7 +559,8 @@ pub fn phase_2_configure_and_expand(sess: &Session,
|
||||||
let features =
|
let features =
|
||||||
syntax::feature_gate::check_crate(sess.codemap(),
|
syntax::feature_gate::check_crate(sess.codemap(),
|
||||||
&sess.parse_sess.span_diagnostic,
|
&sess.parse_sess.span_diagnostic,
|
||||||
&krate, &attributes);
|
&krate, &attributes,
|
||||||
|
sess.opts.unstable_features);
|
||||||
*sess.features.borrow_mut() = features;
|
*sess.features.borrow_mut() = features;
|
||||||
sess.abort_if_errors();
|
sess.abort_if_errors();
|
||||||
});
|
});
|
||||||
|
|
|
@ -35,6 +35,7 @@ use syntax::codemap;
|
||||||
use syntax::codemap::{Span, CodeMap, DUMMY_SP};
|
use syntax::codemap::{Span, CodeMap, DUMMY_SP};
|
||||||
use syntax::diagnostic::{Level, RenderSpan, Bug, Fatal, Error, Warning, Note, Help};
|
use syntax::diagnostic::{Level, RenderSpan, Bug, Fatal, Error, Warning, Note, Help};
|
||||||
use syntax::parse::token;
|
use syntax::parse::token;
|
||||||
|
use syntax::feature_gate::UnstableFeatures;
|
||||||
|
|
||||||
struct Env<'a, 'tcx: 'a> {
|
struct Env<'a, 'tcx: 'a> {
|
||||||
infcx: &'a infer::InferCtxt<'a, 'tcx>,
|
infcx: &'a infer::InferCtxt<'a, 'tcx>,
|
||||||
|
@ -102,6 +103,7 @@ fn test_env<F>(source_string: &str,
|
||||||
let mut options =
|
let mut options =
|
||||||
config::basic_options();
|
config::basic_options();
|
||||||
options.debugging_opts.verbose = true;
|
options.debugging_opts.verbose = true;
|
||||||
|
options.unstable_features = UnstableFeatures::Allow;
|
||||||
let codemap =
|
let codemap =
|
||||||
CodeMap::new();
|
CodeMap::new();
|
||||||
let diagnostic_handler =
|
let diagnostic_handler =
|
||||||
|
|
|
@ -2213,7 +2213,7 @@ pub struct UnstableFeatures;
|
||||||
declare_lint! {
|
declare_lint! {
|
||||||
UNSTABLE_FEATURES,
|
UNSTABLE_FEATURES,
|
||||||
Allow,
|
Allow,
|
||||||
"enabling unstable features"
|
"enabling unstable features (deprecated. do not use)"
|
||||||
}
|
}
|
||||||
|
|
||||||
impl LintPass for UnstableFeatures {
|
impl LintPass for UnstableFeatures {
|
||||||
|
|
|
@ -12,7 +12,6 @@ pub use self::MaybeTyped::*;
|
||||||
use rustc_lint;
|
use rustc_lint;
|
||||||
use rustc_driver::driver;
|
use rustc_driver::driver;
|
||||||
use rustc::session::{self, config};
|
use rustc::session::{self, config};
|
||||||
use rustc::session::config::UnstableFeatures;
|
|
||||||
use rustc::middle::{privacy, ty};
|
use rustc::middle::{privacy, ty};
|
||||||
use rustc::ast_map;
|
use rustc::ast_map;
|
||||||
use rustc::lint;
|
use rustc::lint;
|
||||||
|
@ -20,6 +19,7 @@ use rustc_trans::back::link;
|
||||||
use rustc_resolve as resolve;
|
use rustc_resolve as resolve;
|
||||||
|
|
||||||
use syntax::{ast, codemap, diagnostic};
|
use syntax::{ast, codemap, diagnostic};
|
||||||
|
use syntax::feature_gate::UnstableFeatures;
|
||||||
|
|
||||||
use std::cell::{RefCell, Cell};
|
use std::cell::{RefCell, Cell};
|
||||||
use std::collections::{HashMap, HashSet};
|
use std::collections::{HashMap, HashSet};
|
||||||
|
@ -106,7 +106,7 @@ pub fn run_core(search_paths: SearchPaths, cfgs: Vec<String>, externs: Externs,
|
||||||
target_triple: triple.unwrap_or(config::host_triple().to_string()),
|
target_triple: triple.unwrap_or(config::host_triple().to_string()),
|
||||||
cfg: config::parse_cfgspecs(cfgs),
|
cfg: config::parse_cfgspecs(cfgs),
|
||||||
// Ensure that rustdoc works even if rustc is feature-staged
|
// Ensure that rustdoc works even if rustc is feature-staged
|
||||||
unstable_features: UnstableFeatures::Default,
|
unstable_features: UnstableFeatures::Allow,
|
||||||
..config::basic_options().clone()
|
..config::basic_options().clone()
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -430,18 +430,6 @@ pub fn emit_feature_err(diag: &SpanHandler, feature: &str, span: Span, explain:
|
||||||
feature));
|
feature));
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn emit_feature_warn(diag: &SpanHandler, feature: &str, span: Span, explain: &str) {
|
|
||||||
diag.span_warn(span, explain);
|
|
||||||
|
|
||||||
// #23973: do not suggest `#![feature(...)]` if we are in beta/stable
|
|
||||||
if option_env!("CFG_DISABLE_UNSTABLE_FEATURES").is_some() { return; }
|
|
||||||
if diag.handler.can_emit_warnings {
|
|
||||||
diag.fileline_help(span, &format!("add #![feature({})] to the \
|
|
||||||
crate attributes to silence this warning",
|
|
||||||
feature));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub const EXPLAIN_ASM: &'static str =
|
pub const EXPLAIN_ASM: &'static str =
|
||||||
"inline assembly is not stable enough for use and is subject to change";
|
"inline assembly is not stable enough for use and is subject to change";
|
||||||
|
|
||||||
|
@ -811,9 +799,46 @@ pub fn check_crate_macros(cm: &CodeMap, span_handler: &SpanHandler, krate: &ast:
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn check_crate(cm: &CodeMap, span_handler: &SpanHandler, krate: &ast::Crate,
|
pub fn check_crate(cm: &CodeMap, span_handler: &SpanHandler, krate: &ast::Crate,
|
||||||
plugin_attributes: &[(String, AttributeType)]) -> Features
|
plugin_attributes: &[(String, AttributeType)],
|
||||||
|
unstable: UnstableFeatures) -> Features
|
||||||
{
|
{
|
||||||
|
maybe_stage_features(span_handler, krate, unstable);
|
||||||
|
|
||||||
check_crate_inner(cm, span_handler, krate, plugin_attributes,
|
check_crate_inner(cm, span_handler, krate, plugin_attributes,
|
||||||
|ctx, krate| visit::walk_crate(&mut PostExpansionVisitor { context: ctx },
|
|ctx, krate| visit::walk_crate(&mut PostExpansionVisitor { context: ctx },
|
||||||
krate))
|
krate))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Copy)]
|
||||||
|
pub enum UnstableFeatures {
|
||||||
|
/// Hard errors for unstable features are active, as on
|
||||||
|
/// beta/stable channels.
|
||||||
|
Disallow,
|
||||||
|
/// Allow features to me activated, as on nightly.
|
||||||
|
Allow,
|
||||||
|
/// Errors are bypassed for bootstrapping. This is required any time
|
||||||
|
/// during the build that feature-related lints are set to warn or above
|
||||||
|
/// because the build turns on warnings-as-errors and uses lots of unstable
|
||||||
|
/// features. As a result, this this is always required for building Rust
|
||||||
|
/// itself.
|
||||||
|
Cheat
|
||||||
|
}
|
||||||
|
|
||||||
|
fn maybe_stage_features(span_handler: &SpanHandler, krate: &ast::Crate,
|
||||||
|
unstable: UnstableFeatures) {
|
||||||
|
let allow_features = match unstable {
|
||||||
|
UnstableFeatures::Allow => true,
|
||||||
|
UnstableFeatures::Disallow => false,
|
||||||
|
UnstableFeatures::Cheat => true
|
||||||
|
};
|
||||||
|
if !allow_features {
|
||||||
|
for attr in &krate.attrs {
|
||||||
|
if attr.check_name("feature") {
|
||||||
|
let release_channel = option_env!("CFG_RELEASE_CHANNEL").unwrap_or("(unknown)");
|
||||||
|
let ref msg = format!("#[feature] may not be used on the {} release channel",
|
||||||
|
release_channel);
|
||||||
|
span_handler.span_err(attr.span, msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue