diff --git a/compiler/rustc_attr_data_structures/src/attributes.rs b/compiler/rustc_attr_data_structures/src/attributes.rs index 65061059a02e2..eed44b5c6a667 100644 --- a/compiler/rustc_attr_data_structures/src/attributes.rs +++ b/compiler/rustc_attr_data_structures/src/attributes.rs @@ -187,13 +187,13 @@ pub enum AttributeKind { Align { align: Align, span: Span }, /// Represents `#[rustc_allow_const_fn_unstable]`. - AllowConstFnUnstable(ThinVec), + AllowConstFnUnstable { features: ThinVec<(Symbol, Span)> }, /// Represents `#[allow_internal_unstable]`. - AllowInternalUnstable(ThinVec<(Symbol, Span)>), + AllowInternalUnstable { features: ThinVec<(Symbol, Span)> }, /// Represents `#[rustc_as_ptr]` (used by the `dangling_pointers_from_temporaries` lint). - AsPtr(Span), + AsPtr { span: Span }, /// Represents `#[rustc_default_body_unstable]`. BodyStability { @@ -217,7 +217,7 @@ pub enum AttributeKind { }, /// Represents `#[rustc_const_stable_indirect]`. - ConstStabilityIndirect, + ConstStabilityIndirect { span: Span }, /// Represents [`#[deprecated]`](https://doc.rust-lang.org/stable/reference/attributes/diagnostics.html#the-deprecated-attribute). Deprecation { deprecation: Deprecation, span: Span }, @@ -226,14 +226,14 @@ pub enum AttributeKind { DocComment { style: AttrStyle, kind: CommentKind, span: Span, comment: Symbol }, /// Represents `#[inline]` and `#[rustc_force_inline]`. - Inline(InlineAttr, Span), + Inline { kind: InlineAttr, span: Span }, /// Represents `#[rustc_macro_transparency]`. - MacroTransparency(Transparency), + MacroTransparency { transparency: Transparency, span: Span }, /// Represents `#[optimize(size|speed)]` - Optimize(OptimizeAttr, Span), + Optimize { kind: OptimizeAttr, span: Span }, /// Represents [`#[repr]`](https://doc.rust-lang.org/stable/reference/type-layout.html#representations). - Repr(ThinVec<(ReprAttr, Span)>), + Repr { reprs: ThinVec<(ReprAttr, Span)> }, /// Represents `#[stable]`, `#[unstable]` and `#[rustc_allowed_through_unstable_modules]`. Stability { diff --git a/compiler/rustc_attr_parsing/src/attributes/allow_unstable.rs b/compiler/rustc_attr_parsing/src/attributes/allow_unstable.rs index 21b01a8d071bf..c787c2bc3cd04 100644 --- a/compiler/rustc_attr_parsing/src/attributes/allow_unstable.rs +++ b/compiler/rustc_attr_parsing/src/attributes/allow_unstable.rs @@ -1,5 +1,3 @@ -use std::iter; - use rustc_attr_data_structures::AttributeKind; use rustc_feature::{AttributeTemplate, template}; use rustc_span::{Span, Symbol, sym}; @@ -13,7 +11,8 @@ pub(crate) struct AllowInternalUnstableParser; impl CombineAttributeParser for AllowInternalUnstableParser { const PATH: &[Symbol] = &[sym::allow_internal_unstable]; type Item = (Symbol, Span); - const CONVERT: ConvertFn = AttributeKind::AllowInternalUnstable; + const CONVERT: ConvertFn = + |features| AttributeKind::AllowInternalUnstable { features }; const TEMPLATE: AttributeTemplate = template!(Word, List: "feat1, feat2, ..."); fn extend<'c>( @@ -21,16 +20,15 @@ impl CombineAttributeParser for AllowInternalUnstableParser { args: &'c ArgParser<'_>, ) -> impl IntoIterator { parse_unstable(cx, args, >::PATH[0]) - .into_iter() - .zip(iter::repeat(cx.attr_span)) } } pub(crate) struct AllowConstFnUnstableParser; impl CombineAttributeParser for AllowConstFnUnstableParser { const PATH: &[Symbol] = &[sym::rustc_allow_const_fn_unstable]; - type Item = Symbol; - const CONVERT: ConvertFn = AttributeKind::AllowConstFnUnstable; + type Item = (Symbol, Span); + const CONVERT: ConvertFn = + |features| AttributeKind::AllowConstFnUnstable { features }; const TEMPLATE: AttributeTemplate = template!(Word, List: "feat1, feat2, ..."); fn extend<'c>( @@ -45,7 +43,7 @@ fn parse_unstable( cx: &AcceptContext<'_, '_, S>, args: &ArgParser<'_>, symbol: Symbol, -) -> impl IntoIterator { +) -> impl IntoIterator { let mut res = Vec::new(); let Some(list) = args.list() else { @@ -59,7 +57,7 @@ fn parse_unstable( for param in list.mixed() { let param_span = param.span(); if let Some(ident) = param.meta_item().and_then(|i| i.path().word()) { - res.push(ident.name); + res.push((ident.name, param_span)); } else { cx.emit_err(session_diagnostics::ExpectsFeatures { span: param_span, diff --git a/compiler/rustc_attr_parsing/src/attributes/codegen_attrs.rs b/compiler/rustc_attr_parsing/src/attributes/codegen_attrs.rs index ddcf82cbf7cd5..c8807b9d05d6b 100644 --- a/compiler/rustc_attr_parsing/src/attributes/codegen_attrs.rs +++ b/compiler/rustc_attr_parsing/src/attributes/codegen_attrs.rs @@ -25,7 +25,7 @@ impl SingleAttributeParser for OptimizeParser { return None; }; - let res = match single.meta_item().and_then(|i| i.path().word().map(|i| i.name)) { + let kind = match single.meta_item().and_then(|i| i.path().word().map(|i| i.name)) { Some(sym::size) => OptimizeAttr::Size, Some(sym::speed) => OptimizeAttr::Speed, Some(sym::none) => OptimizeAttr::DoNotOptimize, @@ -35,6 +35,6 @@ impl SingleAttributeParser for OptimizeParser { } }; - Some(AttributeKind::Optimize(res, cx.attr_span)) + Some(AttributeKind::Optimize { kind, span: cx.attr_span }) } } diff --git a/compiler/rustc_attr_parsing/src/attributes/inline.rs b/compiler/rustc_attr_parsing/src/attributes/inline.rs index 25efc3ae49b9d..78321a9741c37 100644 --- a/compiler/rustc_attr_parsing/src/attributes/inline.rs +++ b/compiler/rustc_attr_parsing/src/attributes/inline.rs @@ -21,8 +21,9 @@ impl SingleAttributeParser for InlineParser { const TEMPLATE: AttributeTemplate = template!(Word, List: "always|never"); fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser<'_>) -> Option { + let span = cx.attr_span; match args { - ArgParser::NoArgs => Some(AttributeKind::Inline(InlineAttr::Hint, cx.attr_span)), + ArgParser::NoArgs => Some(AttributeKind::Inline { kind: InlineAttr::Hint, span }), ArgParser::List(list) => { let Some(l) = list.single() else { cx.expected_single_argument(list.span); @@ -31,10 +32,10 @@ impl SingleAttributeParser for InlineParser { match l.meta_item().and_then(|i| i.path().word_sym()) { Some(sym::always) => { - Some(AttributeKind::Inline(InlineAttr::Always, cx.attr_span)) + Some(AttributeKind::Inline { kind: InlineAttr::Always, span }) } Some(sym::never) => { - Some(AttributeKind::Inline(InlineAttr::Never, cx.attr_span)) + Some(AttributeKind::Inline { kind: InlineAttr::Never, span }) } _ => { cx.expected_specific_argument(l.span(), vec!["always", "never"]); @@ -89,9 +90,9 @@ impl SingleAttributeParser for RustcForceInlineParser { } }; - Some(AttributeKind::Inline( - InlineAttr::Force { attr_span: cx.attr_span, reason }, - cx.attr_span, - )) + Some(AttributeKind::Inline { + kind: InlineAttr::Force { attr_span: cx.attr_span, reason }, + span: cx.attr_span, + }) } } diff --git a/compiler/rustc_attr_parsing/src/attributes/lint_helpers.rs b/compiler/rustc_attr_parsing/src/attributes/lint_helpers.rs index d4c846de56eb4..1371b467ff773 100644 --- a/compiler/rustc_attr_parsing/src/attributes/lint_helpers.rs +++ b/compiler/rustc_attr_parsing/src/attributes/lint_helpers.rs @@ -16,6 +16,6 @@ impl SingleAttributeParser for AsPtrParser { fn convert(cx: &mut AcceptContext<'_, '_, S>, _args: &ArgParser<'_>) -> Option { // FIXME: check that there's no args (this is currently checked elsewhere) - Some(AttributeKind::AsPtr(cx.attr_span)) + Some(AttributeKind::AsPtr { span: cx.attr_span }) } } diff --git a/compiler/rustc_attr_parsing/src/attributes/repr.rs b/compiler/rustc_attr_parsing/src/attributes/repr.rs index c9f9f34bdb7c1..e538db13bbcd4 100644 --- a/compiler/rustc_attr_parsing/src/attributes/repr.rs +++ b/compiler/rustc_attr_parsing/src/attributes/repr.rs @@ -23,7 +23,7 @@ pub(crate) struct ReprParser; impl CombineAttributeParser for ReprParser { type Item = (ReprAttr, Span); const PATH: &[Symbol] = &[sym::repr]; - const CONVERT: ConvertFn = AttributeKind::Repr; + const CONVERT: ConvertFn = |reprs| AttributeKind::Repr { reprs }; // FIXME(jdonszelmann): never used const TEMPLATE: AttributeTemplate = template!(List: "C"); diff --git a/compiler/rustc_attr_parsing/src/attributes/stability.rs b/compiler/rustc_attr_parsing/src/attributes/stability.rs index 6871ff4ec9f39..6d3ecfd5e8835 100644 --- a/compiler/rustc_attr_parsing/src/attributes/stability.rs +++ b/compiler/rustc_attr_parsing/src/attributes/stability.rs @@ -139,8 +139,8 @@ impl SingleAttributeParser for ConstStabilityIndirectParser { const ON_DUPLICATE: OnDuplicate = OnDuplicate::Ignore; const TEMPLATE: AttributeTemplate = template!(Word); - fn convert(_cx: &mut AcceptContext<'_, '_, S>, _args: &ArgParser<'_>) -> Option { - Some(AttributeKind::ConstStabilityIndirect) + fn convert(cx: &mut AcceptContext<'_, '_, S>, _args: &ArgParser<'_>) -> Option { + Some(AttributeKind::ConstStabilityIndirect { span: cx.attr_span }) } } diff --git a/compiler/rustc_attr_parsing/src/attributes/transparency.rs b/compiler/rustc_attr_parsing/src/attributes/transparency.rs index ce5ceb9139a5c..cae7a7264cb0e 100644 --- a/compiler/rustc_attr_parsing/src/attributes/transparency.rs +++ b/compiler/rustc_attr_parsing/src/attributes/transparency.rs @@ -26,19 +26,19 @@ impl SingleAttributeParser for TransparencyParser { cx.expected_name_value(cx.attr_span, None); return None; }; - match nv.value_as_str() { - Some(sym::transparent) => Some(Transparency::Transparent), - Some(sym::semiopaque | sym::semitransparent) => Some(Transparency::SemiOpaque), - Some(sym::opaque) => Some(Transparency::Opaque), - Some(_) => { + + let transparency = match nv.value_as_str()? { + sym::transparent => Transparency::Transparent, + sym::semiopaque | sym::semitransparent => Transparency::SemiOpaque, + sym::opaque => Transparency::Opaque, + _ => { cx.expected_specific_argument_strings( nv.value_span, vec!["transparent", "semitransparent", "opaque"], ); - None + return None; } - None => None, - } - .map(AttributeKind::MacroTransparency) + }; + Some(AttributeKind::MacroTransparency { transparency, span: cx.attr_span }) } } diff --git a/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs b/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs index d642851bb77bf..2a453a1cf5813 100644 --- a/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs +++ b/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs @@ -485,7 +485,7 @@ impl<'a> TraitDef<'a> { Annotatable::Item(item) => { let is_packed = matches!( AttributeParser::parse_limited(cx.sess, &item.attrs, sym::repr, item.span, item.id), - Some(Attribute::Parsed(AttributeKind::Repr(r))) if r.iter().any(|(x, _)| matches!(x, ReprPacked(..))) + Some(Attribute::Parsed(AttributeKind::Repr{reprs})) if reprs.iter().any(|(x, _)| matches!(x, ReprPacked(..))) ); let newitem = match &item.kind { diff --git a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs index e855f1d355892..ee8287037bd3d 100644 --- a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs +++ b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs @@ -442,7 +442,7 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs { let inline_span; (codegen_fn_attrs.inline, inline_span) = if let Some((inline_attr, span)) = - find_attr!(attrs, AttributeKind::Inline(i, span) => (*i, *span)) + find_attr!(attrs, AttributeKind::Inline{kind, span} => (*kind, *span)) { (inline_attr, Some(span)) } else { @@ -456,8 +456,8 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs { codegen_fn_attrs.inline = InlineAttr::Never; } - codegen_fn_attrs.optimize = - find_attr!(attrs, AttributeKind::Optimize(i, _) => *i).unwrap_or(OptimizeAttr::Default); + codegen_fn_attrs.optimize = find_attr!(attrs, AttributeKind::Optimize{kind, ..} => *kind) + .unwrap_or(OptimizeAttr::Default); // #73631: closures inherit `#[target_feature]` annotations // diff --git a/compiler/rustc_const_eval/src/check_consts/mod.rs b/compiler/rustc_const_eval/src/check_consts/mod.rs index d84214152255c..ff185520ce00d 100644 --- a/compiler/rustc_const_eval/src/check_consts/mod.rs +++ b/compiler/rustc_const_eval/src/check_consts/mod.rs @@ -82,7 +82,7 @@ pub fn rustc_allow_const_fn_unstable( ) -> bool { let attrs = tcx.hir_attrs(tcx.local_def_id_to_hir_id(def_id)); - attrs::find_attr!(attrs, attrs::AttributeKind::AllowConstFnUnstable(syms) if syms.contains(&feature_gate)) + attrs::find_attr!(attrs, attrs::AttributeKind::AllowConstFnUnstable{features} if features.iter().any(|(f, _)| *f == feature_gate)) } /// Returns `true` if the given `def_id` (trait or function) is "safe to expose on stable". diff --git a/compiler/rustc_expand/src/base.rs b/compiler/rustc_expand/src/base.rs index 7a29f8c9fbdef..113902c59e1f3 100644 --- a/compiler/rustc_expand/src/base.rs +++ b/compiler/rustc_expand/src/base.rs @@ -880,8 +880,8 @@ impl SyntaxExtension { is_local: bool, ) -> SyntaxExtension { let allow_internal_unstable = - find_attr!(attrs, AttributeKind::AllowInternalUnstable(i) => i) - .map(|i| i.as_slice()) + find_attr!(attrs, AttributeKind::AllowInternalUnstable{features} => features) + .map(|f| f.as_slice()) .unwrap_or_default(); // FIXME(jdonszelman): allow_internal_unsafe isn't yet new-style // let allow_internal_unsafe = find_attr!(attrs, AttributeKind::AllowInternalUnsafe); diff --git a/compiler/rustc_expand/src/mbe/macro_rules.rs b/compiler/rustc_expand/src/mbe/macro_rules.rs index 783f061ec6c58..aff5d1f79edfb 100644 --- a/compiler/rustc_expand/src/mbe/macro_rules.rs +++ b/compiler/rustc_expand/src/mbe/macro_rules.rs @@ -540,8 +540,9 @@ pub fn compile_declarative_macro( check_emission(macro_check::check_meta_variables(&sess.psess, node_id, span, &lhses, &rhses)); - let transparency = find_attr!(attrs, AttributeKind::MacroTransparency(x) => *x) - .unwrap_or(Transparency::fallback(macro_rules)); + let transparency = + find_attr!(attrs, AttributeKind::MacroTransparency{transparency, .. } => *transparency) + .unwrap_or(Transparency::fallback(macro_rules)); if let Some(guar) = guar { // To avoid warning noise, only consider the rules of this diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index 556f50a85af7d..c294766d70aa8 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -1297,12 +1297,33 @@ impl AttributeExt for Attribute { #[inline] fn span(&self) -> Span { + use AttributeKind::*; + + fn combine(spans: impl IntoIterator) -> Span { + spans.into_iter().reduce(|a, b| a.to(b)).unwrap_or(DUMMY_SP) + } + match &self { Attribute::Unparsed(u) => u.span, // FIXME: should not be needed anymore when all attrs are parsed - Attribute::Parsed(AttributeKind::Deprecation { span, .. }) => *span, - Attribute::Parsed(AttributeKind::DocComment { span, .. }) => *span, - a => panic!("can't get the span of an arbitrary parsed attribute: {a:?}"), + Attribute::Parsed(p) => match p { + Confusables { first_span: span, .. } + | ConstStability { span, .. } + | Stability { span, .. } + | ConstStabilityIndirect { span } + | Deprecation { span, .. } + | DocComment { span, .. } + | Align { span, .. } + | AsPtr { span } + | Inline { span, .. } + | BodyStability { span, .. } + | MacroTransparency { span, .. } + | Optimize { span, .. } => *span, + AllowConstFnUnstable { features, .. } | AllowInternalUnstable { features, .. } => { + combine(features.iter().map(|(_, s)| s).copied()) + } + Repr { reprs } => combine(reprs.iter().map(|(_, s)| s).copied()), + }, } } diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs index 32fec0604c0f1..780062071447f 100644 --- a/compiler/rustc_hir_analysis/src/check/check.rs +++ b/compiler/rustc_hir_analysis/src/check/check.rs @@ -1249,8 +1249,7 @@ fn check_simd(tcx: TyCtxt<'_>, sp: Span, def_id: LocalDefId) { pub(super) fn check_packed(tcx: TyCtxt<'_>, sp: Span, def: ty::AdtDef<'_>) { let repr = def.repr(); if repr.packed() { - if let Some(reprs) = - attrs::find_attr!(tcx.get_all_attrs(def.did()), attrs::AttributeKind::Repr(r) => r) + if let Some(reprs) = attrs::find_attr!(tcx.get_all_attrs(def.did()), attrs::AttributeKind::Repr{reprs} => reprs) { for (r, _) in reprs { if let ReprPacked(pack) = r @@ -1469,10 +1468,10 @@ fn check_enum(tcx: TyCtxt<'_>, def_id: LocalDefId) { if def.variants().is_empty() { attrs::find_attr!( tcx.get_all_attrs(def_id), - attrs::AttributeKind::Repr(rs) => { + attrs::AttributeKind::Repr{reprs} => { struct_span_code_err!( tcx.dcx(), - rs.first().unwrap().1, + reprs.first().unwrap().1, E0084, "unsupported representation for zero-variant enum" ) diff --git a/compiler/rustc_lint/src/dangling.rs b/compiler/rustc_lint/src/dangling.rs index c737919db9c2d..f8a66decd412e 100644 --- a/compiler/rustc_lint/src/dangling.rs +++ b/compiler/rustc_lint/src/dangling.rs @@ -134,7 +134,7 @@ fn lint_expr(cx: &LateContext<'_>, expr: &Expr<'_>) { && let ty = cx.typeck_results().expr_ty(receiver) && owns_allocation(cx.tcx, ty) && let Some(fn_id) = cx.typeck_results().type_dependent_def_id(expr.hir_id) - && find_attr!(cx.tcx.get_all_attrs(fn_id), AttributeKind::AsPtr(_)) + && find_attr!(cx.tcx.get_all_attrs(fn_id), AttributeKind::AsPtr { .. }) { // FIXME: use `emit_node_lint` when `#[primary_span]` is added. cx.tcx.emit_node_span_lint( diff --git a/compiler/rustc_lint/src/nonstandard_style.rs b/compiler/rustc_lint/src/nonstandard_style.rs index 1b60466a589d2..7362e7f3b09cf 100644 --- a/compiler/rustc_lint/src/nonstandard_style.rs +++ b/compiler/rustc_lint/src/nonstandard_style.rs @@ -165,7 +165,7 @@ impl EarlyLintPass for NonCamelCaseTypes { fn check_item(&mut self, cx: &EarlyContext<'_>, it: &ast::Item) { let has_repr_c = matches!( AttributeParser::parse_limited(cx.sess(), &it.attrs, sym::repr, it.span, it.id), - Some(Attribute::Parsed(AttributeKind::Repr(r))) if r.iter().any(|(r, _)| r == &ReprAttr::ReprC) + Some(Attribute::Parsed(AttributeKind::Repr{reprs})) if reprs.iter().any(|(r, _)| r == &ReprAttr::ReprC) ); if has_repr_c { diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index 97408e31854ae..ddb85532d78ac 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -1538,7 +1538,8 @@ impl<'tcx> TyCtxt<'tcx> { field_shuffle_seed ^= user_seed; } - if let Some(reprs) = attr::find_attr!(self.get_all_attrs(did), AttributeKind::Repr(r) => r) + if let Some(reprs) = + attr::find_attr!(self.get_all_attrs(did), AttributeKind::Repr{reprs} => reprs ) { for (r, _) in reprs { flags.insert(match *r { diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index a5d2ad4dc205b..6ca0ad33b6e81 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -117,50 +117,51 @@ impl<'tcx> CheckAttrVisitor<'tcx> { let attrs = self.tcx.hir_attrs(hir_id); for attr in attrs { match attr { - Attribute::Parsed(AttributeKind::Confusables { first_span, .. }) => { - self.check_confusables(*first_span, target); - } - Attribute::Parsed( + Attribute::Parsed(parsed) => match parsed { + AttributeKind::Confusables { first_span, .. } => { + self.check_confusables(*first_span, target); + } + AttributeKind::Stability { span, .. } - | AttributeKind::ConstStability { span, .. }, - ) => self.check_stability_promotable(*span, target), - Attribute::Parsed(AttributeKind::Inline(InlineAttr::Force { .. }, ..)) => {} // handled separately below - Attribute::Parsed(AttributeKind::Inline(kind, attr_span)) => { - self.check_inline(hir_id, *attr_span, span, kind, target) - } - Attribute::Parsed(AttributeKind::Optimize(_, attr_span)) => { - self.check_optimize(hir_id, *attr_span, span, target) - } - Attribute::Parsed(AttributeKind::AllowInternalUnstable(syms)) => self - .check_allow_internal_unstable( - hir_id, - syms.first().unwrap().1, - span, - target, - attrs, - ), - Attribute::Parsed(AttributeKind::AllowConstFnUnstable { .. }) => { - self.check_rustc_allow_const_fn_unstable(hir_id, attr, span, target) - } - Attribute::Parsed(AttributeKind::Deprecation { .. }) => { - self.check_deprecated(hir_id, attr, span, target) - } - Attribute::Parsed(AttributeKind::DocComment { .. }) => { /* `#[doc]` is actually a lot more than just doc comments, so is checked below*/ - } - Attribute::Parsed(AttributeKind::Repr(_)) => { /* handled below this loop and elsewhere */ - } - Attribute::Parsed(AttributeKind::Align { align, span: repr_span }) => { - self.check_align(span, target, *align, *repr_span) - } + | AttributeKind::ConstStability { span, .. } => { + self.check_stability_promotable(*span, target) + } + AttributeKind::Inline { kind: InlineAttr::Force { .. }, .. } => {} // handled separately below + AttributeKind::Inline { kind, span: attr_span } => { + self.check_inline(hir_id, *attr_span, span, kind, target) + } + AttributeKind::Optimize { span: attr_span, .. } => { + self.check_optimize(hir_id, *attr_span, span, target) + } + AttributeKind::AllowInternalUnstable { features } => self + .check_allow_internal_unstable( + hir_id, + features.first().unwrap().1, + span, + target, + attrs, + ), + AttributeKind::AllowConstFnUnstable { .. } => { + self.check_rustc_allow_const_fn_unstable(hir_id, attr, span, target) + } + AttributeKind::Deprecation { .. } => { + self.check_deprecated(hir_id, attr, span, target) + } + AttributeKind::DocComment { .. } => { /* `#[doc]` is actually a lot more than just doc comments, so is checked below*/ + } + AttributeKind::Repr { .. } => { /* handled below this loop and elsewhere */ } + AttributeKind::Align { align, span: repr_span } => { + self.check_align(span, target, *align, *repr_span) + } - Attribute::Parsed( AttributeKind::BodyStability { .. } - | AttributeKind::ConstStabilityIndirect - | AttributeKind::MacroTransparency(_), - ) => { /* do nothing */ } - Attribute::Parsed(AttributeKind::AsPtr(attr_span)) => { - self.check_applied_to_fn_or_method(hir_id, *attr_span, span, target) - } + | AttributeKind::ConstStabilityIndirect { .. } + | AttributeKind::MacroTransparency { .. } => { /* do nothing */ } + AttributeKind::AsPtr { span: attr_span } => { + self.check_applied_to_fn_or_method(hir_id, *attr_span, span, target) + } + }, + Attribute::Unparsed(_) => { match attr.path().as_slice() { [sym::diagnostic, sym::do_not_recommend, ..] => { @@ -692,7 +693,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { ) => { continue; } - Attribute::Parsed(AttributeKind::Inline(.., span)) => { + Attribute::Parsed(AttributeKind::Inline { span, .. }) => { self.dcx().emit_err(errors::NakedFunctionIncompatibleAttribute { span: *span, naked_span: attr.span(), @@ -2009,7 +2010,8 @@ impl<'tcx> CheckAttrVisitor<'tcx> { // #[repr(foo)] // #[repr(bar, align(8))] // ``` - let reprs = find_attr!(attrs, AttributeKind::Repr(r) => r.as_slice()).unwrap_or(&[]); + let reprs = + find_attr!(attrs, AttributeKind::Repr{reprs} => reprs.as_slice()).unwrap_or(&[]); let mut int_reprs = 0; let mut is_explicit_rust = false; @@ -2426,7 +2428,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { // ugly now but can 100% be removed later. if let Attribute::Parsed(p) = attr { match p { - AttributeKind::Repr(reprs) => { + AttributeKind::Repr { reprs } => { for (r, span) in reprs { if let ReprAttr::ReprEmpty = r { self.tcx.emit_node_span_lint( @@ -2663,7 +2665,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { } fn check_rustc_pub_transparent(&self, attr_span: Span, span: Span, attrs: &[Attribute]) { - if !find_attr!(attrs, AttributeKind::Repr(r) => r.iter().any(|(r, _)| r == &ReprAttr::ReprTransparent)) + if !find_attr!(attrs, AttributeKind::Repr{reprs} => reprs.iter().any(|(r, _)| r == &ReprAttr::ReprTransparent)) .unwrap_or(false) { self.dcx().emit_err(errors::RustcPubTransparent { span, attr_span }); @@ -2679,7 +2681,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { ) { match ( target, - find_attr!(attrs, AttributeKind::Inline(InlineAttr::Force { attr_span, .. }, _) => *attr_span), + find_attr!(attrs, AttributeKind::Inline{kind: InlineAttr::Force {.. }, span} => *span), ) { (Target::Closure, None) => { let is_coro = matches!( @@ -2695,7 +2697,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { if let Some(attr_span) = find_attr!( self.tcx.get_all_attrs(parent_did), - AttributeKind::Inline(InlineAttr::Force { attr_span, .. }, _) => *attr_span + AttributeKind::Inline{kind: InlineAttr::Force { .. }, span} => *span ) && is_coro { self.dcx() @@ -2883,8 +2885,8 @@ fn check_invalid_crate_level_attr(tcx: TyCtxt<'_>, attrs: &[Attribute]) { ATTRS_TO_CHECK.iter().find(|attr_to_check| attr.has_name(**attr_to_check)) { (attr.span(), *a) - } else if let Attribute::Parsed(AttributeKind::Repr(r)) = attr { - (r.first().unwrap().1, sym::repr) + } else if let Attribute::Parsed(AttributeKind::Repr { reprs }) = attr { + (reprs.first().unwrap().1, sym::repr) } else { continue; }; @@ -2925,7 +2927,7 @@ fn check_invalid_crate_level_attr(tcx: TyCtxt<'_>, attrs: &[Attribute]) { fn check_non_exported_macro_for_invalid_attrs(tcx: TyCtxt<'_>, item: &Item<'_>) { let attrs = tcx.hir_attrs(item.hir_id()); - if let Some(attr_span) = find_attr!(attrs, AttributeKind::Inline(i, span) if !matches!(i, InlineAttr::Force{..}) => *span) + if let Some(attr_span) = find_attr!(attrs, AttributeKind::Inline{kind, span} if !matches!(kind, InlineAttr::Force{..}) => *span) { tcx.dcx().emit_err(errors::NonExportedMacroInvalidAttrs { attr_span }); } diff --git a/compiler/rustc_passes/src/stability.rs b/compiler/rustc_passes/src/stability.rs index 56d9f5bf78577..2b7c8f5bd18f9 100644 --- a/compiler/rustc_passes/src/stability.rs +++ b/compiler/rustc_passes/src/stability.rs @@ -122,7 +122,8 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> { debug!("annotate(id = {:?}, attrs = {:?})", def_id, attrs); let depr = attrs::find_attr!(attrs, AttributeKind::Deprecation{deprecation, span} => (*deprecation, *span)); - let const_stability_indirect = find_attr!(attrs, AttributeKind::ConstStabilityIndirect); + let const_stability_indirect = + find_attr!(attrs, AttributeKind::ConstStabilityIndirect { .. }); let mut is_deprecated = false; if let Some((depr, span)) = &depr { diff --git a/compiler/rustc_privacy/src/lib.rs b/compiler/rustc_privacy/src/lib.rs index 963f4c77d809d..5d7b2e2dd249f 100644 --- a/compiler/rustc_privacy/src/lib.rs +++ b/compiler/rustc_privacy/src/lib.rs @@ -496,7 +496,7 @@ impl<'tcx> EmbargoVisitor<'tcx> { let hir_id = self.tcx.local_def_id_to_hir_id(local_def_id); let attrs = self.tcx.hir_attrs(hir_id); - if attrs::find_attr!(attrs, attrs::AttributeKind::MacroTransparency(x) => *x) + if attrs::find_attr!(attrs, attrs::AttributeKind::MacroTransparency{transparency, ..} => *transparency) .unwrap_or(Transparency::fallback(md.macro_rules)) != Transparency::Opaque { diff --git a/tests/ui/attributes/inline-and-trackcaller.rs b/tests/ui/attributes/inline-and-trackcaller.rs new file mode 100644 index 0000000000000..ad4ec12951157 --- /dev/null +++ b/tests/ui/attributes/inline-and-trackcaller.rs @@ -0,0 +1,9 @@ +//! Regression test for . + +#![crate_type = "lib"] + +#[inline] //~ERROR attribute should be applied to function or closure +#[track_caller] +macro_rules! contained { + () => {}; +} diff --git a/tests/ui/attributes/inline-and-trackcaller.stderr b/tests/ui/attributes/inline-and-trackcaller.stderr new file mode 100644 index 0000000000000..dcdf009cbb0af --- /dev/null +++ b/tests/ui/attributes/inline-and-trackcaller.stderr @@ -0,0 +1,9 @@ +error[E0518]: attribute should be applied to function or closure + --> $DIR/inline-and-trackcaller.rs:5:1 + | +LL | #[inline] + | ^^^^^^^^^ not a function or closure + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0518`. diff --git a/tests/ui/feature-gates/feature-gate-allow-internal-unstable-struct.stderr b/tests/ui/feature-gates/feature-gate-allow-internal-unstable-struct.stderr index 076f2df28e3f3..e06d124c71210 100644 --- a/tests/ui/feature-gates/feature-gate-allow-internal-unstable-struct.stderr +++ b/tests/ui/feature-gates/feature-gate-allow-internal-unstable-struct.stderr @@ -8,10 +8,10 @@ LL | #[allow_internal_unstable(something)] = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error: attribute should be applied to a macro - --> $DIR/feature-gate-allow-internal-unstable-struct.rs:6:1 + --> $DIR/feature-gate-allow-internal-unstable-struct.rs:6:27 | LL | #[allow_internal_unstable(something)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^ LL | LL | struct S; | --------- not a macro diff --git a/tests/ui/macros/genercs-in-path-with-prettry-hir.stdout b/tests/ui/macros/genercs-in-path-with-prettry-hir.stdout index 7c41225f95e67..f105fbe24fcde 100644 --- a/tests/ui/macros/genercs-in-path-with-prettry-hir.stdout +++ b/tests/ui/macros/genercs-in-path-with-prettry-hir.stdout @@ -8,7 +8,7 @@ extern crate std; // issue#97006 macro_rules! m { ($attr_path: path) => { #[$attr_path] fn f() {} } } -#[attr = Inline(Hint)] +#[attr = Inline {kind: Hint}] fn f() { } fn main() { } diff --git a/tests/ui/unpretty/exhaustive.hir.stdout b/tests/ui/unpretty/exhaustive.hir.stdout index 5d6e3907d7577..5156edafb5284 100644 --- a/tests/ui/unpretty/exhaustive.hir.stdout +++ b/tests/ui/unpretty/exhaustive.hir.stdout @@ -72,7 +72,8 @@ mod attributes {//! inner single-line doc comment #[doc = "outer doc attribute"] #[doc = "macro"] #[allow()] - #[attr = Repr([ReprC])] + #[attr = Repr {reprs: + [ReprC]}] struct Struct; }