about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMatthias Krüger <matthias.krueger@famsik.de>2022-10-19 21:38:41 +0200
committerGitHub <noreply@github.com>2022-10-19 21:38:41 +0200
commit12775ce16a4449c0f04cbce14efc56ac8d9ed39a (patch)
treee269243eae42d3123a31d8b7ab53362410c3c84a
parentd17cef67a2e07c4146ce25628c5f179099b20596 (diff)
parentc4f829b2e5053cef753e010fa89bcc01b164a306 (diff)
downloadrust-12775ce16a4449c0f04cbce14efc56ac8d9ed39a.tar.gz
rust-12775ce16a4449c0f04cbce14efc56ac8d9ed39a.zip
Rollup merge of #103239 - m-ou-se:unstable-abi-fn-impl-check, r=lcnr
Allow #[unstable] impls for fn() with unstable abi.

This allows `#[unstable]` trait impls for `extern "unwind-C" fn()`, based on the fact that that abi and therefore that type is unstable.

See https://github.com/rust-lang/rust/pull/101263#issuecomment-1283099947
-rw-r--r--compiler/rustc_passes/src/stability.rs17
-rw-r--r--compiler/rustc_target/src/spec/abi.rs268
-rw-r--r--src/test/ui/stability-attribute/stability-attribute-trait-impl.rs16
-rw-r--r--src/test/ui/stability-attribute/stability-attribute-trait-impl.stderr16
4 files changed, 153 insertions, 164 deletions
diff --git a/compiler/rustc_passes/src/stability.rs b/compiler/rustc_passes/src/stability.rs
index cfd6acd8d7c..9591aeb881f 100644
--- a/compiler/rustc_passes/src/stability.rs
+++ b/compiler/rustc_passes/src/stability.rs
@@ -891,8 +891,25 @@ impl<'tcx> Visitor<'tcx> for CheckTraitImplStable<'tcx> {
         if let TyKind::Never = t.kind {
             self.fully_stable = false;
         }
+        if let TyKind::BareFn(f) = t.kind {
+            if rustc_target::spec::abi::is_stable(f.abi.name()).is_err() {
+                self.fully_stable = false;
+            }
+        }
         intravisit::walk_ty(self, t)
     }
+
+    fn visit_fn_decl(&mut self, fd: &'tcx hir::FnDecl<'tcx>) {
+        for ty in fd.inputs {
+            self.visit_ty(ty)
+        }
+        if let hir::FnRetTy::Return(output_ty) = fd.output {
+            match output_ty.kind {
+                TyKind::Never => {} // `-> !` is stable
+                _ => self.visit_ty(output_ty),
+            }
+        }
+    }
 }
 
 /// Given the list of enabled features that were not language features (i.e., that
diff --git a/compiler/rustc_target/src/spec/abi.rs b/compiler/rustc_target/src/spec/abi.rs
index c915124434b..ce45fa13970 100644
--- a/compiler/rustc_target/src/spec/abi.rs
+++ b/compiler/rustc_target/src/spec/abi.rs
@@ -109,175 +109,125 @@ pub enum AbiDisabled {
     Unrecognized,
 }
 
-fn gate_feature_post(
+pub fn is_enabled(
     features: &rustc_feature::Features,
-    feature: Symbol,
     span: Span,
-    explain: &'static str,
+    name: &str,
 ) -> Result<(), AbiDisabled> {
-    if !features.enabled(feature) && !span.allows_unstable(feature) {
-        Err(AbiDisabled::Unstable { feature, explain })
-    } else {
-        Ok(())
+    let s = is_stable(name);
+    if let Err(AbiDisabled::Unstable { feature, .. }) = s {
+        if features.enabled(feature) || span.allows_unstable(feature) {
+            return Ok(());
+        }
     }
+    s
 }
 
-pub fn is_enabled(
-    features: &rustc_feature::Features,
-    span: Span,
-    name: &str,
-) -> Result<(), AbiDisabled> {
+pub fn is_stable(name: &str) -> Result<(), AbiDisabled> {
     match name {
         // Stable
         "Rust" | "C" | "cdecl" | "stdcall" | "fastcall" | "aapcs" | "win64" | "sysv64"
         | "system" => Ok(()),
-        "rust-intrinsic" => {
-            gate_feature_post(features, sym::intrinsics, span, "intrinsics are subject to change")
-        }
-        "platform-intrinsic" => gate_feature_post(
-            features,
-            sym::platform_intrinsics,
-            span,
-            "platform intrinsics are experimental and possibly buggy",
-        ),
-        "vectorcall" => gate_feature_post(
-            features,
-            sym::abi_vectorcall,
-            span,
-            "vectorcall is experimental and subject to change",
-        ),
-        "thiscall" => gate_feature_post(
-            features,
-            sym::abi_thiscall,
-            span,
-            "thiscall is experimental and subject to change",
-        ),
-        "rust-call" => gate_feature_post(
-            features,
-            sym::unboxed_closures,
-            span,
-            "rust-call ABI is subject to change",
-        ),
-        "rust-cold" => gate_feature_post(
-            features,
-            sym::rust_cold_cc,
-            span,
-            "rust-cold is experimental and subject to change",
-        ),
-        "ptx-kernel" => gate_feature_post(
-            features,
-            sym::abi_ptx,
-            span,
-            "PTX ABIs are experimental and subject to change",
-        ),
-        "unadjusted" => gate_feature_post(
-            features,
-            sym::abi_unadjusted,
-            span,
-            "unadjusted ABI is an implementation detail and perma-unstable",
-        ),
-        "msp430-interrupt" => gate_feature_post(
-            features,
-            sym::abi_msp430_interrupt,
-            span,
-            "msp430-interrupt ABI is experimental and subject to change",
-        ),
-        "x86-interrupt" => gate_feature_post(
-            features,
-            sym::abi_x86_interrupt,
-            span,
-            "x86-interrupt ABI is experimental and subject to change",
-        ),
-        "amdgpu-kernel" => gate_feature_post(
-            features,
-            sym::abi_amdgpu_kernel,
-            span,
-            "amdgpu-kernel ABI is experimental and subject to change",
-        ),
-        "avr-interrupt" | "avr-non-blocking-interrupt" => gate_feature_post(
-            features,
-            sym::abi_avr_interrupt,
-            span,
-            "avr-interrupt and avr-non-blocking-interrupt ABIs are experimental and subject to change",
-        ),
-        "efiapi" => gate_feature_post(
-            features,
-            sym::abi_efiapi,
-            span,
-            "efiapi ABI is experimental and subject to change",
-        ),
-        "C-cmse-nonsecure-call" => gate_feature_post(
-            features,
-            sym::abi_c_cmse_nonsecure_call,
-            span,
-            "C-cmse-nonsecure-call ABI is experimental and subject to change",
-        ),
-        "C-unwind" => gate_feature_post(
-            features,
-            sym::c_unwind,
-            span,
-            "C-unwind ABI is experimental and subject to change",
-        ),
-        "stdcall-unwind" => gate_feature_post(
-            features,
-            sym::c_unwind,
-            span,
-            "stdcall-unwind ABI is experimental and subject to change",
-        ),
-        "system-unwind" => gate_feature_post(
-            features,
-            sym::c_unwind,
-            span,
-            "system-unwind ABI is experimental and subject to change",
-        ),
-        "thiscall-unwind" => gate_feature_post(
-            features,
-            sym::c_unwind,
-            span,
-            "thiscall-unwind ABI is experimental and subject to change",
-        ),
-        "cdecl-unwind" => gate_feature_post(
-            features,
-            sym::c_unwind,
-            span,
-            "cdecl-unwind ABI is experimental and subject to change",
-        ),
-        "fastcall-unwind" => gate_feature_post(
-            features,
-            sym::c_unwind,
-            span,
-            "fastcall-unwind ABI is experimental and subject to change",
-        ),
-        "vectorcall-unwind" => gate_feature_post(
-            features,
-            sym::c_unwind,
-            span,
-            "vectorcall-unwind ABI is experimental and subject to change",
-        ),
-        "aapcs-unwind" => gate_feature_post(
-            features,
-            sym::c_unwind,
-            span,
-            "aapcs-unwind ABI is experimental and subject to change",
-        ),
-        "win64-unwind" => gate_feature_post(
-            features,
-            sym::c_unwind,
-            span,
-            "win64-unwind ABI is experimental and subject to change",
-        ),
-        "sysv64-unwind" => gate_feature_post(
-            features,
-            sym::c_unwind,
-            span,
-            "sysv64-unwind ABI is experimental and subject to change",
-        ),
-        "wasm" => gate_feature_post(
-            features,
-            sym::wasm_abi,
-            span,
-            "wasm ABI is experimental and subject to change",
-        ),
+        "rust-intrinsic" => Err(AbiDisabled::Unstable {
+            feature: sym::intrinsics,
+            explain: "intrinsics are subject to change",
+        }),
+        "platform-intrinsic" => Err(AbiDisabled::Unstable {
+            feature: sym::platform_intrinsics,
+            explain: "platform intrinsics are experimental and possibly buggy",
+        }),
+        "vectorcall" => Err(AbiDisabled::Unstable {
+            feature: sym::abi_vectorcall,
+            explain: "vectorcall is experimental and subject to change",
+        }),
+        "thiscall" => Err(AbiDisabled::Unstable {
+            feature: sym::abi_thiscall,
+            explain: "thiscall is experimental and subject to change",
+        }),
+        "rust-call" => Err(AbiDisabled::Unstable {
+            feature: sym::unboxed_closures,
+            explain: "rust-call ABI is subject to change",
+        }),
+        "rust-cold" => Err(AbiDisabled::Unstable {
+            feature: sym::rust_cold_cc,
+            explain: "rust-cold is experimental and subject to change",
+        }),
+        "ptx-kernel" => Err(AbiDisabled::Unstable {
+            feature: sym::abi_ptx,
+            explain: "PTX ABIs are experimental and subject to change",
+        }),
+        "unadjusted" => Err(AbiDisabled::Unstable {
+            feature: sym::abi_unadjusted,
+            explain: "unadjusted ABI is an implementation detail and perma-unstable",
+        }),
+        "msp430-interrupt" => Err(AbiDisabled::Unstable {
+            feature: sym::abi_msp430_interrupt,
+            explain: "msp430-interrupt ABI is experimental and subject to change",
+        }),
+        "x86-interrupt" => Err(AbiDisabled::Unstable {
+            feature: sym::abi_x86_interrupt,
+            explain: "x86-interrupt ABI is experimental and subject to change",
+        }),
+        "amdgpu-kernel" => Err(AbiDisabled::Unstable {
+            feature: sym::abi_amdgpu_kernel,
+            explain: "amdgpu-kernel ABI is experimental and subject to change",
+        }),
+        "avr-interrupt" | "avr-non-blocking-interrupt" => Err(AbiDisabled::Unstable {
+            feature: sym::abi_avr_interrupt,
+            explain: "avr-interrupt and avr-non-blocking-interrupt ABIs are experimental and subject to change",
+        }),
+        "efiapi" => Err(AbiDisabled::Unstable {
+            feature: sym::abi_efiapi,
+            explain: "efiapi ABI is experimental and subject to change",
+        }),
+        "C-cmse-nonsecure-call" => Err(AbiDisabled::Unstable {
+            feature: sym::abi_c_cmse_nonsecure_call,
+            explain: "C-cmse-nonsecure-call ABI is experimental and subject to change",
+        }),
+        "C-unwind" => Err(AbiDisabled::Unstable {
+            feature: sym::c_unwind,
+            explain: "C-unwind ABI is experimental and subject to change",
+        }),
+        "stdcall-unwind" => Err(AbiDisabled::Unstable {
+            feature: sym::c_unwind,
+            explain: "stdcall-unwind ABI is experimental and subject to change",
+        }),
+        "system-unwind" => Err(AbiDisabled::Unstable {
+            feature: sym::c_unwind,
+            explain: "system-unwind ABI is experimental and subject to change",
+        }),
+        "thiscall-unwind" => Err(AbiDisabled::Unstable {
+            feature: sym::c_unwind,
+            explain: "thiscall-unwind ABI is experimental and subject to change",
+        }),
+        "cdecl-unwind" => Err(AbiDisabled::Unstable {
+            feature: sym::c_unwind,
+            explain: "cdecl-unwind ABI is experimental and subject to change",
+        }),
+        "fastcall-unwind" => Err(AbiDisabled::Unstable {
+            feature: sym::c_unwind,
+            explain: "fastcall-unwind ABI is experimental and subject to change",
+        }),
+        "vectorcall-unwind" => Err(AbiDisabled::Unstable {
+            feature: sym::c_unwind,
+            explain: "vectorcall-unwind ABI is experimental and subject to change",
+        }),
+        "aapcs-unwind" => Err(AbiDisabled::Unstable {
+            feature: sym::c_unwind,
+            explain: "aapcs-unwind ABI is experimental and subject to change",
+        }),
+        "win64-unwind" => Err(AbiDisabled::Unstable {
+            feature: sym::c_unwind,
+            explain: "win64-unwind ABI is experimental and subject to change",
+        }),
+        "sysv64-unwind" => Err(AbiDisabled::Unstable {
+            feature: sym::c_unwind,
+            explain: "sysv64-unwind ABI is experimental and subject to change",
+        }),
+        "wasm" => Err(AbiDisabled::Unstable {
+            feature: sym::wasm_abi,
+            explain: "wasm ABI is experimental and subject to change",
+        }),
         _ => Err(AbiDisabled::Unrecognized),
     }
 }
diff --git a/src/test/ui/stability-attribute/stability-attribute-trait-impl.rs b/src/test/ui/stability-attribute/stability-attribute-trait-impl.rs
index ce2726ffde4..0c771ae8795 100644
--- a/src/test/ui/stability-attribute/stability-attribute-trait-impl.rs
+++ b/src/test/ui/stability-attribute/stability-attribute-trait-impl.rs
@@ -1,4 +1,4 @@
-#![feature(staged_api)]
+#![feature(staged_api, never_type, c_unwind)]
 //~^ ERROR module has missing stability attribute
 
 #[stable(feature = "a", since = "1")]
@@ -23,7 +23,21 @@ impl StableTrait for UnstableType {}
 impl UnstableTrait for StableType {}
 
 #[unstable(feature = "h", issue = "none")]
+impl StableTrait for ! {}
+
+// Note: If C-unwind is stabilized, switch this to another (unstable) ABI.
+#[unstable(feature = "i", issue = "none")]
+impl StableTrait for extern "C-unwind" fn() {}
+
+#[unstable(feature = "j", issue = "none")]
 //~^ ERROR an `#[unstable]` annotation here has no effect [ineffective_unstable_trait_impl]
 impl StableTrait for StableType {}
 
+#[unstable(feature = "k", issue = "none")]
+//~^ ERROR an `#[unstable]` annotation here has no effect [ineffective_unstable_trait_impl]
+impl StableTrait for fn() -> ! {}
+
+#[unstable(feature = "l", issue = "none")]
+impl StableTrait for fn() -> UnstableType {}
+
 fn main() {}
diff --git a/src/test/ui/stability-attribute/stability-attribute-trait-impl.stderr b/src/test/ui/stability-attribute/stability-attribute-trait-impl.stderr
index 7645f3c7ef5..b91a1d2e11a 100644
--- a/src/test/ui/stability-attribute/stability-attribute-trait-impl.stderr
+++ b/src/test/ui/stability-attribute/stability-attribute-trait-impl.stderr
@@ -1,16 +1,24 @@
 error: an `#[unstable]` annotation here has no effect
-  --> $DIR/stability-attribute-trait-impl.rs:25:1
+  --> $DIR/stability-attribute-trait-impl.rs:32:1
    |
-LL | #[unstable(feature = "h", issue = "none")]
+LL | #[unstable(feature = "j", issue = "none")]
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = note: see issue #55436 <https://github.com/rust-lang/rust/issues/55436> for more information
    = note: `#[deny(ineffective_unstable_trait_impl)]` on by default
 
+error: an `#[unstable]` annotation here has no effect
+  --> $DIR/stability-attribute-trait-impl.rs:36:1
+   |
+LL | #[unstable(feature = "k", issue = "none")]
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #55436 <https://github.com/rust-lang/rust/issues/55436> for more information
+
 error: module has missing stability attribute
   --> $DIR/stability-attribute-trait-impl.rs:1:1
    |
-LL | / #![feature(staged_api)]
+LL | / #![feature(staged_api, never_type, c_unwind)]
 LL | |
 LL | |
 LL | | #[stable(feature = "a", since = "1")]
@@ -19,5 +27,5 @@ LL | |
 LL | | fn main() {}
    | |____________^
 
-error: aborting due to 2 previous errors
+error: aborting due to 3 previous errors