Skip to content

Commit 2c82574

Browse files
committed
use correct edition when warning for unsafe attributes
If an attribute is re-emitted by a macro, the incorrect edition was used to emit warnings for unsafe attributes
1 parent b6685d7 commit 2c82574

File tree

3 files changed

+57
-1
lines changed

3 files changed

+57
-1
lines changed

compiler/rustc_parse/src/validate_attr.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -180,9 +180,14 @@ pub fn check_attribute_safety(
180180
let diag_span = attr_item.span();
181181

182182
// Attributes can be safe in earlier editions, and become unsafe in later ones.
183+
//
184+
// Use the span of the attribute's name to determine the edition: the span of the
185+
// attribute as a whole may be inaccurate if it was emitted by a macro.
186+
//
187+
// See https://github.com/rust-lang/rust/issues/142182.
183188
let emit_error = match unsafe_since {
184189
None => true,
185-
Some(unsafe_since) => attr.span.edition() >= unsafe_since,
190+
Some(unsafe_since) => path_span.edition() >= unsafe_since,
186191
};
187192

188193
if emit_error {
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
error: unsafe attribute used without unsafe
2+
--> $DIR/unsafe-attr-edition-span.rs:21:3
3+
|
4+
LL | #[no_mangle]
5+
| ^^^^^^^^^ usage of unsafe attribute
6+
|
7+
help: wrap the attribute in `unsafe(...)`
8+
|
9+
LL | #[unsafe(no_mangle)]
10+
| +++++++ +
11+
12+
error: unsafe attribute used without unsafe
13+
--> $DIR/unsafe-attr-edition-span.rs:25:7
14+
|
15+
LL | #[no_mangle]
16+
| ^^^^^^^^^ usage of unsafe attribute
17+
|
18+
help: wrap the attribute in `unsafe(...)`
19+
|
20+
LL | #[unsafe(no_mangle)]
21+
| +++++++ +
22+
23+
error: aborting due to 2 previous errors
24+
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
// Tests that the correct span is used to determine the edition of an attribute that was safe to use
2+
// in earlier editions, but has become `unsafe` in later editions.
3+
//
4+
// Determining the correct edition is non-trivial because of macro expansion. For instance,
5+
// the `thread_local!` macro (defined in std and hence using the most recent edition) parses the
6+
// attribute, and then re-emits it. Therefore, the span of the `#` token starting the
7+
// `#[no_mangle]` attribute has std's edition, while the attribute name has the edition of this
8+
// file, which may be different.
9+
10+
//@ revisions: e2015 e2018 e2021 e2024
11+
12+
//@[e2018] edition:2018
13+
//@[e2021] edition:2021
14+
//@[e2024] edition:2024
15+
//
16+
//@[e2015] check-pass
17+
//@[e2018] check-pass
18+
//@[e2021] check-pass
19+
#![crate_type = "lib"]
20+
21+
#[no_mangle] //[e2024]~ ERROR unsafe attribute used without unsafe
22+
static TEST_OUTSIDE: usize = 0;
23+
24+
thread_local! {
25+
#[no_mangle]//[e2024]~ ERROR unsafe attribute used without unsafe
26+
static TEST: usize = 0;
27+
}

0 commit comments

Comments
 (0)