From b6aa11a02ac81f6ce5d81bed6bc0cf47d29f83c1 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Thu, 16 Jul 2026 14:05:07 +1000 Subject: [PATCH 1/2] Add an unsafe attribute example to a test Just to improve coverage. --- .../proc-macro/capture-macro-rules-invoke.rs | 7 ++ .../capture-macro-rules-invoke.stdout | 108 +++++++++++------- 2 files changed, 73 insertions(+), 42 deletions(-) diff --git a/tests/ui/proc-macro/capture-macro-rules-invoke.rs b/tests/ui/proc-macro/capture-macro-rules-invoke.rs index 101461854c4ae..8c387e2486887 100644 --- a/tests/ui/proc-macro/capture-macro-rules-invoke.rs +++ b/tests/ui/proc-macro/capture-macro-rules-invoke.rs @@ -28,6 +28,12 @@ macro_rules! use_pat { } } +macro_rules! use_meta { + ($meta:meta) => { + print_bang_consume!($meta) + } +} + #[allow(dead_code)] struct Foo; impl Foo { @@ -47,6 +53,7 @@ impl Foo { [ a b c ], -30 ); + use_meta!(unsafe(no_mangle)); } fn with_pat(use_pat!((a, b)): (u32, u32)) { diff --git a/tests/ui/proc-macro/capture-macro-rules-invoke.stdout b/tests/ui/proc-macro/capture-macro-rules-invoke.stdout index 172e5ec6e4277..bd785f6f2919b 100644 --- a/tests/ui/proc-macro/capture-macro-rules-invoke.stdout +++ b/tests/ui/proc-macro/capture-macro-rules-invoke.stdout @@ -5,7 +5,7 @@ PRINT-BANG INPUT (DEBUG): TokenStream [ stream: TokenStream [ Ident { ident: "self", - span: $DIR/capture-macro-rules-invoke.rs:36:24: 36:28 (#0), + span: $DIR/capture-macro-rules-invoke.rs:42:24: 42:28 (#0), }, ], span: $DIR/capture-macro-rules-invoke.rs:21:21: 21:26 (#3), @@ -23,18 +23,18 @@ PRINT-BANG INPUT (DEBUG): TokenStream [ kind: Integer, symbol: "1", suffix: None, - span: $DIR/capture-macro-rules-invoke.rs:38:13: 38:14 (#0), + span: $DIR/capture-macro-rules-invoke.rs:44:13: 44:14 (#0), }, Punct { ch: '+', spacing: Alone, - span: $DIR/capture-macro-rules-invoke.rs:38:15: 38:16 (#0), + span: $DIR/capture-macro-rules-invoke.rs:44:15: 44:16 (#0), }, Literal { kind: Integer, symbol: "1", suffix: None, - span: $DIR/capture-macro-rules-invoke.rs:38:17: 38:18 (#0), + span: $DIR/capture-macro-rules-invoke.rs:44:17: 44:18 (#0), }, ], span: $DIR/capture-macro-rules-invoke.rs:14:29: 14:34 (#7), @@ -54,10 +54,10 @@ PRINT-BANG INPUT (DEBUG): TokenStream [ kind: Str, symbol: "a", suffix: None, - span: $DIR/capture-macro-rules-invoke.rs:39:15: 39:18 (#0), + span: $DIR/capture-macro-rules-invoke.rs:45:15: 45:18 (#0), }, ], - span: $DIR/capture-macro-rules-invoke.rs:39:13: 39:20 (#0), + span: $DIR/capture-macro-rules-invoke.rs:45:13: 45:20 (#0), }, ], span: $DIR/capture-macro-rules-invoke.rs:14:36: 14:42 (#7), @@ -72,22 +72,22 @@ PRINT-BANG INPUT (DEBUG): TokenStream [ stream: TokenStream [ Ident { ident: "let", - span: $DIR/capture-macro-rules-invoke.rs:40:13: 40:16 (#0), + span: $DIR/capture-macro-rules-invoke.rs:46:13: 46:16 (#0), }, Ident { ident: "a", - span: $DIR/capture-macro-rules-invoke.rs:40:17: 40:18 (#0), + span: $DIR/capture-macro-rules-invoke.rs:46:17: 46:18 (#0), }, Punct { ch: '=', spacing: Alone, - span: $DIR/capture-macro-rules-invoke.rs:40:19: 40:20 (#0), + span: $DIR/capture-macro-rules-invoke.rs:46:19: 46:20 (#0), }, Literal { kind: Integer, symbol: "1", suffix: None, - span: $DIR/capture-macro-rules-invoke.rs:40:21: 40:22 (#0), + span: $DIR/capture-macro-rules-invoke.rs:46:21: 46:22 (#0), }, ], span: $DIR/capture-macro-rules-invoke.rs:14:44: 14:49 (#7), @@ -102,7 +102,7 @@ PRINT-BANG INPUT (DEBUG): TokenStream [ stream: TokenStream [ Ident { ident: "String", - span: $DIR/capture-macro-rules-invoke.rs:41:13: 41:19 (#0), + span: $DIR/capture-macro-rules-invoke.rs:47:13: 47:19 (#0), }, ], span: $DIR/capture-macro-rules-invoke.rs:14:51: 14:54 (#7), @@ -114,7 +114,7 @@ PRINT-BANG INPUT (DEBUG): TokenStream [ }, Ident { ident: "my_name", - span: $DIR/capture-macro-rules-invoke.rs:42:13: 42:20 (#0), + span: $DIR/capture-macro-rules-invoke.rs:48:13: 48:20 (#0), }, Punct { ch: ',', @@ -127,11 +127,11 @@ PRINT-BANG INPUT (DEBUG): TokenStream [ Punct { ch: '\'', spacing: Joint, - span: $DIR/capture-macro-rules-invoke.rs:43:13: 43:15 (#0), + span: $DIR/capture-macro-rules-invoke.rs:49:13: 49:15 (#0), }, Ident { ident: "a", - span: $DIR/capture-macro-rules-invoke.rs:43:13: 43:15 (#0), + span: $DIR/capture-macro-rules-invoke.rs:49:13: 49:15 (#0), }, ], span: $DIR/capture-macro-rules-invoke.rs:15:29: 15:38 (#7), @@ -146,18 +146,18 @@ PRINT-BANG INPUT (DEBUG): TokenStream [ stream: TokenStream [ Ident { ident: "my_val", - span: $DIR/capture-macro-rules-invoke.rs:44:13: 44:19 (#0), + span: $DIR/capture-macro-rules-invoke.rs:50:13: 50:19 (#0), }, Punct { ch: '=', spacing: Alone, - span: $DIR/capture-macro-rules-invoke.rs:44:20: 44:21 (#0), + span: $DIR/capture-macro-rules-invoke.rs:50:20: 50:21 (#0), }, Literal { kind: Integer, symbol: "30", suffix: None, - span: $DIR/capture-macro-rules-invoke.rs:44:22: 44:24 (#0), + span: $DIR/capture-macro-rules-invoke.rs:50:22: 50:24 (#0), }, ], span: $DIR/capture-macro-rules-invoke.rs:15:40: 15:45 (#7), @@ -172,35 +172,35 @@ PRINT-BANG INPUT (DEBUG): TokenStream [ stream: TokenStream [ Ident { ident: "std", - span: $DIR/capture-macro-rules-invoke.rs:45:13: 45:16 (#0), + span: $DIR/capture-macro-rules-invoke.rs:51:13: 51:16 (#0), }, Punct { ch: ':', spacing: Joint, - span: $DIR/capture-macro-rules-invoke.rs:45:16: 45:17 (#0), + span: $DIR/capture-macro-rules-invoke.rs:51:16: 51:17 (#0), }, Punct { ch: ':', spacing: Alone, - span: $DIR/capture-macro-rules-invoke.rs:45:17: 45:18 (#0), + span: $DIR/capture-macro-rules-invoke.rs:51:17: 51:18 (#0), }, Ident { ident: "option", - span: $DIR/capture-macro-rules-invoke.rs:45:18: 45:24 (#0), + span: $DIR/capture-macro-rules-invoke.rs:51:18: 51:24 (#0), }, Punct { ch: ':', spacing: Joint, - span: $DIR/capture-macro-rules-invoke.rs:45:24: 45:25 (#0), + span: $DIR/capture-macro-rules-invoke.rs:51:24: 51:25 (#0), }, Punct { ch: ':', spacing: Alone, - span: $DIR/capture-macro-rules-invoke.rs:45:25: 45:26 (#0), + span: $DIR/capture-macro-rules-invoke.rs:51:25: 51:26 (#0), }, Ident { ident: "Option", - span: $DIR/capture-macro-rules-invoke.rs:45:26: 45:32 (#0), + span: $DIR/capture-macro-rules-invoke.rs:51:26: 51:32 (#0), }, ], span: $DIR/capture-macro-rules-invoke.rs:15:47: 15:52 (#7), @@ -215,35 +215,35 @@ PRINT-BANG INPUT (DEBUG): TokenStream [ stream: TokenStream [ Ident { ident: "pub", - span: $DIR/capture-macro-rules-invoke.rs:46:13: 46:16 (#0), + span: $DIR/capture-macro-rules-invoke.rs:52:13: 52:16 (#0), }, Group { delimiter: Parenthesis, stream: TokenStream [ Ident { ident: "in", - span: $DIR/capture-macro-rules-invoke.rs:46:17: 46:19 (#0), + span: $DIR/capture-macro-rules-invoke.rs:52:17: 52:19 (#0), }, Ident { ident: "some", - span: $DIR/capture-macro-rules-invoke.rs:46:20: 46:24 (#0), + span: $DIR/capture-macro-rules-invoke.rs:52:20: 52:24 (#0), }, Punct { ch: ':', spacing: Joint, - span: $DIR/capture-macro-rules-invoke.rs:46:24: 46:25 (#0), + span: $DIR/capture-macro-rules-invoke.rs:52:24: 52:25 (#0), }, Punct { ch: ':', spacing: Alone, - span: $DIR/capture-macro-rules-invoke.rs:46:25: 46:26 (#0), + span: $DIR/capture-macro-rules-invoke.rs:52:25: 52:26 (#0), }, Ident { ident: "path", - span: $DIR/capture-macro-rules-invoke.rs:46:26: 46:30 (#0), + span: $DIR/capture-macro-rules-invoke.rs:52:26: 52:30 (#0), }, ], - span: $DIR/capture-macro-rules-invoke.rs:46:16: 46:31 (#0), + span: $DIR/capture-macro-rules-invoke.rs:52:16: 52:31 (#0), }, ], span: $DIR/capture-macro-rules-invoke.rs:15:54: 15:58 (#7), @@ -258,18 +258,18 @@ PRINT-BANG INPUT (DEBUG): TokenStream [ stream: TokenStream [ Ident { ident: "a", - span: $DIR/capture-macro-rules-invoke.rs:47:15: 47:16 (#0), + span: $DIR/capture-macro-rules-invoke.rs:53:15: 53:16 (#0), }, Ident { ident: "b", - span: $DIR/capture-macro-rules-invoke.rs:47:17: 47:18 (#0), + span: $DIR/capture-macro-rules-invoke.rs:53:17: 53:18 (#0), }, Ident { ident: "c", - span: $DIR/capture-macro-rules-invoke.rs:47:19: 47:20 (#0), + span: $DIR/capture-macro-rules-invoke.rs:53:19: 53:20 (#0), }, ], - span: $DIR/capture-macro-rules-invoke.rs:47:13: 47:22 (#0), + span: $DIR/capture-macro-rules-invoke.rs:53:13: 53:22 (#0), }, Punct { ch: ',', @@ -282,18 +282,42 @@ PRINT-BANG INPUT (DEBUG): TokenStream [ Punct { ch: '-', spacing: Alone, - span: $DIR/capture-macro-rules-invoke.rs:48:13: 48:14 (#0), + span: $DIR/capture-macro-rules-invoke.rs:54:13: 54:14 (#0), }, Literal { kind: Integer, symbol: "30", suffix: None, - span: $DIR/capture-macro-rules-invoke.rs:48:14: 48:16 (#0), + span: $DIR/capture-macro-rules-invoke.rs:54:14: 54:16 (#0), }, ], span: $DIR/capture-macro-rules-invoke.rs:15:65: 15:69 (#7), }, ] +PRINT-BANG INPUT (DISPLAY): unsafe(no_mangle) +PRINT-BANG DEEP-RE-COLLECTED (DISPLAY): unsafe (no_mangle) +PRINT-BANG INPUT (DEBUG): TokenStream [ + Group { + delimiter: None, + stream: TokenStream [ + Ident { + ident: "unsafe", + span: $DIR/capture-macro-rules-invoke.rs:56:19: 56:25 (#0), + }, + Group { + delimiter: Parenthesis, + stream: TokenStream [ + Ident { + ident: "no_mangle", + span: $DIR/capture-macro-rules-invoke.rs:56:26: 56:35 (#0), + }, + ], + span: $DIR/capture-macro-rules-invoke.rs:56:25: 56:36 (#0), + }, + ], + span: $DIR/capture-macro-rules-invoke.rs:33:29: 33:34 (#11), + }, +] PRINT-BANG INPUT (DISPLAY): (a, b) PRINT-BANG INPUT (DEBUG): TokenStream [ Group { @@ -304,21 +328,21 @@ PRINT-BANG INPUT (DEBUG): TokenStream [ stream: TokenStream [ Ident { ident: "a", - span: $DIR/capture-macro-rules-invoke.rs:52:27: 52:28 (#0), + span: $DIR/capture-macro-rules-invoke.rs:59:27: 59:28 (#0), }, Punct { ch: ',', spacing: Alone, - span: $DIR/capture-macro-rules-invoke.rs:52:28: 52:29 (#0), + span: $DIR/capture-macro-rules-invoke.rs:59:28: 59:29 (#0), }, Ident { ident: "b", - span: $DIR/capture-macro-rules-invoke.rs:52:30: 52:31 (#0), + span: $DIR/capture-macro-rules-invoke.rs:59:30: 59:31 (#0), }, ], - span: $DIR/capture-macro-rules-invoke.rs:52:26: 52:32 (#0), + span: $DIR/capture-macro-rules-invoke.rs:59:26: 59:32 (#0), }, ], - span: $DIR/capture-macro-rules-invoke.rs:27:21: 27:25 (#11), + span: $DIR/capture-macro-rules-invoke.rs:27:21: 27:25 (#15), }, ] From ea7bee75156b66bbdc6fb5be57edf4c709e5ac7e Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Thu, 16 Jul 2026 13:42:52 +1000 Subject: [PATCH 2/2] Change `AttrItem::span` from a method to a field Currently the method computes the span from the path's span and the args' span. That used to be fine but then `unsafe(..)`/`safe(..)` were added without it being changed. So it doesn't account for those optional keywords and parentheses. The only way to handle those reliably is with a dedicated span for the entire `AttrItem`. Consequences: - `NormalAttr` grows from 72 bytes to 80. (It's the only AST node that contains an `AttrItem`.) Not ideal, but non-doc-comment attributes aren't that common (not compared to expressions, for example). Also, `NormalAttr` is always boxed and jemalloc will round up 72 byte allocations to 80 bytes anyway. - In `lint-unsafe-code.rs` various spans now point to `unsafe(foo)` rather than just `foo`. (It makes sense to include the `unsafe` keyword in the complaint about unsafety.) --- compiler/rustc_ast/src/ast.rs | 12 +++++- compiler/rustc_ast/src/attr/mod.rs | 18 +++++---- .../rustc_attr_parsing/src/attributes/cfg.rs | 2 +- compiler/rustc_attr_parsing/src/interface.rs | 4 +- compiler/rustc_builtin_macros/src/autodiff.rs | 3 +- .../src/deriving/generic/mod.rs | 1 + compiler/rustc_builtin_macros/src/offload.rs | 4 +- compiler/rustc_expand/src/mbe/transcribe.rs | 2 +- compiler/rustc_parse/src/parser/attr.rs | 4 +- tests/ui/lint/lint-unsafe-code.stderr | 40 +++++++++---------- 10 files changed, 54 insertions(+), 36 deletions(-) diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs index 867c77d129de0..882464c5dcfea 100644 --- a/compiler/rustc_ast/src/ast.rs +++ b/compiler/rustc_ast/src/ast.rs @@ -3445,6 +3445,7 @@ impl NormalAttr { unsafety: Safety::Default, path: Path::from_ident(ident), args: AttrArgs::Empty, + span: ident.span, }, tokens: None, } @@ -3456,6 +3457,15 @@ pub struct AttrItem { pub unsafety: Safety, pub path: Path, pub args: AttrArgs, + /// The span of the entire attr item. For parse attrs this excludes `#[`/`]`. E.g.: + /// ```ignore (illustrative) + /// #[foo(bar)] + /// ^^^^^^^^ + /// #[unsafe(no_mangle)] + /// ^^^^^^^^^^^^^^^^^ + /// ``` + /// For internally constructed spans (`mk_attr_*`) the exact meaning may differ. + pub span: Span, } /// Synthetic attributes are inserted by the compiler. They cannot be written in source code, and @@ -4398,7 +4408,7 @@ mod size_asserts { static_assert_size!(MetaItem, 80); static_assert_size!(MetaItemKind, 40); static_assert_size!(MetaItemLit, 40); - static_assert_size!(NormalAttr, 72); + static_assert_size!(NormalAttr, 80); static_assert_size!(Param, 40); static_assert_size!(Pat, 64); static_assert_size!(PatKind, 48); diff --git a/compiler/rustc_ast/src/attr/mod.rs b/compiler/rustc_ast/src/attr/mod.rs index 424280e3c9be6..2a3251c80d15e 100644 --- a/compiler/rustc_ast/src/attr/mod.rs +++ b/compiler/rustc_ast/src/attr/mod.rs @@ -315,7 +315,7 @@ impl Attribute { // #[deprecated = "..."] if let Some(s) = meta.value_str() { - return Some(Ident { name: s, span: meta.span() }); + return Some(Ident { name: s, span: meta.span }); } // #[deprecated(note = "...")] @@ -342,10 +342,6 @@ impl AttrItem { if let [seg] = &*self.path.segments { Some(seg.ident.name) } else { None } } - pub fn span(&self) -> Span { - self.args.span().map_or(self.path.span, |args_span| self.path.span.to(args_span)) - } - pub fn meta_item_list(&self) -> Option> { match &self.args { AttrArgs::Delimited(args) if args.delim == Delimiter::Parenthesis => { @@ -794,6 +790,8 @@ fn mk_attr_tokens( LazyAttrTokenStream::new_direct(AttrTokenStream::new(tokens)) } +// `span` is used for the `Attribute` and everything within it (except for any span within +// `unsafety`). pub fn mk_attr_word( g: &AttrIdGenerator, style: AttrStyle, @@ -814,9 +812,11 @@ pub fn mk_attr_word( span, )); - mk_attr_from_item(g, AttrItem { unsafety, path, args }, tokens, style, span) + mk_attr_from_item(g, AttrItem { unsafety, path, args, span }, tokens, style, span) } +// `span` is used for the `Attribute` and everything within it (except for any span within +// `unsafety`). pub fn mk_attr_nested_word( g: &AttrIdGenerator, style: AttrStyle, @@ -855,9 +855,11 @@ pub fn mk_attr_nested_word( span, )); - mk_attr_from_item(g, AttrItem { unsafety, path, args: attr_args }, tokens, style, span) + mk_attr_from_item(g, AttrItem { unsafety, path, args: attr_args, span }, tokens, style, span) } +// `span` is used for the `Attribute` and everything within it (except for any span within +// `unsafety`). pub fn mk_attr_name_value_str( g: &AttrIdGenerator, style: AttrStyle, @@ -891,7 +893,7 @@ pub fn mk_attr_name_value_str( span, )); - mk_attr_from_item(g, AttrItem { unsafety, path, args }, tokens, style, span) + mk_attr_from_item(g, AttrItem { unsafety, path, args, span }, tokens, style, span) } pub fn filter_by_name(attrs: &[Attribute], name: Symbol) -> impl Iterator { diff --git a/compiler/rustc_attr_parsing/src/attributes/cfg.rs b/compiler/rustc_attr_parsing/src/attributes/cfg.rs index fc7f7731199e9..c0b0e6f03acc9 100644 --- a/compiler/rustc_attr_parsing/src/attributes/cfg.rs +++ b/compiler/rustc_attr_parsing/src/attributes/cfg.rs @@ -406,7 +406,7 @@ fn parse_cfg_attr_internal<'a>( let cfg_predicate = AttributeParser::parse_single_args( sess, attribute.span, - attribute.get_normal_item().span(), + attribute.get_normal_item().span, attribute.style, AttrPath { segments: attribute.path().into_boxed_slice(), span: attribute.span }, Some(attribute.get_normal_item().unsafety), diff --git a/compiler/rustc_attr_parsing/src/interface.rs b/compiler/rustc_attr_parsing/src/interface.rs index 54ba6c189b544..a15d5bfa175a7 100644 --- a/compiler/rustc_attr_parsing/src/interface.rs +++ b/compiler/rustc_attr_parsing/src/interface.rs @@ -172,7 +172,7 @@ impl<'sess> AttributeParser<'sess> { Self::parse_single_args( sess, attr.span, - attr_item.span(), + attr_item.span, attr.style, path, Some(attr_item.unsafety), @@ -334,7 +334,7 @@ impl<'sess> AttributeParser<'sess> { let attr_path = AttrPath::from_ast(&n.item.path, lower_span); let parts = n.item.path.segments.iter().map(|seg| seg.ident.name).collect::>(); - let inner_span = lower_span(n.item.span()); + let inner_span = lower_span(n.item.span); if let Some(accept) = ATTRIBUTE_PARSERS.accepters.get(parts.as_slice()) { self.check_attribute_safety( diff --git a/compiler/rustc_builtin_macros/src/autodiff.rs b/compiler/rustc_builtin_macros/src/autodiff.rs index 29013d7c8b94d..51ab44d8a03ef 100644 --- a/compiler/rustc_builtin_macros/src/autodiff.rs +++ b/compiler/rustc_builtin_macros/src/autodiff.rs @@ -20,7 +20,7 @@ mod llvm_enzyme { }; use rustc_expand::base::{Annotatable, ExtCtxt}; use rustc_hir::attrs::RustcAutodiff; - use rustc_span::{Ident, Span, Symbol, kw, sym}; + use rustc_span::{DUMMY_SP, Ident, Span, Symbol, kw, sym}; use thin_vec::{ThinVec, thin_vec}; use tracing::{debug, trace}; @@ -362,6 +362,7 @@ mod llvm_enzyme { unsafety: ast::Safety::Default, path: ast::Path::from_ident(Ident::with_dummy_span(sym::inline)), args: ast::AttrArgs::Delimited(never_arg), + span: DUMMY_SP, }; let inline_never_attr = Box::new(ast::NormalAttr { item: inline_item, tokens: None }); let new_id = ecx.sess.psess.attr_id_generator.mk_attr_id(); diff --git a/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs b/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs index fcba0b6be4ee0..78fb93cd1522c 100644 --- a/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs +++ b/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs @@ -825,6 +825,7 @@ impl<'a> TraitDef<'a> { }) .collect(), }), + span: self.span, }, self.span, ), diff --git a/compiler/rustc_builtin_macros/src/offload.rs b/compiler/rustc_builtin_macros/src/offload.rs index 6218674917098..cdb3ba22ec6c8 100644 --- a/compiler/rustc_builtin_macros/src/offload.rs +++ b/compiler/rustc_builtin_macros/src/offload.rs @@ -3,7 +3,7 @@ use rustc_ast::tokenstream::{DelimSpan, Spacing, TokenStream, TokenTree}; use rustc_ast::{AttrItem, ast}; use rustc_expand::base::{Annotatable, ExtCtxt}; use rustc_session::config::Offload; -use rustc_span::{Ident, Span, sym}; +use rustc_span::{DUMMY_SP, Ident, Span, sym}; use thin_vec::thin_vec; use crate::diagnostics; @@ -115,6 +115,7 @@ pub(crate) fn expand_kernel( unsafety: ast::Safety::Unsafe(span), path: ast::Path::from_ident(Ident::new(sym::no_mangle, span)), args: ast::AttrArgs::Empty, + span, }; let no_mangle_attr = Box::new(ast::NormalAttr { item: unsafe_item, tokens: None }); @@ -179,6 +180,7 @@ pub(crate) fn expand_kernel( unsafety: ast::Safety::Default, path: ast::Path::from_ident(Ident::with_dummy_span(sym::inline)), args: ast::AttrArgs::Delimited(never_arg), + span: DUMMY_SP, }; let inline_never_attr = Box::new(ast::NormalAttr { item: inline_item, tokens: None }); diff --git a/compiler/rustc_expand/src/mbe/transcribe.rs b/compiler/rustc_expand/src/mbe/transcribe.rs index 2cf7e6abe2a24..c5c1ed3937e3f 100644 --- a/compiler/rustc_expand/src/mbe/transcribe.rs +++ b/compiler/rustc_expand/src/mbe/transcribe.rs @@ -547,7 +547,7 @@ fn transcribe_pnr<'tx>( ParseNtResult::Meta(attr_item) => { let has_meta_form = attr_item.node.meta_kind().is_some(); mk_delimited( - attr_item.node.span(), + attr_item.node.span, MetaVarKind::Meta { has_meta_form }, TokenStream::from_ast(attr_item), ) diff --git a/compiler/rustc_parse/src/parser/attr.rs b/compiler/rustc_parse/src/parser/attr.rs index c0e3116211d8a..5e3f15fbdf56b 100644 --- a/compiler/rustc_parse/src/parser/attr.rs +++ b/compiler/rustc_parse/src/parser/attr.rs @@ -335,6 +335,7 @@ impl<'a> Parser<'a> { // Attr items don't have attributes. self.collect_tokens(None, AttrWrapper::empty(), force_collect, |this, _empty_attrs| { + let lo = this.token.span; let is_unsafe = this.eat_keyword(exp!(Unsafe)); let unsafety = if is_unsafe { let unsafe_span = this.prev_token.span; @@ -349,8 +350,9 @@ impl<'a> Parser<'a> { if is_unsafe { this.expect(exp!(CloseParen))?; } + let span = lo.to(this.prev_token.span); Ok(( - WithTokens::new(ast::AttrItem { unsafety, path, args }), + WithTokens::new(ast::AttrItem { unsafety, path, args, span }), Trailing::No, UsePreAttrPos::No, )) diff --git a/tests/ui/lint/lint-unsafe-code.stderr b/tests/ui/lint/lint-unsafe-code.stderr index 2f36aecc987da..7580756d612eb 100644 --- a/tests/ui/lint/lint-unsafe-code.stderr +++ b/tests/ui/lint/lint-unsafe-code.stderr @@ -190,34 +190,34 @@ LL | unsafe_in_macro!() = note: this error originates in the macro `unsafe_in_macro` (in Nightly builds, run with -Z macro-backtrace for more info) error: usage of the unsafe `#[naked]` attribute - --> $DIR/lint-unsafe-code.rs:139:10 + --> $DIR/lint-unsafe-code.rs:139:3 | LL | #[unsafe(naked)] fn naked1() { naked_asm!("halt") } - | ^^^^^ + | ^^^^^^^^^^^^^ | = note: the `#[naked]` attribute adds the safety obligation that the function's body must respect the function’s calling convention, uphold its signature, and either return or diverge (i.e., not fall through past the end of the assembly code). error: usage of the unsafe `#[force_target_feature]` attribute - --> $DIR/lint-unsafe-code.rs:168:10 + --> $DIR/lint-unsafe-code.rs:168:3 | LL | #[unsafe(force_target_feature(enable = "avx2"))] fn force_target_feature() { } - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: a function with the signature of the function the attribute is applied to must only be callable if the force-enabled features are guaranteed to be present error: usage of the unsafe `#[naked]` attribute - --> $DIR/lint-unsafe-code.rs:149:14 + --> $DIR/lint-unsafe-code.rs:149:7 | LL | #[unsafe(naked)] fn naked3() { naked_asm!("halt") } - | ^^^^^ + | ^^^^^^^^^^^^^ | = note: the `#[naked]` attribute adds the safety obligation that the function's body must respect the function’s calling convention, uphold its signature, and either return or diverge (i.e., not fall through past the end of the assembly code). error: usage of the unsafe `#[force_target_feature]` attribute - --> $DIR/lint-unsafe-code.rs:178:14 + --> $DIR/lint-unsafe-code.rs:178:7 | LL | #[unsafe(force_target_feature(enable = "avx2"))] fn force_target_feature() { } - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: a function with the signature of the function the attribute is applied to must only be callable if the force-enabled features are guaranteed to be present @@ -254,50 +254,50 @@ LL | #[export_name = "bar"] fn foo() {} = note: the linker's behavior with multiple libraries exporting duplicate symbol names is undefined and Rust cannot provide guarantees when you manually override them error: usage of the unsafe `#[naked]` attribute - --> $DIR/lint-unsafe-code.rs:144:14 + --> $DIR/lint-unsafe-code.rs:144:7 | LL | #[unsafe(naked)] fn naked2() { naked_asm!("halt") } - | ^^^^^ + | ^^^^^^^^^^^^^ | = note: the `#[naked]` attribute adds the safety obligation that the function's body must respect the function’s calling convention, uphold its signature, and either return or diverge (i.e., not fall through past the end of the assembly code). error: usage of the unsafe `#[naked]` attribute - --> $DIR/lint-unsafe-code.rs:154:14 + --> $DIR/lint-unsafe-code.rs:154:7 | LL | #[unsafe(naked)] fn naked4() { naked_asm!("halt") } - | ^^^^^ + | ^^^^^^^^^^^^^ | = note: the `#[naked]` attribute adds the safety obligation that the function's body must respect the function’s calling convention, uphold its signature, and either return or diverge (i.e., not fall through past the end of the assembly code). error: usage of the unsafe `#[force_target_feature]` attribute - --> $DIR/lint-unsafe-code.rs:173:14 + --> $DIR/lint-unsafe-code.rs:173:7 | LL | #[unsafe(force_target_feature(enable = "avx2"))] fn force_target_feature() { } - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: a function with the signature of the function the attribute is applied to must only be callable if the force-enabled features are guaranteed to be present error: usage of the unsafe `#[force_target_feature]` attribute - --> $DIR/lint-unsafe-code.rs:182:14 + --> $DIR/lint-unsafe-code.rs:182:7 | LL | #[unsafe(force_target_feature(enable = "avx2"))] fn force_target_feature() { } - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: a function with the signature of the function the attribute is applied to must only be callable if the force-enabled features are guaranteed to be present error: usage of the unsafe `#[ffi_pure]` attribute - --> $DIR/lint-unsafe-code.rs:159:14 + --> $DIR/lint-unsafe-code.rs:159:7 | LL | #[unsafe(ffi_pure)] - | ^^^^^^^^ + | ^^^^^^^^^^^^^^^^ | = note: `#[ffi_pure]` functions shall have no effects except for its return value, which shall not change across two consecutive function calls with the same parameters. error: usage of the unsafe `#[ffi_const]` attribute - --> $DIR/lint-unsafe-code.rs:163:14 + --> $DIR/lint-unsafe-code.rs:163:7 | LL | #[unsafe(ffi_const)] - | ^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^ | = note: `#[ffi_const]` functions shall have no effects except for its return value, which can only depend on the values of the function parameters, and is not affected by changes to the observable state of the program.