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`.
This commit is contained in:
commit
d0623cf7bd
@ -411,8 +411,8 @@ impl<'a, 'tcx> Checker<'a, 'tcx> {
|
||||
&feature, &r),
|
||||
None => format!("use of unstable library feature '{}'", &feature)
|
||||
};
|
||||
emit_feature_err(&self.tcx.sess.parse_sess.span_diagnostic,
|
||||
&feature, span, GateIssue::Library(Some(issue)), &msg);
|
||||
emit_feature_err(&self.tcx.sess.parse_sess, &feature, span,
|
||||
GateIssue::Library(Some(issue)), &msg);
|
||||
}
|
||||
}
|
||||
Some(&Stability { ref level, ref feature, .. }) => {
|
||||
|
@ -37,7 +37,6 @@ use std::collections::btree_map::Iter as BTreeMapIter;
|
||||
use std::collections::btree_map::Keys as BTreeMapKeysIter;
|
||||
use std::collections::btree_map::Values as BTreeMapValuesIter;
|
||||
|
||||
use std::env;
|
||||
use std::fmt;
|
||||
use std::hash::{Hasher, SipHasher};
|
||||
use std::iter::FromIterator;
|
||||
@ -1525,27 +1524,12 @@ pub fn build_session_options_and_crate_config(matches: &getopts::Matches)
|
||||
crate_name: crate_name,
|
||||
alt_std_name: None,
|
||||
libs: libs,
|
||||
unstable_features: get_unstable_features_setting(),
|
||||
unstable_features: UnstableFeatures::from_environment(),
|
||||
debug_assertions: debug_assertions,
|
||||
},
|
||||
cfg)
|
||||
}
|
||||
|
||||
pub fn get_unstable_features_setting() -> 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 parse_crate_types_from_list(list_list: Vec<String>) -> Result<Vec<CrateType>, String> {
|
||||
let mut crate_types: Vec<CrateType> = Vec::new();
|
||||
for unparsed_crate_type in &list_list {
|
||||
@ -1575,7 +1559,7 @@ pub fn parse_crate_types_from_list(list_list: Vec<String>) -> Result<Vec<CrateTy
|
||||
pub mod nightly_options {
|
||||
use getopts;
|
||||
use syntax::feature_gate::UnstableFeatures;
|
||||
use super::{ErrorOutputType, OptionStability, RustcOptGroup, get_unstable_features_setting};
|
||||
use super::{ErrorOutputType, OptionStability, RustcOptGroup};
|
||||
use session::{early_error, early_warn};
|
||||
|
||||
pub fn is_unstable_enabled(matches: &getopts::Matches) -> bool {
|
||||
@ -1583,18 +1567,13 @@ pub mod nightly_options {
|
||||
}
|
||||
|
||||
pub fn is_nightly_build() -> bool {
|
||||
match get_unstable_features_setting() {
|
||||
UnstableFeatures::Allow | UnstableFeatures::Cheat => true,
|
||||
_ => false,
|
||||
}
|
||||
UnstableFeatures::from_environment().is_nightly_build()
|
||||
}
|
||||
|
||||
pub fn check_nightly_options(matches: &getopts::Matches, flags: &[RustcOptGroup]) {
|
||||
let has_z_unstable_option = matches.opt_strs("Z").iter().any(|x| *x == "unstable-options");
|
||||
let really_allows_unstable_options = match get_unstable_features_setting() {
|
||||
UnstableFeatures::Disallow => false,
|
||||
_ => true,
|
||||
};
|
||||
let really_allows_unstable_options = UnstableFeatures::from_environment()
|
||||
.is_nightly_build();
|
||||
|
||||
for opt in flags.iter() {
|
||||
if opt.stability == OptionStability::Stable {
|
||||
|
@ -73,7 +73,7 @@ use rustc_trans::back::write::{create_target_machine, RELOC_MODEL_ARGS, CODE_GEN
|
||||
use rustc::dep_graph::DepGraph;
|
||||
use rustc::session::{self, config, Session, build_session, CompileResult};
|
||||
use rustc::session::config::{Input, PrintRequest, OutputType, ErrorOutputType};
|
||||
use rustc::session::config::{get_unstable_features_setting, nightly_options};
|
||||
use rustc::session::config::nightly_options;
|
||||
use rustc::lint::Lint;
|
||||
use rustc::lint;
|
||||
use rustc_metadata::loader;
|
||||
@ -649,10 +649,8 @@ impl RustcDefaultCalls {
|
||||
}
|
||||
}
|
||||
PrintRequest::Cfg => {
|
||||
let allow_unstable_cfg = match get_unstable_features_setting() {
|
||||
UnstableFeatures::Disallow => false,
|
||||
_ => true,
|
||||
};
|
||||
let allow_unstable_cfg = UnstableFeatures::from_environment()
|
||||
.is_nightly_build();
|
||||
|
||||
for cfg in cfg {
|
||||
if !allow_unstable_cfg && GatedCfg::gate(&*cfg).is_some() {
|
||||
|
@ -143,7 +143,7 @@ impl<'a, 'ast: 'a> CheckItemRecursionVisitor<'a, 'ast> {
|
||||
});
|
||||
if any_static {
|
||||
if !self.sess.features.borrow().static_recursion {
|
||||
emit_feature_err(&self.sess.parse_sess.span_diagnostic,
|
||||
emit_feature_err(&self.sess.parse_sess,
|
||||
"static_recursion",
|
||||
*self.root_span,
|
||||
GateIssue::Language,
|
||||
|
@ -149,9 +149,9 @@ impl<'a> Resolver<'a> {
|
||||
|
||||
fn insert_custom_derive(&mut self, name: &str, ext: Rc<MultiItemModifier>, sp: Span) {
|
||||
if !self.session.features.borrow().rustc_macro {
|
||||
let diagnostic = &self.session.parse_sess.span_diagnostic;
|
||||
let sess = &self.session.parse_sess;
|
||||
let msg = "loading custom derive macro crates is experimentally supported";
|
||||
emit_feature_err(diagnostic, "rustc_macro", sp, feature_gate::GateIssue::Language, msg);
|
||||
emit_feature_err(sess, "rustc_macro", sp, feature_gate::GateIssue::Language, msg);
|
||||
}
|
||||
if self.derive_modes.insert(token::intern(name), ext).is_some() {
|
||||
self.session.span_err(sp, &format!("cannot shadow existing derive mode `{}`", name));
|
||||
|
@ -795,7 +795,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
|
||||
// For now, require that parenthetical notation be used
|
||||
// only with `Fn()` etc.
|
||||
if !self.tcx().sess.features.borrow().unboxed_closures && trait_def.paren_sugar {
|
||||
emit_feature_err(&self.tcx().sess.parse_sess.span_diagnostic,
|
||||
emit_feature_err(&self.tcx().sess.parse_sess,
|
||||
"unboxed_closures", span, GateIssue::Language,
|
||||
"\
|
||||
the precise format of `Fn`-family traits' \
|
||||
@ -807,7 +807,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
|
||||
// For now, require that parenthetical notation be used
|
||||
// only with `Fn()` etc.
|
||||
if !self.tcx().sess.features.borrow().unboxed_closures && !trait_def.paren_sugar {
|
||||
emit_feature_err(&self.tcx().sess.parse_sess.span_diagnostic,
|
||||
emit_feature_err(&self.tcx().sess.parse_sess,
|
||||
"unboxed_closures", span, GateIssue::Language,
|
||||
"\
|
||||
parenthetical notation is only stable when used with `Fn`-family traits");
|
||||
|
@ -3255,7 +3255,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
||||
if let Some((def_id, variant)) = variant {
|
||||
if variant.kind == ty::VariantKind::Tuple &&
|
||||
!self.tcx.sess.features.borrow().relaxed_adts {
|
||||
emit_feature_err(&self.tcx.sess.parse_sess.span_diagnostic,
|
||||
emit_feature_err(&self.tcx.sess.parse_sess,
|
||||
"relaxed_adts", span, GateIssue::Language,
|
||||
"tuple structs and variants in struct patterns are unstable");
|
||||
}
|
||||
|
@ -27,7 +27,6 @@
|
||||
#![allow(non_camel_case_types)]
|
||||
|
||||
use libc;
|
||||
use rustc::session::config::get_unstable_features_setting;
|
||||
use std::ascii::AsciiExt;
|
||||
use std::cell::RefCell;
|
||||
use std::default::Default;
|
||||
@ -478,13 +477,10 @@ impl LangString {
|
||||
let mut data = LangString::all_false();
|
||||
let mut allow_compile_fail = false;
|
||||
let mut allow_error_code_check = false;
|
||||
match get_unstable_features_setting() {
|
||||
UnstableFeatures::Allow | UnstableFeatures::Cheat => {
|
||||
allow_compile_fail = true;
|
||||
allow_error_code_check = true;
|
||||
}
|
||||
_ => {},
|
||||
};
|
||||
if UnstableFeatures::from_environment().is_nightly_build() {
|
||||
allow_compile_fail = true;
|
||||
allow_error_code_check = true;
|
||||
}
|
||||
|
||||
let tokens = string.split(|c: char|
|
||||
!(c == '_' || c == '-' || c.is_alphanumeric())
|
||||
|
@ -58,7 +58,6 @@ use syntax::feature_gate::UnstableFeatures;
|
||||
use rustc::hir::def_id::{CrateNum, CRATE_DEF_INDEX, DefId, LOCAL_CRATE};
|
||||
use rustc::middle::privacy::AccessLevels;
|
||||
use rustc::middle::stability;
|
||||
use rustc::session::config::get_unstable_features_setting;
|
||||
use rustc::hir;
|
||||
use rustc::util::nodemap::{FnvHashMap, FnvHashSet};
|
||||
use rustc_data_structures::flock;
|
||||
@ -1971,7 +1970,7 @@ fn item_static(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item,
|
||||
fn item_function(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item,
|
||||
f: &clean::Function) -> fmt::Result {
|
||||
// FIXME(#24111): remove when `const_fn` is stabilized
|
||||
let vis_constness = match get_unstable_features_setting() {
|
||||
let vis_constness = match UnstableFeatures::from_environment() {
|
||||
UnstableFeatures::Allow => f.constness,
|
||||
_ => hir::Constness::NotConst
|
||||
};
|
||||
@ -2250,7 +2249,7 @@ fn render_assoc_item(w: &mut fmt::Formatter,
|
||||
}
|
||||
};
|
||||
// FIXME(#24111): remove when `const_fn` is stabilized
|
||||
let vis_constness = match get_unstable_features_setting() {
|
||||
let vis_constness = match UnstableFeatures::from_environment() {
|
||||
UnstableFeatures::Allow => constness,
|
||||
_ => hir::Constness::NotConst
|
||||
};
|
||||
|
@ -25,8 +25,7 @@ use rustc_lint;
|
||||
use rustc::dep_graph::DepGraph;
|
||||
use rustc::hir::map as hir_map;
|
||||
use rustc::session::{self, config};
|
||||
use rustc::session::config::{get_unstable_features_setting, OutputType,
|
||||
OutputTypes, Externs};
|
||||
use rustc::session::config::{OutputType, OutputTypes, Externs};
|
||||
use rustc::session::search_paths::{SearchPaths, PathKind};
|
||||
use rustc_back::dynamic_lib::DynamicLibrary;
|
||||
use rustc_back::tempdir::TempDir;
|
||||
@ -35,6 +34,7 @@ use rustc_driver::driver::phase_2_configure_and_expand;
|
||||
use rustc_metadata::cstore::CStore;
|
||||
use rustc_resolve::MakeGlobMap;
|
||||
use syntax::codemap::CodeMap;
|
||||
use syntax::feature_gate::UnstableFeatures;
|
||||
use errors;
|
||||
use errors::emitter::ColorConfig;
|
||||
|
||||
@ -68,7 +68,7 @@ pub fn run(input: &str,
|
||||
search_paths: libs.clone(),
|
||||
crate_types: vec!(config::CrateTypeDylib),
|
||||
externs: externs.clone(),
|
||||
unstable_features: get_unstable_features_setting(),
|
||||
unstable_features: UnstableFeatures::from_environment(),
|
||||
..config::basic_options().clone()
|
||||
};
|
||||
|
||||
@ -197,7 +197,7 @@ fn runtest(test: &str, cratename: &str, cfgs: Vec<String>, libs: SearchPaths,
|
||||
.. config::basic_codegen_options()
|
||||
},
|
||||
test: as_test_harness,
|
||||
unstable_features: get_unstable_features_setting(),
|
||||
unstable_features: UnstableFeatures::from_environment(),
|
||||
..config::basic_options().clone()
|
||||
};
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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());
|
||||
}
|
||||
|
@ -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 {
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -53,7 +53,7 @@ pub fn expand_asm<'cx>(cx: &'cx mut ExtCtxt,
|
||||
tts: &[tokenstream::TokenTree])
|
||||
-> Box<base::MacResult + 'cx> {
|
||||
if !cx.ecfg.enable_asm() {
|
||||
feature_gate::emit_feature_err(&cx.parse_sess.span_diagnostic,
|
||||
feature_gate::emit_feature_err(&cx.parse_sess,
|
||||
"asm",
|
||||
sp,
|
||||
feature_gate::GateIssue::Language,
|
||||
|
@ -23,7 +23,7 @@ pub fn expand_syntax_ext<'cx>(cx: &'cx mut ExtCtxt,
|
||||
tts: &[TokenTree])
|
||||
-> Box<base::MacResult + 'cx> {
|
||||
if !cx.ecfg.enable_concat_idents() {
|
||||
feature_gate::emit_feature_err(&cx.parse_sess.span_diagnostic,
|
||||
feature_gate::emit_feature_err(&cx.parse_sess,
|
||||
"concat_idents",
|
||||
sp,
|
||||
feature_gate::GateIssue::Language,
|
||||
|
@ -221,7 +221,7 @@ pub fn expand_derive(cx: &mut ExtCtxt,
|
||||
// the old custom derive mechanism. If the feature isn't enabled, we
|
||||
// issue an error, otherwise manufacture the `derive_Foo` attribute.
|
||||
} else if !cx.ecfg.enable_custom_derive() {
|
||||
feature_gate::emit_feature_err(&cx.parse_sess.span_diagnostic,
|
||||
feature_gate::emit_feature_err(&cx.parse_sess,
|
||||
"custom_derive",
|
||||
titem.span,
|
||||
feature_gate::GateIssue::Language,
|
||||
|
@ -19,7 +19,7 @@ pub fn expand_syntax_ext<'cx>(cx: &'cx mut base::ExtCtxt,
|
||||
tts: &[tokenstream::TokenTree])
|
||||
-> Box<base::MacResult + 'cx> {
|
||||
if !cx.ecfg.enable_log_syntax() {
|
||||
feature_gate::emit_feature_err(&cx.parse_sess.span_diagnostic,
|
||||
feature_gate::emit_feature_err(&cx.parse_sess,
|
||||
"log_syntax",
|
||||
sp,
|
||||
feature_gate::GateIssue::Language,
|
||||
|
@ -20,7 +20,7 @@ pub fn expand_trace_macros(cx: &mut ExtCtxt,
|
||||
tt: &[TokenTree])
|
||||
-> Box<base::MacResult + 'static> {
|
||||
if !cx.ecfg.enable_trace_macros() {
|
||||
feature_gate::emit_feature_err(&cx.parse_sess.span_diagnostic,
|
||||
feature_gate::emit_feature_err(&cx.parse_sess,
|
||||
"trace_macros",
|
||||
sp,
|
||||
feature_gate::GateIssue::Language,
|
||||
|
Loading…
Reference in New Issue
Block a user