Skip to content

Commit 087ca1f

Browse files
authored
Rollup merge of #149781 - mu001999-contrib:fix/149756, r=jdonszelmann
Don't suggest wrapping attr in unsafe if it may come from proc macro Don't emit the suggestion if the span may come from proc macro. Check this with the snippet because we cannot check if the span is from macro-rules or proc-macro (maybe this can happen in the future?). Fixes #149756
2 parents b3948e5 + 50e9839 commit 087ca1f

File tree

8 files changed

+110
-13
lines changed

8 files changed

+110
-13
lines changed

compiler/rustc_attr_parsing/src/safety.rs

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -62,16 +62,28 @@ impl<'sess, S: Stage> AttributeParser<'sess, S> {
6262
Some(unsafe_since) => path_span.edition() >= unsafe_since,
6363
};
6464

65+
let mut not_from_proc_macro = true;
66+
if diag_span.from_expansion()
67+
&& let Ok(mut snippet) = self.sess.source_map().span_to_snippet(diag_span)
68+
{
69+
snippet.retain(|c| !c.is_whitespace());
70+
if snippet.contains("!(") || snippet.starts_with("#[") && snippet.ends_with("]")
71+
{
72+
not_from_proc_macro = false;
73+
}
74+
}
75+
6576
if emit_error {
6677
self.stage.emit_err(
6778
self.sess,
6879
crate::session_diagnostics::UnsafeAttrOutsideUnsafe {
6980
span: path_span,
70-
suggestion:
81+
suggestion: not_from_proc_macro.then(|| {
7182
crate::session_diagnostics::UnsafeAttrOutsideUnsafeSuggestion {
7283
left: diag_span.shrink_to_lo(),
7384
right: diag_span.shrink_to_hi(),
74-
},
85+
}
86+
}),
7587
},
7688
);
7789
} else {
@@ -81,7 +93,8 @@ impl<'sess, S: Stage> AttributeParser<'sess, S> {
8193
span: path_span,
8294
kind: AttributeLintKind::UnsafeAttrOutsideUnsafe {
8395
attribute_name_span: path_span,
84-
sugg_spans: (diag_span.shrink_to_lo(), diag_span.shrink_to_hi()),
96+
sugg_spans: not_from_proc_macro
97+
.then(|| (diag_span.shrink_to_lo(), diag_span.shrink_to_hi())),
8598
},
8699
})
87100
}

compiler/rustc_attr_parsing/src/session_diagnostics.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -758,7 +758,7 @@ pub(crate) struct UnsafeAttrOutsideUnsafe {
758758
#[label]
759759
pub span: Span,
760760
#[subdiagnostic]
761-
pub suggestion: UnsafeAttrOutsideUnsafeSuggestion,
761+
pub suggestion: Option<UnsafeAttrOutsideUnsafeSuggestion>,
762762
}
763763

764764
#[derive(Subdiagnostic)]

compiler/rustc_lint/src/early/diagnostics.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -353,14 +353,14 @@ pub fn decorate_attribute_lint(
353353
}
354354
.decorate_lint(diag)
355355
}
356-
&AttributeLintKind::UnsafeAttrOutsideUnsafe {
357-
attribute_name_span,
358-
sugg_spans: (left, right),
359-
} => lints::UnsafeAttrOutsideUnsafeLint {
360-
span: attribute_name_span,
361-
suggestion: lints::UnsafeAttrOutsideUnsafeSuggestion { left, right },
356+
&AttributeLintKind::UnsafeAttrOutsideUnsafe { attribute_name_span, sugg_spans } => {
357+
lints::UnsafeAttrOutsideUnsafeLint {
358+
span: attribute_name_span,
359+
suggestion: sugg_spans
360+
.map(|(left, right)| lints::UnsafeAttrOutsideUnsafeSuggestion { left, right }),
361+
}
362+
.decorate_lint(diag)
362363
}
363-
.decorate_lint(diag),
364364
&AttributeLintKind::UnexpectedCfgName(name, value) => {
365365
check_cfg::unexpected_cfg_name(sess, tcx, name, value).decorate_lint(diag)
366366
}

compiler/rustc_lint/src/lints.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3177,7 +3177,7 @@ pub(crate) struct UnsafeAttrOutsideUnsafeLint {
31773177
#[label]
31783178
pub span: Span,
31793179
#[subdiagnostic]
3180-
pub suggestion: UnsafeAttrOutsideUnsafeSuggestion,
3180+
pub suggestion: Option<UnsafeAttrOutsideUnsafeSuggestion>,
31813181
}
31823182

31833183
#[derive(Subdiagnostic)]

compiler/rustc_lint_defs/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -729,7 +729,7 @@ pub enum AttributeLintKind {
729729
},
730730
UnsafeAttrOutsideUnsafe {
731731
attribute_name_span: Span,
732-
sugg_spans: (Span, Span),
732+
sugg_spans: Option<(Span, Span)>,
733733
},
734734
UnexpectedCfgName((Symbol, Span), Option<(Symbol, Span)>),
735735
UnexpectedCfgValue((Symbol, Span), Option<(Symbol, Span)>),
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
//@ edition: 2024
2+
3+
extern crate proc_macro;
4+
5+
use proc_macro::TokenStream;
6+
7+
#[proc_macro]
8+
pub fn missing_unsafe(_input: TokenStream) -> TokenStream {
9+
"#[no_mangle] pub fn abc() {}".parse().unwrap()
10+
}
11+
12+
#[proc_macro_attribute]
13+
pub fn attr_missing_unsafe(_attr: TokenStream, _input: TokenStream) -> TokenStream {
14+
"#[no_mangle] pub fn bar() {}".parse().unwrap()
15+
}
16+
17+
#[proc_macro_derive(AttrMissingUnsafe)]
18+
pub fn derive_attr_missing_unsafe(_input: TokenStream) -> TokenStream {
19+
"#[no_mangle] pub fn baz() {}".parse().unwrap()
20+
}
21+
22+
#[proc_macro]
23+
pub fn macro_rules_missing_unsafe(_input: TokenStream) -> TokenStream {
24+
"macro_rules! make_fn {
25+
() => { #[no_mangle] pub fn foo() { } };
26+
}"
27+
.parse()
28+
.unwrap()
29+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
// Test for unsafe attributes generated by a proc-macro.
2+
3+
//@ proc-macro: unsafe-attributes-pm-in-2024.rs
4+
//@ ignore-backends: gcc
5+
6+
unsafe_attributes_pm_in_2024::missing_unsafe!(); //~ ERROR unsafe attribute used without unsafe
7+
8+
#[unsafe_attributes_pm_in_2024::attr_missing_unsafe] //~ ERROR unsafe attribute used without unsafe
9+
pub fn bar() {}
10+
11+
#[derive(unsafe_attributes_pm_in_2024::AttrMissingUnsafe)] //~ ERROR unsafe attribute used without unsafe
12+
struct Baz;
13+
14+
unsafe_attributes_pm_in_2024::macro_rules_missing_unsafe!(); //~ ERROR unsafe attribute used without unsafe
15+
16+
make_fn!();
17+
18+
fn main() {}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
error: unsafe attribute used without unsafe
2+
--> $DIR/unsafe-attributes-from-pm-in-2024.rs:6:1
3+
|
4+
LL | unsafe_attributes_pm_in_2024::missing_unsafe!();
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ usage of unsafe attribute
6+
|
7+
= note: this error originates in the macro `unsafe_attributes_pm_in_2024::missing_unsafe` (in Nightly builds, run with -Z macro-backtrace for more info)
8+
9+
error: unsafe attribute used without unsafe
10+
--> $DIR/unsafe-attributes-from-pm-in-2024.rs:8:1
11+
|
12+
LL | #[unsafe_attributes_pm_in_2024::attr_missing_unsafe]
13+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ usage of unsafe attribute
14+
|
15+
= note: this error originates in the attribute macro `unsafe_attributes_pm_in_2024::attr_missing_unsafe` (in Nightly builds, run with -Z macro-backtrace for more info)
16+
17+
error: unsafe attribute used without unsafe
18+
--> $DIR/unsafe-attributes-from-pm-in-2024.rs:11:10
19+
|
20+
LL | #[derive(unsafe_attributes_pm_in_2024::AttrMissingUnsafe)]
21+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ usage of unsafe attribute
22+
|
23+
= note: this error originates in the derive macro `unsafe_attributes_pm_in_2024::AttrMissingUnsafe` (in Nightly builds, run with -Z macro-backtrace for more info)
24+
25+
error: unsafe attribute used without unsafe
26+
--> $DIR/unsafe-attributes-from-pm-in-2024.rs:14:1
27+
|
28+
LL | unsafe_attributes_pm_in_2024::macro_rules_missing_unsafe!();
29+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ usage of unsafe attribute
30+
LL |
31+
LL | make_fn!();
32+
| ---------- in this macro invocation
33+
|
34+
= note: this error originates in the macro `make_fn` (in Nightly builds, run with -Z macro-backtrace for more info)
35+
36+
error: aborting due to 4 previous errors
37+

0 commit comments

Comments
 (0)