diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs index 271fac544a4..2a9fd58f84b 100644 --- a/src/librustc/hir/lowering.rs +++ b/src/librustc/hir/lowering.rs @@ -90,6 +90,7 @@ pub struct LoweringContext<'a> { impl_items: BTreeMap, bodies: BTreeMap, exported_macros: Vec, + non_exported_macro_attrs: Vec, trait_impls: BTreeMap>, @@ -252,6 +253,7 @@ pub fn lower_crate( trait_impls: BTreeMap::new(), modules: BTreeMap::new(), exported_macros: Vec::new(), + non_exported_macro_attrs: Vec::new(), catch_scopes: Vec::new(), loop_scopes: Vec::new(), is_in_loop_condition: false, @@ -662,6 +664,7 @@ impl<'a> LoweringContext<'a> { attrs, span: c.span, exported_macros: hir::HirVec::from(self.exported_macros), + non_exported_macro_attrs: hir::HirVec::from(self.non_exported_macro_attrs), items: self.items, trait_items: self.trait_items, impl_items: self.impl_items, @@ -4022,6 +4025,8 @@ impl<'a> LoweringContext<'a> { body, legacy: def.legacy, }); + } else { + self.non_exported_macro_attrs.extend(attrs.into_iter()); } return None; } diff --git a/src/librustc/hir/map/collector.rs b/src/librustc/hir/map/collector.rs index 8a59f6b69bc..12ea772c1fb 100644 --- a/src/librustc/hir/map/collector.rs +++ b/src/librustc/hir/map/collector.rs @@ -119,6 +119,7 @@ impl<'a, 'hir> NodeCollector<'a, 'hir> { span, // These fields are handled separately: exported_macros: _, + non_exported_macro_attrs: _, items: _, trait_items: _, impl_items: _, diff --git a/src/librustc/hir/mod.rs b/src/librustc/hir/mod.rs index 7b760a87238..e7b37d40b4b 100644 --- a/src/librustc/hir/mod.rs +++ b/src/librustc/hir/mod.rs @@ -727,6 +727,8 @@ pub struct Crate { pub attrs: HirVec, pub span: Span, pub exported_macros: HirVec, + // Attributes from non-exported macros, kept only for collecting the library feature list. + pub non_exported_macro_attrs: HirVec, // N.B., we use a BTreeMap here so that `visit_all_items` iterates // over the ids in increasing order. In principle it should not diff --git a/src/librustc/lint/builtin.rs b/src/librustc/lint/builtin.rs index 45e598531b9..dd879ec6aff 100644 --- a/src/librustc/lint/builtin.rs +++ b/src/librustc/lint/builtin.rs @@ -5,10 +5,12 @@ //! lints are all available in `rustc_lint::builtin`. use crate::lint::{LintPass, LateLintPass, LintArray}; +use crate::middle::stability; use crate::session::Session; use errors::{Applicability, DiagnosticBuilder}; use syntax::ast; use syntax::source_map::Span; +use syntax::symbol::Symbol; declare_lint! { pub EXCEEDING_BITSHIFTS, @@ -461,6 +463,7 @@ pub enum BuiltinLintDiagnostics { UnusedImports(String, Vec<(Span, String)>), NestedImplTrait { outer_impl_trait_span: Span, inner_impl_trait_span: Span }, RedundantImport(Vec<(Span, bool)>, ast::Ident), + DeprecatedMacro(Option, Span), } pub(crate) fn add_elided_lifetime_in_path_suggestion( @@ -586,6 +589,8 @@ impl BuiltinLintDiagnostics { ); } } + BuiltinLintDiagnostics::DeprecatedMacro(suggestion, span) => + stability::deprecation_suggestion(db, suggestion, span), } } } diff --git a/src/librustc/middle/lib_features.rs b/src/librustc/middle/lib_features.rs index 694b0a98629..0d6d016e507 100644 --- a/src/librustc/middle/lib_features.rs +++ b/src/librustc/middle/lib_features.rs @@ -144,6 +144,10 @@ impl Visitor<'tcx> for LibFeatureCollector<'tcx> { pub fn collect(tcx: TyCtxt<'_>) -> LibFeatures { let mut collector = LibFeatureCollector::new(tcx); - intravisit::walk_crate(&mut collector, tcx.hir().krate()); + let krate = tcx.hir().krate(); + for attr in &krate.non_exported_macro_attrs { + collector.visit_attribute(attr); + } + intravisit::walk_crate(&mut collector, krate); collector.lib_features } diff --git a/src/librustc/middle/stability.rs b/src/librustc/middle/stability.rs index 7757336cf9c..5ab762ab225 100644 --- a/src/librustc/middle/stability.rs +++ b/src/librustc/middle/stability.rs @@ -4,6 +4,7 @@ pub use self::StabilityLevel::*; use crate::lint::{self, Lint, in_derive_expansion}; +use crate::lint::builtin::BuiltinLintDiagnostics; use crate::hir::{self, Item, Generics, StructField, Variant, HirId}; use crate::hir::def::{Res, DefKind}; use crate::hir::def_id::{CrateNum, CRATE_DEF_INDEX, DefId, LOCAL_CRATE}; @@ -11,12 +12,13 @@ use crate::hir::intravisit::{self, Visitor, NestedVisitorMap}; use crate::ty::query::Providers; use crate::middle::privacy::AccessLevels; use crate::session::{DiagnosticMessageId, Session}; +use errors::DiagnosticBuilder; use syntax::symbol::{Symbol, sym}; use syntax_pos::{Span, MultiSpan}; -use syntax::ast::Attribute; +use syntax::ast::{Attribute, CRATE_NODE_ID}; use syntax::errors::Applicability; use syntax::feature_gate::{GateIssue, emit_feature_err}; -use syntax::attr::{self, Stability, Deprecation}; +use syntax::attr::{self, Stability, Deprecation, RustcDeprecation}; use crate::ty::{self, TyCtxt}; use crate::util::nodemap::{FxHashSet, FxHashMap}; @@ -477,6 +479,36 @@ pub fn provide(providers: &mut Providers<'_>) { }; } +pub fn report_unstable( + sess: &Session, feature: Symbol, reason: Option, issue: u32, span: Span +) { + let msg = match reason { + Some(r) => format!("use of unstable library feature '{}': {}", feature, r), + None => format!("use of unstable library feature '{}'", &feature) + }; + + let msp: MultiSpan = span.into(); + let cm = &sess.parse_sess.source_map(); + let span_key = msp.primary_span().and_then(|sp: Span| + if !sp.is_dummy() { + let file = cm.lookup_char_pos(sp.lo()).file; + if file.name.is_macros() { + None + } else { + Some(span) + } + } else { + None + } + ); + + let error_id = (DiagnosticMessageId::StabilityId(issue), span_key, msg.clone()); + let fresh = sess.one_time_diagnostics.borrow_mut().insert(error_id); + if fresh { + emit_feature_err(&sess.parse_sess, feature, span, GateIssue::Library(Some(issue)), &msg); + } +} + /// Checks whether an item marked with `deprecated(since="X")` is currently /// deprecated (i.e., whether X is not greater than the current rustc version). pub fn deprecation_in_effect(since: &str) -> bool { @@ -501,6 +533,79 @@ pub fn deprecation_in_effect(since: &str) -> bool { } } +pub fn deprecation_suggestion( + diag: &mut DiagnosticBuilder<'_>, suggestion: Option, span: Span +) { + if let Some(suggestion) = suggestion { + diag.span_suggestion( + span, + "replace the use of the deprecated item", + suggestion.to_string(), + Applicability::MachineApplicable, + ); + } +} + +fn deprecation_message_common(message: String, reason: Option) -> String { + match reason { + Some(reason) => format!("{}: {}", message, reason), + None => message, + } +} + +pub fn deprecation_message(depr: &Deprecation, path: &str) -> (String, &'static Lint) { + let message = format!("use of deprecated item '{}'", path); + (deprecation_message_common(message, depr.note), lint::builtin::DEPRECATED) +} + +pub fn rustc_deprecation_message(depr: &RustcDeprecation, path: &str) -> (String, &'static Lint) { + let (message, lint) = if deprecation_in_effect(&depr.since.as_str()) { + (format!("use of deprecated item '{}'", path), lint::builtin::DEPRECATED) + } else { + (format!("use of item '{}' that will be deprecated in future version {}", path, depr.since), + lint::builtin::DEPRECATED_IN_FUTURE) + }; + (deprecation_message_common(message, Some(depr.reason)), lint) +} + +pub fn early_report_deprecation( + sess: &Session, + message: &str, + suggestion: Option, + lint: &'static Lint, + span: Span, +) { + if in_derive_expansion(span) { + return; + } + + let diag = BuiltinLintDiagnostics::DeprecatedMacro(suggestion, span); + sess.buffer_lint_with_diagnostic(lint, CRATE_NODE_ID, span, message, diag); +} + +fn late_report_deprecation( + tcx: TyCtxt<'_>, + message: &str, + suggestion: Option, + lint: &'static Lint, + span: Span, + def_id: DefId, + hir_id: HirId, +) { + if in_derive_expansion(span) { + return; + } + + let mut diag = tcx.struct_span_lint_hir(lint, hir_id, span, message); + if let hir::Node::Expr(_) = tcx.hir().get(hir_id) { + deprecation_suggestion(&mut diag, suggestion, span); + } + diag.emit(); + if hir_id == hir::DUMMY_HIR_ID { + span_bug!(span, "emitted a {} lint with dummy HIR id: {:?}", lint.name, def_id); + } +} + struct Checker<'tcx> { tcx: TyCtxt<'tcx>, } @@ -563,38 +668,6 @@ impl<'tcx> TyCtxt<'tcx> { /// deprecated. If the item is indeed deprecated, we will emit a deprecation lint attached to /// `id`. pub fn eval_stability(self, def_id: DefId, id: Option, span: Span) -> EvalResult { - let lint_deprecated = |def_id: DefId, - id: HirId, - note: Option, - suggestion: Option, - message: &str, - lint: &'static Lint| { - if in_derive_expansion(span) { - return; - } - let msg = if let Some(note) = note { - format!("{}: {}", message, note) - } else { - format!("{}", message) - }; - - let mut diag = self.struct_span_lint_hir(lint, id, span, &msg); - if let Some(suggestion) = suggestion { - if let hir::Node::Expr(_) = self.hir().get(id) { - diag.span_suggestion( - span, - "replace the use of the deprecated item", - suggestion.to_string(), - Applicability::MachineApplicable, - ); - } - } - diag.emit(); - if id == hir::DUMMY_HIR_ID { - span_bug!(span, "emitted a {} lint with dummy HIR id: {:?}", lint.name, def_id); - } - }; - // Deprecated attributes apply in-crate and cross-crate. if let Some(id) = id { if let Some(depr_entry) = self.lookup_deprecation_entry(def_id) { @@ -604,14 +677,9 @@ impl<'tcx> TyCtxt<'tcx> { .map_or(false, |parent_depr| parent_depr.same_origin(&depr_entry)); if !skip { - let path = self.def_path_str(def_id); - let message = format!("use of deprecated item '{}'", path); - lint_deprecated(def_id, - id, - depr_entry.attr.note, - None, - &message, - lint::builtin::DEPRECATED); + let (message, lint) = + deprecation_message(&depr_entry.attr, &self.def_path_str(def_id)); + late_report_deprecation(self, &message, None, lint, span, def_id, id); } }; } @@ -631,27 +699,11 @@ impl<'tcx> TyCtxt<'tcx> { if let Some(id) = id { if let Some(stability) = stability { if let Some(depr) = &stability.rustc_depr { - let path = self.def_path_str(def_id); - if deprecation_in_effect(&depr.since.as_str()) { - let message = format!("use of deprecated item '{}'", path); - lint_deprecated(def_id, - id, - Some(depr.reason), - depr.suggestion, - &message, - lint::builtin::DEPRECATED); - } else { - let message = format!("use of item '{}' \ - that will be deprecated in future version {}", - path, - depr.since); - lint_deprecated(def_id, - id, - Some(depr.reason), - depr.suggestion, - &message, - lint::builtin::DEPRECATED_IN_FUTURE); - } + let (message, lint) = + rustc_deprecation_message(depr, &self.def_path_str(def_id)); + late_report_deprecation( + self, &message, depr.suggestion, lint, span, def_id, id + ); } } } @@ -715,34 +767,8 @@ impl<'tcx> TyCtxt<'tcx> { pub fn check_stability(self, def_id: DefId, id: Option, span: Span) { match self.eval_stability(def_id, id, span) { EvalResult::Allow => {} - EvalResult::Deny { feature, reason, issue } => { - let msg = match reason { - Some(r) => format!("use of unstable library feature '{}': {}", feature, r), - None => format!("use of unstable library feature '{}'", &feature) - }; - - let msp: MultiSpan = span.into(); - let cm = &self.sess.parse_sess.source_map(); - let span_key = msp.primary_span().and_then(|sp: Span| - if !sp.is_dummy() { - let file = cm.lookup_char_pos(sp.lo()).file; - if file.name.is_macros() { - None - } else { - Some(span) - } - } else { - None - } - ); - - let error_id = (DiagnosticMessageId::StabilityId(issue), span_key, msg.clone()); - let fresh = self.sess.one_time_diagnostics.borrow_mut().insert(error_id); - if fresh { - emit_feature_err(&self.sess.parse_sess, feature, span, - GateIssue::Library(Some(issue)), &msg); - } - } + EvalResult::Deny { feature, reason, issue } => + report_unstable(self.sess, feature, reason, issue, span), EvalResult::Unmarked => { // The API could be uncallable for other reasons, for example when a private module // was referenced. diff --git a/src/librustc_plugin/registry.rs b/src/librustc_plugin/registry.rs index ec2855f826a..bb3c950edae 100644 --- a/src/librustc_plugin/registry.rs +++ b/src/librustc_plugin/registry.rs @@ -84,10 +84,7 @@ impl<'a> Registry<'a> { /// Register a syntax extension of any kind. /// /// This is the most general hook into `libsyntax`'s expansion behavior. - pub fn register_syntax_extension(&mut self, name: ast::Name, mut extension: SyntaxExtension) { - if extension.def_info.is_none() { - extension.def_info = Some((ast::CRATE_NODE_ID, self.krate_span)); - } + pub fn register_syntax_extension(&mut self, name: ast::Name, extension: SyntaxExtension) { self.syntax_exts.push((name, extension)); } diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index 13b9855dbd7..66410482cc6 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -1666,10 +1666,7 @@ pub struct Resolver<'a> { non_macro_attrs: [Lrc; 2], macro_defs: FxHashMap, local_macro_def_scopes: FxHashMap>, - - /// List of crate local macros that we need to warn about as being unused. - /// Right now this only includes macro_rules! macros, and macros 2.0. - unused_macros: FxHashSet, + unused_macros: NodeMap, /// Maps the `Mark` of an expansion to its containing module or block. invocations: FxHashMap>, @@ -1687,6 +1684,9 @@ pub struct Resolver<'a> { current_type_ascription: Vec, injected_crate: Option>, + + /// Features enabled for this crate. + active_features: FxHashSet, } /// Nothing really interesting here; it just provides memory for the rest of the crate. @@ -1925,6 +1925,7 @@ impl<'a> Resolver<'a> { let mut macro_defs = FxHashMap::default(); macro_defs.insert(Mark::root(), root_def_id); + let features = session.features_untracked(); let non_macro_attr = |mark_used| Lrc::new(SyntaxExtension::default( SyntaxExtensionKind::NonMacroAttr { mark_used }, session.edition() )); @@ -2009,9 +2010,13 @@ impl<'a> Resolver<'a> { name_already_seen: FxHashMap::default(), potentially_unused_imports: Vec::new(), struct_constructors: Default::default(), - unused_macros: FxHashSet::default(), + unused_macros: Default::default(), current_type_ascription: Vec::new(), injected_crate: None, + active_features: + features.declared_lib_features.iter().map(|(feat, ..)| *feat) + .chain(features.declared_lang_features.iter().map(|(feat, ..)| *feat)) + .collect(), } } diff --git a/src/librustc_resolve/macros.rs b/src/librustc_resolve/macros.rs index 0955c425f2f..f26c3b8ae6a 100644 --- a/src/librustc_resolve/macros.rs +++ b/src/librustc_resolve/macros.rs @@ -9,10 +9,10 @@ use crate::resolve_imports::ImportResolver; use rustc::hir::def_id::{CrateNum, DefId, DefIndex, CRATE_DEF_INDEX}; use rustc::hir::def::{self, DefKind, NonMacroAttrKind}; use rustc::hir::map::{self, DefCollector}; -use rustc::{ty, lint}; -use rustc::{bug, span_bug}; +use rustc::middle::stability; +use rustc::{ty, lint, span_bug}; use syntax::ast::{self, Ident}; -use syntax::attr; +use syntax::attr::{self, StabilityLevel}; use syntax::errors::DiagnosticBuilder; use syntax::ext::base::{self, Determinacy}; use syntax::ext::base::{MacroKind, SyntaxExtension}; @@ -230,16 +230,19 @@ impl<'a> base::Resolver for Resolver<'a> { Err(determinacy) => return Err(determinacy), }; + let span = invoc.span(); + let path = fast_print_path(path); let format = match kind { - MacroKind::Derive => format!("derive({})", fast_print_path(path)), - _ => fast_print_path(path), + MacroKind::Derive => format!("derive({})", path), + _ => path.clone(), }; - invoc.expansion_data.mark.set_expn_info(ext.expn_info(invoc.span(), &format)); + invoc.expansion_data.mark.set_expn_info(ext.expn_info(span, &format)); + + self.check_stability_and_deprecation(&ext, &path, span); if let Res::Def(_, def_id) = res { if after_derive { - self.session.span_err(invoc.span(), - "macro attributes must be placed before `#[derive]`"); + self.session.span_err(span, "macro attributes must be placed before `#[derive]`"); } self.macro_defs.insert(invoc.expansion_data.mark, def_id); let normal_module_def_id = @@ -259,14 +262,10 @@ impl<'a> base::Resolver for Resolver<'a> { } fn check_unused_macros(&self) { - for did in self.unused_macros.iter() { - if let Some((id, span)) = self.macro_map[did].def_info { - let lint = lint::builtin::UNUSED_MACROS; - let msg = "unused macro definition"; - self.session.buffer_lint(lint, id, span, msg); - } else { - bug!("attempted to create unused macro error, but span not available"); - } + for (&node_id, &span) in self.unused_macros.iter() { + self.session.buffer_lint( + lint::builtin::UNUSED_MACROS, node_id, span, "unused macro definition" + ); } } } @@ -323,7 +322,9 @@ impl<'a> Resolver<'a> { match res { Res::Def(DefKind::Macro(macro_kind), def_id) => { - self.unused_macros.remove(&def_id); + if let Some(node_id) = self.definitions.as_local_node_id(def_id) { + self.unused_macros.remove(&node_id); + } if macro_kind == MacroKind::ProcMacroStub { let msg = "can't use a procedural macro from the same crate that defines it"; self.session.span_err(path.span, msg); @@ -1009,6 +1010,27 @@ impl<'a> Resolver<'a> { } } + fn check_stability_and_deprecation(&self, ext: &SyntaxExtension, path: &str, span: Span) { + if let Some(stability) = &ext.stability { + if let StabilityLevel::Unstable { reason, issue } = stability.level { + let feature = stability.feature; + if !self.active_features.contains(&feature) && !span.allows_unstable(feature) { + stability::report_unstable(self.session, feature, reason, issue, span); + } + } + if let Some(depr) = &stability.rustc_depr { + let (message, lint) = stability::rustc_deprecation_message(depr, path); + stability::early_report_deprecation( + self.session, &message, depr.suggestion, lint, span + ); + } + } + if let Some(depr) = &ext.deprecation { + let (message, lint) = stability::deprecation_message(depr, path); + stability::early_report_deprecation(self.session, &message, None, lint, span); + } + } + fn prohibit_imported_non_macro_attrs(&self, binding: Option<&'a NameBinding<'a>>, res: Option, span: Span) { if let Some(Res::NonMacroAttr(kind)) = res { @@ -1157,13 +1179,13 @@ impl<'a> Resolver<'a> { (res, vis, item.span, expansion, IsMacroExport)); } else { self.check_reserved_macro_name(ident, res); - self.unused_macros.insert(def_id); + self.unused_macros.insert(item.id, item.span); } } else { let module = self.current_module; let vis = self.resolve_visibility(&item.vis); if vis != ty::Visibility::Public { - self.unused_macros.insert(def_id); + self.unused_macros.insert(item.id, item.span); } self.define(module, ident, MacroNS, (res, vis, item.span, expansion)); } diff --git a/src/libserialize/json.rs b/src/libserialize/json.rs index 726306d60ce..d0007074a82 100644 --- a/src/libserialize/json.rs +++ b/src/libserialize/json.rs @@ -103,8 +103,8 @@ //! //! ```rust //! # #![feature(rustc_private)] -//! extern crate serialize; -//! use serialize::json::{self, ToJson, Json}; +//! extern crate serialize as rustc_serialize; +//! use rustc_serialize::json::{self, ToJson, Json}; //! //! // A custom data structure //! struct ComplexNum { @@ -120,7 +120,7 @@ //! } //! //! // Only generate `RustcEncodable` trait implementation -//! #[derive(Encodable)] +//! #[derive(RustcEncodable)] //! pub struct ComplexNumRecord { //! uid: u8, //! dsc: String, @@ -143,12 +143,12 @@ //! //! ```rust //! # #![feature(rustc_private)] -//! extern crate serialize; +//! extern crate serialize as rustc_serialize; //! use std::collections::BTreeMap; -//! use serialize::json::{self, Json, ToJson}; +//! use rustc_serialize::json::{self, Json, ToJson}; //! -//! // Only generate `Decodable` trait implementation -//! #[derive(Decodable)] +//! // Only generate `RustcDecodable` trait implementation +//! #[derive(RustcDecodable)] //! pub struct TestStruct { //! data_int: u8, //! data_str: String, diff --git a/src/libsyntax/attr/builtin.rs b/src/libsyntax/attr/builtin.rs index 752ab5d474d..b41f1047fcb 100644 --- a/src/libsyntax/attr/builtin.rs +++ b/src/libsyntax/attr/builtin.rs @@ -135,6 +135,19 @@ pub enum StabilityLevel { Stable { since: Symbol }, } +impl Stability { + pub fn unstable(feature: Symbol, reason: Option, issue: u32) -> Stability { + Stability { + level: StabilityLevel::Unstable { reason, issue }, + feature, + rustc_depr: None, + const_stability: None, + promotable: false, + allow_const_fn_ptr: false, + } + } +} + impl StabilityLevel { pub fn is_unstable(&self) -> bool { if let StabilityLevel::Unstable {..} = *self { @@ -171,7 +184,8 @@ pub fn contains_feature_attr(attrs: &[Attribute], feature_name: Symbol) -> bool }) } -/// Finds the first stability attribute. `None` if none exists. +/// Collects stability info from all stability attributes in `attrs`. +/// Returns `None` if no stability attributes are found. pub fn find_stability(sess: &ParseSess, attrs: &[Attribute], item_sp: Span) -> Option { find_stability_generic(sess, attrs.iter(), item_sp) diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs index 318a5a3a82a..15c0b6ca5aa 100644 --- a/src/libsyntax/ext/base.rs +++ b/src/libsyntax/ext/base.rs @@ -1,5 +1,5 @@ use crate::ast::{self, Attribute, Name, PatKind}; -use crate::attr::HasAttrs; +use crate::attr::{HasAttrs, Stability, Deprecation}; use crate::source_map::{SourceMap, Spanned, respan}; use crate::edition::Edition; use crate::ext::expand::{self, AstFragment, Invocation}; @@ -606,8 +606,8 @@ pub enum SyntaxExtensionKind { pub struct SyntaxExtension { /// A syntax extension kind. pub kind: SyntaxExtensionKind, - /// Some info about the macro's definition point. - pub def_info: Option<(ast::NodeId, Span)>, + /// Span of the macro definition. + pub span: Span, /// Hygienic properties of spans produced by this macro by default. pub default_transparency: Transparency, /// Whitelist of unstable features that are treated as stable inside this macro. @@ -616,8 +616,10 @@ pub struct SyntaxExtension { pub allow_internal_unsafe: bool, /// Enables the macro helper hack (`ident!(...)` -> `$crate::ident!(...)`) for this macro. pub local_inner_macros: bool, - /// The macro's feature name and tracking issue number if it is unstable. - pub unstable_feature: Option<(Symbol, u32)>, + /// The macro's stability info. + pub stability: Option, + /// The macro's deprecation info. + pub deprecation: Option, /// Names of helper attributes registered by this macro. pub helper_attrs: Vec, /// Edition of the crate in which this macro is defined. @@ -657,12 +659,13 @@ impl SyntaxExtension { /// Constructs a syntax extension with default properties. pub fn default(kind: SyntaxExtensionKind, edition: Edition) -> SyntaxExtension { SyntaxExtension { - def_info: None, + span: DUMMY_SP, default_transparency: kind.default_transparency(), allow_internal_unstable: None, allow_internal_unsafe: false, local_inner_macros: false, - unstable_feature: None, + stability: None, + deprecation: None, helper_attrs: Vec::new(), edition, kind, @@ -681,7 +684,7 @@ impl SyntaxExtension { ExpnInfo { call_site, format: self.expn_format(Symbol::intern(format)), - def_site: self.def_info.map(|(_, span)| span), + def_site: Some(self.span), default_transparency: self.default_transparency, allow_internal_unstable: self.allow_internal_unstable.clone(), allow_internal_unsafe: self.allow_internal_unsafe, @@ -738,7 +741,6 @@ pub struct ExpansionData { pub depth: usize, pub module: Rc, pub directory_ownership: DirectoryOwnership, - pub crate_span: Option, } /// One of these is made during expansion and incrementally updated as we go; @@ -768,7 +770,6 @@ impl<'a> ExtCtxt<'a> { depth: 0, module: Rc::new(ModuleData { mod_path: Vec::new(), directory: PathBuf::new() }), directory_ownership: DirectoryOwnership::Owned { relative: None }, - crate_span: None, }, expansions: FxHashMap::default(), } diff --git a/src/libsyntax/ext/derive.rs b/src/libsyntax/ext/derive.rs index 3b4243ed24f..2a56f3dd756 100644 --- a/src/libsyntax/ext/derive.rs +++ b/src/libsyntax/ext/derive.rs @@ -63,11 +63,11 @@ pub fn add_derived_markers(cx: &mut ExtCtxt<'_>, span: Span, traits: &[ast::P let span = span.with_ctxt(cx.backtrace()); item.visit_attrs(|attrs| { - if names.contains(&Symbol::intern("Eq")) && names.contains(&Symbol::intern("PartialEq")) { - let meta = cx.meta_word(span, Symbol::intern("structural_match")); + if names.contains(&sym::Eq) && names.contains(&sym::PartialEq) { + let meta = cx.meta_word(span, sym::structural_match); attrs.push(cx.attribute(span, meta)); } - if names.contains(&Symbol::intern("Copy")) { + if names.contains(&sym::Copy) { let meta = cx.meta_word(span, sym::rustc_copy_clone_marker); attrs.push(cx.attribute(span, meta)); } diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index 6fbd2ab7c43..74ef5cbe917 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -243,7 +243,6 @@ impl<'a, 'b> MacroExpander<'a, 'b> { module.directory.pop(); self.cx.root_path = module.directory.clone(); self.cx.current_expansion.module = Rc::new(module); - self.cx.current_expansion.crate_span = Some(krate.span); let orig_mod_span = krate.module.inner; @@ -488,7 +487,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> { fn expand_invoc(&mut self, invoc: Invocation, ext: &SyntaxExtension) -> Option { if invoc.fragment_kind == AstFragmentKind::ForeignItems && - !self.cx.ecfg.macros_in_extern_enabled() { + !self.cx.ecfg.macros_in_extern() { if let SyntaxExtensionKind::NonMacroAttr { .. } = ext.kind {} else { emit_feature_err(&self.cx.parse_sess, sym::macros_in_extern, invoc.span(), GateIssue::Language, @@ -668,40 +667,17 @@ impl<'a, 'b> MacroExpander<'a, 'b> { }; let path = &mac.node.path; - let validate = |this: &mut Self| { - // feature-gate the macro invocation - if let Some((feature, issue)) = ext.unstable_feature { - let crate_span = this.cx.current_expansion.crate_span.unwrap(); - // don't stability-check macros in the same crate - // (the only time this is null is for syntax extensions registered as macros) - if ext.def_info.map_or(false, |(_, def_span)| !crate_span.contains(def_span)) - && !span.allows_unstable(feature) - && this.cx.ecfg.features.map_or(true, |feats| { - // macro features will count as lib features - !feats.declared_lib_features.iter().any(|&(feat, _)| feat == feature) - }) { - let explain = format!("macro {}! is unstable", path); - emit_feature_err(this.cx.parse_sess, feature, span, - GateIssue::Library(Some(issue)), &explain); - this.cx.trace_macros_diag(); - } - } - - Ok(()) - }; - let opt_expanded = match &ext.kind { + SyntaxExtensionKind::Bang(expander) => { + self.gate_proc_macro_expansion_kind(span, kind); + let tok_result = expander.expand(self.cx, span, mac.node.stream()); + let result = self.parse_ast_fragment(tok_result, kind, path, span); + self.gate_proc_macro_expansion(span, &result); + result + } SyntaxExtensionKind::LegacyBang(expander) => { - if let Err(dummy_span) = validate(self) { - dummy_span - } else { - kind.make_from(expander.expand( - self.cx, - span, - mac.node.stream(), - ext.def_info.map(|(_, s)| s), - )) - } + let tok_result = expander.expand(self.cx, span, mac.node.stream(), Some(ext.span)); + kind.make_from(tok_result) } SyntaxExtensionKind::Attr(..) | @@ -718,14 +694,6 @@ impl<'a, 'b> MacroExpander<'a, 'b> { self.cx.trace_macros_diag(); kind.dummy(span) } - - SyntaxExtensionKind::Bang(expander) => { - self.gate_proc_macro_expansion_kind(span, kind); - let tok_result = expander.expand(self.cx, span, mac.node.stream()); - let result = self.parse_ast_fragment(tok_result, kind, path, span); - self.gate_proc_macro_expansion(span, &result); - result - } }; if opt_expanded.is_some() { @@ -951,7 +919,7 @@ impl<'a, 'b> InvocationCollector<'a, 'b> { }) .map(|i| attrs.remove(i)); if let Some(attr) = &attr { - if !self.cx.ecfg.enable_custom_inner_attributes() && + if !self.cx.ecfg.custom_inner_attributes() && attr.style == ast::AttrStyle::Inner && attr.path != sym::test { emit_feature_err(&self.cx.parse_sess, sym::custom_inner_attributes, attr.span, GateIssue::Language, @@ -1464,19 +1432,6 @@ pub struct ExpansionConfig<'feat> { pub keep_macs: bool, } -macro_rules! feature_tests { - ($( fn $getter:ident = $field:ident, )*) => { - $( - pub fn $getter(&self) -> bool { - match self.features { - Some(&Features { $field: true, .. }) => true, - _ => false, - } - } - )* - } -} - impl<'feat> ExpansionConfig<'feat> { pub fn default(crate_name: String) -> ExpansionConfig<'static> { ExpansionConfig { @@ -1490,20 +1445,13 @@ impl<'feat> ExpansionConfig<'feat> { } } - feature_tests! { - fn enable_asm = asm, - fn enable_custom_test_frameworks = custom_test_frameworks, - fn enable_global_asm = global_asm, - fn enable_log_syntax = log_syntax, - fn enable_concat_idents = concat_idents, - fn enable_trace_macros = trace_macros, - fn enable_allow_internal_unstable = allow_internal_unstable, - fn enable_format_args_nl = format_args_nl, - fn macros_in_extern_enabled = macros_in_extern, - fn proc_macro_hygiene = proc_macro_hygiene, + fn macros_in_extern(&self) -> bool { + self.features.map_or(false, |features| features.macros_in_extern) } - - fn enable_custom_inner_attributes(&self) -> bool { + fn proc_macro_hygiene(&self) -> bool { + self.features.map_or(false, |features| features.proc_macro_hygiene) + } + fn custom_inner_attributes(&self) -> bool { self.features.map_or(false, |features| features.custom_inner_attributes) } } diff --git a/src/libsyntax/ext/source_util.rs b/src/libsyntax/ext/source_util.rs index 4e2aab46542..c2ba8b983f5 100644 --- a/src/libsyntax/ext/source_util.rs +++ b/src/libsyntax/ext/source_util.rs @@ -4,7 +4,7 @@ use crate::ext::build::AstBuilder; use crate::parse::{self, token, DirectoryOwnership}; use crate::print::pprust; use crate::ptr::P; -use crate::symbol::{Symbol, sym}; +use crate::symbol::Symbol; use crate::tokenstream; use smallvec::SmallVec; @@ -41,16 +41,6 @@ pub fn expand_column(cx: &mut ExtCtxt<'_>, sp: Span, tts: &[tokenstream::TokenTr base::MacEager::expr(cx.expr_u32(topmost, loc.col.to_usize() as u32 + 1)) } -/* __rust_unstable_column!(): expands to the current column number */ -pub fn expand_column_gated(cx: &mut ExtCtxt<'_>, sp: Span, tts: &[tokenstream::TokenTree]) - -> Box { - if sp.allows_unstable(sym::__rust_unstable_column) { - expand_column(cx, sp, tts) - } else { - cx.span_fatal(sp, "the __rust_unstable_column macro is unstable"); - } -} - /// file!(): expands to the current filename */ /// The source_file (`loc.file`) contains a bunch more information we could spit /// out if we wanted. diff --git a/src/libsyntax/ext/tt/macro_rules.rs b/src/libsyntax/ext/tt/macro_rules.rs index cf3c748cd82..665c794422d 100644 --- a/src/libsyntax/ext/tt/macro_rules.rs +++ b/src/libsyntax/ext/tt/macro_rules.rs @@ -422,8 +422,6 @@ pub fn compile( }) }); - let allow_internal_unsafe = attr::contains_name(&def.attrs, sym::allow_internal_unsafe); - let mut local_inner_macros = false; if let Some(macro_export) = attr::find_by_name(&def.attrs, sym::macro_export) { if let Some(l) = macro_export.meta_item_list() { @@ -431,23 +429,15 @@ pub fn compile( } } - let unstable_feature = - attr::find_stability(&sess, &def.attrs, def.span).and_then(|stability| { - if let attr::StabilityLevel::Unstable { issue, .. } = stability.level { - Some((stability.feature, issue)) - } else { - None - } - }); - SyntaxExtension { kind: SyntaxExtensionKind::LegacyBang(expander), - def_info: Some((def.id, def.span)), + span: def.span, default_transparency, allow_internal_unstable, - allow_internal_unsafe, + allow_internal_unsafe: attr::contains_name(&def.attrs, sym::allow_internal_unsafe), local_inner_macros, - unstable_feature, + stability: attr::find_stability(&sess, &def.attrs, def.span), + deprecation: attr::find_deprecation(&sess, &def.attrs, def.span), helper_attrs: Vec::new(), edition, } diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index 2b242a71ad4..f4f0d041e64 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -1568,7 +1568,7 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[ (sym::type_length_limit, CrateLevel, template!(NameValueStr: "N"), Ungated), (sym::test_runner, CrateLevel, template!(List: "path"), Gated(Stability::Unstable, sym::custom_test_frameworks, - EXPLAIN_CUSTOM_TEST_FRAMEWORKS, + "custom test frameworks are an unstable feature", cfg_fn!(custom_test_frameworks))), ]; @@ -1819,26 +1819,6 @@ const EXPLAIN_BOX_SYNTAX: &str = pub const EXPLAIN_STMT_ATTR_SYNTAX: &str = "attributes on expressions are experimental"; -pub const EXPLAIN_ASM: &str = - "inline assembly is not stable enough for use and is subject to change"; - -pub const EXPLAIN_GLOBAL_ASM: &str = - "`global_asm!` is not stable enough for use and is subject to change"; - -pub const EXPLAIN_CUSTOM_TEST_FRAMEWORKS: &str = - "custom test frameworks are an unstable feature"; - -pub const EXPLAIN_LOG_SYNTAX: &str = - "`log_syntax!` is not stable enough for use and is subject to change"; - -pub const EXPLAIN_CONCAT_IDENTS: &str = - "`concat_idents` is not stable enough for use and is subject to change"; - -pub const EXPLAIN_FORMAT_ARGS_NL: &str = - "`format_args_nl` is only for internal language use and is subject to change"; - -pub const EXPLAIN_TRACE_MACROS: &str = - "`trace_macros` is not stable enough for use and is subject to change"; pub const EXPLAIN_ALLOW_INTERNAL_UNSTABLE: &str = "allow_internal_unstable side-steps feature gating and stability checks"; pub const EXPLAIN_ALLOW_INTERNAL_UNSAFE: &str = diff --git a/src/libsyntax/parse/lexer/mod.rs b/src/libsyntax/parse/lexer/mod.rs index 1abbf0ff1ee..d0c4e8d6a56 100644 --- a/src/libsyntax/parse/lexer/mod.rs +++ b/src/libsyntax/parse/lexer/mod.rs @@ -613,7 +613,7 @@ impl<'a> StringReader<'a> { if num_digits == 0 { self.err_span_(start_bpos, self.pos, "no valid digits found for number"); - return (token::Integer, Symbol::intern("0")); + return (token::Integer, sym::integer(0)); } // might be a float, but don't be greedy if this is actually an diff --git a/src/libsyntax_ext/asm.rs b/src/libsyntax_ext/asm.rs index b015815ac9c..c1c2732605c 100644 --- a/src/libsyntax_ext/asm.rs +++ b/src/libsyntax_ext/asm.rs @@ -8,7 +8,6 @@ use errors::DiagnosticBuilder; use syntax::ast; use syntax::ext::base::{self, *}; -use syntax::feature_gate; use syntax::parse; use syntax::parse::token::{self, Token}; use syntax::ptr::P; @@ -46,14 +45,6 @@ pub fn expand_asm<'cx>(cx: &'cx mut ExtCtxt<'_>, sp: Span, tts: &[tokenstream::TokenTree]) -> Box { - if !cx.ecfg.enable_asm() { - feature_gate::emit_feature_err(&cx.parse_sess, - sym::asm, - sp, - feature_gate::GateIssue::Language, - feature_gate::EXPLAIN_ASM); - } - let mut inline_asm = match parse_inline_asm(cx, sp, tts) { Ok(Some(inline_asm)) => inline_asm, Ok(None) => return DummyResult::expr(sp), diff --git a/src/libsyntax_ext/concat_idents.rs b/src/libsyntax_ext/concat_idents.rs index 8f061abc77b..df919141603 100644 --- a/src/libsyntax_ext/concat_idents.rs +++ b/src/libsyntax_ext/concat_idents.rs @@ -2,25 +2,16 @@ use rustc_data_structures::thin_vec::ThinVec; use syntax::ast; use syntax::ext::base::{self, *}; -use syntax::feature_gate; use syntax::parse::token::{self, Token}; use syntax::ptr::P; use syntax_pos::Span; -use syntax_pos::symbol::{Symbol, sym}; +use syntax_pos::symbol::Symbol; use syntax::tokenstream::TokenTree; pub fn expand_syntax_ext<'cx>(cx: &'cx mut ExtCtxt<'_>, sp: Span, tts: &[TokenTree]) -> Box { - if !cx.ecfg.enable_concat_idents() { - feature_gate::emit_feature_err(&cx.parse_sess, - sym::concat_idents, - sp, - feature_gate::GateIssue::Language, - feature_gate::EXPLAIN_CONCAT_IDENTS); - } - if tts.is_empty() { cx.span_err(sp, "concat_idents! takes 1 or more arguments."); return DummyResult::any(sp); diff --git a/src/libsyntax_ext/deriving/decodable.rs b/src/libsyntax_ext/deriving/decodable.rs index d773f3ff7bc..8009f42b8cf 100644 --- a/src/libsyntax_ext/deriving/decodable.rs +++ b/src/libsyntax_ext/deriving/decodable.rs @@ -3,7 +3,6 @@ use crate::deriving::{self, pathvec_std}; use crate::deriving::generic::*; use crate::deriving::generic::ty::*; -use crate::deriving::warn_if_deprecated; use syntax::ast; use syntax::ast::{Expr, MetaItem, Mutability}; @@ -26,7 +25,6 @@ pub fn expand_deriving_decodable(cx: &mut ExtCtxt<'_>, mitem: &MetaItem, item: &Annotatable, push: &mut dyn FnMut(Annotatable)) { - warn_if_deprecated(cx, span, "Decodable"); expand_deriving_decodable_imp(cx, span, mitem, item, push, "serialize") } diff --git a/src/libsyntax_ext/deriving/encodable.rs b/src/libsyntax_ext/deriving/encodable.rs index faaedba3e77..cd89a42cf82 100644 --- a/src/libsyntax_ext/deriving/encodable.rs +++ b/src/libsyntax_ext/deriving/encodable.rs @@ -85,7 +85,6 @@ use crate::deriving::{self, pathvec_std}; use crate::deriving::generic::*; use crate::deriving::generic::ty::*; -use crate::deriving::warn_if_deprecated; use syntax::ast::{Expr, ExprKind, MetaItem, Mutability}; use syntax::ext::base::{Annotatable, ExtCtxt}; @@ -107,7 +106,6 @@ pub fn expand_deriving_encodable(cx: &mut ExtCtxt<'_>, mitem: &MetaItem, item: &Annotatable, push: &mut dyn FnMut(Annotatable)) { - warn_if_deprecated(cx, span, "Encodable"); expand_deriving_encodable_imp(cx, span, mitem, item, push, "serialize") } diff --git a/src/libsyntax_ext/deriving/mod.rs b/src/libsyntax_ext/deriving/mod.rs index aa9913d436c..e491e93256d 100644 --- a/src/libsyntax_ext/deriving/mod.rs +++ b/src/libsyntax_ext/deriving/mod.rs @@ -2,6 +2,7 @@ use rustc_data_structures::sync::Lrc; use syntax::ast::{self, MetaItem}; +use syntax::attr::Deprecation; use syntax::edition::Edition; use syntax::ext::base::{Annotatable, ExtCtxt, Resolver, MultiItemModifier}; use syntax::ext::base::{SyntaxExtension, SyntaxExtensionKind}; @@ -60,10 +61,10 @@ impl MultiItemModifier for BuiltinDerive { } macro_rules! derive_traits { - ($( $name:expr => $func:path, )+) => { + ($( [$deprecation:expr] $name:ident => $func:path, )+) => { pub fn is_builtin_trait(name: ast::Name) -> bool { - match &*name.as_str() { - $( $name )|+ => true, + match name { + $( sym::$name )|+ => true, _ => false, } } @@ -79,8 +80,12 @@ macro_rules! derive_traits { $( resolver.add_builtin( - ast::Ident::with_empty_ctxt(Symbol::intern($name)), + ast::Ident::with_empty_ctxt(sym::$name), Lrc::new(SyntaxExtension { + deprecation: $deprecation.map(|msg| Deprecation { + since: Some(Symbol::intern("1.0.0")), + note: Some(Symbol::intern(msg)), + }), allow_internal_unstable: allow_internal_unstable.clone(), ..SyntaxExtension::default( SyntaxExtensionKind::LegacyDerive(Box::new(BuiltinDerive($func))), @@ -94,42 +99,41 @@ macro_rules! derive_traits { } derive_traits! { - "Clone" => clone::expand_deriving_clone, + [None] + Clone => clone::expand_deriving_clone, - "Hash" => hash::expand_deriving_hash, + [None] + Hash => hash::expand_deriving_hash, - "RustcEncodable" => encodable::expand_deriving_rustc_encodable, + [None] + RustcEncodable => encodable::expand_deriving_rustc_encodable, - "RustcDecodable" => decodable::expand_deriving_rustc_decodable, + [None] + RustcDecodable => decodable::expand_deriving_rustc_decodable, - "PartialEq" => partial_eq::expand_deriving_partial_eq, - "Eq" => eq::expand_deriving_eq, - "PartialOrd" => partial_ord::expand_deriving_partial_ord, - "Ord" => ord::expand_deriving_ord, + [None] + PartialEq => partial_eq::expand_deriving_partial_eq, + [None] + Eq => eq::expand_deriving_eq, + [None] + PartialOrd => partial_ord::expand_deriving_partial_ord, + [None] + Ord => ord::expand_deriving_ord, - "Debug" => debug::expand_deriving_debug, + [None] + Debug => debug::expand_deriving_debug, - "Default" => default::expand_deriving_default, + [None] + Default => default::expand_deriving_default, - "Copy" => bounds::expand_deriving_copy, + [None] + Copy => bounds::expand_deriving_copy, // deprecated - "Encodable" => encodable::expand_deriving_encodable, - "Decodable" => decodable::expand_deriving_decodable, -} - -#[inline] // because `name` is a compile-time constant -fn warn_if_deprecated(ecx: &mut ExtCtxt<'_>, sp: Span, name: &str) { - if let Some(replacement) = match name { - "Encodable" => Some("RustcEncodable"), - "Decodable" => Some("RustcDecodable"), - _ => None, - } { - ecx.span_warn(sp, - &format!("derive({}) is deprecated in favor of derive({})", - name, - replacement)); - } + [Some("derive(Encodable) is deprecated in favor of derive(RustcEncodable)")] + Encodable => encodable::expand_deriving_encodable, + [Some("derive(Decodable) is deprecated in favor of derive(RustcDecodable)")] + Decodable => decodable::expand_deriving_decodable, } /// Construct a name for the inner type parameter that can't collide with any type parameters of diff --git a/src/libsyntax_ext/format.rs b/src/libsyntax_ext/format.rs index a5f96559ca8..c3dbd48cc6e 100644 --- a/src/libsyntax_ext/format.rs +++ b/src/libsyntax_ext/format.rs @@ -9,7 +9,6 @@ use errors::Applicability; use syntax::ast; use syntax::ext::base::{self, *}; use syntax::ext::build::AstBuilder; -use syntax::feature_gate; use syntax::parse::token; use syntax::ptr::P; use syntax::symbol::{Symbol, sym}; @@ -686,14 +685,16 @@ impl<'a, 'b> Context<'a, 'b> { } } -pub fn expand_format_args<'cx>(ecx: &'cx mut ExtCtxt<'_>, - mut sp: Span, - tts: &[tokenstream::TokenTree]) - -> Box { +fn expand_format_args_impl<'cx>( + ecx: &'cx mut ExtCtxt<'_>, + mut sp: Span, + tts: &[tokenstream::TokenTree], + nl: bool, +) -> Box { sp = sp.apply_mark(ecx.current_expansion.mark); match parse_args(ecx, sp, tts) { Ok((efmt, args, names)) => { - MacEager::expr(expand_preparsed_format_args(ecx, sp, efmt, args, names, false)) + MacEager::expr(expand_preparsed_format_args(ecx, sp, efmt, args, names, nl)) } Err(mut err) => { err.emit(); @@ -702,34 +703,20 @@ pub fn expand_format_args<'cx>(ecx: &'cx mut ExtCtxt<'_>, } } -pub fn expand_format_args_nl<'cx>( +pub fn expand_format_args<'cx>( ecx: &'cx mut ExtCtxt<'_>, - mut sp: Span, + sp: Span, tts: &[tokenstream::TokenTree], ) -> Box { - //if !ecx.ecfg.enable_allow_internal_unstable() { + expand_format_args_impl(ecx, sp, tts, false) +} - // For some reason, the only one that actually works for `println` is the first check - if !sp.allows_unstable(sym::format_args_nl) // the span is marked `#[allow_insternal_unsable]` - && !ecx.ecfg.enable_allow_internal_unstable() // NOTE: when is this enabled? - && !ecx.ecfg.enable_format_args_nl() // enabled using `#[feature(format_args_nl]` - { - feature_gate::emit_feature_err(&ecx.parse_sess, - sym::format_args_nl, - sp, - feature_gate::GateIssue::Language, - feature_gate::EXPLAIN_FORMAT_ARGS_NL); - } - sp = sp.apply_mark(ecx.current_expansion.mark); - match parse_args(ecx, sp, tts) { - Ok((efmt, args, names)) => { - MacEager::expr(expand_preparsed_format_args(ecx, sp, efmt, args, names, true)) - } - Err(mut err) => { - err.emit(); - DummyResult::expr(sp) - } - } +pub fn expand_format_args_nl<'cx>( + ecx: &'cx mut ExtCtxt<'_>, + sp: Span, + tts: &[tokenstream::TokenTree], +) -> Box { + expand_format_args_impl(ecx, sp, tts, true) } /// Take the various parts of `format_args!(efmt, args..., name=names...)` diff --git a/src/libsyntax_ext/global_asm.rs b/src/libsyntax_ext/global_asm.rs index 5220143a3cc..112192fac5d 100644 --- a/src/libsyntax_ext/global_asm.rs +++ b/src/libsyntax_ext/global_asm.rs @@ -13,27 +13,15 @@ use errors::DiagnosticBuilder; use syntax::ast; use syntax::source_map::respan; use syntax::ext::base::{self, *}; -use syntax::feature_gate; use syntax::parse::token; use syntax::ptr::P; -use syntax::symbol::{Symbol, sym}; use syntax_pos::Span; use syntax::tokenstream; use smallvec::smallvec; -pub const MACRO: Symbol = sym::global_asm; - pub fn expand_global_asm<'cx>(cx: &'cx mut ExtCtxt<'_>, sp: Span, tts: &[tokenstream::TokenTree]) -> Box { - if !cx.ecfg.enable_global_asm() { - feature_gate::emit_feature_err(&cx.parse_sess, - MACRO, - sp, - feature_gate::GateIssue::Language, - feature_gate::EXPLAIN_GLOBAL_ASM); - } - match parse_global_asm(cx, sp, tts) { Ok(Some(global_asm)) => { MacEager::items(smallvec![P(ast::Item { diff --git a/src/libsyntax_ext/lib.rs b/src/libsyntax_ext/lib.rs index 77b69ddd303..62530f4fe7b 100644 --- a/src/libsyntax_ext/lib.rs +++ b/src/libsyntax_ext/lib.rs @@ -41,12 +41,29 @@ pub mod proc_macro_impl; use rustc_data_structures::sync::Lrc; use syntax::ast; - +use syntax::attr::Stability; use syntax::ext::base::MacroExpanderFn; use syntax::ext::base::{NamedSyntaxExtension, SyntaxExtension, SyntaxExtensionKind}; use syntax::edition::Edition; use syntax::symbol::{sym, Symbol}; +const EXPLAIN_ASM: &str = + "inline assembly is not stable enough for use and is subject to change"; +const EXPLAIN_GLOBAL_ASM: &str = + "`global_asm!` is not stable enough for use and is subject to change"; +const EXPLAIN_CUSTOM_TEST_FRAMEWORKS: &str = + "custom test frameworks are an unstable feature"; +const EXPLAIN_LOG_SYNTAX: &str = + "`log_syntax!` is not stable enough for use and is subject to change"; +const EXPLAIN_CONCAT_IDENTS: &str = + "`concat_idents` is not stable enough for use and is subject to change"; +const EXPLAIN_FORMAT_ARGS_NL: &str = + "`format_args_nl` is only for internal language use and is subject to change"; +const EXPLAIN_TRACE_MACROS: &str = + "`trace_macros` is not stable enough for use and is subject to change"; +const EXPLAIN_UNSTABLE_COLUMN: &str = + "internal implementation detail of the `column` macro"; + pub fn register_builtins(resolver: &mut dyn syntax::ext::base::Resolver, user_exts: Vec, edition: Edition) { @@ -57,23 +74,27 @@ pub fn register_builtins(resolver: &mut dyn syntax::ext::base::Resolver, }; macro_rules! register { ($( $name:ident: $f:expr, )*) => { $( - register(Symbol::intern(stringify!($name)), SyntaxExtension::default( + register(sym::$name, SyntaxExtension::default( SyntaxExtensionKind::LegacyBang(Box::new($f as MacroExpanderFn)), edition )); )* } } - macro_rules! register_attr { - ($( $name:ident: $f:expr, )*) => { $( - register(Symbol::intern(stringify!($name)), SyntaxExtension::default( - SyntaxExtensionKind::LegacyAttr(Box::new($f)), edition - )); + macro_rules! register_unstable { + ($( [$feature:expr, $reason:expr, $issue:expr] $name:ident: $f:expr, )*) => { $( + register(sym::$name, SyntaxExtension { + stability: Some(Stability::unstable( + $feature, Some(Symbol::intern($reason)), $issue + )), + ..SyntaxExtension::default( + SyntaxExtensionKind::LegacyBang(Box::new($f as MacroExpanderFn)), edition + ) + }); )* } } use syntax::ext::source_util::*; register! { line: expand_line, - __rust_unstable_column: expand_column_gated, column: expand_column, file: expand_file, stringify: expand_stringify, @@ -81,35 +102,60 @@ pub fn register_builtins(resolver: &mut dyn syntax::ext::base::Resolver, include_str: expand_include_str, include_bytes: expand_include_bytes, module_path: expand_mod, - - asm: asm::expand_asm, - global_asm: global_asm::expand_global_asm, cfg: cfg::expand_cfg, concat: concat::expand_syntax_ext, - concat_idents: concat_idents::expand_syntax_ext, env: env::expand_env, option_env: env::expand_option_env, - log_syntax: log_syntax::expand_syntax_ext, - trace_macros: trace_macros::expand_trace_macros, compile_error: compile_error::expand_compile_error, assert: assert::expand_assert, } - register_attr! { - test_case: test_case::expand, - test: test::expand_test, - bench: test::expand_bench, + register_unstable! { + [sym::__rust_unstable_column, EXPLAIN_UNSTABLE_COLUMN, 0] + __rust_unstable_column: expand_column, + [sym::asm, EXPLAIN_ASM, 29722] + asm: asm::expand_asm, + [sym::global_asm, EXPLAIN_GLOBAL_ASM, 35119] + global_asm: global_asm::expand_global_asm, + [sym::concat_idents, EXPLAIN_CONCAT_IDENTS, 29599] + concat_idents: concat_idents::expand_syntax_ext, + [sym::log_syntax, EXPLAIN_LOG_SYNTAX, 29598] + log_syntax: log_syntax::expand_syntax_ext, + [sym::trace_macros, EXPLAIN_TRACE_MACROS, 29598] + trace_macros: trace_macros::expand_trace_macros, } + register(sym::test_case, SyntaxExtension { + stability: Some(Stability::unstable( + sym::custom_test_frameworks, + Some(Symbol::intern(EXPLAIN_CUSTOM_TEST_FRAMEWORKS)), + 50297, + )), + ..SyntaxExtension::default( + SyntaxExtensionKind::LegacyAttr(Box::new(test_case::expand)), edition + ) + }); + register(sym::test, SyntaxExtension::default( + SyntaxExtensionKind::LegacyAttr(Box::new(test::expand_test)), edition + )); + register(sym::bench, SyntaxExtension::default( + SyntaxExtensionKind::LegacyAttr(Box::new(test::expand_bench)), edition + )); + // format_args uses `unstable` things internally. let allow_internal_unstable = Some([sym::fmt_internals][..].into()); - register(Symbol::intern("format_args"), SyntaxExtension { + register(sym::format_args, SyntaxExtension { allow_internal_unstable: allow_internal_unstable.clone(), ..SyntaxExtension::default( SyntaxExtensionKind::LegacyBang(Box::new(format::expand_format_args)), edition ) }); register(sym::format_args_nl, SyntaxExtension { + stability: Some(Stability::unstable( + sym::format_args_nl, + Some(Symbol::intern(EXPLAIN_FORMAT_ARGS_NL)), + 0, + )), allow_internal_unstable, ..SyntaxExtension::default( SyntaxExtensionKind::LegacyBang(Box::new(format::expand_format_args_nl)), edition diff --git a/src/libsyntax_ext/log_syntax.rs b/src/libsyntax_ext/log_syntax.rs index 1be3990837c..cbdfd08b497 100644 --- a/src/libsyntax_ext/log_syntax.rs +++ b/src/libsyntax_ext/log_syntax.rs @@ -1,22 +1,12 @@ use syntax::ext::base; -use syntax::feature_gate; use syntax::print; use syntax::tokenstream; -use syntax::symbol::sym; use syntax_pos; -pub fn expand_syntax_ext<'cx>(cx: &'cx mut base::ExtCtxt<'_>, +pub fn expand_syntax_ext<'cx>(_cx: &'cx mut base::ExtCtxt<'_>, sp: syntax_pos::Span, tts: &[tokenstream::TokenTree]) -> Box { - if !cx.ecfg.enable_log_syntax() { - feature_gate::emit_feature_err(&cx.parse_sess, - sym::log_syntax, - sp, - feature_gate::GateIssue::Language, - feature_gate::EXPLAIN_LOG_SYNTAX); - } - println!("{}", print::pprust::tts_to_string(tts)); // any so that `log_syntax` can be invoked as an expression and item. diff --git a/src/libsyntax_ext/proc_macro_server.rs b/src/libsyntax_ext/proc_macro_server.rs index c9d99e5831a..e5027354527 100644 --- a/src/libsyntax_ext/proc_macro_server.rs +++ b/src/libsyntax_ext/proc_macro_server.rs @@ -548,10 +548,10 @@ impl server::Literal for Rustc<'_> { self.lit(token::Float, Symbol::intern(n), None) } fn f32(&mut self, n: &str) -> Self::Literal { - self.lit(token::Float, Symbol::intern(n), Some(Symbol::intern("f32"))) + self.lit(token::Float, Symbol::intern(n), Some(sym::f32)) } fn f64(&mut self, n: &str) -> Self::Literal { - self.lit(token::Float, Symbol::intern(n), Some(Symbol::intern("f64"))) + self.lit(token::Float, Symbol::intern(n), Some(sym::f64)) } fn string(&mut self, string: &str) -> Self::Literal { let mut escaped = String::new(); diff --git a/src/libsyntax_ext/test_case.rs b/src/libsyntax_ext/test_case.rs index 6e3bc05b65e..186673c142f 100644 --- a/src/libsyntax_ext/test_case.rs +++ b/src/libsyntax_ext/test_case.rs @@ -17,7 +17,6 @@ use syntax::source_map::respan; use syntax::symbol::sym; use syntax_pos::Span; use syntax::source_map::{ExpnInfo, MacroAttribute}; -use syntax::feature_gate; pub fn expand( ecx: &mut ExtCtxt<'_>, @@ -25,14 +24,6 @@ pub fn expand( _meta_item: &ast::MetaItem, anno_item: Annotatable ) -> Vec { - if !ecx.ecfg.enable_custom_test_frameworks() { - feature_gate::emit_feature_err(&ecx.parse_sess, - sym::custom_test_frameworks, - attr_sp, - feature_gate::GateIssue::Language, - feature_gate::EXPLAIN_CUSTOM_TEST_FRAMEWORKS); - } - if !ecx.ecfg.should_test { return vec![]; } let sp = { diff --git a/src/libsyntax_ext/trace_macros.rs b/src/libsyntax_ext/trace_macros.rs index 512513e9b41..0dce8a36f4c 100644 --- a/src/libsyntax_ext/trace_macros.rs +++ b/src/libsyntax_ext/trace_macros.rs @@ -1,6 +1,5 @@ use syntax::ext::base::{self, ExtCtxt}; -use syntax::feature_gate; -use syntax::symbol::{kw, sym}; +use syntax::symbol::kw; use syntax_pos::Span; use syntax::tokenstream::TokenTree; @@ -8,14 +7,6 @@ pub fn expand_trace_macros(cx: &mut ExtCtxt<'_>, sp: Span, tt: &[TokenTree]) -> Box { - if !cx.ecfg.enable_trace_macros() { - feature_gate::emit_feature_err(&cx.parse_sess, - sym::trace_macros, - sp, - feature_gate::GateIssue::Language, - feature_gate::EXPLAIN_TRACE_MACROS); - } - match tt { [TokenTree::Token(token)] if token.is_keyword(kw::True) => { cx.set_trace_macros(true); diff --git a/src/libsyntax_pos/symbol.rs b/src/libsyntax_pos/symbol.rs index 410f4b36b67..8bb622a6855 100644 --- a/src/libsyntax_pos/symbol.rs +++ b/src/libsyntax_pos/symbol.rs @@ -141,6 +141,7 @@ symbols! { ArgumentV1, arm_target_feature, asm, + assert, associated_consts, associated_type_bounds, associated_type_defaults, @@ -184,8 +185,10 @@ symbols! { cmp, cmpxchg16b_target_feature, cold, + column, compile_error, compiler_builtins, + concat, concat_idents, conservative_impl_trait, console, @@ -203,6 +206,7 @@ symbols! { contents, context, convert, + Copy, copy_closures, core, core_intrinsics, @@ -217,8 +221,10 @@ symbols! { custom_inner_attributes, custom_test_frameworks, c_variadic, + Debug, declare_lint_pass, decl_macro, + Decodable, Default, default_lib_allocator, default_type_parameter_fallback, @@ -253,9 +259,12 @@ symbols! { eh_personality, eh_unwind_resume, enable, + Encodable, + env, eq, err, Err, + Eq, Equal, except, exclusive_range_pattern, @@ -284,6 +293,7 @@ symbols! { fmt_internals, fn_must_use, forbid, + format_args, format_args_nl, from, From, @@ -335,6 +345,8 @@ symbols! { index_mut, in_band_lifetimes, include, + include_bytes, + include_str, inclusive_range_syntax, infer_outlives_requirements, infer_static_outlives_requirements, @@ -363,6 +375,7 @@ symbols! { lhs, lib, lifetime, + line, link, linkage, link_args, @@ -402,6 +415,7 @@ symbols! { mips_target_feature, mmx_target_feature, module, + module_path, more_struct_aliases, movbe_target_feature, must_use, @@ -447,6 +461,7 @@ symbols! { optin_builtin_traits, option, Option, + option_env, opt_out_copy, or, Ord, @@ -462,6 +477,7 @@ symbols! { parent_trait, partial_cmp, param_attrs, + PartialEq, PartialOrd, passes, pat, @@ -532,6 +548,8 @@ symbols! { rust_2018_preview, rust_begin_unwind, rustc, + RustcDecodable, + RustcEncodable, rustc_allocator, rustc_allocator_nounwind, rustc_allow_const_fn_ptr, @@ -591,7 +609,6 @@ symbols! { _Self, self_in_typedefs, self_struct_ctor, - Send, should_panic, simd, simd_ffi, @@ -613,6 +630,7 @@ symbols! { static_recursion, std, str, + stringify, stmt, stmt_expr_attributes, stop_after_dataflow, diff --git a/src/test/run-pass/macros/macro-stability.rs b/src/test/run-pass/macros/macro-stability.rs index b471aa655e9..817bddf6956 100644 --- a/src/test/run-pass/macros/macro-stability.rs +++ b/src/test/run-pass/macros/macro-stability.rs @@ -1,7 +1,7 @@ // run-pass // aux-build:unstable-macros.rs -#![feature(unstable_macros)] +#![feature(unstable_macros, local_unstable)] #[macro_use] extern crate unstable_macros; diff --git a/src/test/ui-fulldeps/deprecated-derive.stderr b/src/test/ui-fulldeps/deprecated-derive.stderr index 27762910e6a..9afb3a35cb4 100644 --- a/src/test/ui-fulldeps/deprecated-derive.stderr +++ b/src/test/ui-fulldeps/deprecated-derive.stderr @@ -1,6 +1,8 @@ -warning: derive(Encodable) is deprecated in favor of derive(RustcEncodable) +warning: use of deprecated item 'Encodable': derive(Encodable) is deprecated in favor of derive(RustcEncodable) --> $DIR/deprecated-derive.rs:8:10 | LL | #[derive(Encodable)] | ^^^^^^^^^ + | + = note: #[warn(deprecated)] on by default diff --git a/src/test/ui/feature-gates/feature-gate-asm.stderr b/src/test/ui/feature-gates/feature-gate-asm.stderr index ccaf34f0169..30a7582a92b 100644 --- a/src/test/ui/feature-gates/feature-gate-asm.stderr +++ b/src/test/ui/feature-gates/feature-gate-asm.stderr @@ -1,4 +1,4 @@ -error[E0658]: inline assembly is not stable enough for use and is subject to change +error[E0658]: use of unstable library feature 'asm': inline assembly is not stable enough for use and is subject to change --> $DIR/feature-gate-asm.rs:3:9 | LL | asm!(""); diff --git a/src/test/ui/feature-gates/feature-gate-asm2.stderr b/src/test/ui/feature-gates/feature-gate-asm2.stderr index cafe2be9d0b..8f4c6806a97 100644 --- a/src/test/ui/feature-gates/feature-gate-asm2.stderr +++ b/src/test/ui/feature-gates/feature-gate-asm2.stderr @@ -1,4 +1,4 @@ -error[E0658]: inline assembly is not stable enough for use and is subject to change +error[E0658]: use of unstable library feature 'asm': inline assembly is not stable enough for use and is subject to change --> $DIR/feature-gate-asm2.rs:5:26 | LL | println!("{:?}", asm!("")); diff --git a/src/test/ui/feature-gates/feature-gate-concat_idents.stderr b/src/test/ui/feature-gates/feature-gate-concat_idents.stderr index be8c727e2be..2a1e5f54592 100644 --- a/src/test/ui/feature-gates/feature-gate-concat_idents.stderr +++ b/src/test/ui/feature-gates/feature-gate-concat_idents.stderr @@ -1,4 +1,4 @@ -error[E0658]: `concat_idents` is not stable enough for use and is subject to change +error[E0658]: use of unstable library feature 'concat_idents': `concat_idents` is not stable enough for use and is subject to change --> $DIR/feature-gate-concat_idents.rs:5:13 | LL | let a = concat_idents!(X, Y_1); @@ -7,7 +7,7 @@ LL | let a = concat_idents!(X, Y_1); = note: for more information, see https://github.com/rust-lang/rust/issues/29599 = help: add #![feature(concat_idents)] to the crate attributes to enable -error[E0658]: `concat_idents` is not stable enough for use and is subject to change +error[E0658]: use of unstable library feature 'concat_idents': `concat_idents` is not stable enough for use and is subject to change --> $DIR/feature-gate-concat_idents.rs:6:13 | LL | let b = concat_idents!(X, Y_2); diff --git a/src/test/ui/feature-gates/feature-gate-concat_idents2.stderr b/src/test/ui/feature-gates/feature-gate-concat_idents2.stderr index 864ee63b201..0dc6c13734e 100644 --- a/src/test/ui/feature-gates/feature-gate-concat_idents2.stderr +++ b/src/test/ui/feature-gates/feature-gate-concat_idents2.stderr @@ -1,4 +1,4 @@ -error[E0658]: `concat_idents` is not stable enough for use and is subject to change +error[E0658]: use of unstable library feature 'concat_idents': `concat_idents` is not stable enough for use and is subject to change --> $DIR/feature-gate-concat_idents2.rs:4:5 | LL | concat_idents!(a, b); diff --git a/src/test/ui/feature-gates/feature-gate-concat_idents3.stderr b/src/test/ui/feature-gates/feature-gate-concat_idents3.stderr index cb8725ab566..543570f0afc 100644 --- a/src/test/ui/feature-gates/feature-gate-concat_idents3.stderr +++ b/src/test/ui/feature-gates/feature-gate-concat_idents3.stderr @@ -1,4 +1,4 @@ -error[E0658]: `concat_idents` is not stable enough for use and is subject to change +error[E0658]: use of unstable library feature 'concat_idents': `concat_idents` is not stable enough for use and is subject to change --> $DIR/feature-gate-concat_idents3.rs:7:20 | LL | assert_eq!(10, concat_idents!(X, Y_1)); @@ -7,7 +7,7 @@ LL | assert_eq!(10, concat_idents!(X, Y_1)); = note: for more information, see https://github.com/rust-lang/rust/issues/29599 = help: add #![feature(concat_idents)] to the crate attributes to enable -error[E0658]: `concat_idents` is not stable enough for use and is subject to change +error[E0658]: use of unstable library feature 'concat_idents': `concat_idents` is not stable enough for use and is subject to change --> $DIR/feature-gate-concat_idents3.rs:8:20 | LL | assert_eq!(20, concat_idents!(X, Y_2)); diff --git a/src/test/ui/feature-gates/feature-gate-custom_test_frameworks.rs b/src/test/ui/feature-gates/feature-gate-custom_test_frameworks.rs index 0a200497939..83bb153ba08 100644 --- a/src/test/ui/feature-gates/feature-gate-custom_test_frameworks.rs +++ b/src/test/ui/feature-gates/feature-gate-custom_test_frameworks.rs @@ -1,3 +1,6 @@ #![test_runner(main)] //~ ERROR custom test frameworks are an unstable feature +#[test_case] //~ ERROR custom test frameworks are an unstable feature +fn f() {} + fn main() {} diff --git a/src/test/ui/feature-gates/feature-gate-custom_test_frameworks.stderr b/src/test/ui/feature-gates/feature-gate-custom_test_frameworks.stderr index e288af54cb2..31ff7aebe3a 100644 --- a/src/test/ui/feature-gates/feature-gate-custom_test_frameworks.stderr +++ b/src/test/ui/feature-gates/feature-gate-custom_test_frameworks.stderr @@ -1,3 +1,12 @@ +error[E0658]: use of unstable library feature 'custom_test_frameworks': custom test frameworks are an unstable feature + --> $DIR/feature-gate-custom_test_frameworks.rs:3:1 + | +LL | #[test_case] + | ^^^^^^^^^^^^ + | + = note: for more information, see https://github.com/rust-lang/rust/issues/50297 + = help: add #![feature(custom_test_frameworks)] to the crate attributes to enable + error[E0658]: custom test frameworks are an unstable feature --> $DIR/feature-gate-custom_test_frameworks.rs:1:1 | @@ -7,6 +16,6 @@ LL | #![test_runner(main)] = note: for more information, see https://github.com/rust-lang/rust/issues/50297 = help: add #![feature(custom_test_frameworks)] to the crate attributes to enable -error: aborting due to previous error +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/feature-gates/feature-gate-format_args_nl.stderr b/src/test/ui/feature-gates/feature-gate-format_args_nl.stderr index 58d2c790ffe..5cf48d8749c 100644 --- a/src/test/ui/feature-gates/feature-gate-format_args_nl.stderr +++ b/src/test/ui/feature-gates/feature-gate-format_args_nl.stderr @@ -1,4 +1,4 @@ -error[E0658]: `format_args_nl` is only for internal language use and is subject to change +error[E0658]: use of unstable library feature 'format_args_nl': `format_args_nl` is only for internal language use and is subject to change --> $DIR/feature-gate-format_args_nl.rs:2:5 | LL | format_args_nl!(""); diff --git a/src/test/ui/feature-gates/feature-gate-global_asm.stderr b/src/test/ui/feature-gates/feature-gate-global_asm.stderr index 7d8abac3990..c65f8d87a6a 100644 --- a/src/test/ui/feature-gates/feature-gate-global_asm.stderr +++ b/src/test/ui/feature-gates/feature-gate-global_asm.stderr @@ -1,4 +1,4 @@ -error[E0658]: `global_asm!` is not stable enough for use and is subject to change +error[E0658]: use of unstable library feature 'global_asm': `global_asm!` is not stable enough for use and is subject to change --> $DIR/feature-gate-global_asm.rs:1:1 | LL | global_asm!(""); diff --git a/src/test/ui/feature-gates/feature-gate-log_syntax.stderr b/src/test/ui/feature-gates/feature-gate-log_syntax.stderr index 67bd48d3bed..f6a07616c53 100644 --- a/src/test/ui/feature-gates/feature-gate-log_syntax.stderr +++ b/src/test/ui/feature-gates/feature-gate-log_syntax.stderr @@ -1,4 +1,4 @@ -error[E0658]: `log_syntax!` is not stable enough for use and is subject to change +error[E0658]: use of unstable library feature 'log_syntax': `log_syntax!` is not stable enough for use and is subject to change --> $DIR/feature-gate-log_syntax.rs:2:5 | LL | log_syntax!() diff --git a/src/test/ui/feature-gates/feature-gate-log_syntax2.stderr b/src/test/ui/feature-gates/feature-gate-log_syntax2.stderr index ff0fa343c84..cfc2beb8087 100644 --- a/src/test/ui/feature-gates/feature-gate-log_syntax2.stderr +++ b/src/test/ui/feature-gates/feature-gate-log_syntax2.stderr @@ -1,4 +1,4 @@ -error[E0658]: `log_syntax!` is not stable enough for use and is subject to change +error[E0658]: use of unstable library feature 'log_syntax': `log_syntax!` is not stable enough for use and is subject to change --> $DIR/feature-gate-log_syntax2.rs:4:22 | LL | println!("{:?}", log_syntax!()); diff --git a/src/test/ui/feature-gates/feature-gate-trace_macros.stderr b/src/test/ui/feature-gates/feature-gate-trace_macros.stderr index bcce31d873b..e08b173ae84 100644 --- a/src/test/ui/feature-gates/feature-gate-trace_macros.stderr +++ b/src/test/ui/feature-gates/feature-gate-trace_macros.stderr @@ -1,4 +1,4 @@ -error[E0658]: `trace_macros` is not stable enough for use and is subject to change +error[E0658]: use of unstable library feature 'trace_macros': `trace_macros` is not stable enough for use and is subject to change --> $DIR/feature-gate-trace_macros.rs:2:5 | LL | trace_macros!(true); diff --git a/src/test/ui/macros/auxiliary/deprecated-macros.rs b/src/test/ui/macros/auxiliary/deprecated-macros.rs new file mode 100644 index 00000000000..657a7252a36 --- /dev/null +++ b/src/test/ui/macros/auxiliary/deprecated-macros.rs @@ -0,0 +1,3 @@ +#[deprecated(since = "1.0.0", note = "deprecation note")] +#[macro_export] +macro_rules! deprecated_macro{ () => () } diff --git a/src/test/ui/macros/auxiliary/unstable-macros.rs b/src/test/ui/macros/auxiliary/unstable-macros.rs index b8d580702c9..e928dc705d7 100644 --- a/src/test/ui/macros/auxiliary/unstable-macros.rs +++ b/src/test/ui/macros/auxiliary/unstable-macros.rs @@ -1,6 +1,16 @@ +#![feature(decl_macro)] #![feature(staged_api)] #![stable(feature = "unit_test", since = "1.0.0")] #[unstable(feature = "unstable_macros", issue = "0")] #[macro_export] macro_rules! unstable_macro{ () => () } + +#[stable(feature = "deprecated_macros", since = "1.0.0")] +#[rustc_deprecated(since = "1.0.0", reason = "deprecation reason")] +#[macro_export] +macro_rules! deprecated_macro{ () => () } + +// FIXME: Cannot use a `pub` macro 2.0 in a staged API crate due to reachability issues. +// #[unstable(feature = "unstable_macros", issue = "0")] +// pub macro unstable_macro_modern() {} diff --git a/src/test/ui/macros/macro-deprecation.rs b/src/test/ui/macros/macro-deprecation.rs new file mode 100644 index 00000000000..9636b48c2da --- /dev/null +++ b/src/test/ui/macros/macro-deprecation.rs @@ -0,0 +1,13 @@ +// check-pass +// aux-build:deprecated-macros.rs + +#[macro_use] extern crate deprecated_macros; + +#[deprecated(since = "1.0.0", note = "local deprecation note")] +#[macro_export] +macro_rules! local_deprecated{ () => () } + +fn main() { + local_deprecated!(); //~ WARN use of deprecated item 'local_deprecated': local deprecation note + deprecated_macro!(); //~ WARN use of deprecated item 'deprecated_macro': deprecation note +} diff --git a/src/test/ui/macros/macro-deprecation.stderr b/src/test/ui/macros/macro-deprecation.stderr new file mode 100644 index 00000000000..e5f4df52237 --- /dev/null +++ b/src/test/ui/macros/macro-deprecation.stderr @@ -0,0 +1,14 @@ +warning: use of deprecated item 'local_deprecated': local deprecation note + --> $DIR/macro-deprecation.rs:11:5 + | +LL | local_deprecated!(); + | ^^^^^^^^^^^^^^^^^^^^ + | + = note: #[warn(deprecated)] on by default + +warning: use of deprecated item 'deprecated_macro': deprecation note + --> $DIR/macro-deprecation.rs:12:5 + | +LL | deprecated_macro!(); + | ^^^^^^^^^^^^^^^^^^^^ + diff --git a/src/test/ui/macros/macro-stability.rs b/src/test/ui/macros/macro-stability.rs index 7d1ee6a43b6..ab927e419b4 100644 --- a/src/test/ui/macros/macro-stability.rs +++ b/src/test/ui/macros/macro-stability.rs @@ -1,12 +1,28 @@ // aux-build:unstable-macros.rs +#![feature(decl_macro)] #![feature(staged_api)] #[macro_use] extern crate unstable_macros; #[unstable(feature = "local_unstable", issue = "0")] macro_rules! local_unstable { () => () } +#[unstable(feature = "local_unstable", issue = "0")] +macro local_unstable_modern() {} + +#[stable(feature = "deprecated_macros", since = "1.0.0")] +#[rustc_deprecated(since = "1.0.0", reason = "local deprecation reason")] +#[macro_export] +macro_rules! local_deprecated{ () => () } + fn main() { - local_unstable!(); - unstable_macro!(); //~ ERROR: macro unstable_macro! is unstable + local_unstable!(); //~ ERROR use of unstable library feature 'local_unstable' + local_unstable_modern!(); //~ ERROR use of unstable library feature 'local_unstable' + unstable_macro!(); //~ ERROR use of unstable library feature 'unstable_macros' + // unstable_macro_modern!(); // ERROR use of unstable library feature 'unstable_macros' + + deprecated_macro!(); + //~^ WARN use of deprecated item 'deprecated_macro': deprecation reason + local_deprecated!(); + //~^ WARN use of deprecated item 'local_deprecated': local deprecation reason } diff --git a/src/test/ui/macros/macro-stability.stderr b/src/test/ui/macros/macro-stability.stderr index a0e0c351a48..88edadc3811 100644 --- a/src/test/ui/macros/macro-stability.stderr +++ b/src/test/ui/macros/macro-stability.stderr @@ -1,11 +1,41 @@ -error[E0658]: macro unstable_macro! is unstable - --> $DIR/macro-stability.rs:11:5 +error[E0658]: use of unstable library feature 'local_unstable' + --> $DIR/macro-stability.rs:19:5 + | +LL | local_unstable!(); + | ^^^^^^^^^^^^^^^^^^ + | + = help: add #![feature(local_unstable)] to the crate attributes to enable + +error[E0658]: use of unstable library feature 'local_unstable' + --> $DIR/macro-stability.rs:20:5 + | +LL | local_unstable_modern!(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: add #![feature(local_unstable)] to the crate attributes to enable + +error[E0658]: use of unstable library feature 'unstable_macros' + --> $DIR/macro-stability.rs:21:5 | LL | unstable_macro!(); | ^^^^^^^^^^^^^^^^^^ | = help: add #![feature(unstable_macros)] to the crate attributes to enable -error: aborting due to previous error +warning: use of deprecated item 'deprecated_macro': deprecation reason + --> $DIR/macro-stability.rs:24:5 + | +LL | deprecated_macro!(); + | ^^^^^^^^^^^^^^^^^^^^ + | + = note: #[warn(deprecated)] on by default + +warning: use of deprecated item 'local_deprecated': local deprecation reason + --> $DIR/macro-stability.rs:26:5 + | +LL | local_deprecated!(); + | ^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 3 previous errors For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/rust-unstable-column-gated.rs b/src/test/ui/rust-unstable-column-gated.rs index ed5e6f2489c..053806ead2d 100644 --- a/src/test/ui/rust-unstable-column-gated.rs +++ b/src/test/ui/rust-unstable-column-gated.rs @@ -1,4 +1,4 @@ fn main() { println!("{}", __rust_unstable_column!()); - //~^ERROR the __rust_unstable_column macro is unstable + //~^ ERROR use of unstable library feature '__rust_unstable_column' } diff --git a/src/test/ui/rust-unstable-column-gated.stderr b/src/test/ui/rust-unstable-column-gated.stderr index b9f1df2bcc9..70b3654b5af 100644 --- a/src/test/ui/rust-unstable-column-gated.stderr +++ b/src/test/ui/rust-unstable-column-gated.stderr @@ -1,8 +1,11 @@ -error: the __rust_unstable_column macro is unstable +error[E0658]: use of unstable library feature '__rust_unstable_column': internal implementation detail of the `column` macro --> $DIR/rust-unstable-column-gated.rs:2:20 | LL | println!("{}", __rust_unstable_column!()); | ^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: add #![feature(__rust_unstable_column)] to the crate attributes to enable error: aborting due to previous error +For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/trace_macros-gate.stderr b/src/test/ui/trace_macros-gate.stderr index e0ffcfe295f..18745e9ab5a 100644 --- a/src/test/ui/trace_macros-gate.stderr +++ b/src/test/ui/trace_macros-gate.stderr @@ -1,4 +1,4 @@ -error[E0658]: `trace_macros` is not stable enough for use and is subject to change +error[E0658]: use of unstable library feature 'trace_macros': `trace_macros` is not stable enough for use and is subject to change --> $DIR/trace_macros-gate.rs:4:5 | LL | trace_macros!(); @@ -13,7 +13,7 @@ error: trace_macros! accepts only `true` or `false` LL | trace_macros!(); | ^^^^^^^^^^^^^^^^ -error[E0658]: `trace_macros` is not stable enough for use and is subject to change +error[E0658]: use of unstable library feature 'trace_macros': `trace_macros` is not stable enough for use and is subject to change --> $DIR/trace_macros-gate.rs:6:5 | LL | trace_macros!(true); @@ -22,7 +22,7 @@ LL | trace_macros!(true); = note: for more information, see https://github.com/rust-lang/rust/issues/29598 = help: add #![feature(trace_macros)] to the crate attributes to enable -error[E0658]: `trace_macros` is not stable enough for use and is subject to change +error[E0658]: use of unstable library feature 'trace_macros': `trace_macros` is not stable enough for use and is subject to change --> $DIR/trace_macros-gate.rs:7:5 | LL | trace_macros!(false); @@ -31,7 +31,7 @@ LL | trace_macros!(false); = note: for more information, see https://github.com/rust-lang/rust/issues/29598 = help: add #![feature(trace_macros)] to the crate attributes to enable -error[E0658]: `trace_macros` is not stable enough for use and is subject to change +error[E0658]: use of unstable library feature 'trace_macros': `trace_macros` is not stable enough for use and is subject to change --> $DIR/trace_macros-gate.rs:10:26 | LL | ($x: ident) => { trace_macros!($x) }