diff options
| author | Mazdak Farrokhzad <twingoow@gmail.com> | 2019-07-07 17:00:17 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2019-07-07 17:00:17 +0200 |
| commit | 3250b8ee596afc9881aee092279efaa57486d2ea (patch) | |
| tree | c445db0b21aa62544140ff60894f770dc8fade07 /src/libsyntax | |
| parent | 9cd75fb35f1d24f805c6759fd6236cd708b81ee1 (diff) | |
| parent | 941653b528deb96d5ed13935143db14c45d99d6e (diff) | |
| download | rust-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.rs | 16 | ||||
| -rw-r--r-- | src/libsyntax/ext/base.rs | 21 | ||||
| -rw-r--r-- | src/libsyntax/ext/derive.rs | 6 | ||||
| -rw-r--r-- | src/libsyntax/ext/expand.rs | 86 | ||||
| -rw-r--r-- | src/libsyntax/ext/source_util.rs | 12 | ||||
| -rw-r--r-- | src/libsyntax/ext/tt/macro_rules.rs | 18 | ||||
| -rw-r--r-- | src/libsyntax/feature_gate.rs | 22 | ||||
| -rw-r--r-- | src/libsyntax/parse/lexer/mod.rs | 2 |
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 |
