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
This commit is contained in:
parent
b6685d748f
commit
2c8257493d
3 changed files with 57 additions and 1 deletions
|
|
@ -180,9 +180,14 @@ pub fn check_attribute_safety(
|
|||
let diag_span = attr_item.span();
|
||||
|
||||
// Attributes can be safe in earlier editions, and become unsafe in later ones.
|
||||
//
|
||||
// Use the span of the attribute's name to determine the edition: the span of the
|
||||
// attribute as a whole may be inaccurate if it was emitted by a macro.
|
||||
//
|
||||
// See https://github.com/rust-lang/rust/issues/142182.
|
||||
let emit_error = match unsafe_since {
|
||||
None => true,
|
||||
Some(unsafe_since) => attr.span.edition() >= unsafe_since,
|
||||
Some(unsafe_since) => path_span.edition() >= unsafe_since,
|
||||
};
|
||||
|
||||
if emit_error {
|
||||
|
|
|
|||
24
tests/ui/editions/unsafe-attr-edition-span.e2024.stderr
Normal file
24
tests/ui/editions/unsafe-attr-edition-span.e2024.stderr
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
error: unsafe attribute used without unsafe
|
||||
--> $DIR/unsafe-attr-edition-span.rs:21:3
|
||||
|
|
||||
LL | #[no_mangle]
|
||||
| ^^^^^^^^^ usage of unsafe attribute
|
||||
|
|
||||
help: wrap the attribute in `unsafe(...)`
|
||||
|
|
||||
LL | #[unsafe(no_mangle)]
|
||||
| +++++++ +
|
||||
|
||||
error: unsafe attribute used without unsafe
|
||||
--> $DIR/unsafe-attr-edition-span.rs:25:7
|
||||
|
|
||||
LL | #[no_mangle]
|
||||
| ^^^^^^^^^ usage of unsafe attribute
|
||||
|
|
||||
help: wrap the attribute in `unsafe(...)`
|
||||
|
|
||||
LL | #[unsafe(no_mangle)]
|
||||
| +++++++ +
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
27
tests/ui/editions/unsafe-attr-edition-span.rs
Normal file
27
tests/ui/editions/unsafe-attr-edition-span.rs
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
// Tests that the correct span is used to determine the edition of an attribute that was safe to use
|
||||
// in earlier editions, but has become `unsafe` in later editions.
|
||||
//
|
||||
// Determining the correct edition is non-trivial because of macro expansion. For instance,
|
||||
// the `thread_local!` macro (defined in std and hence using the most recent edition) parses the
|
||||
// attribute, and then re-emits it. Therefore, the span of the `#` token starting the
|
||||
// `#[no_mangle]` attribute has std's edition, while the attribute name has the edition of this
|
||||
// file, which may be different.
|
||||
|
||||
//@ revisions: e2015 e2018 e2021 e2024
|
||||
|
||||
//@[e2018] edition:2018
|
||||
//@[e2021] edition:2021
|
||||
//@[e2024] edition:2024
|
||||
//
|
||||
//@[e2015] check-pass
|
||||
//@[e2018] check-pass
|
||||
//@[e2021] check-pass
|
||||
#![crate_type = "lib"]
|
||||
|
||||
#[no_mangle] //[e2024]~ ERROR unsafe attribute used without unsafe
|
||||
static TEST_OUTSIDE: usize = 0;
|
||||
|
||||
thread_local! {
|
||||
#[no_mangle]//[e2024]~ ERROR unsafe attribute used without unsafe
|
||||
static TEST: usize = 0;
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue