From d9c7abba55762f7ec25fc1d9a322f26896381e4f Mon Sep 17 00:00:00 2001 From: Jubilee Young Date: Sun, 9 Feb 2025 23:03:24 -0800 Subject: [PATCH 1/5] compiler: narrow scope of nightly cfg in rustc_abi --- compiler/rustc_abi/src/extern_abi.rs | 3 ++- compiler/rustc_abi/src/lib.rs | 6 +----- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/compiler/rustc_abi/src/extern_abi.rs b/compiler/rustc_abi/src/extern_abi.rs index f3cf7f583cebd..a4dc87247a080 100644 --- a/compiler/rustc_abi/src/extern_abi.rs +++ b/compiler/rustc_abi/src/extern_abi.rs @@ -1,5 +1,6 @@ use std::fmt; +#[cfg(feature = "nightly")] use rustc_macros::{Decodable, Encodable, HashStable_Generic}; #[cfg(test)] @@ -8,7 +9,7 @@ mod tests; use ExternAbi as Abi; #[derive(PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Copy, Debug)] -#[derive(HashStable_Generic, Encodable, Decodable)] +#[cfg_attr(feature = "nightly", derive(HashStable_Generic, 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 diff --git a/compiler/rustc_abi/src/lib.rs b/compiler/rustc_abi/src/lib.rs index 259f1c18ea8e9..1e4685dc2a39b 100644 --- a/compiler/rustc_abi/src/lib.rs +++ b/compiler/rustc_abi/src/lib.rs @@ -52,20 +52,16 @@ use bitflags::bitflags; use rustc_data_structures::stable_hasher::StableOrd; use rustc_index::{Idx, IndexSlice, IndexVec}; #[cfg(feature = "nightly")] -use rustc_macros::HashStable_Generic; -#[cfg(feature = "nightly")] -use rustc_macros::{Decodable_Generic, Encodable_Generic}; +use rustc_macros::{Decodable_Generic, Encodable_Generic, HashStable_Generic}; mod callconv; mod layout; #[cfg(test)] mod tests; -#[cfg(feature = "nightly")] mod extern_abi; pub use callconv::{Heterogeneous, HomogeneousAggregate, Reg, RegKind}; -#[cfg(feature = "nightly")] pub use extern_abi::{AbiDatas, AbiUnsupported, ExternAbi, all_names, lookup}; #[cfg(feature = "nightly")] pub use layout::{FIRST_VARIANT, FieldIdx, Layout, TyAbiInterface, TyAndLayout, VariantIdx}; From 038c183d5f94b5ca3bed351374b01be4b1c90176 Mon Sep 17 00:00:00 2001 From: Jubilee Young Date: Sun, 9 Feb 2025 23:55:16 -0800 Subject: [PATCH 2/5] compiler: remove rustc_target reexport of rustc_abi::HashStableContext The last public reexport of rustc_abi in rustc_target is finally gone. --- Cargo.lock | 3 +-- compiler/rustc_ast_passes/Cargo.toml | 1 - compiler/rustc_hir/src/stable_hash_impls.rs | 4 +--- compiler/rustc_query_system/Cargo.toml | 2 +- compiler/rustc_query_system/src/ich/impls_syntax.rs | 2 +- compiler/rustc_target/src/lib.rs | 2 +- 6 files changed, 5 insertions(+), 9 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 20b715e59a6e6..d31ef9c4b17e6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3409,7 +3409,6 @@ dependencies = [ "rustc_parse", "rustc_session", "rustc_span", - "rustc_target", "thin-vec", ] @@ -4423,6 +4422,7 @@ version = "0.0.0" dependencies = [ "parking_lot", "rustc-rayon-core", + "rustc_abi", "rustc_ast", "rustc_data_structures", "rustc_errors", @@ -4434,7 +4434,6 @@ dependencies = [ "rustc_serialize", "rustc_session", "rustc_span", - "rustc_target", "smallvec", "thin-vec", "tracing", diff --git a/compiler/rustc_ast_passes/Cargo.toml b/compiler/rustc_ast_passes/Cargo.toml index 19c379c8599a8..e4c227532085f 100644 --- a/compiler/rustc_ast_passes/Cargo.toml +++ b/compiler/rustc_ast_passes/Cargo.toml @@ -18,6 +18,5 @@ rustc_macros = { path = "../rustc_macros" } rustc_parse = { path = "../rustc_parse" } rustc_session = { path = "../rustc_session" } rustc_span = { path = "../rustc_span" } -rustc_target = { path = "../rustc_target" } thin-vec = "0.2.12" # tidy-alphabetical-end diff --git a/compiler/rustc_hir/src/stable_hash_impls.rs b/compiler/rustc_hir/src/stable_hash_impls.rs index db0d0fcf3b916..d7c8a3d5c0a5f 100644 --- a/compiler/rustc_hir/src/stable_hash_impls.rs +++ b/compiler/rustc_hir/src/stable_hash_impls.rs @@ -10,9 +10,7 @@ use crate::hir_id::{HirId, ItemLocalId}; /// Requirements for a `StableHashingContext` to be used in this crate. /// This is a hack to allow using the `HashStable_Generic` derive macro /// instead of implementing everything in `rustc_middle`. -pub trait HashStableContext: - rustc_ast::HashStableContext + rustc_target::HashStableContext -{ +pub trait HashStableContext: rustc_ast::HashStableContext + rustc_abi::HashStableContext { fn hash_attr(&mut self, _: &Attribute, hasher: &mut StableHasher); } diff --git a/compiler/rustc_query_system/Cargo.toml b/compiler/rustc_query_system/Cargo.toml index 96b210accdb37..a42329b4614f0 100644 --- a/compiler/rustc_query_system/Cargo.toml +++ b/compiler/rustc_query_system/Cargo.toml @@ -7,6 +7,7 @@ edition = "2021" # tidy-alphabetical-start parking_lot = "0.12" rustc-rayon-core = { version = "0.5.0" } +rustc_abi = { path = "../rustc_abi" } rustc_ast = { path = "../rustc_ast" } rustc_data_structures = { path = "../rustc_data_structures" } rustc_errors = { path = "../rustc_errors" } @@ -18,7 +19,6 @@ rustc_macros = { path = "../rustc_macros" } rustc_serialize = { path = "../rustc_serialize" } rustc_session = { path = "../rustc_session" } rustc_span = { path = "../rustc_span" } -rustc_target = { path = "../rustc_target" } smallvec = { version = "1.8.1", features = ["union", "may_dangle"] } thin-vec = "0.2.12" tracing = "0.1" diff --git a/compiler/rustc_query_system/src/ich/impls_syntax.rs b/compiler/rustc_query_system/src/ich/impls_syntax.rs index 480fd49772833..7d508b8201bdf 100644 --- a/compiler/rustc_query_system/src/ich/impls_syntax.rs +++ b/compiler/rustc_query_system/src/ich/impls_syntax.rs @@ -8,7 +8,7 @@ use smallvec::SmallVec; use crate::ich::StableHashingContext; -impl<'ctx> rustc_target::HashStableContext for StableHashingContext<'ctx> {} +impl<'ctx> rustc_abi::HashStableContext for StableHashingContext<'ctx> {} impl<'ctx> rustc_ast::HashStableContext for StableHashingContext<'ctx> {} impl<'a> HashStable> for [hir::Attribute] { diff --git a/compiler/rustc_target/src/lib.rs b/compiler/rustc_target/src/lib.rs index bde4af643fa6c..7ebe96960ed0f 100644 --- a/compiler/rustc_target/src/lib.rs +++ b/compiler/rustc_target/src/lib.rs @@ -30,7 +30,7 @@ pub mod target_features; #[cfg(test)] mod tests; -pub use rustc_abi::HashStableContext; +use rustc_abi::HashStableContext; /// The name of rustc's own place to organize libraries. /// From 8abff35b41b8de89da35ab851f931d6a582f7670 Mon Sep 17 00:00:00 2001 From: Jubilee Young Date: Mon, 10 Feb 2025 03:57:32 -0800 Subject: [PATCH 3/5] compiler: compare and hash ExternAbi like its string Directly map each ExternAbi variant to its string and back again. This has a few advantages: - By making the ABIs compare equal to their strings, we can easily lexicographically sort them and use that sorted slice at runtime. - We no longer need a workaround to make sure the hashes remain stable, as they already naturally are (by being the hashes of unique strings). - The compiler can carry around less &str wide pointers --- compiler/rustc_abi/src/extern_abi.rs | 141 ++++++++++++++++-- compiler/rustc_abi/src/extern_abi/tests.rs | 8 + compiler/rustc_ast_lowering/src/stability.rs | 9 +- compiler/rustc_driver_impl/src/lib.rs | 3 +- tests/ui/symbol-names/basic.legacy.stderr | 4 +- .../ui/symbol-names/issue-60925.legacy.stderr | 4 +- 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 a4dc87247a080..2355c64cfc984 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 { + 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(&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 HashStable 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 { - 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 72c0f183d50c1..44ea58d47c252 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 e7c166850a46b..14410600fab87 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 6efd11a8c3c07..2bcc33241dfa1 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 2f26c0cf0d3b3..167262dcf06b3 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 cc79cc8b5169e..4e17bdc45777f 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::foo::h71f988fda3b6b180) +error: demangling(issue_60925::foo::Foo::foo::hbddb77d6f71afb32) --> $DIR/issue-60925.rs:21:9 | LL | #[rustc_symbol_name] From edff4fe2cc7613a80624a768c0138671bcf97f7d Mon Sep 17 00:00:00 2001 From: Jubilee Young Date: Mon, 10 Feb 2025 16:41:02 -0800 Subject: [PATCH 4/5] compiler: remove AbiDatas These were a way to ensure hashes were stable over time for ExternAbi, but simply hashing the strings is more stable in the face of changes. As a result, we can do away with them. --- compiler/rustc_abi/src/extern_abi.rs | 116 +------------------ compiler/rustc_abi/src/extern_abi/tests.rs | 11 +- compiler/rustc_abi/src/lib.rs | 13 +-- compiler/rustc_ast_lowering/src/stability.rs | 8 +- compiler/rustc_symbol_mangling/src/v0.rs | 2 +- 5 files changed, 14 insertions(+), 136 deletions(-) diff --git a/compiler/rustc_abi/src/extern_abi.rs b/compiler/rustc_abi/src/extern_abi.rs index 2355c64cfc984..9ac3057e413ac 100644 --- a/compiler/rustc_abi/src/extern_abi.rs +++ b/compiler/rustc_abi/src/extern_abi.rs @@ -214,54 +214,6 @@ impl ExternAbi { } } -#[derive(Copy, Clone)] -pub struct AbiData { - pub abi: Abi, - - /// Name of this ABI as we like it called. - pub name: &'static str, -} - -#[allow(non_upper_case_globals)] -pub const AbiDatas: &[AbiData] = &[ - AbiData { abi: Abi::Rust, name: "Rust" }, - AbiData { abi: Abi::C { unwind: false }, name: "C" }, - AbiData { abi: Abi::C { unwind: true }, name: "C-unwind" }, - AbiData { abi: Abi::Cdecl { unwind: false }, name: "cdecl" }, - AbiData { abi: Abi::Cdecl { unwind: true }, name: "cdecl-unwind" }, - AbiData { abi: Abi::Stdcall { unwind: false }, name: "stdcall" }, - AbiData { abi: Abi::Stdcall { unwind: true }, name: "stdcall-unwind" }, - AbiData { abi: Abi::Fastcall { unwind: false }, name: "fastcall" }, - AbiData { abi: Abi::Fastcall { unwind: true }, name: "fastcall-unwind" }, - AbiData { abi: Abi::Vectorcall { unwind: false }, name: "vectorcall" }, - AbiData { abi: Abi::Vectorcall { unwind: true }, name: "vectorcall-unwind" }, - AbiData { abi: Abi::Thiscall { unwind: false }, name: "thiscall" }, - AbiData { abi: Abi::Thiscall { unwind: true }, name: "thiscall-unwind" }, - AbiData { abi: Abi::Aapcs { unwind: false }, name: "aapcs" }, - AbiData { abi: Abi::Aapcs { unwind: true }, name: "aapcs-unwind" }, - AbiData { abi: Abi::Win64 { unwind: false }, name: "win64" }, - AbiData { abi: Abi::Win64 { unwind: true }, name: "win64-unwind" }, - AbiData { abi: Abi::SysV64 { unwind: false }, name: "sysv64" }, - AbiData { abi: Abi::SysV64 { unwind: true }, name: "sysv64-unwind" }, - AbiData { abi: Abi::PtxKernel, name: "ptx-kernel" }, - AbiData { abi: Abi::Msp430Interrupt, name: "msp430-interrupt" }, - AbiData { abi: Abi::X86Interrupt, name: "x86-interrupt" }, - AbiData { abi: Abi::GpuKernel, name: "gpu-kernel" }, - AbiData { abi: Abi::EfiApi, name: "efiapi" }, - AbiData { abi: Abi::AvrInterrupt, name: "avr-interrupt" }, - AbiData { abi: Abi::AvrNonBlockingInterrupt, name: "avr-non-blocking-interrupt" }, - AbiData { abi: Abi::CCmseNonSecureCall, name: "C-cmse-nonsecure-call" }, - AbiData { abi: Abi::CCmseNonSecureEntry, name: "C-cmse-nonsecure-entry" }, - AbiData { abi: Abi::System { unwind: false }, name: "system" }, - AbiData { abi: Abi::System { unwind: true }, name: "system-unwind" }, - AbiData { abi: Abi::RustIntrinsic, name: "rust-intrinsic" }, - AbiData { abi: Abi::RustCall, name: "rust-call" }, - AbiData { abi: Abi::Unadjusted, name: "unadjusted" }, - AbiData { abi: Abi::RustCold, name: "rust-cold" }, - AbiData { abi: Abi::RiscvInterruptM, name: "riscv-interrupt-m" }, - AbiData { abi: Abi::RiscvInterruptS, name: "riscv-interrupt-s" }, -]; - #[derive(Copy, Clone, Debug)] pub struct AbiUnsupported {} /// Returns the ABI with the given name (if any). @@ -273,76 +225,12 @@ pub fn all_names() -> Vec<&'static str> { ExternAbi::ALL_VARIANTS.iter().map(|abi| abi.as_str()).collect() } -impl Abi { +impl ExternAbi { /// Default ABI chosen for `extern fn` declarations without an explicit ABI. pub const FALLBACK: Abi = Abi::C { unwind: false }; - #[inline] - pub fn index(self) -> usize { - // N.B., this ordering MUST match the AbiDatas array above. - // (This is ensured by the test indices_are_correct().) - use Abi::*; - let i = match self { - // Cross-platform ABIs - Rust => 0, - C { unwind: false } => 1, - C { unwind: true } => 2, - // Platform-specific ABIs - Cdecl { unwind: false } => 3, - Cdecl { unwind: true } => 4, - Stdcall { unwind: false } => 5, - Stdcall { unwind: true } => 6, - Fastcall { unwind: false } => 7, - Fastcall { unwind: true } => 8, - Vectorcall { unwind: false } => 9, - Vectorcall { unwind: true } => 10, - Thiscall { unwind: false } => 11, - Thiscall { unwind: true } => 12, - Aapcs { unwind: false } => 13, - Aapcs { unwind: true } => 14, - Win64 { unwind: false } => 15, - Win64 { unwind: true } => 16, - SysV64 { unwind: false } => 17, - SysV64 { unwind: true } => 18, - PtxKernel => 19, - Msp430Interrupt => 20, - X86Interrupt => 21, - GpuKernel => 22, - EfiApi => 23, - AvrInterrupt => 24, - AvrNonBlockingInterrupt => 25, - CCmseNonSecureCall => 26, - CCmseNonSecureEntry => 27, - // Cross-platform ABIs - System { unwind: false } => 28, - System { unwind: true } => 29, - RustIntrinsic => 30, - RustCall => 31, - Unadjusted => 32, - RustCold => 33, - RiscvInterruptM => 34, - RiscvInterruptS => 35, - }; - debug_assert!( - AbiDatas - .iter() - .enumerate() - .find(|(_, AbiData { abi, .. })| *abi == self) - .map(|(index, _)| index) - .expect("abi variant has associated data") - == i, - "Abi index did not match `AbiDatas` ordering" - ); - i - } - - #[inline] - pub fn data(self) -> &'static AbiData { - &AbiDatas[self.index()] - } - pub fn name(self) -> &'static str { - self.data().name + self.as_str() } } diff --git a/compiler/rustc_abi/src/extern_abi/tests.rs b/compiler/rustc_abi/src/extern_abi/tests.rs index 44ea58d47c252..5cc186aecb25c 100644 --- a/compiler/rustc_abi/src/extern_abi/tests.rs +++ b/compiler/rustc_abi/src/extern_abi/tests.rs @@ -6,13 +6,13 @@ use super::*; #[test] fn lookup_Rust() { let abi = lookup("Rust"); - assert!(abi.is_ok() && abi.unwrap().data().name == "Rust"); + assert!(abi.is_ok() && abi.unwrap().as_str() == "Rust"); } #[test] fn lookup_cdecl() { let abi = lookup("cdecl"); - assert!(abi.is_ok() && abi.unwrap().data().name == "cdecl"); + assert!(abi.is_ok() && abi.unwrap().as_str() == "cdecl"); } #[test] @@ -21,13 +21,6 @@ fn lookup_baz() { assert_matches!(abi, Err(AbiUnsupported {})); } -#[test] -fn indices_are_correct() { - for (i, abi_data) in AbiDatas.iter().enumerate() { - assert_eq!(i, abi_data.abi.index()); - } -} - #[test] fn guarantee_lexicographic_ordering() { let abis = ExternAbi::ALL_VARIANTS; diff --git a/compiler/rustc_abi/src/lib.rs b/compiler/rustc_abi/src/lib.rs index 1e4685dc2a39b..6724b42114361 100644 --- a/compiler/rustc_abi/src/lib.rs +++ b/compiler/rustc_abi/src/lib.rs @@ -62,7 +62,7 @@ mod tests; mod extern_abi; pub use callconv::{Heterogeneous, HomogeneousAggregate, Reg, RegKind}; -pub use extern_abi::{AbiDatas, AbiUnsupported, ExternAbi, all_names, lookup}; +pub use extern_abi::{AbiUnsupported, ExternAbi, all_names, lookup}; #[cfg(feature = "nightly")] pub use layout::{FIRST_VARIANT, FieldIdx, Layout, TyAbiInterface, TyAndLayout, VariantIdx}; pub use layout::{LayoutCalculator, LayoutCalculatorError}; @@ -1178,13 +1178,10 @@ impl Scalar { #[inline] pub fn is_bool(&self) -> bool { use Integer::*; - matches!( - self, - Scalar::Initialized { - value: Primitive::Int(I8, false), - valid_range: WrappingRange { start: 0, end: 1 } - } - ) + matches!(self, Scalar::Initialized { + value: Primitive::Int(I8, false), + valid_range: WrappingRange { start: 0, end: 1 } + }) } /// Get the primitive representation of this type, ignoring the valid range and whether the diff --git a/compiler/rustc_ast_lowering/src/stability.rs b/compiler/rustc_ast_lowering/src/stability.rs index 14410600fab87..a2004bbb39f09 100644 --- a/compiler/rustc_ast_lowering/src/stability.rs +++ b/compiler/rustc_ast_lowering/src/stability.rs @@ -8,10 +8,10 @@ use rustc_span::symbol::sym; use rustc_span::{Span, Symbol}; pub(crate) fn enabled_names(features: &rustc_feature::Features, span: Span) -> Vec<&'static str> { - rustc_abi::AbiDatas - .iter() - .filter(|data| extern_abi_enabled(features, span, data.abi).is_ok()) - .map(|d| d.name) + ExternAbi::ALL_VARIANTS + .into_iter() + .filter(|abi| extern_abi_enabled(features, span, **abi).is_ok()) + .map(|abi| abi.as_str()) .collect() } diff --git a/compiler/rustc_symbol_mangling/src/v0.rs b/compiler/rustc_symbol_mangling/src/v0.rs index 0ac6f17b97bd0..4fafd1ac3509a 100644 --- a/compiler/rustc_symbol_mangling/src/v0.rs +++ b/compiler/rustc_symbol_mangling/src/v0.rs @@ -480,7 +480,7 @@ impl<'tcx> Printer<'tcx> for SymbolMangler<'tcx> { ExternAbi::C { unwind: false } => cx.push("KC"), abi => { cx.push("K"); - let name = abi.name(); + let name = abi.as_str(); if name.contains('-') { cx.push_ident(&name.replace('-', "_")); } else { From f8570e8ac504324031c3ab41393ffb6a199b0479 Mon Sep 17 00:00:00 2001 From: Jubilee Young Date: Mon, 10 Feb 2025 23:03:10 -0800 Subject: [PATCH 5/5] compiler: remove rustc_abi::lookup and AbiUnsupported These can be entirely replaced by the FromStr implementation. --- compiler/rustc_abi/src/extern_abi.rs | 9 +-------- compiler/rustc_abi/src/extern_abi/tests.rs | 9 +++++---- compiler/rustc_abi/src/lib.rs | 13 ++++++++----- compiler/rustc_ast_lowering/src/item.rs | 2 +- 4 files changed, 15 insertions(+), 18 deletions(-) diff --git a/compiler/rustc_abi/src/extern_abi.rs b/compiler/rustc_abi/src/extern_abi.rs index 9ac3057e413ac..c29db522511d8 100644 --- a/compiler/rustc_abi/src/extern_abi.rs +++ b/compiler/rustc_abi/src/extern_abi.rs @@ -1,7 +1,6 @@ use std::cmp::Ordering; use std::fmt; use std::hash::{Hash, Hasher}; -use std::str::FromStr; #[cfg(feature = "nightly")] use rustc_data_structures::stable_hasher::{HashStable, StableHasher, StableOrd}; @@ -101,6 +100,7 @@ macro_rules! abi_impls { } } +#[derive(Debug)] pub enum AbiFromStrErr { Unknown, } @@ -214,13 +214,6 @@ impl ExternAbi { } } -#[derive(Copy, Clone, Debug)] -pub struct AbiUnsupported {} -/// Returns the ABI with the given name (if any). -pub fn lookup(name: &str) -> Result { - ExternAbi::from_str(name).map_err(|_| AbiUnsupported {}) -} - pub fn all_names() -> Vec<&'static str> { ExternAbi::ALL_VARIANTS.iter().map(|abi| abi.as_str()).collect() } diff --git a/compiler/rustc_abi/src/extern_abi/tests.rs b/compiler/rustc_abi/src/extern_abi/tests.rs index 5cc186aecb25c..fc546a6570f0a 100644 --- a/compiler/rustc_abi/src/extern_abi/tests.rs +++ b/compiler/rustc_abi/src/extern_abi/tests.rs @@ -1,24 +1,25 @@ use std::assert_matches::assert_matches; +use std::str::FromStr; use super::*; #[allow(non_snake_case)] #[test] fn lookup_Rust() { - let abi = lookup("Rust"); + let abi = ExternAbi::from_str("Rust"); assert!(abi.is_ok() && abi.unwrap().as_str() == "Rust"); } #[test] fn lookup_cdecl() { - let abi = lookup("cdecl"); + let abi = ExternAbi::from_str("cdecl"); assert!(abi.is_ok() && abi.unwrap().as_str() == "cdecl"); } #[test] fn lookup_baz() { - let abi = lookup("baz"); - assert_matches!(abi, Err(AbiUnsupported {})); + let abi = ExternAbi::from_str("baz"); + assert_matches!(abi, Err(AbiFromStrErr::Unknown)); } #[test] diff --git a/compiler/rustc_abi/src/lib.rs b/compiler/rustc_abi/src/lib.rs index 6724b42114361..da1c706d67cc4 100644 --- a/compiler/rustc_abi/src/lib.rs +++ b/compiler/rustc_abi/src/lib.rs @@ -62,7 +62,7 @@ mod tests; mod extern_abi; pub use callconv::{Heterogeneous, HomogeneousAggregate, Reg, RegKind}; -pub use extern_abi::{AbiUnsupported, ExternAbi, all_names, lookup}; +pub use extern_abi::{ExternAbi, all_names}; #[cfg(feature = "nightly")] pub use layout::{FIRST_VARIANT, FieldIdx, Layout, TyAbiInterface, TyAndLayout, VariantIdx}; pub use layout::{LayoutCalculator, LayoutCalculatorError}; @@ -1178,10 +1178,13 @@ impl Scalar { #[inline] pub fn is_bool(&self) -> bool { use Integer::*; - matches!(self, Scalar::Initialized { - value: Primitive::Int(I8, false), - valid_range: WrappingRange { start: 0, end: 1 } - }) + matches!( + self, + Scalar::Initialized { + value: Primitive::Int(I8, false), + valid_range: WrappingRange { start: 0, end: 1 } + } + ) } /// Get the primitive representation of this type, ignoring the valid range and whether the diff --git a/compiler/rustc_ast_lowering/src/item.rs b/compiler/rustc_ast_lowering/src/item.rs index 85642c8ccb56e..bc2db41546989 100644 --- a/compiler/rustc_ast_lowering/src/item.rs +++ b/compiler/rustc_ast_lowering/src/item.rs @@ -1475,7 +1475,7 @@ impl<'hir> LoweringContext<'_, 'hir> { pub(super) fn lower_abi(&mut self, abi_str: StrLit) -> ExternAbi { let ast::StrLit { symbol_unescaped, span, .. } = abi_str; - let extern_abi = rustc_abi::lookup(symbol_unescaped.as_str()).unwrap_or_else(|_| { + let extern_abi = symbol_unescaped.as_str().parse().unwrap_or_else(|_| { self.error_on_invalid_abi(abi_str); ExternAbi::Rust });