From 9e97c57cc8fff134c6beb7d1e520c2724d7a0a75 Mon Sep 17 00:00:00 2001 From: cyrgani Date: Fri, 13 Mar 2026 10:00:39 +0000 Subject: [PATCH 1/6] relocate several ui tests --- tests/ui/README.md | 10 ---------- .../box-arithmetic-14915.rs | 0 .../box-arithmetic-14915.stderr | 0 .../less-than-greater-than.rs | 0 .../less-than-greater-than.stderr | 0 tests/ui/{operator-recovery => binop}/spaceship.rs | 0 tests/ui/{operator-recovery => binop}/spaceship.stderr | 0 .../removed-syntax-obsolete-in-place.rs} | 0 .../removed-syntax-obsolete-in-place.stderr} | 4 ++-- 9 files changed, 2 insertions(+), 12 deletions(-) rename tests/ui/{operator-recovery => binop}/box-arithmetic-14915.rs (100%) rename tests/ui/{operator-recovery => binop}/box-arithmetic-14915.stderr (100%) rename tests/ui/{operator-recovery => binop}/less-than-greater-than.rs (100%) rename tests/ui/{operator-recovery => binop}/less-than-greater-than.stderr (100%) rename tests/ui/{operator-recovery => binop}/spaceship.rs (100%) rename tests/ui/{operator-recovery => binop}/spaceship.stderr (100%) rename tests/ui/{obsolete-in-place/bad.rs => parser/removed-syntax/removed-syntax-obsolete-in-place.rs} (100%) rename tests/ui/{obsolete-in-place/bad.stderr => parser/removed-syntax/removed-syntax-obsolete-in-place.stderr} (77%) diff --git a/tests/ui/README.md b/tests/ui/README.md index 248f1208d8d9e..9911353af5cd0 100644 --- a/tests/ui/README.md +++ b/tests/ui/README.md @@ -1000,12 +1000,6 @@ Tests on lifetimes on objects, such as a lifetime bound not being able to be ded **FIXME**: Just a more specific subset of `ui/lifetimes`. -## `tests/ui/obsolete-in-place/` - -Contains a single test. Check that we reject the ancient Rust syntax `x <- y` and `in(BINDING) {}` construct. - -**FIXME**: Definitely should be rehomed, maybe to `tests/ui/deprecation/`. - ## `tests/ui/offload` Exercises the offload feature. @@ -1023,10 +1017,6 @@ Exercises the [`std::mem::offset_of` macro](https://doc.rust-lang.org/beta/std/m Exercises the `#[rustc_on_unimplemented]`. -## `tests/ui/operator-recovery/` - -**FIXME**: Probably move under `tests/ui/binop/` or `tests/ui/parser/`. - ## `tests/ui/or-patterns/` Exercises `||` and `|` in patterns. diff --git a/tests/ui/operator-recovery/box-arithmetic-14915.rs b/tests/ui/binop/box-arithmetic-14915.rs similarity index 100% rename from tests/ui/operator-recovery/box-arithmetic-14915.rs rename to tests/ui/binop/box-arithmetic-14915.rs diff --git a/tests/ui/operator-recovery/box-arithmetic-14915.stderr b/tests/ui/binop/box-arithmetic-14915.stderr similarity index 100% rename from tests/ui/operator-recovery/box-arithmetic-14915.stderr rename to tests/ui/binop/box-arithmetic-14915.stderr diff --git a/tests/ui/operator-recovery/less-than-greater-than.rs b/tests/ui/binop/less-than-greater-than.rs similarity index 100% rename from tests/ui/operator-recovery/less-than-greater-than.rs rename to tests/ui/binop/less-than-greater-than.rs diff --git a/tests/ui/operator-recovery/less-than-greater-than.stderr b/tests/ui/binop/less-than-greater-than.stderr similarity index 100% rename from tests/ui/operator-recovery/less-than-greater-than.stderr rename to tests/ui/binop/less-than-greater-than.stderr diff --git a/tests/ui/operator-recovery/spaceship.rs b/tests/ui/binop/spaceship.rs similarity index 100% rename from tests/ui/operator-recovery/spaceship.rs rename to tests/ui/binop/spaceship.rs diff --git a/tests/ui/operator-recovery/spaceship.stderr b/tests/ui/binop/spaceship.stderr similarity index 100% rename from tests/ui/operator-recovery/spaceship.stderr rename to tests/ui/binop/spaceship.stderr diff --git a/tests/ui/obsolete-in-place/bad.rs b/tests/ui/parser/removed-syntax/removed-syntax-obsolete-in-place.rs similarity index 100% rename from tests/ui/obsolete-in-place/bad.rs rename to tests/ui/parser/removed-syntax/removed-syntax-obsolete-in-place.rs diff --git a/tests/ui/obsolete-in-place/bad.stderr b/tests/ui/parser/removed-syntax/removed-syntax-obsolete-in-place.stderr similarity index 77% rename from tests/ui/obsolete-in-place/bad.stderr rename to tests/ui/parser/removed-syntax/removed-syntax-obsolete-in-place.stderr index a1321a46351a9..7cdc85be349a4 100644 --- a/tests/ui/obsolete-in-place/bad.stderr +++ b/tests/ui/parser/removed-syntax/removed-syntax-obsolete-in-place.stderr @@ -1,5 +1,5 @@ error: unexpected token: `<-` - --> $DIR/bad.rs:5:7 + --> $DIR/removed-syntax-obsolete-in-place.rs:5:7 | LL | x <- y; | ^^ @@ -10,7 +10,7 @@ LL | x < - y; | + error: expected expression, found keyword `in` - --> $DIR/bad.rs:10:5 + --> $DIR/removed-syntax-obsolete-in-place.rs:10:5 | LL | in(foo) { bar }; | ^^ expected expression From 7d4ee745ebec42583a519f3440e5342c5e5b8a6f Mon Sep 17 00:00:00 2001 From: Zalathar Date: Fri, 13 Mar 2026 13:49:59 +1100 Subject: [PATCH 2/6] Don't pass a separate `DepKind` to `query_feed` The query's dep kind can be obtained from its vtable instead. This commit also renames the `query_vtable` parameter to `query`, to be more consistent with other functions that take a QueryVTable. --- compiler/rustc_middle/src/queries.rs | 2 +- compiler/rustc_middle/src/query/inner.rs | 26 ++++++++++----------- compiler/rustc_middle/src/query/plumbing.rs | 1 - 3 files changed, 14 insertions(+), 15 deletions(-) diff --git a/compiler/rustc_middle/src/queries.rs b/compiler/rustc_middle/src/queries.rs index 6c30762725b77..ffe96c9db3da6 100644 --- a/compiler/rustc_middle/src/queries.rs +++ b/compiler/rustc_middle/src/queries.rs @@ -120,7 +120,7 @@ use crate::ty::{ self, CrateInherentImpls, GenericArg, GenericArgsRef, LitToConstInput, PseudoCanonicalInput, SizedTraitKind, Ty, TyCtxt, TyCtxtFeed, }; -use crate::{dep_graph, mir, thir}; +use crate::{mir, thir}; // Each of these queries corresponds to a function pointer field in the // `Providers` struct for requesting a value of that type, and a method diff --git a/compiler/rustc_middle/src/query/inner.rs b/compiler/rustc_middle/src/query/inner.rs index 2c3959805d9d1..7395c5476dc1e 100644 --- a/compiler/rustc_middle/src/query/inner.rs +++ b/compiler/rustc_middle/src/query/inner.rs @@ -4,7 +4,7 @@ use rustc_span::{DUMMY_SP, ErrorGuaranteed, Span}; use crate::dep_graph; -use crate::dep_graph::{DepKind, DepNodeKey}; +use crate::dep_graph::DepNodeKey; use crate::query::erase::{self, Erasable, Erased}; use crate::query::plumbing::QueryVTable; use crate::query::{EnsureMode, QueryCache, QueryMode}; @@ -98,26 +98,26 @@ where } } -/// Common implementation of query feeding, used by `define_feedable!`. +/// "Feeds" a feedable query by adding a given key/value pair to its in-memory cache. +/// Called by macro-generated methods of [`rustc_middle::ty::TyCtxtFeed`]. pub(crate) fn query_feed<'tcx, C>( tcx: TyCtxt<'tcx>, - dep_kind: DepKind, - query_vtable: &QueryVTable<'tcx, C>, + query: &'tcx QueryVTable<'tcx, C>, key: C::Key, value: C::Value, ) where C: QueryCache, C::Key: DepNodeKey<'tcx>, { - let format_value = query_vtable.format_value; + let format_value = query.format_value; // Check whether the in-memory cache already has a value for this key. - match try_get_cached(tcx, &query_vtable.cache, key) { + match try_get_cached(tcx, &query.cache, key) { Some(old) => { // The query already has a cached value for this key. // That's OK if both values are the same, i.e. they have the same hash, // so now we check their hashes. - if let Some(hash_value_fn) = query_vtable.hash_value_fn { + if let Some(hash_value_fn) = query.hash_value_fn { let (old_hash, value_hash) = tcx.with_stable_hashing_context(|ref mut hcx| { (hash_value_fn(hcx, &old), hash_value_fn(hcx, &value)) }); @@ -126,7 +126,7 @@ pub(crate) fn query_feed<'tcx, C>( // results is tainted by errors. In this case, delay a bug to // ensure compilation is doomed, and keep the `old` value. tcx.dcx().delayed_bug(format!( - "Trying to feed an already recorded value for query {dep_kind:?} key={key:?}:\n\ + "Trying to feed an already recorded value for query {query:?} key={key:?}:\n\ old value: {old}\nnew value: {value}", old = format_value(&old), value = format_value(&value), @@ -137,7 +137,7 @@ pub(crate) fn query_feed<'tcx, C>( // If feeding the same value multiple times needs to be supported, // the query should not be marked `no_hash`. bug!( - "Trying to feed an already recorded value for query {dep_kind:?} key={key:?}:\n\ + "Trying to feed an already recorded value for query {query:?} key={key:?}:\n\ old value: {old}\nnew value: {value}", old = format_value(&old), value = format_value(&value), @@ -147,15 +147,15 @@ pub(crate) fn query_feed<'tcx, C>( None => { // There is no cached value for this key, so feed the query by // adding the provided value to the cache. - let dep_node = dep_graph::DepNode::construct(tcx, dep_kind, &key); + let dep_node = dep_graph::DepNode::construct(tcx, query.dep_kind, &key); let dep_node_index = tcx.dep_graph.with_feed_task( dep_node, tcx, &value, - query_vtable.hash_value_fn, - query_vtable.format_value, + query.hash_value_fn, + query.format_value, ); - query_vtable.cache.complete(key, value, dep_node_index); + query.cache.complete(key, value, dep_node_index); } } } diff --git a/compiler/rustc_middle/src/query/plumbing.rs b/compiler/rustc_middle/src/query/plumbing.rs index f388898465246..128350a89ecf1 100644 --- a/compiler/rustc_middle/src/query/plumbing.rs +++ b/compiler/rustc_middle/src/query/plumbing.rs @@ -493,7 +493,6 @@ macro_rules! define_callbacks { let erased_value = $name::provided_to_erased(self.tcx, value); $crate::query::inner::query_feed( self.tcx, - dep_graph::DepKind::$name, &self.tcx.query_system.query_vtables.$name, key, erased_value, From 17c079625c1f8ccd91a9a810e3bd8af73e67ebe8 Mon Sep 17 00:00:00 2001 From: Martin Nordholts Date: Sat, 14 Mar 2026 00:03:43 +0100 Subject: [PATCH 3/6] tests/debuginfo/basic-stepping.rs: Add cdb test --- tests/debuginfo/basic-stepping.rs | 39 +++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/tests/debuginfo/basic-stepping.rs b/tests/debuginfo/basic-stepping.rs index 6aa8aeceb1e69..c82120e8a426a 100644 --- a/tests/debuginfo/basic-stepping.rs +++ b/tests/debuginfo/basic-stepping.rs @@ -88,6 +88,45 @@ //@ lldb-command: frame select //@ lldb-check: [...]let m: *const() = &a;[...] +// === CDB TESTS =================================================================================== + +// Enable source line support. See +// https://learn.microsoft.com/en-us/windows-hardware/drivers/debuggercmds/-lines--toggle-source-line-support-. +//@ cdb-command: .lines -e +// Display source lines and source line numbers at the command prompt. See +// https://learn.microsoft.com/en-us/windows-hardware/drivers/debuggercmds/l---l---set-source-options-. +//@ cdb-command: l+s +// Enter "source mode" so `p` steps source lines and not assembly instructions. +//@ cdb-command: l+t + +// `g` means "go". See +// https://learn.microsoft.com/en-us/windows-hardware/drivers/debuggercmds/g--go-. +//@ cdb-command: g +// `p` means "step". See +// https://learn.microsoft.com/en-us/windows-hardware/drivers/debuggercmds/p--step-. +//@ cdb-command: p +//@ cdb-check: [...]: let mut c = 27; +//@ cdb-command: p +//@ cdb-check: [...]: let d = c = 99; +//@ [no-SingleUseConsts-mir-pass] cdb-command: p +//@ [no-SingleUseConsts-mir-pass] cdb-check: [...]: let e = "hi bob"; +//@ [no-SingleUseConsts-mir-pass] cdb-command: p +//@ [no-SingleUseConsts-mir-pass] cdb-check: [...]: let f = b"hi bob"; +//@ [no-SingleUseConsts-mir-pass] cdb-command: p +//@ [no-SingleUseConsts-mir-pass] cdb-check: [...]: let g = b'9'; +//@ cdb-command: p +//@ cdb-check: [...]: let h = ["whatever"; 8]; +//@ cdb-command: p +//@ cdb-check: [...]: let i = [1,2,3,4]; +//@ cdb-command: p +//@ cdb-check: [...]: let j = (23, "hi"); +//@ cdb-command: p +//@ cdb-check: [...]: let k = 2..3; +//@ cdb-command: p +//@ cdb-check: [...]: let l = &i[k]; +//@ cdb-command: p +//@ cdb-check: [...]: let m: *const() = &a; + #![allow(unused_assignments, unused_variables)] fn main () { From c4fb58ff9a8ddd916cfb8fb285b152d482aa5a6a Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Thu, 12 Mar 2026 11:51:19 +0100 Subject: [PATCH 4/6] target specs: tighten checks for llvm_abiname and llvm_floatabi, and tie them to cfg(target_abi) --- .../rustc_target/src/spec/base/apple/mod.rs | 7 +- compiler/rustc_target/src/spec/mod.rs | 287 +++++++++++++++--- 2 files changed, 254 insertions(+), 40 deletions(-) diff --git a/compiler/rustc_target/src/spec/base/apple/mod.rs b/compiler/rustc_target/src/spec/base/apple/mod.rs index 542c5e278499f..18b41d10062be 100644 --- a/compiler/rustc_target/src/spec/base/apple/mod.rs +++ b/compiler/rustc_target/src/spec/base/apple/mod.rs @@ -127,7 +127,12 @@ pub(crate) fn base( let link_env_remove = link_env_remove(&os); let unversioned_llvm_target = unversioned_llvm_target(&os, arch, env); let mut opts = TargetOptions { - llvm_floatabi: Some(FloatAbi::Hard), + llvm_floatabi: if arch.target_arch() == crate::spec::Arch::Arm { + Some(FloatAbi::Hard) + } else { + // `llvm_floatabi` makes no sense on x86 and aarch64. + None + }, os, env: env.target_env(), abi: env.target_abi(), diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs index 77cc6dd1036c8..a28794eee458a 100644 --- a/compiler/rustc_target/src/spec/mod.rs +++ b/compiler/rustc_target/src/spec/mod.rs @@ -1005,7 +1005,7 @@ crate::target_spec_enum! { pub enum RustcAbi { /// On x86-32 only: make use of SSE and SSE2 for ABI purposes. X86Sse2 = "x86-sse2", - /// On x86-32/64 and S390x: do not use any FPU or SIMD registers for the ABI. + /// On x86-32/64, aarch64, and S390x: do not use any FPU or SIMD registers for the ABI. Softfloat = "softfloat", "x86-softfloat", } @@ -3183,69 +3183,277 @@ impl Target { ); } - // Check that RISC-V targets always specify which ABI they use, - // and that ARM targets specify their float ABI. + // Check ABI flag consistency, for the architectures where we have proper ABI treatment. + // To ensure targets are trated consistently, please consult with the team before allowing + // new cases. match self.arch { + Arch::X86 => { + check!(self.llvm_abiname.is_empty(), "`llvm_abiname` is unused on x86-32"); + check!(self.llvm_floatabi.is_none(), "`llvm_floatabi` is unused on x86-32"); + check_matches!( + (&self.rustc_abi, &self.abi), + // FIXME: we do not currently set a target_abi for softfloat targets here, + // but we probably should, so we already allow it. + (Some(RustcAbi::Softfloat), Abi::SoftFloat | Abi::Unspecified | Abi::Other(_)) + | ( + Some(RustcAbi::X86Sse2) | None, + Abi::Uwp | Abi::Llvm | Abi::Sim | Abi::Unspecified | Abi::Other(_) + ), + "invalid x86-32 Rust-specific ABI and `cfg(target_abi)` combination:\n\ + Rust-specific ABI: {:?}\n\ + cfg(target_abi): {}", + self.rustc_abi, + self.abi, + ); + } + Arch::X86_64 => { + check!(self.llvm_abiname.is_empty(), "`llvm_abiname` is unused on x86-64"); + check!(self.llvm_floatabi.is_none(), "`llvm_floatabi` is unused on x86-64"); + // FIXME: we do not currently set a target_abi for softfloat targets here, but we + // probably should, so we already allow it. + // FIXME: Ensure that target_abi = "x32" correlates with actually using that ABI. + // Do any of the others need a similar check? + check_matches!( + (&self.rustc_abi, &self.abi), + (Some(RustcAbi::Softfloat), Abi::SoftFloat | Abi::Unspecified | Abi::Other(_)) + | ( + None, + Abi::X32 + | Abi::Llvm + | Abi::Fortanix + | Abi::Uwp + | Abi::MacAbi + | Abi::Sim + | Abi::Unspecified + | Abi::Other(_) + ), + "invalid x86-64 Rust-specific ABI and `cfg(target_abi)` combination:\n\ + Rust-specific ABI: {:?}\n\ + cfg(target_abi): {}", + self.rustc_abi, + self.abi, + ); + } Arch::RiscV32 => { + check!(self.llvm_floatabi.is_none(), "`llvm_floatabi` is unused on RISC-V"); + check!(self.rustc_abi.is_none(), "`rustc_abi` is unused on RISC-V"); check_matches!( - &*self.llvm_abiname, - "ilp32" | "ilp32f" | "ilp32d" | "ilp32e", - "invalid RISC-V ABI name: {}", + (&*self.llvm_abiname, &self.abi), + ("ilp32", Abi::Unspecified | Abi::Other(_)) + | ("ilp32f", Abi::Unspecified | Abi::Other(_)) + | ("ilp32d", Abi::Unspecified | Abi::Other(_)) + | ("ilp32e", Abi::Ilp32e), + "invalid RISC-V ABI name and `cfg(target_abi)` combination:\n\ + ABI name: {}\n\ + cfg(target_abi): {}", self.llvm_abiname, + self.abi, ); } Arch::RiscV64 => { // Note that the `lp64e` is still unstable as it's not (yet) part of the ELF psABI. + check!(self.llvm_floatabi.is_none(), "`llvm_floatabi` is unused on RISC-V"); + check!(self.rustc_abi.is_none(), "`rustc_abi` is unused on RISC-V"); check_matches!( - &*self.llvm_abiname, - "lp64" | "lp64f" | "lp64d" | "lp64e", - "invalid RISC-V ABI name: {}", + (&*self.llvm_abiname, &self.abi), + ("lp64", Abi::Unspecified | Abi::Other(_)) + | ("lp64f", Abi::Unspecified | Abi::Other(_)) + | ("lp64d", Abi::Unspecified | Abi::Other(_)) + | ("lp64e", Abi::Unspecified | Abi::Other(_)), + "invalid RISC-V ABI name and `cfg(target_abi)` combination:\n\ + ABI name: {}\n\ + cfg(target_abi): {}", self.llvm_abiname, + self.abi, ); } Arch::Arm => { - check!( - self.llvm_floatabi.is_some(), - "ARM targets must set `llvm-floatabi` to `hard` or `soft`", + check!(self.llvm_abiname.is_empty(), "`llvm_abiname` is unused on ARM"); + check!(self.rustc_abi.is_none(), "`rustc_abi` is unused on ARM"); + check_matches!( + (&self.llvm_floatabi, &self.abi), + ( + Some(FloatAbi::Hard), + Abi::EabiHf | Abi::Uwp | Abi::Unspecified | Abi::Other(_) + ) | (Some(FloatAbi::Soft), Abi::Eabi), + "Invalid combination of float ABI and `cfg(target_abi)` for ARM target\n\ + float ABI: {:?}\n\ + cfg(target_abi): {}", + self.llvm_floatabi, + self.abi, ) } - // PowerPC64 targets that are not AIX must set their ABI to either ELFv1 or ELFv2 + Arch::AArch64 => { + check!(self.llvm_abiname.is_empty(), "`llvm_abiname` is unused on aarch64"); + check!(self.llvm_floatabi.is_none(), "`llvm_floatabi` is unused on aarch64"); + // FIXME: Ensure that target_abi = "ilp32" correlates with actually using that ABI. + // Do any of the others need a similar check? + check_matches!( + (&self.rustc_abi, &self.abi), + (Some(RustcAbi::Softfloat), Abi::SoftFloat) + | ( + None, + Abi::Ilp32 + | Abi::Llvm + | Abi::MacAbi + | Abi::Sim + | Abi::Uwp + | Abi::Unspecified + | Abi::Other(_) + ), + "invalid aarch64 Rust-specific ABI and `cfg(target_abi)` combination:\n\ + Rust-specific ABI: {:?}\n\ + cfg(target_abi): {}", + self.rustc_abi, + self.abi, + ); + } + Arch::PowerPC => { + check!(self.llvm_abiname.is_empty(), "`llvm_abiname` is unused on PowerPC"); + check!(self.llvm_floatabi.is_none(), "`llvm_floatabi` is unused on PowerPC"); + check!(self.rustc_abi.is_none(), "`rustc_abi` is unused on PowerPC"); + // FIXME: Check that `target_abi` matches the actually configured ABI (with or + // without SPE). + check_matches!( + self.abi, + Abi::Spe | Abi::Unspecified | Abi::Other(_), + "invalid `target_abi` for PowerPC" + ); + } Arch::PowerPC64 => { + check!(self.llvm_floatabi.is_none(), "`llvm_floatabi` is unused on PowerPC64"); + check!(self.rustc_abi.is_none(), "`rustc_abi` is unused on PowerPC64"); + // PowerPC64 targets that are not AIX must set their ABI to either ELFv1 or ELFv2 if self.os == Os::Aix { - check!( - self.llvm_abiname.is_empty(), - "AIX targets always use the AIX ABI and `llvm_abiname` should be left empty", + // FIXME: Check that `target_abi` matches the actually configured ABI + // (vec-default vs vec-ext). + check_matches!( + (&*self.llvm_abiname, &self.abi), + ("", Abi::VecDefault | Abi::VecExtAbi), + "invalid PowerPC64 AIX ABI name and `cfg(target_abi)` combination:\n\ + ABI name: {}\n\ + cfg(target_abi): {}", + self.llvm_abiname, + self.abi, ); } else if self.endian == Endian::Big { check_matches!( - &*self.llvm_abiname, - "elfv1" | "elfv2", - "invalid PowerPC64 ABI name: {}", + (&*self.llvm_abiname, &self.abi), + ("elfv1", Abi::ElfV1) | ("elfv2", Abi::ElfV2), + "invalid PowerPC64 big-endian ABI name and `cfg(target_abi)` combination:\n\ + ABI name: {}\n\ + cfg(target_abi): {}", self.llvm_abiname, + self.abi, ); } else { - check!( - self.llvm_abiname == "elfv2", - "little-endian PowerPC64 targets only support the `elfv2` ABI", + check_matches!( + (&*self.llvm_abiname, &self.abi), + ("elfv2", Abi::ElfV2), + "invalid PowerPC64 little-endian ABI name and `cfg(target_abi)` combination:\n\ + ABI name: {}\n\ + cfg(target_abi): {}", + self.llvm_abiname, + self.abi, ); } } - _ => {} - } - - // Check consistency of Rust ABI declaration. - if let Some(rust_abi) = self.rustc_abi { - match rust_abi { - RustcAbi::X86Sse2 => check_matches!( - self.arch, - Arch::X86, - "`x86-sse2` ABI is only valid for x86-32 targets" - ), - RustcAbi::Softfloat => check_matches!( - self.arch, - Arch::X86 | Arch::X86_64 | Arch::S390x | Arch::AArch64, - "`softfloat` ABI is only valid for x86, s390x, and aarch64 targets" - ), + Arch::S390x => { + check!(self.llvm_abiname.is_empty(), "`llvm_abiname` is unused on s390x"); + check!(self.llvm_floatabi.is_none(), "`llvm_floatabi` is unused on s390x"); + check_matches!( + (&self.rustc_abi, &self.abi), + (Some(RustcAbi::Softfloat), Abi::SoftFloat) + | (None, Abi::Unspecified | Abi::Other(_)), + "invalid s390x Rust-specific ABI and `cfg(target_abi)` combination:\n\ + Rust-specific ABI: {:?}\n\ + cfg(target_abi): {}", + self.rustc_abi, + self.abi, + ); + } + Arch::LoongArch32 => { + check!(self.llvm_floatabi.is_none(), "`llvm_floatabi` is unused on LoongArch"); + check!(self.rustc_abi.is_none(), "`rustc_abi` is unused on LoongArch"); + check_matches!( + (&*self.llvm_abiname, &self.abi), + ("ilp32s", Abi::SoftFloat) + | ("ilp32f", Abi::Unspecified | Abi::Other(_)) + | ("ilp32d", Abi::Unspecified | Abi::Other(_)), + "invalid LoongArch ABI name and `cfg(target_abi)` combination:\n\ + ABI name: {}\n\ + cfg(target_abi): {}", + self.llvm_abiname, + self.abi, + ); + } + Arch::LoongArch64 => { + check!(self.llvm_floatabi.is_none(), "`llvm_floatabi` is unused on LoongArch"); + check!(self.rustc_abi.is_none(), "`rustc_abi` is unused on LoongArch"); + check_matches!( + (&*self.llvm_abiname, &self.abi), + ("lp64s", Abi::SoftFloat) + | ("lp64f", Abi::Unspecified | Abi::Other(_)) + | ("lp64d", Abi::Unspecified | Abi::Other(_)), + "invalid LoongArch ABI name and `cfg(target_abi)` combination:\n\ + ABI name: {}\n\ + cfg(target_abi): {}", + self.llvm_abiname, + self.abi, + ); + } + Arch::Mips => { + check!(self.llvm_floatabi.is_none(), "`llvm_floatabi` is unused on MIPS"); + check!(self.rustc_abi.is_none(), "`rustc_abi` is unused on MIPS"); + check_matches!( + (&*self.llvm_abiname, &self.abi), + // FIXME: we should force it to always be non-empty. + ("o32", Abi::Unspecified | Abi::Other(_)) + | ("", Abi::Unspecified | Abi::Other(_)), + "invalid MIPS ABI name and `cfg(target_abi)` combination:\n\ + ABI name: {}\n\ + cfg(target_abi): {}", + self.llvm_abiname, + self.abi, + ); + } + Arch::Mips64 | Arch::Mips64r6 => { + check!(self.llvm_floatabi.is_none(), "`llvm_floatabi` is unused on MIPS"); + check!(self.rustc_abi.is_none(), "`rustc_abi` is unused on MIPS"); + check_matches!( + (&*self.llvm_abiname, &self.abi), + ("n64", Abi::Abi64), + "invalid MIPS ABI name and `cfg(target_abi)` combination:\n\ + ABI name: {}\n\ + cfg(target_abi): {}", + self.llvm_abiname, + self.abi, + ); + } + Arch::CSky => { + check!(self.llvm_abiname.is_empty(), "`llvm_abiname` is unused on CSky"); + check!(self.llvm_floatabi.is_none(), "`llvm_floatabi` is unused on CSky"); + check!(self.rustc_abi.is_none(), "`rustc_abi` is unused on CSky"); + // FIXME: Check that `target_abi` matches the actually configured ABI (v2 vs v2hf). + check_matches!( + self.abi, + Abi::AbiV2 | Abi::AbiV2Hf, + "invalid `target_abi` for CSky" + ); + } + ref arch => { + check!(self.rustc_abi.is_none(), "`rustc_abi` is unused on {arch}"); + // Ensure consistency among built-in targets, but give JSON targets the opportunity + // to experiment with these. + if kind == TargetKind::Builtin { + check!(self.llvm_abiname.is_empty(), "`llvm_abiname` is unused on {arch}"); + check!(self.llvm_floatabi.is_none(), "`llvm_floatabi` is unused on {arch}"); + check_matches!( + self.abi, + Abi::Unspecified | Abi::Other(_), + "`target_abi` is unused on {arch}" + ); + } } } @@ -3305,7 +3513,8 @@ impl Target { let recycled_target = Target::from_json(&serde_json::to_string(&self.to_json()).unwrap()).map(|(j, _)| j); self.update_to_cli(); - self.check_consistency(TargetKind::Builtin).unwrap(); + self.check_consistency(TargetKind::Builtin) + .unwrap_or_else(|err| panic!("Target consistency check failed:\n{err}")); assert_eq!(recycled_target, Ok(self)); } From 0a90f8ddc27a88ec02b3f6897c8dc7c165cd5502 Mon Sep 17 00:00:00 2001 From: Zalathar Date: Sat, 14 Mar 2026 21:03:59 +1100 Subject: [PATCH 5/6] Use named fields in ChunkedBitSet's `Chunk::Mixed` This helps to clarify that the field with type `ChunkSize` is a count of 1s, not a length or size. --- compiler/rustc_index/src/bit_set.rs | 81 ++++++++++++----------- compiler/rustc_index/src/bit_set/tests.rs | 24 +++---- 2 files changed, 56 insertions(+), 49 deletions(-) diff --git a/compiler/rustc_index/src/bit_set.rs b/compiler/rustc_index/src/bit_set.rs index 184fa409d9605..68384c73ba25a 100644 --- a/compiler/rustc_index/src/bit_set.rs +++ b/compiler/rustc_index/src/bit_set.rs @@ -509,14 +509,20 @@ enum Chunk { /// to store the length, which would make this type larger. These excess /// words are always zero, as are any excess bits in the final in-use word. /// - /// The `ChunkSize` field is the count of 1s set in the chunk, and - /// must satisfy `0 < count < chunk_domain_size`. - /// /// The words are within an `Rc` because it's surprisingly common to /// duplicate an entire chunk, e.g. in `ChunkedBitSet::clone_from()`, or /// when a `Mixed` chunk is union'd into a `Zeros` chunk. When we do need /// to modify a chunk we use `Rc::make_mut`. - Mixed(ChunkSize, Rc<[Word; CHUNK_WORDS]>), + Mixed { + /// Count of set bits (1s) in this chunk's words. + /// + /// Invariant: `0 < ones_count < chunk_domain_size`. + /// + /// Tracking this separately allows individual insert/remove calls to + /// know that the chunk has become all-zeroes or all-ones, in O(1) time. + ones_count: ChunkSize, + words: Rc<[Word; CHUNK_WORDS]>, + }, } // This type is used a lot. Make sure it doesn't unintentionally get bigger. @@ -613,7 +619,7 @@ impl ChunkedBitSet { match &chunk { Zeros => false, Ones => true, - Mixed(_, words) => { + Mixed { ones_count: _, words } => { let (word_index, mask) = chunk_word_index_and_mask(elem); (words[word_index] & mask) != 0 } @@ -644,19 +650,19 @@ impl ChunkedBitSet { let (word_index, mask) = chunk_word_index_and_mask(elem); words_ref[word_index] |= mask; - *chunk = Mixed(1, words); + *chunk = Mixed { ones_count: 1, words }; } else { *chunk = Ones; } true } Ones => false, - Mixed(ref mut count, ref mut words) => { + Mixed { ref mut ones_count, ref mut words } => { // We skip all the work if the bit is already set. let (word_index, mask) = chunk_word_index_and_mask(elem); if (words[word_index] & mask) == 0 { - *count += 1; - if *count < chunk_domain_size { + *ones_count += 1; + if *ones_count < chunk_domain_size { let words = Rc::make_mut(words); words[word_index] |= mask; } else { @@ -702,18 +708,18 @@ impl ChunkedBitSet { ); let (word_index, mask) = chunk_word_index_and_mask(elem); words_ref[word_index] &= !mask; - *chunk = Mixed(chunk_domain_size - 1, words); + *chunk = Mixed { ones_count: chunk_domain_size - 1, words }; } else { *chunk = Zeros; } true } - Mixed(ref mut count, ref mut words) => { + Mixed { ref mut ones_count, ref mut words } => { // We skip all the work if the bit is already clear. let (word_index, mask) = chunk_word_index_and_mask(elem); if (words[word_index] & mask) != 0 { - *count -= 1; - if *count > 0 { + *ones_count -= 1; + if *ones_count > 0 { let words = Rc::make_mut(words); words[word_index] &= !mask; } else { @@ -732,7 +738,7 @@ impl ChunkedBitSet { match self.chunks.get(chunk_index) { Some(Zeros) => ChunkIter::Zeros, Some(Ones) => ChunkIter::Ones(0..chunk_domain_size as usize), - Some(Mixed(_, words)) => { + Some(Mixed { ones_count: _, words }) => { let num_words = num_words(chunk_domain_size as usize); ChunkIter::Mixed(BitIter::new(&words[0..num_words])) } @@ -765,14 +771,14 @@ impl BitRelations> for ChunkedBitSet { match (&mut self_chunk, &other_chunk) { (_, Zeros) | (Ones, _) => {} - (Zeros, _) | (Mixed(..), Ones) => { + (Zeros, _) | (Mixed { .. }, Ones) => { // `other_chunk` fully overwrites `self_chunk` *self_chunk = other_chunk.clone(); changed = true; } ( - Mixed(self_chunk_count, self_chunk_words), - Mixed(_other_chunk_count, other_chunk_words), + Mixed { ones_count: self_chunk_ones, words: self_chunk_words }, + Mixed { ones_count: _, words: other_chunk_words }, ) => { // First check if the operation would change // `self_chunk.words`. If not, we can avoid allocating some @@ -807,8 +813,8 @@ impl BitRelations> for ChunkedBitSet { op, ); debug_assert!(has_changed); - *self_chunk_count = count_ones(&self_chunk_words[0..num_words]) as ChunkSize; - if *self_chunk_count == chunk_domain_size { + *self_chunk_ones = count_ones(&self_chunk_words[0..num_words]) as ChunkSize; + if *self_chunk_ones == chunk_domain_size { *self_chunk = Ones; } changed = true; @@ -839,11 +845,11 @@ impl BitRelations> for ChunkedBitSet { match (&mut self_chunk, &other_chunk) { (Zeros, _) | (_, Zeros) => {} - (Ones | Mixed(..), Ones) => { + (Ones | Mixed { .. }, Ones) => { changed = true; *self_chunk = Zeros; } - (Ones, Mixed(other_chunk_count, other_chunk_words)) => { + (Ones, Mixed { ones_count: other_chunk_ones, words: other_chunk_words }) => { changed = true; let num_words = num_words(chunk_domain_size as usize); debug_assert!(num_words > 0 && num_words <= CHUNK_WORDS); @@ -854,16 +860,17 @@ impl BitRelations> for ChunkedBitSet { *word = !*word & tail_mask; tail_mask = Word::MAX; } - let self_chunk_count = chunk_domain_size - *other_chunk_count; + let self_chunk_ones = chunk_domain_size - *other_chunk_ones; debug_assert_eq!( - self_chunk_count, + self_chunk_ones, count_ones(&self_chunk_words[0..num_words]) as ChunkSize ); - *self_chunk = Mixed(self_chunk_count, Rc::new(self_chunk_words)); + *self_chunk = + Mixed { ones_count: self_chunk_ones, words: Rc::new(self_chunk_words) }; } ( - Mixed(self_chunk_count, self_chunk_words), - Mixed(_other_chunk_count, other_chunk_words), + Mixed { ones_count: self_chunk_ones, words: self_chunk_words }, + Mixed { ones_count: _, words: other_chunk_words }, ) => { // See `ChunkedBitSet::union` for details on what is happening here. let num_words = num_words(chunk_domain_size as usize); @@ -883,8 +890,8 @@ impl BitRelations> for ChunkedBitSet { op, ); debug_assert!(has_changed); - *self_chunk_count = count_ones(&self_chunk_words[0..num_words]) as ChunkSize; - if *self_chunk_count == 0 { + *self_chunk_ones = count_ones(&self_chunk_words[0..num_words]) as ChunkSize; + if *self_chunk_ones == 0 { *self_chunk = Zeros; } changed = true; @@ -915,13 +922,13 @@ impl BitRelations> for ChunkedBitSet { match (&mut self_chunk, &other_chunk) { (Zeros, _) | (_, Ones) => {} - (Ones, Zeros | Mixed(..)) | (Mixed(..), Zeros) => { + (Ones, Zeros | Mixed { .. }) | (Mixed { .. }, Zeros) => { changed = true; *self_chunk = other_chunk.clone(); } ( - Mixed(self_chunk_count, self_chunk_words), - Mixed(_other_chunk_count, other_chunk_words), + Mixed { ones_count: self_chunk_ones, words: self_chunk_words }, + Mixed { ones_count: _, words: other_chunk_words }, ) => { // See `ChunkedBitSet::union` for details on what is happening here. let num_words = num_words(chunk_domain_size as usize); @@ -941,8 +948,8 @@ impl BitRelations> for ChunkedBitSet { op, ); debug_assert!(has_changed); - *self_chunk_count = count_ones(&self_chunk_words[0..num_words]) as ChunkSize; - if *self_chunk_count == 0 { + *self_chunk_ones = count_ones(&self_chunk_words[0..num_words]) as ChunkSize; + if *self_chunk_ones == 0 { *self_chunk = Zeros; } changed = true; @@ -1023,11 +1030,11 @@ impl Chunk { assert!(chunk_domain_size as usize <= CHUNK_BITS); match *self { Zeros | Ones => {} - Mixed(count, ref words) => { - assert!(0 < count && count < chunk_domain_size); + Mixed { ones_count, ref words } => { + assert!(0 < ones_count && ones_count < chunk_domain_size); // Check the number of set bits matches `count`. - assert_eq!(count_ones(words.as_slice()) as ChunkSize, count); + assert_eq!(count_ones(words.as_slice()) as ChunkSize, ones_count); // Check the not-in-use words are all zeroed. let num_words = num_words(chunk_domain_size as usize); @@ -1043,7 +1050,7 @@ impl Chunk { match *self { Zeros => 0, Ones => chunk_domain_size as usize, - Mixed(count, _) => count as usize, + Mixed { ones_count, words: _ } => usize::from(ones_count), } } } diff --git a/compiler/rustc_index/src/bit_set/tests.rs b/compiler/rustc_index/src/bit_set/tests.rs index 341e0622df75e..a0184c5c47f30 100644 --- a/compiler/rustc_index/src/bit_set/tests.rs +++ b/compiler/rustc_index/src/bit_set/tests.rs @@ -162,16 +162,16 @@ fn chunked_bitset() { assert!(!b100.contains(20) && b100.contains(30) && !b100.contains(99) && b100.contains(50)); assert_eq!( b100.chunks(), - vec![Mixed( - 97, + vec![Mixed { + ones_count: 97, #[rustfmt::skip] - Rc::new([ + words: Rc::new([ 0b11111111_11111111_11111110_11111111_11111111_11101111_11111111_11111111, 0b00000000_00000000_00000000_00000111_11111111_11111111_11111111_11111111, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ]) - )], + }], ); b100.assert_valid(); let mut num_removed = 0; @@ -228,14 +228,14 @@ fn chunked_bitset() { b4096.chunks(), #[rustfmt::skip] vec![ - Mixed(1, Rc::new([ + Mixed { ones_count: 1, words:Rc::new([ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 - ])), - Mixed(1, Rc::new([ + ])}, + Mixed { ones_count: 1, words: Rc::new([ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x8000_0000_0000_0000 - ])), + ])}, ], ); assert_eq!(b4096.count(), 2); @@ -265,14 +265,14 @@ fn chunked_bitset() { #[rustfmt::skip] vec![ Zeros, - Mixed(1, Rc::new([ + Mixed { ones_count: 1, words: Rc::new([ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x0100_0000_0000_0000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - ])), - Mixed(1, Rc::new([ + ])}, + Mixed { ones_count: 1, words: Rc::new([ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x0100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - ])), + ])}, Zeros, Zeros, ], From 2662303112bcfa768f525c9bcf8f3bb5d62acdd3 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Thu, 12 Mar 2026 12:39:41 +0100 Subject: [PATCH 6/6] mips: require LLVM ABI to be explicitly set, but also allow n32 --- compiler/rustc_codegen_ssa/src/back/metadata.rs | 11 +++-------- compiler/rustc_target/src/spec/mod.rs | 10 +++++----- .../src/spec/targets/mips_mti_none_elf.rs | 1 + .../src/spec/targets/mips_unknown_linux_gnu.rs | 1 + .../src/spec/targets/mips_unknown_linux_musl.rs | 7 ++++++- .../src/spec/targets/mips_unknown_linux_uclibc.rs | 1 + .../src/spec/targets/mipsel_mti_none_elf.rs | 1 + .../rustc_target/src/spec/targets/mipsel_sony_psp.rs | 1 + .../src/spec/targets/mipsel_unknown_linux_gnu.rs | 1 + .../src/spec/targets/mipsel_unknown_linux_musl.rs | 2 +- .../src/spec/targets/mipsel_unknown_linux_uclibc.rs | 1 + .../src/spec/targets/mipsel_unknown_netbsd.rs | 1 + .../src/spec/targets/mipsel_unknown_none.rs | 1 + .../src/spec/targets/mipsisa32r6_unknown_linux_gnu.rs | 1 + .../spec/targets/mipsisa32r6el_unknown_linux_gnu.rs | 1 + 15 files changed, 26 insertions(+), 15 deletions(-) diff --git a/compiler/rustc_codegen_ssa/src/back/metadata.rs b/compiler/rustc_codegen_ssa/src/back/metadata.rs index 8a2a6823fdf4b..240267c362f69 100644 --- a/compiler/rustc_codegen_ssa/src/back/metadata.rs +++ b/compiler/rustc_codegen_ssa/src/back/metadata.rs @@ -294,18 +294,13 @@ pub(super) fn elf_e_flags(architecture: Architecture, sess: &Session) -> u32 { _ => elf::EF_MIPS_ARCH_64R2, }; - // If the ABI is explicitly given, use it, or default to O32 on 32-bit MIPS, - // which is the only "true" 32-bit option that LLVM supports. + // Use the explicitly given ABI. match sess.target.options.llvm_abiname.as_ref() { "o32" if is_32bit => e_flags |= elf::EF_MIPS_ABI_O32, "n32" if !is_32bit => e_flags |= elf::EF_MIPS_ABI2, "n64" if !is_32bit => {} - "" if is_32bit => e_flags |= elf::EF_MIPS_ABI_O32, - "" => sess.dcx().fatal("LLVM ABI must be specified for 64-bit MIPS targets"), - s if is_32bit => { - sess.dcx().fatal(format!("invalid LLVM ABI `{}` for 32-bit MIPS target", s)) - } - s => sess.dcx().fatal(format!("invalid LLVM ABI `{}` for 64-bit MIPS target", s)), + // The rest is invalid (which is already ensured by the target spec check). + s => bug!("invalid LLVM ABI `{}` for MIPS target", s), }; if sess.target.options.relocation_model != RelocModel::Static { diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs index a28794eee458a..8683e4f51279e 100644 --- a/compiler/rustc_target/src/spec/mod.rs +++ b/compiler/rustc_target/src/spec/mod.rs @@ -3402,14 +3402,12 @@ impl Target { self.abi, ); } - Arch::Mips => { + Arch::Mips | Arch::Mips32r6 => { check!(self.llvm_floatabi.is_none(), "`llvm_floatabi` is unused on MIPS"); check!(self.rustc_abi.is_none(), "`rustc_abi` is unused on MIPS"); check_matches!( (&*self.llvm_abiname, &self.abi), - // FIXME: we should force it to always be non-empty. - ("o32", Abi::Unspecified | Abi::Other(_)) - | ("", Abi::Unspecified | Abi::Other(_)), + ("o32", Abi::Unspecified | Abi::Other(_)), "invalid MIPS ABI name and `cfg(target_abi)` combination:\n\ ABI name: {}\n\ cfg(target_abi): {}", @@ -3422,7 +3420,9 @@ impl Target { check!(self.rustc_abi.is_none(), "`rustc_abi` is unused on MIPS"); check_matches!( (&*self.llvm_abiname, &self.abi), - ("n64", Abi::Abi64), + // No in-tree targets use "n32" but at least for now we let out-of-tree targets + // experiment with that. + ("n64", Abi::Abi64) | ("n32", Abi::Unspecified | Abi::Other(_)), "invalid MIPS ABI name and `cfg(target_abi)` combination:\n\ ABI name: {}\n\ cfg(target_abi): {}", diff --git a/compiler/rustc_target/src/spec/targets/mips_mti_none_elf.rs b/compiler/rustc_target/src/spec/targets/mips_mti_none_elf.rs index 54039925e7957..ed024c6f9cd44 100644 --- a/compiler/rustc_target/src/spec/targets/mips_mti_none_elf.rs +++ b/compiler/rustc_target/src/spec/targets/mips_mti_none_elf.rs @@ -24,6 +24,7 @@ pub(crate) fn target() -> Target { endian: Endian::Big, cpu: "mips32r2".into(), + llvm_abiname: "o32".into(), max_atomic_width: Some(32), features: "+mips32r2,+soft-float,+noabicalls".into(), diff --git a/compiler/rustc_target/src/spec/targets/mips_unknown_linux_gnu.rs b/compiler/rustc_target/src/spec/targets/mips_unknown_linux_gnu.rs index ea6e237895ae3..9eb3173d64bc2 100644 --- a/compiler/rustc_target/src/spec/targets/mips_unknown_linux_gnu.rs +++ b/compiler/rustc_target/src/spec/targets/mips_unknown_linux_gnu.rs @@ -18,6 +18,7 @@ pub(crate) fn target() -> Target { endian: Endian::Big, cpu: "mips32r2".into(), features: "+mips32r2,+fpxx,+nooddspreg".into(), + llvm_abiname: "o32".into(), max_atomic_width: Some(32), mcount: "_mcount".into(), diff --git a/compiler/rustc_target/src/spec/targets/mips_unknown_linux_musl.rs b/compiler/rustc_target/src/spec/targets/mips_unknown_linux_musl.rs index ab68c2495b5ac..5737e42f9919c 100644 --- a/compiler/rustc_target/src/spec/targets/mips_unknown_linux_musl.rs +++ b/compiler/rustc_target/src/spec/targets/mips_unknown_linux_musl.rs @@ -18,6 +18,11 @@ pub(crate) fn target() -> Target { pointer_width: 32, data_layout: "E-m:m-p:32:32-i8:8:32-i16:16:32-i64:64-n32-S64".into(), arch: Arch::Mips, - options: TargetOptions { endian: Endian::Big, mcount: "_mcount".into(), ..base }, + options: TargetOptions { + endian: Endian::Big, + llvm_abiname: "o32".into(), + mcount: "_mcount".into(), + ..base + }, } } diff --git a/compiler/rustc_target/src/spec/targets/mips_unknown_linux_uclibc.rs b/compiler/rustc_target/src/spec/targets/mips_unknown_linux_uclibc.rs index c699f7e20b065..d9bfa12169c32 100644 --- a/compiler/rustc_target/src/spec/targets/mips_unknown_linux_uclibc.rs +++ b/compiler/rustc_target/src/spec/targets/mips_unknown_linux_uclibc.rs @@ -18,6 +18,7 @@ pub(crate) fn target() -> Target { endian: Endian::Big, cpu: "mips32r2".into(), features: "+mips32r2,+soft-float".into(), + llvm_abiname: "o32".into(), max_atomic_width: Some(32), mcount: "_mcount".into(), diff --git a/compiler/rustc_target/src/spec/targets/mipsel_mti_none_elf.rs b/compiler/rustc_target/src/spec/targets/mipsel_mti_none_elf.rs index 06c4d14be4323..767c57e3e8601 100644 --- a/compiler/rustc_target/src/spec/targets/mipsel_mti_none_elf.rs +++ b/compiler/rustc_target/src/spec/targets/mipsel_mti_none_elf.rs @@ -24,6 +24,7 @@ pub(crate) fn target() -> Target { endian: Endian::Little, cpu: "mips32r2".into(), + llvm_abiname: "o32".into(), max_atomic_width: Some(32), features: "+mips32r2,+soft-float,+noabicalls".into(), diff --git a/compiler/rustc_target/src/spec/targets/mipsel_sony_psp.rs b/compiler/rustc_target/src/spec/targets/mipsel_sony_psp.rs index 370e585f65ade..bc8f29c1bf1e3 100644 --- a/compiler/rustc_target/src/spec/targets/mipsel_sony_psp.rs +++ b/compiler/rustc_target/src/spec/targets/mipsel_sony_psp.rs @@ -36,6 +36,7 @@ pub(crate) fn target() -> Target { // PSP does not support trap-on-condition instructions. llvm_args: cvs!["-mno-check-zero-division"], + llvm_abiname: "o32".into(), pre_link_args, link_script: Some(LINKER_SCRIPT.into()), ..Default::default() diff --git a/compiler/rustc_target/src/spec/targets/mipsel_unknown_linux_gnu.rs b/compiler/rustc_target/src/spec/targets/mipsel_unknown_linux_gnu.rs index 79a22e518b0cb..752de4623e919 100644 --- a/compiler/rustc_target/src/spec/targets/mipsel_unknown_linux_gnu.rs +++ b/compiler/rustc_target/src/spec/targets/mipsel_unknown_linux_gnu.rs @@ -16,6 +16,7 @@ pub(crate) fn target() -> Target { options: TargetOptions { cpu: "mips32r2".into(), features: "+mips32r2,+fpxx,+nooddspreg".into(), + llvm_abiname: "o32".into(), max_atomic_width: Some(32), mcount: "_mcount".into(), diff --git a/compiler/rustc_target/src/spec/targets/mipsel_unknown_linux_musl.rs b/compiler/rustc_target/src/spec/targets/mipsel_unknown_linux_musl.rs index 8c64b17a37b57..fb3375285d508 100644 --- a/compiler/rustc_target/src/spec/targets/mipsel_unknown_linux_musl.rs +++ b/compiler/rustc_target/src/spec/targets/mipsel_unknown_linux_musl.rs @@ -16,6 +16,6 @@ pub(crate) fn target() -> Target { pointer_width: 32, data_layout: "e-m:m-p:32:32-i8:8:32-i16:16:32-i64:64-n32-S64".into(), arch: Arch::Mips, - options: TargetOptions { mcount: "_mcount".into(), ..base }, + options: TargetOptions { llvm_abiname: "o32".into(), mcount: "_mcount".into(), ..base }, } } diff --git a/compiler/rustc_target/src/spec/targets/mipsel_unknown_linux_uclibc.rs b/compiler/rustc_target/src/spec/targets/mipsel_unknown_linux_uclibc.rs index 295b1788877ce..830cdd1238db8 100644 --- a/compiler/rustc_target/src/spec/targets/mipsel_unknown_linux_uclibc.rs +++ b/compiler/rustc_target/src/spec/targets/mipsel_unknown_linux_uclibc.rs @@ -16,6 +16,7 @@ pub(crate) fn target() -> Target { options: TargetOptions { cpu: "mips32r2".into(), features: "+mips32r2,+soft-float".into(), + llvm_abiname: "o32".into(), max_atomic_width: Some(32), mcount: "_mcount".into(), diff --git a/compiler/rustc_target/src/spec/targets/mipsel_unknown_netbsd.rs b/compiler/rustc_target/src/spec/targets/mipsel_unknown_netbsd.rs index 69b232d71ea1e..2620629400306 100644 --- a/compiler/rustc_target/src/spec/targets/mipsel_unknown_netbsd.rs +++ b/compiler/rustc_target/src/spec/targets/mipsel_unknown_netbsd.rs @@ -20,6 +20,7 @@ pub(crate) fn target() -> Target { arch: Arch::Mips, options: TargetOptions { features: "+soft-float".into(), + llvm_abiname: "o32".into(), mcount: "__mcount".into(), endian: Endian::Little, ..base diff --git a/compiler/rustc_target/src/spec/targets/mipsel_unknown_none.rs b/compiler/rustc_target/src/spec/targets/mipsel_unknown_none.rs index 7012651afc348..b66be0bef216c 100644 --- a/compiler/rustc_target/src/spec/targets/mipsel_unknown_none.rs +++ b/compiler/rustc_target/src/spec/targets/mipsel_unknown_none.rs @@ -23,6 +23,7 @@ pub(crate) fn target() -> Target { linker_flavor: LinkerFlavor::Gnu(Cc::No, Lld::Yes), cpu: "mips32r2".into(), features: "+mips32r2,+soft-float,+noabicalls".into(), + llvm_abiname: "o32".into(), max_atomic_width: Some(32), linker: Some("rust-lld".into()), panic_strategy: PanicStrategy::Abort, diff --git a/compiler/rustc_target/src/spec/targets/mipsisa32r6_unknown_linux_gnu.rs b/compiler/rustc_target/src/spec/targets/mipsisa32r6_unknown_linux_gnu.rs index b45511446d8d3..9b063365b8d50 100644 --- a/compiler/rustc_target/src/spec/targets/mipsisa32r6_unknown_linux_gnu.rs +++ b/compiler/rustc_target/src/spec/targets/mipsisa32r6_unknown_linux_gnu.rs @@ -18,6 +18,7 @@ pub(crate) fn target() -> Target { endian: Endian::Big, cpu: "mips32r6".into(), features: "+mips32r6".into(), + llvm_abiname: "o32".into(), max_atomic_width: Some(32), mcount: "_mcount".into(), diff --git a/compiler/rustc_target/src/spec/targets/mipsisa32r6el_unknown_linux_gnu.rs b/compiler/rustc_target/src/spec/targets/mipsisa32r6el_unknown_linux_gnu.rs index 36845029de3b9..a5a05d56a4928 100644 --- a/compiler/rustc_target/src/spec/targets/mipsisa32r6el_unknown_linux_gnu.rs +++ b/compiler/rustc_target/src/spec/targets/mipsisa32r6el_unknown_linux_gnu.rs @@ -16,6 +16,7 @@ pub(crate) fn target() -> Target { options: TargetOptions { cpu: "mips32r6".into(), features: "+mips32r6".into(), + llvm_abiname: "o32".into(), max_atomic_width: Some(32), mcount: "_mcount".into(),