about summary refs log tree commit diff
path: root/src/libsyntax
diff options
context:
space:
mode:
authorMazdak Farrokhzad <twingoow@gmail.com>2019-07-07 17:00:17 +0200
committerGitHub <noreply@github.com>2019-07-07 17:00:17 +0200
commit3250b8ee596afc9881aee092279efaa57486d2ea (patch)
treec445db0b21aa62544140ff60894f770dc8fade07 /src/libsyntax
parent9cd75fb35f1d24f805c6759fd6236cd708b81ee1 (diff)
parent941653b528deb96d5ed13935143db14c45d99d6e (diff)
downloadrust-3250b8ee596afc9881aee092279efaa57486d2ea.tar.gz
rust-3250b8ee596afc9881aee092279efaa57486d2ea.zip
Rollup merge of #62042 - petrochenkov:macstab, r=matthewjasper
Support stability and deprecation checking for all macros

RELNOTES: Deprecation attributes on macros now have effect.

Fixes https://github.com/rust-lang/rust/issues/34079
Fixes https://github.com/rust-lang/rust/issues/49912
Unblocks https://github.com/rust-lang/rust/pull/62086
Unblocks https://github.com/rust-lang/rust/pull/61000
Diffstat (limited to 'src/libsyntax')
-rw-r--r--src/libsyntax/attr/builtin.rs16
-rw-r--r--src/libsyntax/ext/base.rs21
-rw-r--r--src/libsyntax/ext/derive.rs6
-rw-r--r--src/libsyntax/ext/expand.rs86
-rw-r--r--src/libsyntax/ext/source_util.rs12
-rw-r--r--src/libsyntax/ext/tt/macro_rules.rs18
-rw-r--r--src/libsyntax/feature_gate.rs22
-rw-r--r--src/libsyntax/parse/lexer/mod.rs2
8 files changed, 53 insertions, 130 deletions
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<Symbol>, 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<Stability> {
     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<Stability>,
+    /// The macro's deprecation info.
+    pub deprecation: Option<Deprecation>,
     /// Names of helper attributes registered by this macro.
     pub helper_attrs: Vec<Symbol>,
     /// 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<ModuleData>,
     pub directory_ownership: DirectoryOwnership,
-    pub crate_span: Option<Span>,
 }
 
 /// 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<T>(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<AstFragment> {
         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<dyn base::MacResult+'static> {
-    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