From 7e6c083873b7b98aa52d47896107af11560aeaf5 Mon Sep 17 00:00:00 2001 From: Folkert Date: Tue, 16 Jul 2024 23:35:02 +0200 Subject: [PATCH] improve error message when `#[naked]` is used with `#[track-caller] and `#[target-feature]`` --- compiler/rustc_passes/messages.ftl | 2 +- compiler/rustc_passes/src/check_attr.rs | 26 ++++++++++--------- compiler/rustc_passes/src/errors.rs | 2 +- .../ui/asm/naked-functions-target-feature.rs | 13 ++++++++++ .../asm/naked-functions-target-feature.stderr | 12 +++++++++ .../rfc-2091-track-caller/error-with-naked.rs | 4 +-- .../error-with-naked.stderr | 14 +++++++--- 7 files changed, 53 insertions(+), 20 deletions(-) create mode 100644 tests/ui/asm/naked-functions-target-feature.rs create mode 100644 tests/ui/asm/naked-functions-target-feature.stderr diff --git a/compiler/rustc_passes/messages.ftl b/compiler/rustc_passes/messages.ftl index 2b6841181a7..8dec24feeba 100644 --- a/compiler/rustc_passes/messages.ftl +++ b/compiler/rustc_passes/messages.ftl @@ -485,7 +485,7 @@ passes_naked_functions_asm_options = passes_naked_functions_codegen_attribute = cannot use additional code generation attributes with `#[naked]` .label = this attribute is incompatible with `#[naked]` - .label2 = function marked with `#[naked]` here + .naked_attribute = function marked with `#[naked]` here passes_naked_functions_must_use_noreturn = asm in naked functions must use `noreturn` option diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index 739847d73d3..311c11a0388 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -421,20 +421,22 @@ impl<'tcx> CheckAttrVisitor<'tcx> { const FORBIDDEN: [rustc_span::Symbol; 3] = [sym::track_caller, sym::inline, sym::target_feature]; - for other_attr in attrs { - if FORBIDDEN.into_iter().any(|name| other_attr.has_name(name)) { - self.dcx().emit_err(errors::NakedFunctionCodegenAttribute { - span: other_attr.span, - naked_span: attr.span, - }); - - return false; - } - } - match target { Target::Fn - | Target::Method(MethodKind::Trait { body: true } | MethodKind::Inherent) => true, + | Target::Method(MethodKind::Trait { body: true } | MethodKind::Inherent) => { + for other_attr in attrs { + if FORBIDDEN.into_iter().any(|name| other_attr.has_name(name)) { + self.dcx().emit_err(errors::NakedFunctionCodegenAttribute { + span: other_attr.span, + naked_span: attr.span, + }); + + return false; + } + } + + true + } // FIXME(#80564): We permit struct fields, match arms and macro defs to have an // `#[naked]` attribute with just a lint, because we previously // erroneously allowed it and some crates used it accidentally, to be compatible diff --git a/compiler/rustc_passes/src/errors.rs b/compiler/rustc_passes/src/errors.rs index 03105795bfc..b6be096b43b 100644 --- a/compiler/rustc_passes/src/errors.rs +++ b/compiler/rustc_passes/src/errors.rs @@ -1188,7 +1188,7 @@ pub struct NakedFunctionCodegenAttribute { #[primary_span] #[label] pub span: Span, - #[label(passes_label2)] + #[label(passes_naked_attribute)] pub naked_span: Span, } diff --git a/tests/ui/asm/naked-functions-target-feature.rs b/tests/ui/asm/naked-functions-target-feature.rs new file mode 100644 index 00000000000..264e7e0976b --- /dev/null +++ b/tests/ui/asm/naked-functions-target-feature.rs @@ -0,0 +1,13 @@ +//@ only-x86_64 +//@ needs-asm-support +#![feature(naked_functions)] +#![crate_type = "lib"] + +use std::arch::asm; + +#[target_feature(enable = "sse2")] +//~^ ERROR [E0736] +#[naked] +pub unsafe extern "C" fn naked_target_feature() { + asm!("", options(noreturn)); +} diff --git a/tests/ui/asm/naked-functions-target-feature.stderr b/tests/ui/asm/naked-functions-target-feature.stderr new file mode 100644 index 00000000000..1a8b59f61fe --- /dev/null +++ b/tests/ui/asm/naked-functions-target-feature.stderr @@ -0,0 +1,12 @@ +error[E0736]: cannot use additional code generation attributes with `#[naked]` + --> $DIR/naked-functions-target-feature.rs:8:1 + | +LL | #[target_feature(enable = "sse2")] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this attribute is incompatible with `#[naked]` +LL | +LL | #[naked] + | -------- function marked with `#[naked]` here + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0736`. diff --git a/tests/ui/rfcs/rfc-2091-track-caller/error-with-naked.rs b/tests/ui/rfcs/rfc-2091-track-caller/error-with-naked.rs index 6eaa7d4d9bc..0c73b9abf35 100644 --- a/tests/ui/rfcs/rfc-2091-track-caller/error-with-naked.rs +++ b/tests/ui/rfcs/rfc-2091-track-caller/error-with-naked.rs @@ -3,7 +3,7 @@ use std::arch::asm; -#[track_caller] //~ ERROR cannot use `#[track_caller]` with `#[naked]` +#[track_caller] //~ ERROR [E0736] //~^ ERROR `#[track_caller]` requires Rust ABI #[naked] extern "C" fn f() { @@ -15,7 +15,7 @@ extern "C" fn f() { struct S; impl S { - #[track_caller] //~ ERROR cannot use `#[track_caller]` with `#[naked]` + #[track_caller] //~ ERROR [E0736] //~^ ERROR `#[track_caller]` requires Rust ABI #[naked] extern "C" fn g() { diff --git a/tests/ui/rfcs/rfc-2091-track-caller/error-with-naked.stderr b/tests/ui/rfcs/rfc-2091-track-caller/error-with-naked.stderr index 04c5c649d7f..7ab9f8b39eb 100644 --- a/tests/ui/rfcs/rfc-2091-track-caller/error-with-naked.stderr +++ b/tests/ui/rfcs/rfc-2091-track-caller/error-with-naked.stderr @@ -1,14 +1,20 @@ -error[E0736]: cannot use `#[track_caller]` with `#[naked]` +error[E0736]: cannot use additional code generation attributes with `#[naked]` --> $DIR/error-with-naked.rs:6:1 | LL | #[track_caller] - | ^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^ this attribute is incompatible with `#[naked]` +LL | +LL | #[naked] + | -------- function marked with `#[naked]` here -error[E0736]: cannot use `#[track_caller]` with `#[naked]` +error[E0736]: cannot use additional code generation attributes with `#[naked]` --> $DIR/error-with-naked.rs:18:5 | LL | #[track_caller] - | ^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^ this attribute is incompatible with `#[naked]` +LL | +LL | #[naked] + | -------- function marked with `#[naked]` here error[E0737]: `#[track_caller]` requires Rust ABI --> $DIR/error-with-naked.rs:6:1