diff options
| author | David Tolnay <dtolnay@gmail.com> | 2025-06-19 23:56:23 -0700 |
|---|---|---|
| committer | David Tolnay <dtolnay@gmail.com> | 2025-06-21 11:11:34 -0700 |
| commit | 6729b667ce4b013a5ec6f50b096bde3edabc28e3 (patch) | |
| tree | 6dd17554e5f0fa05f182850551cfcef764f6df9b /compiler | |
| parent | 715e02ff3ce28e330a278db1eb834547b7ab86f2 (diff) | |
| download | rust-6729b667ce4b013a5ec6f50b096bde3edabc28e3.tar.gz rust-6729b667ce4b013a5ec6f50b096bde3edabc28e3.zip | |
All HIR attributes are outer
Diffstat (limited to 'compiler')
| -rw-r--r-- | compiler/rustc_hir/src/hir.rs | 21 | ||||
| -rw-r--r-- | compiler/rustc_hir_pretty/src/lib.rs | 94 | ||||
| -rw-r--r-- | compiler/rustc_hir_typeck/src/expr.rs | 9 | ||||
| -rw-r--r-- | compiler/rustc_lint/src/context.rs | 7 | ||||
| -rw-r--r-- | compiler/rustc_passes/src/check_attr.rs | 66 |
5 files changed, 89 insertions, 108 deletions
diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index 73ece05377c..679904c7cfe 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -1207,14 +1207,6 @@ pub enum Attribute { } impl Attribute { - pub fn style(&self) -> AttrStyle { - match &self { - Attribute::Unparsed(u) => u.style, - Attribute::Parsed(AttributeKind::DocComment { style, .. }) => *style, - _ => panic!(), - } - } - pub fn get_normal_item(&self) -> &AttrItem { match &self { Attribute::Unparsed(normal) => &normal, @@ -2290,16 +2282,9 @@ pub struct Expr<'hir> { } impl Expr<'_> { - pub fn precedence( - &self, - for_each_attr: &dyn Fn(HirId, &mut dyn FnMut(&Attribute)), - ) -> ExprPrecedence { + pub fn precedence(&self, has_attr: &dyn Fn(HirId) -> bool) -> ExprPrecedence { let prefix_attrs_precedence = || -> ExprPrecedence { - let mut has_outer_attr = false; - for_each_attr(self.hir_id, &mut |attr: &Attribute| { - has_outer_attr |= matches!(attr.style(), AttrStyle::Outer) - }); - if has_outer_attr { ExprPrecedence::Prefix } else { ExprPrecedence::Unambiguous } + if has_attr(self.hir_id) { ExprPrecedence::Prefix } else { ExprPrecedence::Unambiguous } }; match &self.kind { @@ -2355,7 +2340,7 @@ impl Expr<'_> { | ExprKind::Use(..) | ExprKind::Err(_) => prefix_attrs_precedence(), - ExprKind::DropTemps(expr, ..) => expr.precedence(for_each_attr), + ExprKind::DropTemps(expr, ..) => expr.precedence(has_attr), } } diff --git a/compiler/rustc_hir_pretty/src/lib.rs b/compiler/rustc_hir_pretty/src/lib.rs index 233bb5cd5b8..d3289e4cc6d 100644 --- a/compiler/rustc_hir_pretty/src/lib.rs +++ b/compiler/rustc_hir_pretty/src/lib.rs @@ -10,7 +10,7 @@ use std::vec; use rustc_abi::ExternAbi; use rustc_ast::util::parser::{self, ExprPrecedence, Fixity}; -use rustc_ast::{AttrStyle, DUMMY_NODE_ID, DelimArgs}; +use rustc_ast::{DUMMY_NODE_ID, DelimArgs}; use rustc_ast_pretty::pp::Breaks::{Consistent, Inconsistent}; use rustc_ast_pretty::pp::{self, BoxMarker, Breaks}; use rustc_ast_pretty::pprust::state::MacHeader; @@ -81,32 +81,24 @@ impl<'a> State<'a> { } fn precedence(&self, expr: &hir::Expr<'_>) -> ExprPrecedence { - let for_each_attr = |id: HirId, callback: &mut dyn FnMut(&hir::Attribute)| { - self.attrs(id).iter().for_each(callback); - }; - expr.precedence(&for_each_attr) - } - - fn print_attrs_as_inner(&mut self, attrs: &[hir::Attribute]) { - self.print_either_attributes(attrs, ast::AttrStyle::Inner) - } - - fn print_attrs_as_outer(&mut self, attrs: &[hir::Attribute]) { - self.print_either_attributes(attrs, ast::AttrStyle::Outer) + let has_attr = |id: HirId| !self.attrs(id).is_empty(); + expr.precedence(&has_attr) } - fn print_either_attributes(&mut self, attrs: &[hir::Attribute], style: ast::AttrStyle) { + fn print_attrs(&mut self, attrs: &[hir::Attribute]) { if attrs.is_empty() { return; } for attr in attrs { - self.print_attribute_inline(attr, style); + self.print_attribute_as_style(attr, ast::AttrStyle::Outer); } self.hardbreak_if_not_bol(); } - fn print_attribute_inline(&mut self, attr: &hir::Attribute, style: AttrStyle) { + /// Print a single attribute as if it has style `style`, disregarding the + /// actual style of the attribute. + fn print_attribute_as_style(&mut self, attr: &hir::Attribute, style: ast::AttrStyle) { match &attr { hir::Attribute::Unparsed(unparsed) => { self.maybe_print_comment(unparsed.span.lo()); @@ -118,14 +110,17 @@ impl<'a> State<'a> { self.word("]"); self.hardbreak() } - hir::Attribute::Parsed(AttributeKind::DocComment { style, kind, comment, .. }) => { + hir::Attribute::Parsed(AttributeKind::DocComment { kind, comment, .. }) => { self.word(rustc_ast_pretty::pprust::state::doc_comment_to_string( - *kind, *style, *comment, + *kind, style, *comment, )); self.hardbreak() } hir::Attribute::Parsed(pa) => { - self.word("#[attr = "); + match style { + ast::AttrStyle::Inner => self.word("#![attr = "), + ast::AttrStyle::Outer => self.word("#[attr = "), + } pa.print_attribute(self); self.word("]"); self.hardbreak() @@ -281,10 +276,17 @@ pub fn print_crate<'a>( ann, }; + // Print all attributes, regardless of actual style, as inner attributes + // since this is the crate root with nothing above it to print outer + // attributes. + for attr in s.attrs(hir::CRATE_HIR_ID) { + s.print_attribute_as_style(attr, ast::AttrStyle::Inner); + } + // When printing the AST, we sometimes need to inject `#[no_std]` here. // Since you can't compile the HIR, it's not necessary. - s.print_mod(krate, (*attrs)(hir::CRATE_HIR_ID)); + s.print_mod(krate); s.print_remaining_comments(); s.s.eof() } @@ -299,7 +301,7 @@ where } pub fn attribute_to_string(ann: &dyn PpAnn, attr: &hir::Attribute) -> String { - to_string(ann, |s| s.print_attribute_inline(attr, AttrStyle::Outer)) + to_string(ann, |s| s.print_attribute_as_style(attr, ast::AttrStyle::Outer)) } pub fn ty_to_string(ann: &dyn PpAnn, ty: &hir::Ty<'_>) -> String { @@ -361,8 +363,7 @@ impl<'a> State<'a> { self.commasep_cmnt(b, exprs, |s, e| s.print_expr(e), |e| e.span); } - fn print_mod(&mut self, _mod: &hir::Mod<'_>, attrs: &[hir::Attribute]) { - self.print_attrs_as_inner(attrs); + fn print_mod(&mut self, _mod: &hir::Mod<'_>) { for &item_id in _mod.item_ids { self.ann.nested(self, Nested::Item(item_id)); } @@ -479,7 +480,7 @@ impl<'a> State<'a> { fn print_foreign_item(&mut self, item: &hir::ForeignItem<'_>) { self.hardbreak_if_not_bol(); self.maybe_print_comment(item.span.lo()); - self.print_attrs_as_outer(self.attrs(item.hir_id())); + self.print_attrs(self.attrs(item.hir_id())); match item.kind { hir::ForeignItemKind::Fn(sig, arg_idents, generics) => { let (cb, ib) = self.head(""); @@ -565,7 +566,7 @@ impl<'a> State<'a> { self.hardbreak_if_not_bol(); self.maybe_print_comment(item.span.lo()); let attrs = self.attrs(item.hir_id()); - self.print_attrs_as_outer(attrs); + self.print_attrs(attrs); self.ann.pre(self, AnnNode::Item(item)); match item.kind { hir::ItemKind::ExternCrate(orig_name, ident) => { @@ -647,14 +648,13 @@ impl<'a> State<'a> { self.print_ident(ident); self.nbsp(); self.bopen(ib); - self.print_mod(mod_, attrs); + self.print_mod(mod_); self.bclose(item.span, cb); } hir::ItemKind::ForeignMod { abi, items } => { let (cb, ib) = self.head("extern"); self.word_nbsp(abi.to_string()); self.bopen(ib); - self.print_attrs_as_inner(self.attrs(item.hir_id())); for item in items { self.ann.nested(self, Nested::ForeignItem(item.id)); } @@ -731,7 +731,6 @@ impl<'a> State<'a> { self.space(); self.bopen(ib); - self.print_attrs_as_inner(attrs); for impl_item in items { self.ann.nested(self, Nested::ImplItem(impl_item.id)); } @@ -822,7 +821,7 @@ impl<'a> State<'a> { for v in variants { self.space_if_not_bol(); self.maybe_print_comment(v.span.lo()); - self.print_attrs_as_outer(self.attrs(v.hir_id)); + self.print_attrs(self.attrs(v.hir_id)); let ib = self.ibox(INDENT_UNIT); self.print_variant(v); self.word(","); @@ -857,7 +856,7 @@ impl<'a> State<'a> { self.popen(); self.commasep(Inconsistent, struct_def.fields(), |s, field| { s.maybe_print_comment(field.span.lo()); - s.print_attrs_as_outer(s.attrs(field.hir_id)); + s.print_attrs(s.attrs(field.hir_id)); s.print_type(field.ty); }); self.pclose(); @@ -878,7 +877,7 @@ impl<'a> State<'a> { for field in struct_def.fields() { self.hardbreak_if_not_bol(); self.maybe_print_comment(field.span.lo()); - self.print_attrs_as_outer(self.attrs(field.hir_id)); + self.print_attrs(self.attrs(field.hir_id)); self.print_ident(field.ident); self.word_nbsp(":"); self.print_type(field.ty); @@ -916,7 +915,7 @@ impl<'a> State<'a> { self.ann.pre(self, AnnNode::SubItem(ti.hir_id())); self.hardbreak_if_not_bol(); self.maybe_print_comment(ti.span.lo()); - self.print_attrs_as_outer(self.attrs(ti.hir_id())); + self.print_attrs(self.attrs(ti.hir_id())); match ti.kind { hir::TraitItemKind::Const(ty, default) => { self.print_associated_const(ti.ident, ti.generics, ty, default); @@ -944,7 +943,7 @@ impl<'a> State<'a> { self.ann.pre(self, AnnNode::SubItem(ii.hir_id())); self.hardbreak_if_not_bol(); self.maybe_print_comment(ii.span.lo()); - self.print_attrs_as_outer(self.attrs(ii.hir_id())); + self.print_attrs(self.attrs(ii.hir_id())); match ii.kind { hir::ImplItemKind::Const(ty, expr) => { @@ -1028,27 +1027,16 @@ impl<'a> State<'a> { } fn print_block(&mut self, blk: &hir::Block<'_>, cb: BoxMarker, ib: BoxMarker) { - self.print_block_with_attrs(blk, &[], cb, ib) + self.print_block_maybe_unclosed(blk, Some(cb), ib) } fn print_block_unclosed(&mut self, blk: &hir::Block<'_>, ib: BoxMarker) { - self.print_block_maybe_unclosed(blk, &[], None, ib) - } - - fn print_block_with_attrs( - &mut self, - blk: &hir::Block<'_>, - attrs: &[hir::Attribute], - cb: BoxMarker, - ib: BoxMarker, - ) { - self.print_block_maybe_unclosed(blk, attrs, Some(cb), ib) + self.print_block_maybe_unclosed(blk, None, ib) } fn print_block_maybe_unclosed( &mut self, blk: &hir::Block<'_>, - attrs: &[hir::Attribute], cb: Option<BoxMarker>, ib: BoxMarker, ) { @@ -1060,8 +1048,6 @@ impl<'a> State<'a> { self.ann.pre(self, AnnNode::Block(blk)); self.bopen(ib); - self.print_attrs_as_inner(attrs); - for st in blk.stmts { self.print_stmt(st); } @@ -1251,7 +1237,7 @@ impl<'a> State<'a> { fn print_expr_field(&mut self, field: &hir::ExprField<'_>) { let cb = self.cbox(INDENT_UNIT); - self.print_attrs_as_outer(self.attrs(field.hir_id)); + self.print_attrs(self.attrs(field.hir_id)); if !field.is_shorthand { self.print_ident(field.ident); self.word_space(":"); @@ -1451,7 +1437,7 @@ impl<'a> State<'a> { fn print_expr(&mut self, expr: &hir::Expr<'_>) { self.maybe_print_comment(expr.span.lo()); - self.print_attrs_as_outer(self.attrs(expr.hir_id)); + self.print_attrs(self.attrs(expr.hir_id)); let ib = self.ibox(INDENT_UNIT); self.ann.pre(self, AnnNode::Expr(expr)); match expr.kind { @@ -2076,7 +2062,7 @@ impl<'a> State<'a> { self.space(); } let cb = self.cbox(INDENT_UNIT); - self.print_attrs_as_outer(self.attrs(field.hir_id)); + self.print_attrs(self.attrs(field.hir_id)); if !field.is_shorthand { self.print_ident(field.ident); self.word_nbsp(":"); @@ -2086,7 +2072,7 @@ impl<'a> State<'a> { } fn print_param(&mut self, arg: &hir::Param<'_>) { - self.print_attrs_as_outer(self.attrs(arg.hir_id)); + self.print_attrs(self.attrs(arg.hir_id)); self.print_pat(arg.pat); } @@ -2121,7 +2107,7 @@ impl<'a> State<'a> { let cb = self.cbox(INDENT_UNIT); self.ann.pre(self, AnnNode::Arm(arm)); let ib = self.ibox(0); - self.print_attrs_as_outer(self.attrs(arm.hir_id)); + self.print_attrs(self.attrs(arm.hir_id)); self.print_pat(arm.pat); self.space(); if let Some(ref g) = arm.guard { @@ -2409,7 +2395,7 @@ impl<'a> State<'a> { } fn print_where_predicate(&mut self, predicate: &hir::WherePredicate<'_>) { - self.print_attrs_as_outer(self.attrs(predicate.hir_id)); + self.print_attrs(self.attrs(predicate.hir_id)); match *predicate.kind { hir::WherePredicateKind::BoundPredicate(hir::WhereBoundPredicate { bound_generic_params, diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs index 223cadc056f..bd3ca8317eb 100644 --- a/compiler/rustc_hir_typeck/src/expr.rs +++ b/compiler/rustc_hir_typeck/src/expr.rs @@ -18,7 +18,7 @@ use rustc_errors::{ use rustc_hir::def::{CtorKind, DefKind, Res}; use rustc_hir::def_id::DefId; use rustc_hir::lang_items::LangItem; -use rustc_hir::{Attribute, ExprKind, HirId, QPath}; +use rustc_hir::{ExprKind, HirId, QPath}; use rustc_hir_analysis::NoVariantNamed; use rustc_hir_analysis::hir_ty_lowering::{FeedConstTy, HirTyLowerer as _}; use rustc_infer::infer; @@ -55,7 +55,7 @@ use crate::{ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { pub(crate) fn precedence(&self, expr: &hir::Expr<'_>) -> ExprPrecedence { - let for_each_attr = |id: HirId, callback: &mut dyn FnMut(&Attribute)| { + let has_attr = |id: HirId| -> bool { for attr in self.tcx.hir_attrs(id) { // For the purpose of rendering suggestions, disregard attributes // that originate from desugaring of any kind. For example, `x?` @@ -71,11 +71,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // let y: u32 = (x?).try_into().unwrap(); // + +++++++++++++++++++++ if attr.span().desugaring_kind().is_none() { - callback(attr); + return true; } } + false }; - expr.precedence(&for_each_attr) + expr.precedence(&has_attr) } /// Check an expr with an expectation type, and also demand that the expr's diff --git a/compiler/rustc_lint/src/context.rs b/compiler/rustc_lint/src/context.rs index b6bf45dfbcf..414f2a1846b 100644 --- a/compiler/rustc_lint/src/context.rs +++ b/compiler/rustc_lint/src/context.rs @@ -855,14 +855,15 @@ impl<'tcx> LateContext<'tcx> { /// rendering diagnostic. This is not the same as the precedence that would /// be used for pretty-printing HIR by rustc_hir_pretty. pub fn precedence(&self, expr: &hir::Expr<'_>) -> ExprPrecedence { - let for_each_attr = |id: hir::HirId, callback: &mut dyn FnMut(&hir::Attribute)| { + let has_attr = |id: hir::HirId| -> bool { for attr in self.tcx.hir_attrs(id) { if attr.span().desugaring_kind().is_none() { - callback(attr); + return true; } } + false }; - expr.precedence(&for_each_attr) + expr.precedence(&has_attr) } /// If the given expression is a local binding, find the initializer expression. diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index d0630383477..30ac1bbe94b 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -116,6 +116,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { let mut seen = FxHashMap::default(); let attrs = self.tcx.hir_attrs(hir_id); for attr in attrs { + let mut style = None; match attr { Attribute::Parsed(AttributeKind::Confusables { first_span, .. }) => { self.check_confusables(*first_span, target); @@ -163,10 +164,11 @@ impl<'tcx> CheckAttrVisitor<'tcx> { Attribute::Parsed(AttributeKind::AsPtr(attr_span)) => { self.check_applied_to_fn_or_method(hir_id, *attr_span, span, target) } - &Attribute::Parsed(AttributeKind::MayDangle(attr_span)) => { - self.check_may_dangle(hir_id, attr_span) + Attribute::Parsed(AttributeKind::MayDangle(attr_span)) => { + self.check_may_dangle(hir_id, *attr_span) } - Attribute::Unparsed(_) => { + Attribute::Unparsed(attr_item) => { + style = Some(attr_item.style); match attr.path().as_slice() { [sym::diagnostic, sym::do_not_recommend, ..] => { self.check_do_not_recommend(attr.span(), hir_id, target, attr, item) @@ -189,6 +191,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { } [sym::doc, ..] => self.check_doc_attrs( attr, + attr_item.style, hir_id, target, &mut specified_inline, @@ -350,14 +353,14 @@ impl<'tcx> CheckAttrVisitor<'tcx> { if let Some(BuiltinAttribute { type_: AttributeType::CrateLevel, .. }) = attr.ident().and_then(|ident| BUILTIN_ATTRIBUTE_MAP.get(&ident.name)) { - match attr.style() { - ast::AttrStyle::Outer => self.tcx.emit_node_span_lint( + match style { + Some(ast::AttrStyle::Outer) => self.tcx.emit_node_span_lint( UNUSED_ATTRIBUTES, hir_id, attr.span(), errors::OuterCrateLevelAttr, ), - ast::AttrStyle::Inner => self.tcx.emit_node_span_lint( + Some(ast::AttrStyle::Inner) | None => self.tcx.emit_node_span_lint( UNUSED_ATTRIBUTES, hir_id, attr.span(), @@ -371,7 +374,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { check_duplicates(self.tcx, attr, hir_id, *duplicates, &mut seen); } - self.check_unused_attribute(hir_id, attr) + self.check_unused_attribute(hir_id, attr, style) } self.check_repr(attrs, span, target, item, hir_id); @@ -1194,7 +1197,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { /// the first `inline`/`no_inline` attribute. fn check_doc_inline( &self, - attr: &Attribute, + style: AttrStyle, meta: &MetaItemInner, hir_id: HirId, target: Target, @@ -1224,8 +1227,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { meta.span(), errors::DocInlineOnlyUse { attr_span: meta.span(), - item_span: (attr.style() == AttrStyle::Outer) - .then(|| self.tcx.hir_span(hir_id)), + item_span: (style == AttrStyle::Outer).then(|| self.tcx.hir_span(hir_id)), }, ); } @@ -1234,7 +1236,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { fn check_doc_masked( &self, - attr: &Attribute, + style: AttrStyle, meta: &MetaItemInner, hir_id: HirId, target: Target, @@ -1246,8 +1248,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { meta.span(), errors::DocMaskedOnlyExternCrate { attr_span: meta.span(), - item_span: (attr.style() == AttrStyle::Outer) - .then(|| self.tcx.hir_span(hir_id)), + item_span: (style == AttrStyle::Outer).then(|| self.tcx.hir_span(hir_id)), }, ); return; @@ -1260,8 +1261,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { meta.span(), errors::DocMaskedNotExternCrateSelf { attr_span: meta.span(), - item_span: (attr.style() == AttrStyle::Outer) - .then(|| self.tcx.hir_span(hir_id)), + item_span: (style == AttrStyle::Outer).then(|| self.tcx.hir_span(hir_id)), }, ); } @@ -1285,13 +1285,14 @@ impl<'tcx> CheckAttrVisitor<'tcx> { fn check_attr_crate_level( &self, attr: &Attribute, + style: AttrStyle, meta: &MetaItemInner, hir_id: HirId, ) -> bool { if hir_id != CRATE_HIR_ID { // insert a bang between `#` and `[...` let bang_span = attr.span().lo() + BytePos(1); - let sugg = (attr.style() == AttrStyle::Outer + let sugg = (style == AttrStyle::Outer && self.tcx.hir_get_parent_item(hir_id) == CRATE_OWNER_ID) .then_some(errors::AttrCrateLevelOnlySugg { attr: attr.span().with_lo(bang_span).with_hi(bang_span), @@ -1308,7 +1309,13 @@ impl<'tcx> CheckAttrVisitor<'tcx> { } /// Checks that `doc(test(...))` attribute contains only valid attributes and are at the right place. - fn check_test_attr(&self, attr: &Attribute, meta: &MetaItemInner, hir_id: HirId) { + fn check_test_attr( + &self, + attr: &Attribute, + style: AttrStyle, + meta: &MetaItemInner, + hir_id: HirId, + ) { if let Some(metas) = meta.meta_item_list() { for i_meta in metas { match (i_meta.name(), i_meta.meta_item()) { @@ -1316,7 +1323,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { // Allowed everywhere like `#[doc]` } (Some(sym::no_crate_inject), _) => { - self.check_attr_crate_level(attr, meta, hir_id); + self.check_attr_crate_level(attr, style, meta, hir_id); } (_, Some(m)) => { self.tcx.emit_node_span_lint( @@ -1370,6 +1377,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { fn check_doc_attrs( &self, attr: &Attribute, + style: AttrStyle, hir_id: HirId, target: Target, specified_inline: &mut Option<(bool, Span)>, @@ -1404,7 +1412,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { } Some(sym::test) => { - self.check_test_attr(attr, meta, hir_id); + self.check_test_attr(attr, style, meta, hir_id); } Some( @@ -1415,25 +1423,25 @@ impl<'tcx> CheckAttrVisitor<'tcx> { | sym::html_root_url | sym::html_no_source, ) => { - self.check_attr_crate_level(attr, meta, hir_id); + self.check_attr_crate_level(attr, style, meta, hir_id); } Some(sym::cfg_hide) => { - if self.check_attr_crate_level(attr, meta, hir_id) { + if self.check_attr_crate_level(attr, style, meta, hir_id) { self.check_doc_cfg_hide(meta, hir_id); } } Some(sym::inline | sym::no_inline) => { - self.check_doc_inline(attr, meta, hir_id, target, specified_inline) + self.check_doc_inline(style, meta, hir_id, target, specified_inline) } - Some(sym::masked) => self.check_doc_masked(attr, meta, hir_id, target), + Some(sym::masked) => self.check_doc_masked(style, meta, hir_id, target), Some(sym::cfg | sym::hidden | sym::notable_trait) => {} Some(sym::rust_logo) => { - if self.check_attr_crate_level(attr, meta, hir_id) + if self.check_attr_crate_level(attr, style, meta, hir_id) && !self.tcx.features().rustdoc_internals() { feature_err( @@ -1472,7 +1480,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { errors::DocTestUnknownInclude { path, value: value.to_string(), - inner: match attr.style() { + inner: match style { AttrStyle::Inner => "!", AttrStyle::Outer => "", }, @@ -2426,7 +2434,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { } } - fn check_unused_attribute(&self, hir_id: HirId, attr: &Attribute) { + fn check_unused_attribute(&self, hir_id: HirId, attr: &Attribute, style: Option<AttrStyle>) { // FIXME(jdonszelmann): deduplicate these checks after more attrs are parsed. This is very // ugly now but can 100% be removed later. if let Attribute::Parsed(p) = attr { @@ -2479,14 +2487,14 @@ impl<'tcx> CheckAttrVisitor<'tcx> { }) { if hir_id != CRATE_HIR_ID { - match attr.style() { - ast::AttrStyle::Outer => self.tcx.emit_node_span_lint( + match style { + Some(ast::AttrStyle::Outer) => self.tcx.emit_node_span_lint( UNUSED_ATTRIBUTES, hir_id, attr.span(), errors::OuterCrateLevelAttr, ), - ast::AttrStyle::Inner => self.tcx.emit_node_span_lint( + Some(ast::AttrStyle::Inner) | None => self.tcx.emit_node_span_lint( UNUSED_ATTRIBUTES, hir_id, attr.span(), |
