about summary refs log tree commit diff
diff options
context:
space:
mode:
authorFolkert de Vries <folkert@folkertdev.nl>2025-03-26 19:44:53 +0100
committerFolkert de Vries <folkert@folkertdev.nl>2025-04-07 21:42:12 +0200
commit8866af388497e9ed3254147c015379d5d6cdb054 (patch)
tree2e1fd4da75487598fabe9d1f0722cd1fbe561b65
parent19cab6b878ab18dce4816d85ac52b317214c485f (diff)
downloadrust-8866af388497e9ed3254147c015379d5d6cdb054.tar.gz
rust-8866af388497e9ed3254147c015379d5d6cdb054.zip
Add `naked_functions_rustic_abi` feature gate
-rw-r--r--compiler/rustc_feature/src/unstable.rs2
-rw-r--r--compiler/rustc_lint/src/lib.rs5
-rw-r--r--compiler/rustc_lint_defs/src/builtin.rs34
-rw-r--r--compiler/rustc_passes/messages.ftl3
-rw-r--r--compiler/rustc_passes/src/check_attr.rs15
-rw-r--r--compiler/rustc_passes/src/errors.rs4
-rw-r--r--compiler/rustc_passes/src/naked_functions.rs33
-rw-r--r--compiler/rustc_span/src/symbol.rs1
-rw-r--r--tests/ui/asm/naked-functions-rustic-abi.rs27
-rw-r--r--tests/ui/asm/naked-functions-testattrs.rs9
-rw-r--r--tests/ui/asm/naked-functions-testattrs.stderr8
-rw-r--r--tests/ui/asm/naked-functions.rs12
-rw-r--r--tests/ui/asm/naked-functions.stderr22
-rw-r--r--tests/ui/feature-gates/feature-gate-naked_functions_rustic_abi.rs26
-rw-r--r--tests/ui/feature-gates/feature-gate-naked_functions_rustic_abi.stderr33
-rw-r--r--tests/ui/lint/removed-lints/undefined_naked_function_abi.rs5
-rw-r--r--tests/ui/lint/removed-lints/undefined_naked_function_abi.stderr10
17 files changed, 142 insertions, 107 deletions
diff --git a/compiler/rustc_feature/src/unstable.rs b/compiler/rustc_feature/src/unstable.rs
index 72468dd4714..e0af871d3fd 100644
--- a/compiler/rustc_feature/src/unstable.rs
+++ b/compiler/rustc_feature/src/unstable.rs
@@ -566,6 +566,8 @@ declare_features! (
     (incomplete, mut_ref, "1.79.0", Some(123076)),
     /// Allows using `#[naked]` on functions.
     (unstable, naked_functions, "1.9.0", Some(90957)),
+    /// Allows using `#[naked]` on `extern "Rust"` functions.
+    (unstable, naked_functions_rustic_abi, "CURRENT_RUSTC_VERSION", Some(138997)),
     /// Allows using `#[target_feature(enable = "...")]` on `#[naked]` on functions.
     (unstable, naked_functions_target_feature, "1.86.0", Some(138568)),
     /// Allows specifying the as-needed link modifier
diff --git a/compiler/rustc_lint/src/lib.rs b/compiler/rustc_lint/src/lib.rs
index c38a7540018..1863ba8f8fb 100644
--- a/compiler/rustc_lint/src/lib.rs
+++ b/compiler/rustc_lint/src/lib.rs
@@ -604,6 +604,11 @@ fn register_builtins(store: &mut LintStore) {
         "converted into hard error, see issue #127323 \
          <https://github.com/rust-lang/rust/issues/127323> for more information",
     );
+    store.register_removed(
+        "undefined_naked_function_abi",
+        "converted into hard error, see PR #139001 \
+         <https://github.com/rust-lang/rust/issues/139001> for more information",
+    );
 }
 
 fn register_internals(store: &mut LintStore) {
diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs
index 8a761a0a096..b25d2a30681 100644
--- a/compiler/rustc_lint_defs/src/builtin.rs
+++ b/compiler/rustc_lint_defs/src/builtin.rs
@@ -110,7 +110,6 @@ declare_lint_pass! {
         UNCONDITIONAL_PANIC,
         UNCONDITIONAL_RECURSION,
         UNCOVERED_PARAM_IN_PROJECTION,
-        UNDEFINED_NAKED_FUNCTION_ABI,
         UNEXPECTED_CFGS,
         UNFULFILLED_LINT_EXPECTATIONS,
         UNINHABITED_STATIC,
@@ -2831,39 +2830,6 @@ declare_lint! {
 }
 
 declare_lint! {
-    /// The `undefined_naked_function_abi` lint detects naked function definitions that
-    /// either do not specify an ABI or specify the Rust ABI.
-    ///
-    /// ### Example
-    ///
-    /// ```rust
-    /// #![feature(asm_experimental_arch, naked_functions)]
-    ///
-    /// use std::arch::naked_asm;
-    ///
-    /// #[naked]
-    /// pub fn default_abi() -> u32 {
-    ///     unsafe { naked_asm!(""); }
-    /// }
-    ///
-    /// #[naked]
-    /// pub extern "Rust" fn rust_abi() -> u32 {
-    ///     unsafe { naked_asm!(""); }
-    /// }
-    /// ```
-    ///
-    /// {{produces}}
-    ///
-    /// ### Explanation
-    ///
-    /// The Rust ABI is currently undefined. Therefore, naked functions should
-    /// specify a non-Rust ABI.
-    pub UNDEFINED_NAKED_FUNCTION_ABI,
-    Warn,
-    "undefined naked function ABI"
-}
-
-declare_lint! {
     /// The `ineffective_unstable_trait_impl` lint detects `#[unstable]` attributes which are not used.
     ///
     /// ### Example
diff --git a/compiler/rustc_passes/messages.ftl b/compiler/rustc_passes/messages.ftl
index 06398dd4f72..18cbbad92b6 100644
--- a/compiler/rustc_passes/messages.ftl
+++ b/compiler/rustc_passes/messages.ftl
@@ -738,9 +738,6 @@ passes_trait_impl_const_stable =
 passes_transparent_incompatible =
     transparent {$target} cannot have other repr hints
 
-passes_undefined_naked_function_abi =
-    Rust ABI is unsupported in naked functions
-
 passes_unknown_external_lang_item =
     unknown external lang item: `{$lang_item}`
 
diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs
index 9238c73cdb1..50ce2064129 100644
--- a/compiler/rustc_passes/src/check_attr.rs
+++ b/compiler/rustc_passes/src/check_attr.rs
@@ -607,6 +607,21 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
         match target {
             Target::Fn
             | Target::Method(MethodKind::Trait { body: true } | MethodKind::Inherent) => {
+                let fn_sig = self.tcx.hir_node(hir_id).fn_sig().unwrap();
+                let abi = fn_sig.header.abi;
+                if abi.is_rustic_abi() && !self.tcx.features().naked_functions_rustic_abi() {
+                    feature_err(
+                        &self.tcx.sess,
+                        sym::naked_functions_rustic_abi,
+                        fn_sig.span,
+                        format!(
+                            "`#[naked]` is currently unstable on `extern \"{}\"` functions",
+                            abi.as_str()
+                        ),
+                    )
+                    .emit();
+                }
+
                 for other_attr in attrs {
                     // this covers "sugared doc comments" of the form `/// ...`
                     // it does not cover `#[doc = "..."]`, which is handled below
diff --git a/compiler/rustc_passes/src/errors.rs b/compiler/rustc_passes/src/errors.rs
index 0ee17430aab..536cb96bf46 100644
--- a/compiler/rustc_passes/src/errors.rs
+++ b/compiler/rustc_passes/src/errors.rs
@@ -1197,10 +1197,6 @@ pub(crate) struct UnlabeledCfInWhileCondition<'a> {
     pub cf_type: &'a str,
 }
 
-#[derive(LintDiagnostic)]
-#[diag(passes_undefined_naked_function_abi)]
-pub(crate) struct UndefinedNakedFunctionAbi;
-
 #[derive(Diagnostic)]
 #[diag(passes_no_patterns)]
 pub(crate) struct NoPatterns {
diff --git a/compiler/rustc_passes/src/naked_functions.rs b/compiler/rustc_passes/src/naked_functions.rs
index d35aedf9a56..3c9f8b72c36 100644
--- a/compiler/rustc_passes/src/naked_functions.rs
+++ b/compiler/rustc_passes/src/naked_functions.rs
@@ -1,6 +1,5 @@
 //! Checks validity of naked functions.
 
-use rustc_abi::ExternAbi;
 use rustc_hir as hir;
 use rustc_hir::def::DefKind;
 use rustc_hir::def_id::{LocalDefId, LocalModDefId};
@@ -10,12 +9,11 @@ use rustc_middle::hir::nested_filter::OnlyBodies;
 use rustc_middle::query::Providers;
 use rustc_middle::span_bug;
 use rustc_middle::ty::TyCtxt;
-use rustc_session::lint::builtin::UNDEFINED_NAKED_FUNCTION_ABI;
 use rustc_span::{Span, sym};
 
 use crate::errors::{
     NakedAsmOutsideNakedFn, NakedFunctionsAsmBlock, NakedFunctionsMustNakedAsm, NoPatterns,
-    ParamsNotAllowed, UndefinedNakedFunctionAbi,
+    ParamsNotAllowed,
 };
 
 pub(crate) fn provide(providers: &mut Providers) {
@@ -29,26 +27,21 @@ fn check_mod_naked_functions(tcx: TyCtxt<'_>, module_def_id: LocalModDefId) {
             continue;
         }
 
-        let (fn_header, body_id) = match tcx.hir_node_by_def_id(def_id) {
+        let body = match tcx.hir_node_by_def_id(def_id) {
             hir::Node::Item(hir::Item {
-                kind: hir::ItemKind::Fn { sig, body: body_id, .. },
-                ..
+                kind: hir::ItemKind::Fn { body: body_id, .. }, ..
             })
             | hir::Node::TraitItem(hir::TraitItem {
-                kind: hir::TraitItemKind::Fn(sig, hir::TraitFn::Provided(body_id)),
+                kind: hir::TraitItemKind::Fn(_, hir::TraitFn::Provided(body_id)),
                 ..
             })
             | hir::Node::ImplItem(hir::ImplItem {
-                kind: hir::ImplItemKind::Fn(sig, body_id),
-                ..
-            }) => (sig.header, *body_id),
+                kind: hir::ImplItemKind::Fn(_, body_id), ..
+            }) => tcx.hir_body(*body_id),
             _ => continue,
         };
 
-        let body = tcx.hir_body(body_id);
-
         if tcx.has_attr(def_id, sym::naked) {
-            check_abi(tcx, def_id, fn_header.abi);
             check_no_patterns(tcx, body.params);
             check_no_parameters_use(tcx, body);
             check_asm(tcx, def_id, body);
@@ -60,20 +53,6 @@ fn check_mod_naked_functions(tcx: TyCtxt<'_>, module_def_id: LocalModDefId) {
     }
 }
 
-/// Checks that function uses non-Rust ABI.
-fn check_abi(tcx: TyCtxt<'_>, def_id: LocalDefId, abi: ExternAbi) {
-    if abi == ExternAbi::Rust {
-        let hir_id = tcx.local_def_id_to_hir_id(def_id);
-        let span = tcx.def_span(def_id);
-        tcx.emit_node_span_lint(
-            UNDEFINED_NAKED_FUNCTION_ABI,
-            hir_id,
-            span,
-            UndefinedNakedFunctionAbi,
-        );
-    }
-}
-
 /// Checks that parameters don't use patterns. Mirrors the checks for function declarations.
 fn check_no_patterns(tcx: TyCtxt<'_>, params: &[hir::Param<'_>]) {
     for param in params {
diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs
index 3e474243965..5906b242dda 100644
--- a/compiler/rustc_span/src/symbol.rs
+++ b/compiler/rustc_span/src/symbol.rs
@@ -1387,6 +1387,7 @@ symbols! {
         naked,
         naked_asm,
         naked_functions,
+        naked_functions_rustic_abi,
         naked_functions_target_feature,
         name,
         names,
diff --git a/tests/ui/asm/naked-functions-rustic-abi.rs b/tests/ui/asm/naked-functions-rustic-abi.rs
new file mode 100644
index 00000000000..b654d38ccc1
--- /dev/null
+++ b/tests/ui/asm/naked-functions-rustic-abi.rs
@@ -0,0 +1,27 @@
+//@ revisions: x86_64 aarch64
+//
+//@[aarch64] only-aarch64
+//@[x86_64] only-x86_64
+//
+//@ build-pass
+//@ needs-asm-support
+
+#![feature(naked_functions, naked_functions_rustic_abi, rust_cold_cc)]
+#![crate_type = "lib"]
+
+use std::arch::{asm, naked_asm};
+
+#[naked]
+pub unsafe fn rust_implicit() {
+    naked_asm!("ret");
+}
+
+#[naked]
+pub unsafe extern "Rust" fn rust_explicit() {
+    naked_asm!("ret");
+}
+
+#[naked]
+pub unsafe extern "rust-cold" fn rust_cold() {
+    naked_asm!("ret");
+}
diff --git a/tests/ui/asm/naked-functions-testattrs.rs b/tests/ui/asm/naked-functions-testattrs.rs
index 7e373270e9f..ad31876a77a 100644
--- a/tests/ui/asm/naked-functions-testattrs.rs
+++ b/tests/ui/asm/naked-functions-testattrs.rs
@@ -1,7 +1,6 @@
 //@ needs-asm-support
 //@ compile-flags: --test
 
-#![allow(undefined_naked_function_abi)]
 #![feature(naked_functions)]
 #![feature(test)]
 #![crate_type = "lib"]
@@ -11,7 +10,7 @@ use std::arch::naked_asm;
 #[test]
 #[naked]
 //~^ ERROR [E0736]
-fn test_naked() {
+extern "C" fn test_naked() {
     unsafe { naked_asm!("") };
 }
 
@@ -19,7 +18,7 @@ fn test_naked() {
 #[test]
 #[naked]
 //~^ ERROR [E0736]
-fn test_naked_should_panic() {
+extern "C" fn test_naked_should_panic() {
     unsafe { naked_asm!("") };
 }
 
@@ -27,13 +26,13 @@ fn test_naked_should_panic() {
 #[test]
 #[naked]
 //~^ ERROR [E0736]
-fn test_naked_ignore() {
+extern "C" fn test_naked_ignore() {
     unsafe { naked_asm!("") };
 }
 
 #[bench]
 #[naked]
 //~^ ERROR [E0736]
-fn bench_naked() {
+extern "C" fn bench_naked() {
     unsafe { naked_asm!("") };
 }
diff --git a/tests/ui/asm/naked-functions-testattrs.stderr b/tests/ui/asm/naked-functions-testattrs.stderr
index 4dabe41964a..0f0bb91b954 100644
--- a/tests/ui/asm/naked-functions-testattrs.stderr
+++ b/tests/ui/asm/naked-functions-testattrs.stderr
@@ -1,5 +1,5 @@
 error[E0736]: cannot use `#[naked]` with testing attributes
-  --> $DIR/naked-functions-testattrs.rs:12:1
+  --> $DIR/naked-functions-testattrs.rs:11:1
    |
 LL | #[test]
    | ------- function marked with testing attribute here
@@ -7,7 +7,7 @@ LL | #[naked]
    | ^^^^^^^^ `#[naked]` is incompatible with testing attributes
 
 error[E0736]: cannot use `#[naked]` with testing attributes
-  --> $DIR/naked-functions-testattrs.rs:20:1
+  --> $DIR/naked-functions-testattrs.rs:19:1
    |
 LL | #[test]
    | ------- function marked with testing attribute here
@@ -15,7 +15,7 @@ LL | #[naked]
    | ^^^^^^^^ `#[naked]` is incompatible with testing attributes
 
 error[E0736]: cannot use `#[naked]` with testing attributes
-  --> $DIR/naked-functions-testattrs.rs:28:1
+  --> $DIR/naked-functions-testattrs.rs:27:1
    |
 LL | #[test]
    | ------- function marked with testing attribute here
@@ -23,7 +23,7 @@ LL | #[naked]
    | ^^^^^^^^ `#[naked]` is incompatible with testing attributes
 
 error[E0736]: cannot use `#[naked]` with testing attributes
-  --> $DIR/naked-functions-testattrs.rs:35:1
+  --> $DIR/naked-functions-testattrs.rs:34:1
    |
 LL | #[bench]
    | -------- function marked with testing attribute here
diff --git a/tests/ui/asm/naked-functions.rs b/tests/ui/asm/naked-functions.rs
index 3d4d414539c..5bf2e2a3abd 100644
--- a/tests/ui/asm/naked-functions.rs
+++ b/tests/ui/asm/naked-functions.rs
@@ -123,18 +123,6 @@ unsafe extern "C" fn invalid_may_unwind() {
 }
 
 #[naked]
-pub unsafe fn default_abi() {
-    //~^ WARN Rust ABI is unsupported in naked functions
-    naked_asm!("");
-}
-
-#[naked]
-pub unsafe fn rust_abi() {
-    //~^ WARN Rust ABI is unsupported in naked functions
-    naked_asm!("");
-}
-
-#[naked]
 pub extern "C" fn valid_a<T>() -> T {
     unsafe {
         naked_asm!("");
diff --git a/tests/ui/asm/naked-functions.stderr b/tests/ui/asm/naked-functions.stderr
index 0898f3620f2..0a55bb9cd83 100644
--- a/tests/ui/asm/naked-functions.stderr
+++ b/tests/ui/asm/naked-functions.stderr
@@ -53,19 +53,19 @@ LL |     naked_asm!("", options(may_unwind));
    |                            ^^^^^^^^^^ the `may_unwind` option is not meaningful for global-scoped inline assembly
 
 error: this is a user specified error
-  --> $DIR/naked-functions.rs:169:5
+  --> $DIR/naked-functions.rs:157:5
    |
 LL |     compile_error!("this is a user specified error")
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: this is a user specified error
-  --> $DIR/naked-functions.rs:175:5
+  --> $DIR/naked-functions.rs:163:5
    |
 LL |     compile_error!("this is a user specified error");
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: asm template must be a string literal
-  --> $DIR/naked-functions.rs:182:16
+  --> $DIR/naked-functions.rs:170:16
    |
 LL |     naked_asm!(invalid_syntax)
    |                ^^^^^^^^^^^^^^
@@ -175,20 +175,6 @@ LL |
 LL |         *&y
    |         --- not allowed in naked functions
 
-warning: Rust ABI is unsupported in naked functions
-  --> $DIR/naked-functions.rs:126:1
-   |
-LL | pub unsafe fn default_abi() {
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = note: `#[warn(undefined_naked_function_abi)]` on by default
-
-warning: Rust ABI is unsupported in naked functions
-  --> $DIR/naked-functions.rs:132:1
-   |
-LL | pub unsafe fn rust_abi() {
-   | ^^^^^^^^^^^^^^^^^^^^^^^^
-
-error: aborting due to 25 previous errors; 2 warnings emitted
+error: aborting due to 25 previous errors
 
 For more information about this error, try `rustc --explain E0787`.
diff --git a/tests/ui/feature-gates/feature-gate-naked_functions_rustic_abi.rs b/tests/ui/feature-gates/feature-gate-naked_functions_rustic_abi.rs
new file mode 100644
index 00000000000..c91d8339944
--- /dev/null
+++ b/tests/ui/feature-gates/feature-gate-naked_functions_rustic_abi.rs
@@ -0,0 +1,26 @@
+//@ needs-asm-support
+//@ only-x86_64
+
+#![feature(naked_functions, rust_cold_cc)]
+
+use std::arch::naked_asm;
+
+#[naked]
+pub unsafe fn rust_implicit() {
+    //~^ ERROR `#[naked]` is currently unstable on `extern "Rust"` functions
+    naked_asm!("ret");
+}
+
+#[naked]
+pub unsafe extern "Rust" fn rust_explicit() {
+    //~^ ERROR `#[naked]` is currently unstable on `extern "Rust"` functions
+    naked_asm!("ret");
+}
+
+#[naked]
+pub unsafe extern "rust-cold" fn rust_cold() {
+    //~^ ERROR `#[naked]` is currently unstable on `extern "rust-cold"` functions
+    naked_asm!("ret");
+}
+
+fn main() {}
diff --git a/tests/ui/feature-gates/feature-gate-naked_functions_rustic_abi.stderr b/tests/ui/feature-gates/feature-gate-naked_functions_rustic_abi.stderr
new file mode 100644
index 00000000000..ba45e15ec86
--- /dev/null
+++ b/tests/ui/feature-gates/feature-gate-naked_functions_rustic_abi.stderr
@@ -0,0 +1,33 @@
+error[E0658]: `#[naked]` is currently unstable on `extern "Rust"` functions
+  --> $DIR/feature-gate-naked_functions_rustic_abi.rs:9:1
+   |
+LL | pub unsafe fn rust_implicit() {
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #138997 <https://github.com/rust-lang/rust/issues/138997> for more information
+   = help: add `#![feature(naked_functions_rustic_abi)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: `#[naked]` is currently unstable on `extern "Rust"` functions
+  --> $DIR/feature-gate-naked_functions_rustic_abi.rs:15:1
+   |
+LL | pub unsafe extern "Rust" fn rust_explicit() {
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #138997 <https://github.com/rust-lang/rust/issues/138997> for more information
+   = help: add `#![feature(naked_functions_rustic_abi)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: `#[naked]` is currently unstable on `extern "rust-cold"` functions
+  --> $DIR/feature-gate-naked_functions_rustic_abi.rs:21:1
+   |
+LL | pub unsafe extern "rust-cold" fn rust_cold() {
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #138997 <https://github.com/rust-lang/rust/issues/138997> for more information
+   = help: add `#![feature(naked_functions_rustic_abi)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0658`.
diff --git a/tests/ui/lint/removed-lints/undefined_naked_function_abi.rs b/tests/ui/lint/removed-lints/undefined_naked_function_abi.rs
new file mode 100644
index 00000000000..cf3ac66ac86
--- /dev/null
+++ b/tests/ui/lint/removed-lints/undefined_naked_function_abi.rs
@@ -0,0 +1,5 @@
+//@ check-pass
+
+#![deny(undefined_naked_function_abi)]
+//~^ WARN  lint `undefined_naked_function_abi` has been removed
+fn main() {}
diff --git a/tests/ui/lint/removed-lints/undefined_naked_function_abi.stderr b/tests/ui/lint/removed-lints/undefined_naked_function_abi.stderr
new file mode 100644
index 00000000000..5a546688beb
--- /dev/null
+++ b/tests/ui/lint/removed-lints/undefined_naked_function_abi.stderr
@@ -0,0 +1,10 @@
+warning: lint `undefined_naked_function_abi` has been removed: converted into hard error, see PR #139001 <https://github.com/rust-lang/rust/issues/139001> for more information
+  --> $DIR/undefined_naked_function_abi.rs:3:9
+   |
+LL | #![deny(undefined_naked_function_abi)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: `#[warn(renamed_and_removed_lints)]` on by default
+
+warning: 1 warning emitted
+