1
Fork 0

Rollup merge of #90826 - petrochenkov:binattr, r=cjgillot

rustc_feature: Convert `BuiltinAttribute` from tuple to a struct

The tuple starts having too many fields.
Noticed while reviewing https://github.com/rust-lang/rust/pull/88681.
This commit is contained in:
Matthias Krüger 2021-11-12 19:17:34 +01:00 committed by GitHub
commit 5e7c031397
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 62 additions and 44 deletions

View file

@ -3,7 +3,7 @@ use rustc_ast::visit::{self, AssocCtxt, FnCtxt, FnKind, Visitor};
use rustc_ast::{AssocTyConstraint, AssocTyConstraintKind, NodeId}; use rustc_ast::{AssocTyConstraint, AssocTyConstraintKind, NodeId};
use rustc_ast::{PatKind, RangeEnd, VariantData}; use rustc_ast::{PatKind, RangeEnd, VariantData};
use rustc_errors::struct_span_err; 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_feature::{Features, GateIssue};
use rustc_session::parse::{feature_err, feature_err_issue}; use rustc_session::parse::{feature_err, feature_err_issue};
use rustc_session::Session; use rustc_session::Session;
@ -301,11 +301,14 @@ impl<'a> PostExpansionVisitor<'a> {
impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
fn visit_attribute(&mut self, attr: &ast::Attribute) { fn visit_attribute(&mut self, attr: &ast::Attribute) {
let attr_info = let attr_info = attr.ident().and_then(|ident| BUILTIN_ATTRIBUTE_MAP.get(&ident.name));
attr.ident().and_then(|ident| BUILTIN_ATTRIBUTE_MAP.get(&ident.name)).map(|a| **a);
// Check feature gates for built-in attributes. // Check feature gates for built-in attributes.
if let Some((.., AttributeGate::Gated(_, name, descr, has_feature))) = attr_info { if let Some(BuiltinAttribute {
gate_feature_fn!(self, has_feature, attr.span, name, descr); 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. // Check unstable flavors of the `#[doc]` attribute.
if attr.has_name(sym::doc) { if attr.has_name(sym::doc) {

View file

@ -115,16 +115,26 @@ macro_rules! template {
macro_rules! ungated { macro_rules! ungated {
($attr:ident, $typ:expr, $tpl:expr $(,)?) => { ($attr:ident, $typ:expr, $tpl:expr $(,)?) => {
(sym::$attr, $typ, $tpl, Ungated) BuiltinAttribute { name: sym::$attr, type_: $typ, template: $tpl, gate: Ungated }
}; };
} }
macro_rules! gated { macro_rules! gated {
($attr:ident, $typ:expr, $tpl:expr, $gate:ident, $msg:expr $(,)?) => { ($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 $(,)?) => { ($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 $(,)?) => { ($attr:ident, $typ:expr, $tpl:expr, $msg:expr $(,)?) => {
( BuiltinAttribute {
sym::$attr, name: sym::$attr,
$typ, type_: $typ,
$tpl, template: $tpl,
Gated(Stability::Unstable, sym::rustc_attrs, $msg, cfg_fn!(rustc_attrs)), 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 IMPL_DETAIL: &str = "internal implementation detail";
const INTERNAL_UNSTABLE: &str = "this is an internal attribute that will never be stable"; 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. /// Attributes that have a special meaning to rustc or rustdoc.
#[rustfmt::skip] #[rustfmt::skip]
@ -290,9 +305,11 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
), ),
// Plugins: // Plugins:
( BuiltinAttribute {
sym::plugin, CrateLevel, template!(List: "name"), name: sym::plugin,
Gated( type_: CrateLevel,
template: template!(List: "name"),
gate: Gated(
Stability::Deprecated( Stability::Deprecated(
"https://github.com/rust-lang/rust/pull/64675", "https://github.com/rust-lang/rust/pull/64675",
Some("may be removed in a future compiler version"), Some("may be removed in a future compiler version"),
@ -300,8 +317,8 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
sym::plugin, sym::plugin,
"compiler plugins are deprecated", "compiler plugins are deprecated",
cfg_fn!(plugin) cfg_fn!(plugin)
) ),
), },
// Testing: // Testing:
gated!(allow_fail, Normal, template!(Word), experimental!(allow_fail)), 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, lang, Normal, template!(NameValueStr: "name"), lang_items,
"language items are subject to change", "language items are subject to change",
), ),
( BuiltinAttribute {
sym::rustc_diagnostic_item, name: sym::rustc_diagnostic_item,
Normal, type_: Normal,
template!(NameValueStr: "name"), template: template!(NameValueStr: "name"),
Gated( gate: Gated(
Stability::Unstable, Stability::Unstable,
sym::rustc_attrs, sym::rustc_attrs,
"diagnostic items compiler internal support for linting", "diagnostic items compiler internal support for linting",
cfg_fn!(rustc_attrs), cfg_fn!(rustc_attrs),
), ),
), },
gated!( gated!(
// Used in resolve: // Used in resolve:
prelude_import, Normal, template!(Word), prelude_import, Normal, template!(Word),
@ -601,7 +618,7 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
]; ];
pub fn deprecated_attributes() -> Vec<&'static 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 { pub fn is_builtin_attr_name(name: Symbol) -> bool {
@ -612,8 +629,8 @@ pub static BUILTIN_ATTRIBUTE_MAP: SyncLazy<FxHashMap<Symbol, &BuiltinAttribute>>
SyncLazy::new(|| { SyncLazy::new(|| {
let mut map = FxHashMap::default(); let mut map = FxHashMap::default();
for attr in BUILTIN_ATTRIBUTES.iter() { for attr in BUILTIN_ATTRIBUTES.iter() {
if map.insert(attr.0, attr).is_some() { if map.insert(attr.name, attr).is_some() {
panic!("duplicate builtin attribute `{}`", attr.0); panic!("duplicate builtin attribute `{}`", attr.name);
} }
} }
map map

View file

@ -32,8 +32,7 @@ use rustc_ast_pretty::pprust::{self, expr_to_string};
use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_data_structures::stack::ensure_sufficient_stack; use rustc_data_structures::stack::ensure_sufficient_stack;
use rustc_errors::{Applicability, DiagnosticBuilder, DiagnosticStyledString}; use rustc_errors::{Applicability, DiagnosticBuilder, DiagnosticStyledString};
use rustc_feature::{deprecated_attributes, AttributeGate, AttributeTemplate, AttributeType}; use rustc_feature::{deprecated_attributes, AttributeGate, BuiltinAttribute, GateIssue, Stability};
use rustc_feature::{GateIssue, Stability};
use rustc_hir as hir; use rustc_hir as hir;
use rustc_hir::def::{DefKind, Res}; use rustc_hir::def::{DefKind, Res};
use rustc_hir::def_id::{DefId, LocalDefId, LocalDefIdSet, CRATE_DEF_ID}; use rustc_hir::def_id::{DefId, LocalDefId, LocalDefIdSet, CRATE_DEF_ID};
@ -959,7 +958,7 @@ impl EarlyLintPass for AnonymousParameters {
pub struct DeprecatedAttr { pub struct DeprecatedAttr {
// This is not free to compute, so we want to keep it around, rather than // This is not free to compute, so we want to keep it around, rather than
// compute it for every attribute. // compute it for every attribute.
depr_attrs: Vec<&'static (Symbol, AttributeType, AttributeTemplate, AttributeGate)>, depr_attrs: Vec<&'static BuiltinAttribute>,
} }
impl_lint_pass!(DeprecatedAttr => []); impl_lint_pass!(DeprecatedAttr => []);
@ -990,14 +989,14 @@ fn lint_deprecated_attr(
impl EarlyLintPass for DeprecatedAttr { impl EarlyLintPass for DeprecatedAttr {
fn check_attribute(&mut self, cx: &EarlyContext<'_>, attr: &ast::Attribute) { fn check_attribute(&mut self, cx: &EarlyContext<'_>, attr: &ast::Attribute) {
for &&(n, _, _, ref g) in &self.depr_attrs { for BuiltinAttribute { name, gate, .. } in &self.depr_attrs {
if attr.ident().map(|ident| ident.name) == Some(n) { if attr.ident().map(|ident| ident.name) == Some(*name) {
if let &AttributeGate::Gated( if let &AttributeGate::Gated(
Stability::Deprecated(link, suggestion), Stability::Deprecated(link, suggestion),
name, name,
reason, reason,
_, _,
) = g ) = gate
{ {
let msg = let msg =
format!("use of deprecated attribute `{}`: {}. See {}", name, reason, link); format!("use of deprecated attribute `{}`: {}. See {}", name, reason, link);

View file

@ -5,7 +5,7 @@ use crate::parse_in;
use rustc_ast::tokenstream::{DelimSpan, TokenTree}; use rustc_ast::tokenstream::{DelimSpan, TokenTree};
use rustc_ast::{self as ast, Attribute, MacArgs, MacDelimiter, MetaItem, MetaItemKind}; use rustc_ast::{self as ast, Attribute, MacArgs, MacDelimiter, MetaItem, MetaItemKind};
use rustc_errors::{Applicability, FatalError, PResult}; 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::lint::builtin::ILL_FORMED_ATTRIBUTE_INPUT;
use rustc_session::parse::ParseSess; use rustc_session::parse::ParseSess;
use rustc_span::{sym, Symbol}; use rustc_span::{sym, Symbol};
@ -15,14 +15,13 @@ pub fn check_meta(sess: &ParseSess, attr: &Attribute) {
return; return;
} }
let attr_info = let attr_info = attr.ident().and_then(|ident| BUILTIN_ATTRIBUTE_MAP.get(&ident.name));
attr.ident().and_then(|ident| BUILTIN_ATTRIBUTE_MAP.get(&ident.name)).map(|a| **a);
// Check input tokens for built-in and key-value attributes. // Check input tokens for built-in and key-value attributes.
match attr_info { match attr_info {
// `rustc_dummy` doesn't have any restrictions specific to built-in attributes. // `rustc_dummy` doesn't have any restrictions specific to built-in attributes.
Some((name, _, template, _)) if name != sym::rustc_dummy => { Some(BuiltinAttribute { name, template, .. }) if *name != sym::rustc_dummy => {
check_builtin_attribute(sess, attr, name, template) check_builtin_attribute(sess, attr, *name, *template)
} }
_ if let MacArgs::Eq(..) = attr.get_normal_item().args => { _ if let MacArgs::Eq(..) = attr.get_normal_item().args => {
// All key-value attributes are restricted to meta-item syntax. // All key-value attributes are restricted to meta-item syntax.
@ -168,7 +167,7 @@ pub fn emit_fatal_malformed_builtin_attribute(
attr: &Attribute, attr: &Attribute,
name: Symbol, 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); emit_malformed_attribute(sess, attr, name, template);
// This is fatal, otherwise it will likely cause a cascade of other errors // This is fatal, otherwise it will likely cause a cascade of other errors
// (and an error here is expected to be very rare). // (and an error here is expected to be very rare).

View file

@ -11,7 +11,7 @@ use rustc_middle::ty::TyCtxt;
use rustc_ast::{ast, AttrStyle, Attribute, Lit, LitKind, NestedMetaItem}; use rustc_ast::{ast, AttrStyle, Attribute, Lit, LitKind, NestedMetaItem};
use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_errors::{pluralize, struct_span_err, Applicability}; 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 as hir;
use rustc_hir::def_id::LocalDefId; use rustc_hir::def_id::LocalDefId;
use rustc_hir::intravisit::{self, NestedVisitorMap, Visitor}; use rustc_hir::intravisit::{self, NestedVisitorMap, Visitor};
@ -148,7 +148,7 @@ impl CheckAttrVisitor<'tcx> {
} }
if hir_id != CRATE_HIR_ID { 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)) attr.ident().and_then(|ident| BUILTIN_ATTRIBUTE_MAP.get(&ident.name))
{ {
self.tcx.struct_span_lint_hir(UNUSED_ATTRIBUTES, hir_id, attr.span, |lint| { self.tcx.struct_span_lint_hir(UNUSED_ATTRIBUTES, hir_id, attr.span, |lint| {

View file

@ -731,7 +731,7 @@ impl<'a> Resolver<'a> {
suggestions.extend( suggestions.extend(
BUILTIN_ATTRIBUTES BUILTIN_ATTRIBUTES
.iter() .iter()
.map(|(name, ..)| TypoSuggestion::typo_from_res(*name, res)), .map(|attr| TypoSuggestion::typo_from_res(attr.name, res)),
); );
} }
} }