diff --git a/compiler/rustc_ast_passes/src/feature_gate.rs b/compiler/rustc_ast_passes/src/feature_gate.rs index f45a79f026f..b011a2e8117 100644 --- a/compiler/rustc_ast_passes/src/feature_gate.rs +++ b/compiler/rustc_ast_passes/src/feature_gate.rs @@ -3,7 +3,7 @@ use rustc_ast::visit::{self, AssocCtxt, FnCtxt, FnKind, Visitor}; use rustc_ast::{AssocTyConstraint, AssocTyConstraintKind, NodeId}; use rustc_ast::{PatKind, RangeEnd, VariantData}; use rustc_errors::struct_span_err; -use rustc_feature::{AttributeGate, BUILTIN_ATTRIBUTE_MAP}; +use rustc_feature::{AttributeGate, BuiltinAttribute, BUILTIN_ATTRIBUTE_MAP}; use rustc_feature::{Features, GateIssue}; use rustc_session::parse::{feature_err, feature_err_issue}; use rustc_session::Session; @@ -301,11 +301,14 @@ impl<'a> PostExpansionVisitor<'a> { impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { fn visit_attribute(&mut self, attr: &ast::Attribute) { - let attr_info = - attr.ident().and_then(|ident| BUILTIN_ATTRIBUTE_MAP.get(&ident.name)).map(|a| **a); + let attr_info = attr.ident().and_then(|ident| BUILTIN_ATTRIBUTE_MAP.get(&ident.name)); // Check feature gates for built-in attributes. - if let Some((.., AttributeGate::Gated(_, name, descr, has_feature))) = attr_info { - gate_feature_fn!(self, has_feature, attr.span, name, descr); + if let Some(BuiltinAttribute { + gate: AttributeGate::Gated(_, name, descr, has_feature), + .. + }) = attr_info + { + gate_feature_fn!(self, has_feature, attr.span, *name, descr); } // Check unstable flavors of the `#[doc]` attribute. if attr.has_name(sym::doc) { diff --git a/compiler/rustc_feature/src/builtin_attrs.rs b/compiler/rustc_feature/src/builtin_attrs.rs index 33188d375f5..7212bbf38c7 100644 --- a/compiler/rustc_feature/src/builtin_attrs.rs +++ b/compiler/rustc_feature/src/builtin_attrs.rs @@ -115,16 +115,26 @@ macro_rules! template { macro_rules! ungated { ($attr:ident, $typ:expr, $tpl:expr $(,)?) => { - (sym::$attr, $typ, $tpl, Ungated) + BuiltinAttribute { name: sym::$attr, type_: $typ, template: $tpl, gate: Ungated } }; } macro_rules! gated { ($attr:ident, $typ:expr, $tpl:expr, $gate:ident, $msg:expr $(,)?) => { - (sym::$attr, $typ, $tpl, Gated(Stability::Unstable, sym::$gate, $msg, cfg_fn!($gate))) + BuiltinAttribute { + name: sym::$attr, + type_: $typ, + template: $tpl, + gate: Gated(Stability::Unstable, sym::$gate, $msg, cfg_fn!($gate)), + } }; ($attr:ident, $typ:expr, $tpl:expr, $msg:expr $(,)?) => { - (sym::$attr, $typ, $tpl, Gated(Stability::Unstable, sym::$attr, $msg, cfg_fn!($attr))) + BuiltinAttribute { + name: sym::$attr, + type_: $typ, + template: $tpl, + gate: Gated(Stability::Unstable, sym::$attr, $msg, cfg_fn!($attr)), + } }; } @@ -143,12 +153,12 @@ macro_rules! rustc_attr { ) }; ($attr:ident, $typ:expr, $tpl:expr, $msg:expr $(,)?) => { - ( - sym::$attr, - $typ, - $tpl, - Gated(Stability::Unstable, sym::rustc_attrs, $msg, cfg_fn!(rustc_attrs)), - ) + BuiltinAttribute { + name: sym::$attr, + type_: $typ, + template: $tpl, + gate: Gated(Stability::Unstable, sym::rustc_attrs, $msg, cfg_fn!(rustc_attrs)), + } }; } @@ -161,7 +171,12 @@ macro_rules! experimental { const IMPL_DETAIL: &str = "internal implementation detail"; const INTERNAL_UNSTABLE: &str = "this is an internal attribute that will never be stable"; -pub type BuiltinAttribute = (Symbol, AttributeType, AttributeTemplate, AttributeGate); +pub struct BuiltinAttribute { + pub name: Symbol, + pub type_: AttributeType, + pub template: AttributeTemplate, + pub gate: AttributeGate, +} /// Attributes that have a special meaning to rustc or rustdoc. #[rustfmt::skip] @@ -290,9 +305,11 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[ ), // Plugins: - ( - sym::plugin, CrateLevel, template!(List: "name"), - Gated( + BuiltinAttribute { + name: sym::plugin, + type_: CrateLevel, + template: template!(List: "name"), + gate: Gated( Stability::Deprecated( "https://github.com/rust-lang/rust/pull/64675", Some("may be removed in a future compiler version"), @@ -300,8 +317,8 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[ sym::plugin, "compiler plugins are deprecated", cfg_fn!(plugin) - ) - ), + ), + }, // Testing: gated!(allow_fail, Normal, template!(Word), experimental!(allow_fail)), @@ -497,17 +514,17 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[ lang, Normal, template!(NameValueStr: "name"), lang_items, "language items are subject to change", ), - ( - sym::rustc_diagnostic_item, - Normal, - template!(NameValueStr: "name"), - Gated( + BuiltinAttribute { + name: sym::rustc_diagnostic_item, + type_: Normal, + template: template!(NameValueStr: "name"), + gate: Gated( Stability::Unstable, sym::rustc_attrs, "diagnostic items compiler internal support for linting", cfg_fn!(rustc_attrs), ), - ), + }, gated!( // Used in resolve: prelude_import, Normal, template!(Word), @@ -601,7 +618,7 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[ ]; pub fn deprecated_attributes() -> Vec<&'static BuiltinAttribute> { - BUILTIN_ATTRIBUTES.iter().filter(|(.., gate)| gate.is_deprecated()).collect() + BUILTIN_ATTRIBUTES.iter().filter(|attr| attr.gate.is_deprecated()).collect() } pub fn is_builtin_attr_name(name: Symbol) -> bool { @@ -612,8 +629,8 @@ pub static BUILTIN_ATTRIBUTE_MAP: SyncLazy> SyncLazy::new(|| { let mut map = FxHashMap::default(); for attr in BUILTIN_ATTRIBUTES.iter() { - if map.insert(attr.0, attr).is_some() { - panic!("duplicate builtin attribute `{}`", attr.0); + if map.insert(attr.name, attr).is_some() { + panic!("duplicate builtin attribute `{}`", attr.name); } } map diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs index 6548cdc0fdc..f2e4e70a197 100644 --- a/compiler/rustc_lint/src/builtin.rs +++ b/compiler/rustc_lint/src/builtin.rs @@ -32,8 +32,7 @@ use rustc_ast_pretty::pprust::{self, expr_to_string}; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_data_structures::stack::ensure_sufficient_stack; use rustc_errors::{Applicability, DiagnosticBuilder, DiagnosticStyledString}; -use rustc_feature::{deprecated_attributes, AttributeGate, AttributeTemplate, AttributeType}; -use rustc_feature::{GateIssue, Stability}; +use rustc_feature::{deprecated_attributes, AttributeGate, BuiltinAttribute, GateIssue, Stability}; use rustc_hir as hir; use rustc_hir::def::{DefKind, Res}; use rustc_hir::def_id::{DefId, LocalDefId, LocalDefIdSet, CRATE_DEF_ID}; @@ -959,7 +958,7 @@ impl EarlyLintPass for AnonymousParameters { pub struct DeprecatedAttr { // This is not free to compute, so we want to keep it around, rather than // compute it for every attribute. - depr_attrs: Vec<&'static (Symbol, AttributeType, AttributeTemplate, AttributeGate)>, + depr_attrs: Vec<&'static BuiltinAttribute>, } impl_lint_pass!(DeprecatedAttr => []); @@ -990,14 +989,14 @@ fn lint_deprecated_attr( impl EarlyLintPass for DeprecatedAttr { fn check_attribute(&mut self, cx: &EarlyContext<'_>, attr: &ast::Attribute) { - for &&(n, _, _, ref g) in &self.depr_attrs { - if attr.ident().map(|ident| ident.name) == Some(n) { + for BuiltinAttribute { name, gate, .. } in &self.depr_attrs { + if attr.ident().map(|ident| ident.name) == Some(*name) { if let &AttributeGate::Gated( Stability::Deprecated(link, suggestion), name, reason, _, - ) = g + ) = gate { let msg = format!("use of deprecated attribute `{}`: {}. See {}", name, reason, link); diff --git a/compiler/rustc_parse/src/validate_attr.rs b/compiler/rustc_parse/src/validate_attr.rs index 2aa20d02c88..4781813ee8e 100644 --- a/compiler/rustc_parse/src/validate_attr.rs +++ b/compiler/rustc_parse/src/validate_attr.rs @@ -5,7 +5,7 @@ use crate::parse_in; use rustc_ast::tokenstream::{DelimSpan, TokenTree}; use rustc_ast::{self as ast, Attribute, MacArgs, MacDelimiter, MetaItem, MetaItemKind}; use rustc_errors::{Applicability, FatalError, PResult}; -use rustc_feature::{AttributeTemplate, BUILTIN_ATTRIBUTE_MAP}; +use rustc_feature::{AttributeTemplate, BuiltinAttribute, BUILTIN_ATTRIBUTE_MAP}; use rustc_session::lint::builtin::ILL_FORMED_ATTRIBUTE_INPUT; use rustc_session::parse::ParseSess; use rustc_span::{sym, Symbol}; @@ -15,14 +15,13 @@ pub fn check_meta(sess: &ParseSess, attr: &Attribute) { return; } - let attr_info = - attr.ident().and_then(|ident| BUILTIN_ATTRIBUTE_MAP.get(&ident.name)).map(|a| **a); + let attr_info = attr.ident().and_then(|ident| BUILTIN_ATTRIBUTE_MAP.get(&ident.name)); // Check input tokens for built-in and key-value attributes. match attr_info { // `rustc_dummy` doesn't have any restrictions specific to built-in attributes. - Some((name, _, template, _)) if name != sym::rustc_dummy => { - check_builtin_attribute(sess, attr, name, template) + Some(BuiltinAttribute { name, template, .. }) if *name != sym::rustc_dummy => { + check_builtin_attribute(sess, attr, *name, *template) } _ if let MacArgs::Eq(..) = attr.get_normal_item().args => { // All key-value attributes are restricted to meta-item syntax. @@ -168,7 +167,7 @@ pub fn emit_fatal_malformed_builtin_attribute( attr: &Attribute, name: Symbol, ) -> ! { - let template = BUILTIN_ATTRIBUTE_MAP.get(&name).expect("builtin attr defined").2; + let template = BUILTIN_ATTRIBUTE_MAP.get(&name).expect("builtin attr defined").template; emit_malformed_attribute(sess, attr, name, template); // This is fatal, otherwise it will likely cause a cascade of other errors // (and an error here is expected to be very rare). diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index 596d13d2d9a..129a9fdab82 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -11,7 +11,7 @@ use rustc_middle::ty::TyCtxt; use rustc_ast::{ast, AttrStyle, Attribute, Lit, LitKind, NestedMetaItem}; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_errors::{pluralize, struct_span_err, Applicability}; -use rustc_feature::{AttributeType, BUILTIN_ATTRIBUTE_MAP}; +use rustc_feature::{AttributeType, BuiltinAttribute, BUILTIN_ATTRIBUTE_MAP}; use rustc_hir as hir; use rustc_hir::def_id::LocalDefId; use rustc_hir::intravisit::{self, NestedVisitorMap, Visitor}; @@ -148,7 +148,7 @@ impl CheckAttrVisitor<'tcx> { } if hir_id != CRATE_HIR_ID { - if let Some((_, AttributeType::CrateLevel, ..)) = + if let Some(BuiltinAttribute { type_: AttributeType::CrateLevel, .. }) = attr.ident().and_then(|ident| BUILTIN_ATTRIBUTE_MAP.get(&ident.name)) { self.tcx.struct_span_lint_hir(UNUSED_ATTRIBUTES, hir_id, attr.span, |lint| { diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs index 094a5ed7bfb..c46a18e5103 100644 --- a/compiler/rustc_resolve/src/diagnostics.rs +++ b/compiler/rustc_resolve/src/diagnostics.rs @@ -731,7 +731,7 @@ impl<'a> Resolver<'a> { suggestions.extend( BUILTIN_ATTRIBUTES .iter() - .map(|(name, ..)| TypoSuggestion::typo_from_res(*name, res)), + .map(|attr| TypoSuggestion::typo_from_res(attr.name, res)), ); } }