about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_abi/src/extern_abi.rs141
-rw-r--r--compiler/rustc_abi/src/extern_abi/tests.rs8
-rw-r--r--compiler/rustc_ast_lowering/src/stability.rs9
-rw-r--r--compiler/rustc_driver_impl/src/lib.rs3
-rw-r--r--tests/ui/symbol-names/basic.legacy.stderr4
-rw-r--r--tests/ui/symbol-names/issue-60925.legacy.stderr4
6 files changed, 144 insertions, 25 deletions
diff --git a/compiler/rustc_abi/src/extern_abi.rs b/compiler/rustc_abi/src/extern_abi.rs
index a4dc87247a0..2355c64cfc9 100644
--- a/compiler/rustc_abi/src/extern_abi.rs
+++ b/compiler/rustc_abi/src/extern_abi.rs
@@ -1,15 +1,20 @@
+use std::cmp::Ordering;
 use std::fmt;
+use std::hash::{Hash, Hasher};
+use std::str::FromStr;
 
 #[cfg(feature = "nightly")]
-use rustc_macros::{Decodable, Encodable, HashStable_Generic};
+use rustc_data_structures::stable_hasher::{HashStable, StableHasher, StableOrd};
+#[cfg(feature = "nightly")]
+use rustc_macros::{Decodable, Encodable};
 
 #[cfg(test)]
 mod tests;
 
 use ExternAbi as Abi;
 
-#[derive(PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Copy, Debug)]
-#[cfg_attr(feature = "nightly", derive(HashStable_Generic, Encodable, Decodable))]
+#[derive(Clone, Copy, Debug)]
+#[cfg_attr(feature = "nightly", derive(Encodable, Decodable))]
 pub enum ExternAbi {
     // Some of the ABIs come first because every time we add a new ABI, we have to re-bless all the
     // hashing tests. These are used in many places, so giving them stable values reduces test
@@ -69,7 +74,123 @@ pub enum ExternAbi {
     RiscvInterruptS,
 }
 
-impl Abi {
+macro_rules! abi_impls {
+    ($e_name:ident = {
+        $($variant:ident $({ unwind: $uw:literal })? =><= $tok:literal,)*
+    }) => {
+        impl $e_name {
+            pub const ALL_VARIANTS: &[Self] = &[
+                $($e_name::$variant $({ unwind: $uw })*,)*
+            ];
+            pub const fn as_str(&self) -> &'static str {
+                match self {
+                    $($e_name::$variant $( { unwind: $uw } )* => $tok,)*
+                }
+            }
+        }
+
+        impl ::core::str::FromStr for $e_name {
+            type Err = AbiFromStrErr;
+            fn from_str(s: &str) -> Result<$e_name, Self::Err> {
+                match s {
+                    $($tok => Ok($e_name::$variant $({ unwind: $uw })*),)*
+                    _ => Err(AbiFromStrErr::Unknown),
+                }
+            }
+        }
+    }
+}
+
+pub enum AbiFromStrErr {
+    Unknown,
+}
+
+abi_impls! {
+    ExternAbi = {
+            C { unwind: false } =><= "C",
+            CCmseNonSecureCall =><= "C-cmse-nonsecure-call",
+            CCmseNonSecureEntry =><= "C-cmse-nonsecure-entry",
+            C { unwind: true } =><= "C-unwind",
+            Rust =><= "Rust",
+            Aapcs { unwind: false } =><= "aapcs",
+            Aapcs { unwind: true } =><= "aapcs-unwind",
+            AvrInterrupt =><= "avr-interrupt",
+            AvrNonBlockingInterrupt =><= "avr-non-blocking-interrupt",
+            Cdecl { unwind: false } =><= "cdecl",
+            Cdecl { unwind: true } =><= "cdecl-unwind",
+            EfiApi =><= "efiapi",
+            Fastcall { unwind: false } =><= "fastcall",
+            Fastcall { unwind: true } =><= "fastcall-unwind",
+            GpuKernel =><= "gpu-kernel",
+            Msp430Interrupt =><= "msp430-interrupt",
+            PtxKernel =><= "ptx-kernel",
+            RiscvInterruptM =><= "riscv-interrupt-m",
+            RiscvInterruptS =><= "riscv-interrupt-s",
+            RustCall =><= "rust-call",
+            RustCold =><= "rust-cold",
+            RustIntrinsic =><= "rust-intrinsic",
+            Stdcall { unwind: false } =><= "stdcall",
+            Stdcall { unwind: true } =><= "stdcall-unwind",
+            System { unwind: false } =><= "system",
+            System { unwind: true } =><= "system-unwind",
+            SysV64 { unwind: false } =><= "sysv64",
+            SysV64 { unwind: true } =><= "sysv64-unwind",
+            Thiscall { unwind: false } =><= "thiscall",
+            Thiscall { unwind: true } =><= "thiscall-unwind",
+            Unadjusted =><= "unadjusted",
+            Vectorcall { unwind: false } =><= "vectorcall",
+            Vectorcall { unwind: true } =><= "vectorcall-unwind",
+            Win64 { unwind: false } =><= "win64",
+            Win64 { unwind: true } =><= "win64-unwind",
+            X86Interrupt =><= "x86-interrupt",
+    }
+}
+
+impl Ord for ExternAbi {
+    fn cmp(&self, rhs: &Self) -> Ordering {
+        self.as_str().cmp(rhs.as_str())
+    }
+}
+
+impl PartialOrd for ExternAbi {
+    fn partial_cmp(&self, rhs: &Self) -> Option<Ordering> {
+        Some(self.cmp(rhs))
+    }
+}
+
+impl PartialEq for ExternAbi {
+    fn eq(&self, rhs: &Self) -> bool {
+        self.cmp(rhs) == Ordering::Equal
+    }
+}
+
+impl Eq for ExternAbi {}
+
+impl Hash for ExternAbi {
+    fn hash<H: Hasher>(&self, state: &mut H) {
+        self.as_str().hash(state);
+        // double-assurance of a prefix breaker
+        u32::from_be_bytes(*b"ABI\0").hash(state);
+    }
+}
+
+#[cfg(feature = "nightly")]
+impl<C> HashStable<C> for ExternAbi {
+    #[inline]
+    fn hash_stable(&self, _: &mut C, hasher: &mut StableHasher) {
+        Hash::hash(self, hasher);
+    }
+}
+
+#[cfg(feature = "nightly")]
+impl StableOrd for ExternAbi {
+    const CAN_USE_UNSTABLE_SORT: bool = true;
+
+    // because each ABI is hashed like a string, there is no possible instability
+    const THIS_IMPLEMENTATION_HAS_BEEN_TRIPLE_CHECKED: () = ();
+}
+
+impl ExternAbi {
     pub fn supports_varargs(self) -> bool {
         // * C and Cdecl obviously support varargs.
         // * C can be based on Aapcs, SysV64 or Win64, so they must support varargs.
@@ -145,15 +266,11 @@ pub const AbiDatas: &[AbiData] = &[
 pub struct AbiUnsupported {}
 /// Returns the ABI with the given name (if any).
 pub fn lookup(name: &str) -> Result<Abi, AbiUnsupported> {
-    AbiDatas
-        .iter()
-        .find(|abi_data| name == abi_data.name)
-        .map(|&x| x.abi)
-        .ok_or_else(|| AbiUnsupported {})
+    ExternAbi::from_str(name).map_err(|_| AbiUnsupported {})
 }
 
 pub fn all_names() -> Vec<&'static str> {
-    AbiDatas.iter().map(|d| d.name).collect()
+    ExternAbi::ALL_VARIANTS.iter().map(|abi| abi.as_str()).collect()
 }
 
 impl Abi {
@@ -229,8 +346,8 @@ impl Abi {
     }
 }
 
-impl fmt::Display for Abi {
+impl fmt::Display for ExternAbi {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        write!(f, "\"{}\"", self.name())
+        write!(f, "\"{}\"", self.as_str())
     }
 }
diff --git a/compiler/rustc_abi/src/extern_abi/tests.rs b/compiler/rustc_abi/src/extern_abi/tests.rs
index 72c0f183d50..44ea58d47c2 100644
--- a/compiler/rustc_abi/src/extern_abi/tests.rs
+++ b/compiler/rustc_abi/src/extern_abi/tests.rs
@@ -27,3 +27,11 @@ fn indices_are_correct() {
         assert_eq!(i, abi_data.abi.index());
     }
 }
+
+#[test]
+fn guarantee_lexicographic_ordering() {
+    let abis = ExternAbi::ALL_VARIANTS;
+    let mut sorted_abis = abis.to_vec();
+    sorted_abis.sort_unstable();
+    assert_eq!(abis, sorted_abis);
+}
diff --git a/compiler/rustc_ast_lowering/src/stability.rs b/compiler/rustc_ast_lowering/src/stability.rs
index e7c166850a4..14410600fab 100644
--- a/compiler/rustc_ast_lowering/src/stability.rs
+++ b/compiler/rustc_ast_lowering/src/stability.rs
@@ -54,17 +54,12 @@ enum GateReason {
 impl fmt::Display for UnstableAbi {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         let Self { abi, .. } = self;
-        let name = abi.to_string();
-        let name = name.trim_matches('"');
         match self.explain {
             GateReason::Experimental => {
-                write!(f, r#"the extern "{name}" ABI is experimental and subject to change"#)
+                write!(f, "the extern {abi} ABI is experimental and subject to change")
             }
             GateReason::ImplDetail => {
-                write!(
-                    f,
-                    r#"the extern "{name}" ABI is an implementation detail and perma-unstable"#
-                )
+                write!(f, "the extern {abi} ABI is an implementation detail and perma-unstable")
             }
         }
     }
diff --git a/compiler/rustc_driver_impl/src/lib.rs b/compiler/rustc_driver_impl/src/lib.rs
index 6efd11a8c3c..2bcc33241df 100644
--- a/compiler/rustc_driver_impl/src/lib.rs
+++ b/compiler/rustc_driver_impl/src/lib.rs
@@ -747,8 +747,7 @@ fn print_crate_info(
                 }
             }
             CallingConventions => {
-                let mut calling_conventions = rustc_abi::all_names();
-                calling_conventions.sort_unstable();
+                let calling_conventions = rustc_abi::all_names();
                 println_info!("{}", calling_conventions.join("\n"));
             }
             RelocationModels
diff --git a/tests/ui/symbol-names/basic.legacy.stderr b/tests/ui/symbol-names/basic.legacy.stderr
index 2f26c0cf0d3..167262dcf06 100644
--- a/tests/ui/symbol-names/basic.legacy.stderr
+++ b/tests/ui/symbol-names/basic.legacy.stderr
@@ -1,10 +1,10 @@
-error: symbol-name(_ZN5basic4main17h144191e1523a280eE)
+error: symbol-name(_ZN5basic4main17hc88b9d80a69d119aE)
   --> $DIR/basic.rs:8:1
    |
 LL | #[rustc_symbol_name]
    | ^^^^^^^^^^^^^^^^^^^^
 
-error: demangling(basic::main::h144191e1523a280e)
+error: demangling(basic::main::hc88b9d80a69d119a)
   --> $DIR/basic.rs:8:1
    |
 LL | #[rustc_symbol_name]
diff --git a/tests/ui/symbol-names/issue-60925.legacy.stderr b/tests/ui/symbol-names/issue-60925.legacy.stderr
index cc79cc8b516..4e17bdc4577 100644
--- a/tests/ui/symbol-names/issue-60925.legacy.stderr
+++ b/tests/ui/symbol-names/issue-60925.legacy.stderr
@@ -1,10 +1,10 @@
-error: symbol-name(_ZN11issue_609253foo37Foo$LT$issue_60925..llv$u6d$..Foo$GT$3foo17h71f988fda3b6b180E)
+error: symbol-name(_ZN11issue_609253foo37Foo$LT$issue_60925..llv$u6d$..Foo$GT$3foo17hbddb77d6f71afb32E)
   --> $DIR/issue-60925.rs:21:9
    |
 LL |         #[rustc_symbol_name]
    |         ^^^^^^^^^^^^^^^^^^^^
 
-error: demangling(issue_60925::foo::Foo<issue_60925::llvm::Foo>::foo::h71f988fda3b6b180)
+error: demangling(issue_60925::foo::Foo<issue_60925::llvm::Foo>::foo::hbddb77d6f71afb32)
   --> $DIR/issue-60925.rs:21:9
    |
 LL |         #[rustc_symbol_name]