Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 16 additions & 3 deletions compiler/rustc_attr_parsing/src/safety.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,16 +62,28 @@ impl<'sess, S: Stage> AttributeParser<'sess, S> {
Some(unsafe_since) => path_span.edition() >= unsafe_since,
};

let mut not_from_proc_macro = true;
if diag_span.from_expansion()
&& let Ok(mut snippet) = self.sess.source_map().span_to_snippet(diag_span)
{
snippet.retain(|c| !c.is_whitespace());
if snippet.contains("!(") || snippet.starts_with("#[") && snippet.ends_with("]")
{
not_from_proc_macro = false;
}
}

if emit_error {
self.stage.emit_err(
self.sess,
crate::session_diagnostics::UnsafeAttrOutsideUnsafe {
span: path_span,
suggestion:
suggestion: not_from_proc_macro.then(|| {
crate::session_diagnostics::UnsafeAttrOutsideUnsafeSuggestion {
left: diag_span.shrink_to_lo(),
right: diag_span.shrink_to_hi(),
},
}
}),
},
);
} else {
Expand All @@ -81,7 +93,8 @@ impl<'sess, S: Stage> AttributeParser<'sess, S> {
span: path_span,
kind: AttributeLintKind::UnsafeAttrOutsideUnsafe {
attribute_name_span: path_span,
sugg_spans: (diag_span.shrink_to_lo(), diag_span.shrink_to_hi()),
sugg_spans: not_from_proc_macro
.then(|| (diag_span.shrink_to_lo(), diag_span.shrink_to_hi())),
},
})
}
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_attr_parsing/src/session_diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -758,7 +758,7 @@ pub(crate) struct UnsafeAttrOutsideUnsafe {
#[label]
pub span: Span,
#[subdiagnostic]
pub suggestion: UnsafeAttrOutsideUnsafeSuggestion,
pub suggestion: Option<UnsafeAttrOutsideUnsafeSuggestion>,
}

#[derive(Subdiagnostic)]
Expand Down
14 changes: 7 additions & 7 deletions compiler/rustc_lint/src/early/diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -353,14 +353,14 @@ pub fn decorate_attribute_lint(
}
.decorate_lint(diag)
}
&AttributeLintKind::UnsafeAttrOutsideUnsafe {
attribute_name_span,
sugg_spans: (left, right),
} => lints::UnsafeAttrOutsideUnsafeLint {
span: attribute_name_span,
suggestion: lints::UnsafeAttrOutsideUnsafeSuggestion { left, right },
&AttributeLintKind::UnsafeAttrOutsideUnsafe { attribute_name_span, sugg_spans } => {
lints::UnsafeAttrOutsideUnsafeLint {
span: attribute_name_span,
suggestion: sugg_spans
.map(|(left, right)| lints::UnsafeAttrOutsideUnsafeSuggestion { left, right }),
}
.decorate_lint(diag)
}
.decorate_lint(diag),
&AttributeLintKind::UnexpectedCfgName(name, value) => {
check_cfg::unexpected_cfg_name(sess, tcx, name, value).decorate_lint(diag)
}
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_lint/src/lints.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3177,7 +3177,7 @@ pub(crate) struct UnsafeAttrOutsideUnsafeLint {
#[label]
pub span: Span,
#[subdiagnostic]
pub suggestion: UnsafeAttrOutsideUnsafeSuggestion,
pub suggestion: Option<UnsafeAttrOutsideUnsafeSuggestion>,
}

#[derive(Subdiagnostic)]
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_lint_defs/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -729,7 +729,7 @@ pub enum AttributeLintKind {
},
UnsafeAttrOutsideUnsafe {
attribute_name_span: Span,
sugg_spans: (Span, Span),
sugg_spans: Option<(Span, Span)>,
},
UnexpectedCfgName((Symbol, Span), Option<(Symbol, Span)>),
UnexpectedCfgValue((Symbol, Span), Option<(Symbol, Span)>),
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
//@ edition: 2024

extern crate proc_macro;

use proc_macro::TokenStream;

#[proc_macro]
pub fn missing_unsafe(_input: TokenStream) -> TokenStream {
"#[no_mangle] pub fn abc() {}".parse().unwrap()
}

#[proc_macro_attribute]
pub fn attr_missing_unsafe(_attr: TokenStream, _input: TokenStream) -> TokenStream {
"#[no_mangle] pub fn bar() {}".parse().unwrap()
}

#[proc_macro_derive(AttrMissingUnsafe)]
pub fn derive_attr_missing_unsafe(_input: TokenStream) -> TokenStream {
"#[no_mangle] pub fn baz() {}".parse().unwrap()
}

#[proc_macro]
pub fn macro_rules_missing_unsafe(_input: TokenStream) -> TokenStream {
"macro_rules! make_fn {
() => { #[no_mangle] pub fn foo() { } };
}"
.parse()
.unwrap()
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// Test for unsafe attributes generated by a proc-macro.

//@ proc-macro: unsafe-attributes-pm-in-2024.rs
//@ ignore-backends: gcc

unsafe_attributes_pm_in_2024::missing_unsafe!(); //~ ERROR unsafe attribute used without unsafe

#[unsafe_attributes_pm_in_2024::attr_missing_unsafe] //~ ERROR unsafe attribute used without unsafe
pub fn bar() {}

#[derive(unsafe_attributes_pm_in_2024::AttrMissingUnsafe)] //~ ERROR unsafe attribute used without unsafe
struct Baz;

unsafe_attributes_pm_in_2024::macro_rules_missing_unsafe!(); //~ ERROR unsafe attribute used without unsafe

make_fn!();

fn main() {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
error: unsafe attribute used without unsafe
--> $DIR/unsafe-attributes-from-pm-in-2024.rs:6:1
|
LL | unsafe_attributes_pm_in_2024::missing_unsafe!();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ usage of unsafe attribute
|
= 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)

error: unsafe attribute used without unsafe
--> $DIR/unsafe-attributes-from-pm-in-2024.rs:8:1
|
LL | #[unsafe_attributes_pm_in_2024::attr_missing_unsafe]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ usage of unsafe attribute
|
= 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)

error: unsafe attribute used without unsafe
--> $DIR/unsafe-attributes-from-pm-in-2024.rs:11:10
|
LL | #[derive(unsafe_attributes_pm_in_2024::AttrMissingUnsafe)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ usage of unsafe attribute
|
= 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)

error: unsafe attribute used without unsafe
--> $DIR/unsafe-attributes-from-pm-in-2024.rs:14:1
|
LL | unsafe_attributes_pm_in_2024::macro_rules_missing_unsafe!();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ usage of unsafe attribute
LL |
LL | make_fn!();
| ---------- in this macro invocation
|
= note: this error originates in the macro `make_fn` (in Nightly builds, run with -Z macro-backtrace for more info)

error: aborting due to 4 previous errors

Loading