diff --git a/compiler/rustc_attr_parsing/src/validate_attr.rs b/compiler/rustc_attr_parsing/src/validate_attr.rs index 927417f89f8c0..4065fe7ce1735 100644 --- a/compiler/rustc_attr_parsing/src/validate_attr.rs +++ b/compiler/rustc_attr_parsing/src/validate_attr.rs @@ -209,7 +209,7 @@ pub fn check_attribute_safety( // - Normal builtin attribute // - Writing `#[unsafe(..)]` is not permitted on normal builtin attributes - (Some(AttributeSafety::Normal), Safety::Unsafe(unsafe_span)) => { + (None | Some(AttributeSafety::Normal), Safety::Unsafe(unsafe_span)) => { psess.dcx().emit_err(errors::InvalidAttrUnsafe { span: unsafe_span, name: attr_item.path.clone(), @@ -218,15 +218,10 @@ pub fn check_attribute_safety( // - Normal builtin attribute // - No explicit `#[unsafe(..)]` written. - (Some(AttributeSafety::Normal), Safety::Default) => { + (None | Some(AttributeSafety::Normal), Safety::Default) => { // OK } - // - Non-builtin attribute - (None, Safety::Unsafe(_) | Safety::Default) => { - // OK (not checked here) - } - ( Some(AttributeSafety::Unsafe { .. } | AttributeSafety::Normal) | None, Safety::Safe(..), diff --git a/compiler/rustc_expand/src/expand.rs b/compiler/rustc_expand/src/expand.rs index 276490bc0c9d5..1dbf7b4726498 100644 --- a/compiler/rustc_expand/src/expand.rs +++ b/compiler/rustc_expand/src/expand.rs @@ -886,9 +886,6 @@ impl<'a, 'b> MacroExpander<'a, 'b> { } } } else if let SyntaxExtensionKind::NonMacroAttr = ext { - if let ast::Safety::Unsafe(span) = attr.get_normal_item().unsafety { - self.cx.dcx().span_err(span, "unnecessary `unsafe` on safe attribute"); - } // `-Zmacro-stats` ignores these because they don't do any real expansion. self.cx.expanded_inert_attrs.mark(&attr); item.visit_attrs(|attrs| attrs.insert(pos, attr)); diff --git a/tests/ui/attributes/proc-macro-unsafe.rs b/tests/ui/attributes/proc-macro-unsafe.rs new file mode 100644 index 0000000000000..7849df8256098 --- /dev/null +++ b/tests/ui/attributes/proc-macro-unsafe.rs @@ -0,0 +1,9 @@ +//@ proc-macro: external-macro-use.rs + +extern crate external_macro_use; + +#[unsafe(external_macro_use::a)] +//~^ ERROR unnecessary `unsafe` on safe attribute +fn f() {} + +fn main() {} diff --git a/tests/ui/attributes/proc-macro-unsafe.stderr b/tests/ui/attributes/proc-macro-unsafe.stderr new file mode 100644 index 0000000000000..ccc19bb01d2fe --- /dev/null +++ b/tests/ui/attributes/proc-macro-unsafe.stderr @@ -0,0 +1,8 @@ +error: unnecessary `unsafe` on safe attribute + --> $DIR/proc-macro-unsafe.rs:5:3 + | +LL | #[unsafe(external_macro_use::a)] + | ^^^^^^ + +error: aborting due to 1 previous error + diff --git a/tests/ui/attributes/unsafe/double-unsafe-attributes.rs b/tests/ui/attributes/unsafe/double-unsafe-attributes.rs index c0181d960539c..894d1327da799 100644 --- a/tests/ui/attributes/unsafe/double-unsafe-attributes.rs +++ b/tests/ui/attributes/unsafe/double-unsafe-attributes.rs @@ -1,7 +1,7 @@ #[unsafe(unsafe(no_mangle))] //~^ ERROR expected identifier, found keyword `unsafe` //~| ERROR cannot find attribute `r#unsafe` in this scope -//~| ERROR unnecessary `unsafe` +//~| ERROR `r#unsafe` is not an unsafe attribute fn a() {} fn main() {} diff --git a/tests/ui/attributes/unsafe/double-unsafe-attributes.stderr b/tests/ui/attributes/unsafe/double-unsafe-attributes.stderr index 846800daa5465..0825cf794083d 100644 --- a/tests/ui/attributes/unsafe/double-unsafe-attributes.stderr +++ b/tests/ui/attributes/unsafe/double-unsafe-attributes.stderr @@ -9,11 +9,13 @@ help: escape `unsafe` to use it as an identifier LL | #[unsafe(r#unsafe(no_mangle))] | ++ -error: unnecessary `unsafe` on safe attribute +error: `r#unsafe` is not an unsafe attribute --> $DIR/double-unsafe-attributes.rs:1:3 | LL | #[unsafe(unsafe(no_mangle))] - | ^^^^^^ + | ^^^^^^ this is not an unsafe attribute + | + = note: extraneous unsafe is not allowed in attributes error: cannot find attribute `r#unsafe` in this scope --> $DIR/double-unsafe-attributes.rs:1:10 diff --git a/tests/ui/attributes/unsafe/unsafe-safe-attribute_diagnostic.rs b/tests/ui/attributes/unsafe/unsafe-safe-attribute_diagnostic.rs index d9054248a292c..b74dffe9eb185 100644 --- a/tests/ui/attributes/unsafe/unsafe-safe-attribute_diagnostic.rs +++ b/tests/ui/attributes/unsafe/unsafe-safe-attribute_diagnostic.rs @@ -1,4 +1,4 @@ -#[unsafe(diagnostic::on_unimplemented( //~ ERROR: unnecessary `unsafe` +#[unsafe(diagnostic::on_unimplemented( //~ ERROR: `diagnostic::on_unimplemented` is not an unsafe attribute message = "testing", ))] trait Foo {} diff --git a/tests/ui/attributes/unsafe/unsafe-safe-attribute_diagnostic.stderr b/tests/ui/attributes/unsafe/unsafe-safe-attribute_diagnostic.stderr index a7662f5ee6c7d..3bc291db5acf8 100644 --- a/tests/ui/attributes/unsafe/unsafe-safe-attribute_diagnostic.stderr +++ b/tests/ui/attributes/unsafe/unsafe-safe-attribute_diagnostic.stderr @@ -1,8 +1,10 @@ -error: unnecessary `unsafe` on safe attribute +error: `diagnostic::on_unimplemented` is not an unsafe attribute --> $DIR/unsafe-safe-attribute_diagnostic.rs:1:3 | LL | #[unsafe(diagnostic::on_unimplemented( - | ^^^^^^ + | ^^^^^^ this is not an unsafe attribute + | + = note: extraneous unsafe is not allowed in attributes error: aborting due to 1 previous error