From 5914fb779ff22ca2e58f78bace7176c5fccbd788 Mon Sep 17 00:00:00 2001 From: Urgau Date: Sun, 15 Dec 2024 16:17:05 +0100 Subject: [PATCH 01/20] Stabilize `num_midpoint_signed` feature --- library/core/src/num/mod.rs | 8 ++++---- library/coretests/tests/lib.rs | 1 - 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/library/core/src/num/mod.rs b/library/core/src/num/mod.rs index 6c1b568e231d0..b479b8502a8e4 100644 --- a/library/core/src/num/mod.rs +++ b/library/core/src/num/mod.rs @@ -163,14 +163,14 @@ macro_rules! midpoint_impl { /// # Examples /// /// ``` - /// #![feature(num_midpoint_signed)] #[doc = concat!("assert_eq!(0", stringify!($SelfT), ".midpoint(4), 2);")] #[doc = concat!("assert_eq!((-1", stringify!($SelfT), ").midpoint(2), 0);")] #[doc = concat!("assert_eq!((-7", stringify!($SelfT), ").midpoint(0), -3);")] #[doc = concat!("assert_eq!(0", stringify!($SelfT), ".midpoint(-7), -3);")] #[doc = concat!("assert_eq!(0", stringify!($SelfT), ".midpoint(7), 3);")] /// ``` - #[unstable(feature = "num_midpoint_signed", issue = "110840")] + #[stable(feature = "num_midpoint_signed", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "num_midpoint_signed", since = "CURRENT_RUSTC_VERSION")] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] @@ -215,14 +215,14 @@ macro_rules! midpoint_impl { /// # Examples /// /// ``` - /// #![feature(num_midpoint_signed)] #[doc = concat!("assert_eq!(0", stringify!($SelfT), ".midpoint(4), 2);")] #[doc = concat!("assert_eq!((-1", stringify!($SelfT), ").midpoint(2), 0);")] #[doc = concat!("assert_eq!((-7", stringify!($SelfT), ").midpoint(0), -3);")] #[doc = concat!("assert_eq!(0", stringify!($SelfT), ".midpoint(-7), -3);")] #[doc = concat!("assert_eq!(0", stringify!($SelfT), ".midpoint(7), 3);")] /// ``` - #[unstable(feature = "num_midpoint_signed", issue = "110840")] + #[stable(feature = "num_midpoint_signed", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "num_midpoint_signed", since = "CURRENT_RUSTC_VERSION")] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] diff --git a/library/coretests/tests/lib.rs b/library/coretests/tests/lib.rs index 0607d508a48e5..7353f12f45779 100644 --- a/library/coretests/tests/lib.rs +++ b/library/coretests/tests/lib.rs @@ -63,7 +63,6 @@ #![feature(maybe_uninit_write_slice)] #![feature(min_specialization)] #![feature(never_type)] -#![feature(num_midpoint_signed)] #![feature(numfmt)] #![feature(pattern)] #![feature(pointer_is_aligned_to)] From 2445dd794e4e24d62ab8d79ba8924baba44865ae Mon Sep 17 00:00:00 2001 From: kulst Date: Sun, 9 Feb 2025 11:50:06 +0100 Subject: [PATCH 02/20] Persist target features used for codegen beyond tcx Bitcode linkers like llvm-bitcode-linker or bpf linker hand over the target features to llvm during link stage. During link stage the `TyCtxt` is already gone so it is not possible to create a query for the global backend features any longer. The features preserved in `Session.target_features` only incorporate target features known to rustc. This would contradict with the behaviour during codegen stage which also passes target features to llvm which are unknown to rustc. This commit adds target features as a field to the `CrateInfo` struct and queries the target features in its new function. This way the target features are preserved beyond tcx and available at link stage. To make sure the `global_backend_features` query is always registered even if the CodegenBackend does not register it, this registration is added to the `provide`function of the `rustc_codegen_ssa` crate. --- compiler/rustc_codegen_ssa/src/base.rs | 1 + compiler/rustc_codegen_ssa/src/lib.rs | 2 ++ 2 files changed, 3 insertions(+) diff --git a/compiler/rustc_codegen_ssa/src/base.rs b/compiler/rustc_codegen_ssa/src/base.rs index e800492dad02f..0b420fcfaae26 100644 --- a/compiler/rustc_codegen_ssa/src/base.rs +++ b/compiler/rustc_codegen_ssa/src/base.rs @@ -921,6 +921,7 @@ impl CrateInfo { let n_crates = crates.len(); let mut info = CrateInfo { target_cpu, + target_features: tcx.global_backend_features(()).clone(), crate_types, exported_symbols, linked_symbols, diff --git a/compiler/rustc_codegen_ssa/src/lib.rs b/compiler/rustc_codegen_ssa/src/lib.rs index 428a45975f1ec..9d2ac219d592c 100644 --- a/compiler/rustc_codegen_ssa/src/lib.rs +++ b/compiler/rustc_codegen_ssa/src/lib.rs @@ -190,6 +190,7 @@ impl From<&cstore::NativeLib> for NativeLib { #[derive(Debug, Encodable, Decodable)] pub struct CrateInfo { pub target_cpu: String, + pub target_features: Vec, pub crate_types: Vec, pub exported_symbols: UnordMap>, pub linked_symbols: FxIndexMap>, @@ -230,6 +231,7 @@ pub fn provide(providers: &mut Providers) { crate::base::provide(providers); crate::target_features::provide(providers); crate::codegen_attrs::provide(providers); + providers.queries.global_backend_features = |_tcx: TyCtxt<'_>, ()| vec![]; } /// Checks if the given filename ends with the `.rcgu.o` extension that `rustc` From 831d9f39e9c330934b7c4f35010477ba4a738d96 Mon Sep 17 00:00:00 2001 From: kulst Date: Wed, 5 Feb 2025 21:33:58 +0100 Subject: [PATCH 03/20] Pass through of target features to llvm-bitcode-linker and handling them The .ptx version produced by llc can be specified by passing it with --mattr. Currently it is not possible to specify the .ptx version with -Ctarget-feature because these are not passed through to llvm-bitcode-linker and handled by it. This commit adds both. --target-feature and -mattr are passed with equals to mitigate issues when the value starts with a - (minus). --- compiler/rustc_codegen_ssa/src/back/link.rs | 6 ++++++ .../src/bin/llvm-bitcode-linker.rs | 6 +++++- src/tools/llvm-bitcode-linker/src/linker.rs | 13 ++++++++++++- 3 files changed, 23 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs index 105a4cb81f0d1..dceef52e81a2f 100644 --- a/compiler/rustc_codegen_ssa/src/back/link.rs +++ b/compiler/rustc_codegen_ssa/src/back/link.rs @@ -2518,6 +2518,12 @@ fn add_order_independent_options( "--target-cpu", &codegen_results.crate_info.target_cpu, ]); + if codegen_results.crate_info.target_features.len() > 0 { + cmd.link_arg(&format!( + "--target-feature={}", + &codegen_results.crate_info.target_features.join(",") + )); + } } else if flavor == LinkerFlavor::Ptx { cmd.link_args(&["--fallback-arch", &codegen_results.crate_info.target_cpu]); } else if flavor == LinkerFlavor::Bpf { diff --git a/src/tools/llvm-bitcode-linker/src/bin/llvm-bitcode-linker.rs b/src/tools/llvm-bitcode-linker/src/bin/llvm-bitcode-linker.rs index fdbf6171c53f2..608c6605304f4 100644 --- a/src/tools/llvm-bitcode-linker/src/bin/llvm-bitcode-linker.rs +++ b/src/tools/llvm-bitcode-linker/src/bin/llvm-bitcode-linker.rs @@ -27,6 +27,10 @@ pub struct Args { #[arg(long)] target_cpu: Option, + /// The target features + #[arg(long)] + target_feature: Option, + /// Write output to the filename #[arg(short, long)] output: PathBuf, @@ -49,7 +53,7 @@ fn main() -> anyhow::Result<()> { let args = Args::parse(); - let mut linker = Session::new(args.target, args.target_cpu, args.output); + let mut linker = Session::new(args.target, args.target_cpu, args.target_feature, args.output); linker.add_exported_symbols(args.export_symbol); diff --git a/src/tools/llvm-bitcode-linker/src/linker.rs b/src/tools/llvm-bitcode-linker/src/linker.rs index 9f579d1009408..dafd847e76808 100644 --- a/src/tools/llvm-bitcode-linker/src/linker.rs +++ b/src/tools/llvm-bitcode-linker/src/linker.rs @@ -8,6 +8,7 @@ use crate::{Optimization, Target}; pub struct Session { target: Target, cpu: Option, + feature: Option, symbols: Vec, /// A file that `llvm-link` supports, like a bitcode file or an archive. @@ -21,7 +22,12 @@ pub struct Session { } impl Session { - pub fn new(target: crate::Target, cpu: Option, out_path: PathBuf) -> Self { + pub fn new( + target: crate::Target, + cpu: Option, + feature: Option, + out_path: PathBuf, + ) -> Self { let link_path = out_path.with_extension("o"); let opt_path = out_path.with_extension("optimized.o"); let sym_path = out_path.with_extension("symbols.txt"); @@ -29,6 +35,7 @@ impl Session { Session { target, cpu, + feature, symbols: Vec::new(), files: Vec::new(), link_path, @@ -134,6 +141,10 @@ impl Session { lcc_command.arg("--mcpu").arg(mcpu); } + if let Some(mattr) = &self.feature { + lcc_command.arg(&format!("--mattr={}", mattr)); + } + let lcc_output = lcc_command .arg(&self.opt_path) .arg("-o").arg(&self.out_path) From 35febd7a6d57179f41cb5b4a37f9545915e4d7a5 Mon Sep 17 00:00:00 2001 From: Li Keqing Date: Wed, 19 Feb 2025 18:05:37 +0800 Subject: [PATCH 04/20] Fix `*-win7-windows-msvc` target since 26eeac1a1e9fe46ffd80dd0d3dafdd2c2a644306 --- library/std/src/sys/pal/windows/c.rs | 4 ++-- library/std/src/sys/random/windows.rs | 2 +- library/std/src/sys/sync/mutex/windows7.rs | 2 +- library/std/src/sys/sync/thread_parking/windows7.rs | 8 ++++---- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/library/std/src/sys/pal/windows/c.rs b/library/std/src/sys/pal/windows/c.rs index 8dc61edb603f4..4fbdc839939c9 100644 --- a/library/std/src/sys/pal/windows/c.rs +++ b/library/std/src/sys/pal/windows/c.rs @@ -204,7 +204,7 @@ compat_fn_with_fallback! { pub fn NtReleaseKeyedEvent( EventHandle: HANDLE, Key: *const c_void, - Alertable: BOOLEAN, + Alertable: bool, Timeout: *mut i64 ) -> NTSTATUS { panic!("keyed events not available") @@ -213,7 +213,7 @@ compat_fn_with_fallback! { pub fn NtWaitForKeyedEvent( EventHandle: HANDLE, Key: *const c_void, - Alertable: BOOLEAN, + Alertable: bool, Timeout: *mut i64 ) -> NTSTATUS { panic!("keyed events not available") diff --git a/library/std/src/sys/random/windows.rs b/library/std/src/sys/random/windows.rs index 7566000f9e6ff..f5da637f56ca9 100644 --- a/library/std/src/sys/random/windows.rs +++ b/library/std/src/sys/random/windows.rs @@ -14,7 +14,7 @@ pub fn fill_bytes(mut bytes: &mut [u8]) { while !bytes.is_empty() { let len = bytes.len().try_into().unwrap_or(u32::MAX); let ret = unsafe { c::RtlGenRandom(bytes.as_mut_ptr().cast(), len) }; - assert_ne!(ret, 0, "failed to generate random data"); + assert!(ret, "failed to generate random data"); bytes = &mut bytes[len as usize..]; } } diff --git a/library/std/src/sys/sync/mutex/windows7.rs b/library/std/src/sys/sync/mutex/windows7.rs index 689dba10f01ed..0b57de78ba6dd 100644 --- a/library/std/src/sys/sync/mutex/windows7.rs +++ b/library/std/src/sys/sync/mutex/windows7.rs @@ -44,7 +44,7 @@ impl Mutex { #[inline] pub fn try_lock(&self) -> bool { - unsafe { c::TryAcquireSRWLockExclusive(raw(self)) != 0 } + unsafe { c::TryAcquireSRWLockExclusive(raw(self)) } } #[inline] diff --git a/library/std/src/sys/sync/thread_parking/windows7.rs b/library/std/src/sys/sync/thread_parking/windows7.rs index f7585e882f055..a1a0f8427cd83 100644 --- a/library/std/src/sys/sync/thread_parking/windows7.rs +++ b/library/std/src/sys/sync/thread_parking/windows7.rs @@ -195,7 +195,7 @@ mod keyed_events { pub unsafe fn park(parker: Pin<&Parker>) { // Wait for unpark() to produce this event. - c::NtWaitForKeyedEvent(keyed_event_handle(), parker.ptr(), 0, ptr::null_mut()); + c::NtWaitForKeyedEvent(keyed_event_handle(), parker.ptr(), false, ptr::null_mut()); // Set the state back to EMPTY (from either PARKED or NOTIFIED). // Note that we don't just write EMPTY, but use swap() to also // include an acquire-ordered read to synchronize with unpark()'s @@ -218,7 +218,7 @@ mod keyed_events { // Wait for unpark() to produce this event. let unparked = - c::NtWaitForKeyedEvent(handle, parker.ptr(), 0, &mut timeout) == c::STATUS_SUCCESS; + c::NtWaitForKeyedEvent(handle, parker.ptr(), false, &mut timeout) == c::STATUS_SUCCESS; // Set the state back to EMPTY (from either PARKED or NOTIFIED). let prev_state = parker.state.swap(EMPTY, Acquire); @@ -228,7 +228,7 @@ mod keyed_events { // was set to NOTIFIED, which means we *just* missed an // unpark(), which is now blocked on us to wait for it. // Wait for it to consume the event and unblock that thread. - c::NtWaitForKeyedEvent(handle, parker.ptr(), 0, ptr::null_mut()); + c::NtWaitForKeyedEvent(handle, parker.ptr(), false, ptr::null_mut()); } } pub unsafe fn unpark(parker: Pin<&Parker>) { @@ -239,7 +239,7 @@ mod keyed_events { // To prevent this thread from blocking indefinitely in that case, // park_impl() will, after seeing the state set to NOTIFIED after // waking up, call NtWaitForKeyedEvent again to unblock us. - c::NtReleaseKeyedEvent(keyed_event_handle(), parker.ptr(), 0, ptr::null_mut()); + c::NtReleaseKeyedEvent(keyed_event_handle(), parker.ptr(), false, ptr::null_mut()); } fn keyed_event_handle() -> c::HANDLE { From 78ddabf31d3147a19be77c3b38b49fe60915d75a Mon Sep 17 00:00:00 2001 From: Patryk Wychowaniec Date: Sun, 13 Oct 2024 14:58:44 +0200 Subject: [PATCH 05/20] Create a generic AVR target: avr-none This commit removes the `avr-unknown-gnu-atmega328` target and replaces it with a more generic `avr-none` variant that must be specialized with the `-C target-cpu` flag (e.g. `-C target-cpu=atmega328p`). --- compiler/rustc_codegen_ssa/src/back/link.rs | 1 + compiler/rustc_codegen_ssa/src/back/linker.rs | 12 +++ .../src/spec/base/{avr_gnu.rs => avr.rs} | 40 --------- compiler/rustc_target/src/spec/base/mod.rs | 2 +- compiler/rustc_target/src/spec/mod.rs | 9 ++- .../rustc_target/src/spec/targets/avr_none.rs | 32 ++++++++ .../spec/targets/avr_unknown_gnu_atmega328.rs | 5 -- src/doc/rustc/src/platform-support.md | 2 +- .../rustc/src/platform-support/avr-none.md | 81 +++++++++++++++++++ src/tools/compiletest/src/header/tests.rs | 3 + .../src/external_deps/rustc.rs | 7 ++ tests/assembly/asm/avr-modifiers.rs | 2 +- tests/assembly/asm/avr-types.rs | 2 +- tests/assembly/targets/targets-pe.rs | 6 +- tests/codegen/asm/avr-clobbers.rs | 2 +- tests/codegen/avr/avr-func-addrspace.rs | 2 +- tests/run-make/avr-rjmp-offset/rmake.rs | 4 +- .../feature-gate-abi-avr-interrupt.rs | 2 +- tests/ui/repr/16-bit-repr-c-enum.rs | 2 +- 19 files changed, 156 insertions(+), 60 deletions(-) rename compiler/rustc_target/src/spec/base/{avr_gnu.rs => avr.rs} (91%) create mode 100644 compiler/rustc_target/src/spec/targets/avr_none.rs delete mode 100644 compiler/rustc_target/src/spec/targets/avr_unknown_gnu_atmega328.rs create mode 100644 src/doc/rustc/src/platform-support/avr-none.md diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs index 105a4cb81f0d1..0399ea77c72af 100644 --- a/compiler/rustc_codegen_ssa/src/back/link.rs +++ b/compiler/rustc_codegen_ssa/src/back/link.rs @@ -1990,6 +1990,7 @@ fn add_pre_link_args(cmd: &mut dyn Linker, sess: &Session, flavor: LinkerFlavor) if let Some(args) = sess.target.pre_link_args.get(&flavor) { cmd.verbatim_args(args.iter().map(Deref::deref)); } + cmd.verbatim_args(&sess.opts.unstable_opts.pre_link_args); } diff --git a/compiler/rustc_codegen_ssa/src/back/linker.rs b/compiler/rustc_codegen_ssa/src/back/linker.rs index e3ace01c1eb54..8900405c1b8f8 100644 --- a/compiler/rustc_codegen_ssa/src/back/linker.rs +++ b/compiler/rustc_codegen_ssa/src/back/linker.rs @@ -153,6 +153,7 @@ pub(crate) fn get_linker<'a>( hinted_static: None, is_ld: cc == Cc::No, is_gnu: flavor.is_gnu(), + uses_lld: flavor.uses_lld(), }) as Box, LinkerFlavor::Msvc(..) => Box::new(MsvcLinker { cmd, sess }) as Box, LinkerFlavor::EmCc => Box::new(EmLinker { cmd, sess }) as Box, @@ -361,6 +362,7 @@ struct GccLinker<'a> { // Link as ld is_ld: bool, is_gnu: bool, + uses_lld: bool, } impl<'a> GccLinker<'a> { @@ -552,6 +554,7 @@ impl<'a> Linker for GccLinker<'a> { self.link_args(&["--entry", "_initialize"]); } } + // VxWorks compiler driver introduced `--static-crt` flag specifically for rustc, // it switches linking for libc and similar system libraries to static without using // any `#[link]` attributes in the `libc` crate, see #72782 for details. @@ -567,6 +570,15 @@ impl<'a> Linker for GccLinker<'a> { { self.cc_arg("--static-crt"); } + + // avr-none doesn't have default ISA, users must specify which specific + // CPU (well, microcontroller) they are targetting using `-Ctarget-cpu`. + // + // Currently this makes sense only when using avr-gcc as a linker, since + // it brings a couple of hand-written important intrinsics from libgcc. + if self.sess.target.arch == "avr" && !self.uses_lld { + self.verbatim_arg(format!("-mmcu={}", self.target_cpu)); + } } fn link_dylib_by_name(&mut self, name: &str, verbatim: bool, as_needed: bool) { diff --git a/compiler/rustc_target/src/spec/base/avr_gnu.rs b/compiler/rustc_target/src/spec/base/avr.rs similarity index 91% rename from compiler/rustc_target/src/spec/base/avr_gnu.rs rename to compiler/rustc_target/src/spec/base/avr.rs index 3554dcfcb4a13..85b73e61e52cd 100644 --- a/compiler/rustc_target/src/spec/base/avr_gnu.rs +++ b/compiler/rustc_target/src/spec/base/avr.rs @@ -1,45 +1,5 @@ use object::elf; -use crate::spec::{Cc, LinkerFlavor, Lld, RelocModel, Target, TargetOptions}; - -/// A base target for AVR devices using the GNU toolchain. -/// -/// Requires GNU avr-gcc and avr-binutils on the host system. -/// FIXME: Remove the second parameter when const string concatenation is possible. -pub(crate) fn target(target_cpu: &'static str, mmcu: &'static str) -> Target { - Target { - arch: "avr".into(), - metadata: crate::spec::TargetMetadata { - description: None, - tier: None, - host_tools: None, - std: None, - }, - data_layout: "e-P1-p:16:8-i8:8-i16:8-i32:8-i64:8-f32:8-f64:8-n8-a:8".into(), - llvm_target: "avr-unknown-unknown".into(), - pointer_width: 16, - options: TargetOptions { - env: "gnu".into(), - - c_int_width: "16".into(), - cpu: target_cpu.into(), - exe_suffix: ".elf".into(), - - linker: Some("avr-gcc".into()), - eh_frame_header: false, - pre_link_args: TargetOptions::link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &[mmcu]), - late_link_args: TargetOptions::link_args( - LinkerFlavor::Gnu(Cc::Yes, Lld::No), - &["-lgcc"], - ), - max_atomic_width: Some(16), - atomic_cas: false, - relocation_model: RelocModel::Static, - ..TargetOptions::default() - }, - } -} - /// Resolve the value of the EF_AVR_ARCH field for AVR ELF files, given the /// name of the target CPU / MCU. /// diff --git a/compiler/rustc_target/src/spec/base/mod.rs b/compiler/rustc_target/src/spec/base/mod.rs index b9139c8452c5f..6f88be5d37f16 100644 --- a/compiler/rustc_target/src/spec/base/mod.rs +++ b/compiler/rustc_target/src/spec/base/mod.rs @@ -1,7 +1,7 @@ pub(crate) mod aix; pub(crate) mod android; pub(crate) mod apple; -pub(crate) mod avr_gnu; +pub(crate) mod avr; pub(crate) mod bpf; pub(crate) mod cygwin; pub(crate) mod dragonfly; diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs index f7e467b0c1155..3b943fc178f27 100644 --- a/compiler/rustc_target/src/spec/mod.rs +++ b/compiler/rustc_target/src/spec/mod.rs @@ -60,7 +60,7 @@ pub mod crt_objects; mod base; mod json; -pub use base::avr_gnu::ef_avr_arch; +pub use base::avr::ef_avr_arch; /// Linker is called through a C/C++ compiler. #[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)] @@ -1797,7 +1797,7 @@ supported_targets! { ("riscv64gc-unknown-fuchsia", riscv64gc_unknown_fuchsia), ("x86_64-unknown-fuchsia", x86_64_unknown_fuchsia), - ("avr-unknown-gnu-atmega328", avr_unknown_gnu_atmega328), + ("avr-none", avr_none), ("x86_64-unknown-l4re-uclibc", x86_64_unknown_l4re_uclibc), @@ -3062,7 +3062,10 @@ impl Target { &self.post_link_args, ] { for (&flavor, flavor_args) in args { - check!(!flavor_args.is_empty(), "linker flavor args must not be empty"); + check!( + !flavor_args.is_empty() || self.arch == "avr", + "linker flavor args must not be empty" + ); // Check that flavors mentioned in link args are compatible with the default flavor. match self.linker_flavor { LinkerFlavor::Gnu(..) => { diff --git a/compiler/rustc_target/src/spec/targets/avr_none.rs b/compiler/rustc_target/src/spec/targets/avr_none.rs new file mode 100644 index 0000000000000..91d3197d0998e --- /dev/null +++ b/compiler/rustc_target/src/spec/targets/avr_none.rs @@ -0,0 +1,32 @@ +use crate::spec::{Cc, LinkerFlavor, Lld, RelocModel, Target, TargetOptions}; + +pub(crate) fn target() -> Target { + Target { + arch: "avr".into(), + metadata: crate::spec::TargetMetadata { + description: None, + tier: None, + host_tools: None, + std: None, + }, + data_layout: "e-P1-p:16:8-i8:8-i16:8-i32:8-i64:8-f32:8-f64:8-n8-a:8".into(), + llvm_target: "avr-unknown-unknown".into(), + pointer_width: 16, + options: TargetOptions { + c_int_width: "16".into(), + exe_suffix: ".elf".into(), + linker: Some("avr-gcc".into()), + eh_frame_header: false, + pre_link_args: TargetOptions::link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &[]), + late_link_args: TargetOptions::link_args( + LinkerFlavor::Gnu(Cc::Yes, Lld::No), + &["-lgcc"], + ), + max_atomic_width: Some(16), + atomic_cas: false, + relocation_model: RelocModel::Static, + need_explicit_cpu: true, + ..TargetOptions::default() + }, + } +} diff --git a/compiler/rustc_target/src/spec/targets/avr_unknown_gnu_atmega328.rs b/compiler/rustc_target/src/spec/targets/avr_unknown_gnu_atmega328.rs deleted file mode 100644 index c3d6fb722733d..0000000000000 --- a/compiler/rustc_target/src/spec/targets/avr_unknown_gnu_atmega328.rs +++ /dev/null @@ -1,5 +0,0 @@ -use crate::spec::{Target, base}; - -pub(crate) fn target() -> Target { - base::avr_gnu::target("atmega328", "-mmcu=atmega328") -} diff --git a/src/doc/rustc/src/platform-support.md b/src/doc/rustc/src/platform-support.md index b5cd3864620d3..c7f4ab48ab13e 100644 --- a/src/doc/rustc/src/platform-support.md +++ b/src/doc/rustc/src/platform-support.md @@ -301,7 +301,7 @@ target | std | host | notes [`armv8r-none-eabihf`](platform-support/armv8r-none-eabihf.md) | * | | Bare Armv8-R, hardfloat [`armv7a-nuttx-eabi`](platform-support/nuttx.md) | ✓ | | ARMv7-A with NuttX [`armv7a-nuttx-eabihf`](platform-support/nuttx.md) | ✓ | | ARMv7-A with NuttX, hardfloat -`avr-unknown-gnu-atmega328` | * | | AVR. Requires `-Z build-std=core` +`avr-none` | * | | AVR; requires `-Zbuild-std=core` and `-Ctarget-cpu=...` `bpfeb-unknown-none` | * | | BPF (big endian) `bpfel-unknown-none` | * | | BPF (little endian) `csky-unknown-linux-gnuabiv2` | ✓ | | C-SKY abiv2 Linux (little endian) diff --git a/src/doc/rustc/src/platform-support/avr-none.md b/src/doc/rustc/src/platform-support/avr-none.md new file mode 100644 index 0000000000000..9c1836222c103 --- /dev/null +++ b/src/doc/rustc/src/platform-support/avr-none.md @@ -0,0 +1,81 @@ +# `avr-none` + +Series of microcontrollers from Atmel: ATmega8, ATmega328p etc. + +**Tier: 3** + +## Target maintainers + +- [Patryk Wychowaniec](https://github.com/Patryk27) + +## Requirements + +This target is only cross-compiled; x86-64 Linux, x86-64 macOS and aarch64 macOS +hosts are confirmed to work, but in principle any machine able to run rustc and +avr-gcc should be good. + +Compiling for this target requires `avr-gcc` installed, because a couple of +intrinsics (like 32-bit multiplication) rely on [`libgcc`](https://github.com/gcc-mirror/gcc/blob/3269a722b7a03613e9c4e2862bc5088c4a17cc11/libgcc/config/avr/lib1funcs.S) +and can't be provided through `compiler-builtins` yet. This is a limitation that +[we hope to lift in the future](https://github.com/rust-lang/compiler-builtins/issues/711). + +You'll also need to setup the `.cargo/config` file - see below for details. + +## Building the target + +Rust comes with AVR support enabled, you don't have to rebuild the compiler. + +## Building Rust programs + +Install `avr-gcc`: + +```console +# Ubuntu: +$ sudo apt-get install gcc-avr + +# Mac: +$ brew tap osx-cross/avr && brew install avr-gcc + +# NixOS (takes a couple of minutes, since it's not provided through Hydra): +$ nix shell nixpkgs#pkgsCross.avr.buildPackages.gcc11 +``` + +... setup `.cargo/config` for your project: + +```toml +[build] +target = "avr-none" +rustflags = ["-C", "target-cpu=atmega328p"] + +[unstable] +build-std = ["core"] +``` + +... and then simply run: + +```console +$ cargo build --release +``` + +The final binary will be placed into +`./target/avr-none/release/your-project.elf`. + +Note that since AVRs have rather small amounts of registers, ROM and RAM, it's +recommended to always use `--release` to avoid running out of space. + +Also, please note that specifying `-C target-cpu` is required - here's a list of +the possible variants: + +https://github.com/llvm/llvm-project/blob/093d4db2f3c874d4683fb01194b00dbb20e5c713/clang/lib/Basic/Targets/AVR.cpp#L32 + +## Testing + +You can use [`simavr`](https://github.com/buserror/simavr) to emulate the +resulting firmware on your machine: + +```console +$ simavr -m atmega328p ./target/avr-none/release/your-project.elf +``` + +Alternatively, if you want to write a couple of actual `#[test]`s, you can use +[`avr-tester`](https://github.com/Patryk27/avr-tester). diff --git a/src/tools/compiletest/src/header/tests.rs b/src/tools/compiletest/src/header/tests.rs index 55292c46bba9c..c65f10a52bd5b 100644 --- a/src/tools/compiletest/src/header/tests.rs +++ b/src/tools/compiletest/src/header/tests.rs @@ -465,7 +465,10 @@ fn profiler_runtime() { #[test] fn asm_support() { let asms = [ + #[cfg(bootstrap)] ("avr-unknown-gnu-atmega328", false), + #[cfg(not(bootstrap))] + ("avr-none", false), ("i686-unknown-netbsd", true), ("riscv32gc-unknown-linux-gnu", true), ("riscv64imac-unknown-none-elf", true), diff --git a/src/tools/run-make-support/src/external_deps/rustc.rs b/src/tools/run-make-support/src/external_deps/rustc.rs index fd4a20278addd..710ba025830a8 100644 --- a/src/tools/run-make-support/src/external_deps/rustc.rs +++ b/src/tools/run-make-support/src/external_deps/rustc.rs @@ -253,6 +253,13 @@ impl Rustc { self } + /// Specify the target CPU. + pub fn target_cpu>(&mut self, target_cpu: S) -> &mut Self { + let target_cpu = target_cpu.as_ref(); + self.cmd.arg(format!("-Ctarget-cpu={target_cpu}")); + self + } + /// Specify the crate type. pub fn crate_type(&mut self, crate_type: &str) -> &mut Self { self.cmd.arg("--crate-type"); diff --git a/tests/assembly/asm/avr-modifiers.rs b/tests/assembly/asm/avr-modifiers.rs index 585fdd7b72534..124cad9bef6a8 100644 --- a/tests/assembly/asm/avr-modifiers.rs +++ b/tests/assembly/asm/avr-modifiers.rs @@ -1,6 +1,6 @@ //@ add-core-stubs //@ assembly-output: emit-asm -//@ compile-flags: --target avr-unknown-gnu-atmega328 +//@ compile-flags: --target avr-none -C target-cpu=atmega328p //@ needs-llvm-components: avr #![feature(no_core, asm_experimental_arch)] diff --git a/tests/assembly/asm/avr-types.rs b/tests/assembly/asm/avr-types.rs index 25cf3ec3b4bde..309405f4d51e7 100644 --- a/tests/assembly/asm/avr-types.rs +++ b/tests/assembly/asm/avr-types.rs @@ -1,6 +1,6 @@ //@ add-core-stubs //@ assembly-output: emit-asm -//@ compile-flags: --target avr-unknown-gnu-atmega328 +//@ compile-flags: --target avr-none -C target-cpu=atmega328p //@ needs-llvm-components: avr #![feature(no_core, asm_experimental_arch)] diff --git a/tests/assembly/targets/targets-pe.rs b/tests/assembly/targets/targets-pe.rs index 1fa4dc821dd37..b74d0181c4d67 100644 --- a/tests/assembly/targets/targets-pe.rs +++ b/tests/assembly/targets/targets-pe.rs @@ -15,9 +15,9 @@ //@ revisions: arm64ec_pc_windows_msvc //@ [arm64ec_pc_windows_msvc] compile-flags: --target arm64ec-pc-windows-msvc //@ [arm64ec_pc_windows_msvc] needs-llvm-components: aarch64 -//@ revisions: avr_unknown_gnu_atmega328 -//@ [avr_unknown_gnu_atmega328] compile-flags: --target avr-unknown-gnu-atmega328 -//@ [avr_unknown_gnu_atmega328] needs-llvm-components: avr +//@ revisions: avr_none +//@ [avr_none] compile-flags: --target avr-none -C target-cpu=atmega328p +//@ [avr_none] needs-llvm-components: avr //@ revisions: bpfeb_unknown_none //@ [bpfeb_unknown_none] compile-flags: --target bpfeb-unknown-none //@ [bpfeb_unknown_none] needs-llvm-components: bpf diff --git a/tests/codegen/asm/avr-clobbers.rs b/tests/codegen/asm/avr-clobbers.rs index 56218cd7bcffb..9451127bf04ab 100644 --- a/tests/codegen/asm/avr-clobbers.rs +++ b/tests/codegen/asm/avr-clobbers.rs @@ -1,6 +1,6 @@ //@ add-core-stubs //@ assembly-output: emit-asm -//@ compile-flags: --target avr-unknown-gnu-atmega328 +//@ compile-flags: --target avr-none -C target-cpu=atmega328p //@ needs-llvm-components: avr #![crate_type = "rlib"] diff --git a/tests/codegen/avr/avr-func-addrspace.rs b/tests/codegen/avr/avr-func-addrspace.rs index ed8acccb1ad85..2ec7c86b5f43c 100644 --- a/tests/codegen/avr/avr-func-addrspace.rs +++ b/tests/codegen/avr/avr-func-addrspace.rs @@ -1,4 +1,4 @@ -//@ compile-flags: -Copt-level=3 --target=avr-unknown-gnu-atmega328 --crate-type=rlib -C panic=abort +//@ compile-flags: -Copt-level=3 --target=avr-none -C target-cpu=atmega328p --crate-type=rlib -C panic=abort //@ needs-llvm-components: avr // This test validates that function pointers can be stored in global variables diff --git a/tests/run-make/avr-rjmp-offset/rmake.rs b/tests/run-make/avr-rjmp-offset/rmake.rs index de64b724eed2d..73b6ab3977e97 100644 --- a/tests/run-make/avr-rjmp-offset/rmake.rs +++ b/tests/run-make/avr-rjmp-offset/rmake.rs @@ -22,7 +22,8 @@ fn main() { .input("avr-rjmp-offsets.rs") .opt_level("s") .panic("abort") - .target("avr-unknown-gnu-atmega328") + .target("avr-none") + .target_cpu("avr") // normally one links with `avr-gcc`, but this is not available in CI, // hence this test diverges from the default behavior to enable linking // at all, which is necessary for the test (to resolve the labels). To @@ -49,6 +50,7 @@ fn main() { // of the Rust compiler did produce a label `rjmp .-4` (misses the first // instruction in the loop). assert!(disassembly.contains("
"), "no main function in output"); + disassembly .trim() .lines() diff --git a/tests/ui/feature-gates/feature-gate-abi-avr-interrupt.rs b/tests/ui/feature-gates/feature-gate-abi-avr-interrupt.rs index 5386628a8e069..ce3d3fc645d76 100644 --- a/tests/ui/feature-gates/feature-gate-abi-avr-interrupt.rs +++ b/tests/ui/feature-gates/feature-gate-abi-avr-interrupt.rs @@ -1,5 +1,5 @@ //@ needs-llvm-components: avr -//@ compile-flags: --target=avr-unknown-gnu-atmega328 --crate-type=rlib +//@ compile-flags: --target=avr-none -C target-cpu=atmega328p --crate-type=rlib #![no_core] #![feature(no_core, lang_items)] #[lang="sized"] diff --git a/tests/ui/repr/16-bit-repr-c-enum.rs b/tests/ui/repr/16-bit-repr-c-enum.rs index 2b6bbf1265083..011076882d24f 100644 --- a/tests/ui/repr/16-bit-repr-c-enum.rs +++ b/tests/ui/repr/16-bit-repr-c-enum.rs @@ -2,7 +2,7 @@ //@ revisions: avr msp430 // //@ [avr] needs-llvm-components: avr -//@ [avr] compile-flags: --target=avr-unknown-gnu-atmega328 --crate-type=rlib +//@ [avr] compile-flags: --target=avr-none -C target-cpu=atmega328p --crate-type=rlib //@ [msp430] needs-llvm-components: msp430 //@ [msp430] compile-flags: --target=msp430-none-elf --crate-type=rlib #![feature(no_core, lang_items, intrinsics, staged_api, rustc_attrs)] From 81ab20f34e5447108c8103c10cd3f106f338e7e1 Mon Sep 17 00:00:00 2001 From: Jordan McQueen Date: Thu, 20 Feb 2025 10:37:28 +0000 Subject: [PATCH 06/20] Update references to cc_detect.rs The locations of these files have since been changed. This is a simple change to update the references to these files. --- config.example.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/config.example.toml b/config.example.toml index fd27b24e46191..a17d3ec9f8841 100644 --- a/config.example.toml +++ b/config.example.toml @@ -793,12 +793,12 @@ # C compiler to be used to compile C code. Note that the # default value is platform specific, and if not specified it may also depend on # what platform is crossing to what platform. -# See `src/bootstrap/cc_detect.rs` for details. +# See `src/bootstrap/src/utils/cc_detect.rs` for details. #cc = "cc" (path) # C++ compiler to be used to compile C++ code (e.g. LLVM and our LLVM shims). # This is only used for host targets. -# See `src/bootstrap/cc_detect.rs` for details. +# See `src/bootstrap/src/utils/cc_detect.rs` for details. #cxx = "c++" (path) # Archiver to be used to assemble static libraries compiled from C/C++ code. From c23bf48e4fedafee67ae1e52edeb8f3f94268a7d Mon Sep 17 00:00:00 2001 From: usamoi Date: Mon, 3 Feb 2025 16:43:24 +0800 Subject: [PATCH 07/20] infer linker flavor by linker name if it's sufficiently specific --- compiler/rustc_target/src/spec/mod.rs | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs index f7e467b0c1155..60e1699b11d68 100644 --- a/compiler/rustc_target/src/spec/mod.rs +++ b/compiler/rustc_target/src/spec/mod.rs @@ -303,15 +303,16 @@ impl LinkerFlavor { } } - fn infer_linker_hints(linker_stem: &str) -> (Option, Option) { + fn infer_linker_hints(linker_stem: &str) -> Result, Option)> { // Remove any version postfix. let stem = linker_stem .rsplit_once('-') .and_then(|(lhs, rhs)| rhs.chars().all(char::is_numeric).then_some(lhs)) .unwrap_or(linker_stem); - // GCC/Clang can have an optional target prefix. - if stem == "emcc" + if stem == "llvm-bitcode-linker" { + Ok(Self::Llbc) + } else if stem == "emcc" // GCC/Clang can have an optional target prefix. || stem == "gcc" || stem.ends_with("-gcc") || stem == "g++" @@ -321,7 +322,7 @@ impl LinkerFlavor { || stem == "clang++" || stem.ends_with("-clang++") { - (Some(Cc::Yes), Some(Lld::No)) + Err((Some(Cc::Yes), Some(Lld::No))) } else if stem == "wasm-ld" || stem.ends_with("-wasm-ld") || stem == "ld.lld" @@ -329,11 +330,11 @@ impl LinkerFlavor { || stem == "rust-lld" || stem == "lld-link" { - (Some(Cc::No), Some(Lld::Yes)) + Err((Some(Cc::No), Some(Lld::Yes))) } else if stem == "ld" || stem.ends_with("-ld") || stem == "link" { - (Some(Cc::No), Some(Lld::No)) + Err((Some(Cc::No), Some(Lld::No))) } else { - (None, None) + Err((None, None)) } } @@ -357,7 +358,10 @@ impl LinkerFlavor { } pub fn with_linker_hints(self, linker_stem: &str) -> LinkerFlavor { - self.with_hints(LinkerFlavor::infer_linker_hints(linker_stem)) + match LinkerFlavor::infer_linker_hints(linker_stem) { + Ok(linker_flavor) => linker_flavor, + Err(hints) => self.with_hints(hints), + } } pub fn check_compatibility(self, cli: LinkerFlavorCli) -> Option { From d5128f92745774a93cd4384a71c7df727bc87377 Mon Sep 17 00:00:00 2001 From: Patryk Wychowaniec Date: Thu, 20 Feb 2025 15:05:06 +0100 Subject: [PATCH 08/20] avr-rjmp-offset: Explain `.target_cpu()` --- tests/run-make/avr-rjmp-offset/rmake.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/run-make/avr-rjmp-offset/rmake.rs b/tests/run-make/avr-rjmp-offset/rmake.rs index 73b6ab3977e97..da314f26ca782 100644 --- a/tests/run-make/avr-rjmp-offset/rmake.rs +++ b/tests/run-make/avr-rjmp-offset/rmake.rs @@ -23,6 +23,10 @@ fn main() { .opt_level("s") .panic("abort") .target("avr-none") + // rust-lld has some troubles understanding the -mmcu flag, so for the + // time being let's tell rustc to emit binary that's compatible with the + // target CPU that lld defaults to, i.e. just `avr` (that's simply the + // minimal common instruction set across all AVRs) .target_cpu("avr") // normally one links with `avr-gcc`, but this is not available in CI, // hence this test diverges from the default behavior to enable linking From 18c210c7869b5786acde4d343a47df99113dba9b Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Thu, 20 Feb 2025 15:06:53 +0000 Subject: [PATCH 09/20] Workaround Cranelift not yet properly supporting vectors smaller than 128bit While it would technically be possible to workaround this in cg_clif, it quickly becomes very messy and would likely cause correctness issues. Working around it in rustc instead is much simper and won't have any negative impact for code running on stable as vectors smaller than 128bit can only be made on nightly using core::simd or #[repr(simd)]. --- compiler/rustc_target/src/callconv/mod.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_target/src/callconv/mod.rs b/compiler/rustc_target/src/callconv/mod.rs index c2a176facdfa1..b90a006ac51ad 100644 --- a/compiler/rustc_target/src/callconv/mod.rs +++ b/compiler/rustc_target/src/callconv/mod.rs @@ -737,7 +737,9 @@ impl<'a, Ty> FnAbi<'a, Ty> { // to 128-bit-sized vectors. "x86" if spec.rustc_abi == Some(RustcAbi::X86Sse2) => arg.layout.size.bits() <= 128, "x86_64" if spec.rustc_abi != Some(RustcAbi::X86Softfloat) => { - arg.layout.size.bits() <= 128 + // FIXME once https://github.com/bytecodealliance/wasmtime/issues/10254 is fixed + // accept vectors up to 128bit rather than vectors of exactly 128bit. + arg.layout.size.bits() == 128 } // So far, we haven't implemented this logic for any other target. _ => false, From c2aed39ea7285d86d4a9c1b02e221bddc1d9a45f Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Thu, 20 Feb 2025 08:15:07 -0800 Subject: [PATCH 10/20] Update docs for default features of wasm targets LLVM 20 enabled the `nontrapping-fptoint` and `bulk-memory` features by default, so this updates the corresponding documentation for the `wasm32-*` targets (which all point to `wasm32-unknown-unknown`). cc #137315 --- src/doc/rustc/src/platform-support/wasm32-unknown-unknown.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/doc/rustc/src/platform-support/wasm32-unknown-unknown.md b/src/doc/rustc/src/platform-support/wasm32-unknown-unknown.md index 73264aba85809..ba95ab7af6d1a 100644 --- a/src/doc/rustc/src/platform-support/wasm32-unknown-unknown.md +++ b/src/doc/rustc/src/platform-support/wasm32-unknown-unknown.md @@ -129,6 +129,8 @@ As of the time of this writing the proposals that are enabled by default (the * `mutable-globals` * `reference-types` * `sign-ext` +* `nontrapping-fptoint` (Rust 1.87.0+, LLVM 20+) +* `bulk-memory` (Rust 1.87.0+, LLVM 20+) If you're compiling WebAssembly code for an engine that does not support a feature in LLVM's default feature set then the feature must be disabled at From 32a1ff1aafba04670f557c7175d6962148a0260f Mon Sep 17 00:00:00 2001 From: Florian Bartels Date: Thu, 20 Feb 2025 16:40:50 +0000 Subject: [PATCH 11/20] Make x86 QNX target name consistent with other Rust targets --- compiler/rustc_target/src/spec/mod.rs | 2 +- .../{i586_pc_nto_qnx700.rs => i686_pc_nto_qnx700.rs} | 0 src/doc/rustc/src/platform-support.md | 2 +- src/doc/rustc/src/platform-support/nto-qnx.md | 2 +- src/tools/tidy/src/target_policy.rs | 1 + tests/assembly/targets/targets-elf.rs | 6 +++--- 6 files changed, 7 insertions(+), 6 deletions(-) rename compiler/rustc_target/src/spec/targets/{i586_pc_nto_qnx700.rs => i686_pc_nto_qnx700.rs} (100%) diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs index f7e467b0c1155..e9733113acc78 100644 --- a/compiler/rustc_target/src/spec/mod.rs +++ b/compiler/rustc_target/src/spec/mod.rs @@ -2001,7 +2001,7 @@ supported_targets! { ("x86_64-pc-nto-qnx710", x86_64_pc_nto_qnx710), ("x86_64-pc-nto-qnx710_iosock", x86_64_pc_nto_qnx710_iosock), ("x86_64-pc-nto-qnx800", x86_64_pc_nto_qnx800), - ("i586-pc-nto-qnx700", i586_pc_nto_qnx700), + ("i686-pc-nto-qnx700", i686_pc_nto_qnx700), ("aarch64-unknown-linux-ohos", aarch64_unknown_linux_ohos), ("armv7-unknown-linux-ohos", armv7_unknown_linux_ohos), diff --git a/compiler/rustc_target/src/spec/targets/i586_pc_nto_qnx700.rs b/compiler/rustc_target/src/spec/targets/i686_pc_nto_qnx700.rs similarity index 100% rename from compiler/rustc_target/src/spec/targets/i586_pc_nto_qnx700.rs rename to compiler/rustc_target/src/spec/targets/i686_pc_nto_qnx700.rs diff --git a/src/doc/rustc/src/platform-support.md b/src/doc/rustc/src/platform-support.md index b5cd3864620d3..86a210a0d9c0d 100644 --- a/src/doc/rustc/src/platform-support.md +++ b/src/doc/rustc/src/platform-support.md @@ -309,10 +309,10 @@ target | std | host | notes [`hexagon-unknown-linux-musl`](platform-support/hexagon-unknown-linux-musl.md) | ✓ | | Hexagon Linux with musl 1.2.3 [`hexagon-unknown-none-elf`](platform-support/hexagon-unknown-none-elf.md)| * | | Bare Hexagon (v60+, HVX) [`i386-apple-ios`](platform-support/apple-ios.md) | ✓ | | 32-bit x86 iOS (Penryn) [^x86_32-floats-return-ABI] -[`i586-pc-nto-qnx700`](platform-support/nto-qnx.md) | * | | 32-bit x86 QNX Neutrino 7.0 RTOS (Pentium 4) [^x86_32-floats-return-ABI] [`i586-unknown-netbsd`](platform-support/netbsd.md) | ✓ | | 32-bit x86 (original Pentium) [^x86_32-floats-x87] [`i586-unknown-redox`](platform-support/redox.md) | ✓ | | 32-bit x86 Redox OS (PentiumPro) [^x86_32-floats-x87] [`i686-apple-darwin`](platform-support/apple-darwin.md) | ✓ | ✓ | 32-bit macOS (10.12+, Sierra+, Penryn) [^x86_32-floats-return-ABI] +[`i686-pc-nto-qnx700`](platform-support/nto-qnx.md) | * | | 32-bit x86 QNX Neutrino 7.0 RTOS (Pentium 4) [^x86_32-floats-return-ABI] `i686-unknown-haiku` | ✓ | ✓ | 32-bit Haiku (Pentium 4) [^x86_32-floats-return-ABI] [`i686-unknown-hurd-gnu`](platform-support/hurd.md) | ✓ | ✓ | 32-bit GNU/Hurd (Pentium 4) [^x86_32-floats-return-ABI] [`i686-unknown-netbsd`](platform-support/netbsd.md) | ✓ | ✓ | NetBSD/i386 (Pentium 4) [^x86_32-floats-return-ABI] diff --git a/src/doc/rustc/src/platform-support/nto-qnx.md b/src/doc/rustc/src/platform-support/nto-qnx.md index 339741f14727d..77e8caaee4cdc 100644 --- a/src/doc/rustc/src/platform-support/nto-qnx.md +++ b/src/doc/rustc/src/platform-support/nto-qnx.md @@ -31,7 +31,7 @@ Currently, the following QNX versions and compilation targets are supported: | `aarch64-unknown-nto-qnx710_iosock` | QNX Neutrino 7.1 with io-sock | AArch64 | ? | ✓ | | `x86_64-pc-nto-qnx710_iosock` | QNX Neutrino 7.1 with io-sock | x86_64 | ? | ✓ | | `aarch64-unknown-nto-qnx700` | QNX Neutrino 7.0 | AArch64 | ? | ✓ | -| `i586-pc-nto-qnx700` | QNX Neutrino 7.0 | x86 | | ✓ | +| `i686-pc-nto-qnx700` | QNX Neutrino 7.0 | x86 | | ✓ | On QNX Neutrino 7.0 and 7.1, `io-pkt` is used as network stack by default. QNX Neutrino 7.1 includes the optional network stack `io-sock`. diff --git a/src/tools/tidy/src/target_policy.rs b/src/tools/tidy/src/target_policy.rs index 776221d306233..b2681934417cb 100644 --- a/src/tools/tidy/src/target_policy.rs +++ b/src/tools/tidy/src/target_policy.rs @@ -21,6 +21,7 @@ const EXCEPTIONS: &[&str] = &[ "xtensa_esp32s2_espidf", "xtensa_esp32s3_none_elf", "xtensa_esp32s3_espidf", + "i586_pc_nto_qnx700", // Renamed to i686-pc-nto-qnx700, see https://github.com/rust-lang/rust/issues/136495 ]; pub fn check(root_path: &Path, bad: &mut bool) { diff --git a/tests/assembly/targets/targets-elf.rs b/tests/assembly/targets/targets-elf.rs index b5c0ee5a10741..3e73d2c6eb72d 100644 --- a/tests/assembly/targets/targets-elf.rs +++ b/tests/assembly/targets/targets-elf.rs @@ -216,9 +216,9 @@ //@ revisions: hexagon_unknown_none_elf //@ [hexagon_unknown_none_elf] compile-flags: --target hexagon-unknown-none-elf //@ [hexagon_unknown_none_elf] needs-llvm-components: hexagon -//@ revisions: i586_pc_nto_qnx700 -//@ [i586_pc_nto_qnx700] compile-flags: --target i586-pc-nto-qnx700 -//@ [i586_pc_nto_qnx700] needs-llvm-components: x86 +//@ revisions: i686_pc_nto_qnx700 +//@ [i686_pc_nto_qnx700] compile-flags: --target i686-pc-nto-qnx700 +//@ [i686_pc_nto_qnx700] needs-llvm-components: x86 //@ revisions: i586_unknown_linux_gnu //@ [i586_unknown_linux_gnu] compile-flags: --target i586-unknown-linux-gnu //@ [i586_unknown_linux_gnu] needs-llvm-components: x86 From 7ba3d7b54e7688f6f1a0fd22fe274ee7b06fea3e Mon Sep 17 00:00:00 2001 From: Zachary S Date: Sat, 25 Jan 2025 20:15:24 -0600 Subject: [PATCH 12/20] Remove `BackendRepr::Uninhabited`, replaced with an `uninhabited: bool` field in `LayoutData`. Also update comments that refered to BackendRepr::Uninhabited. --- compiler/rustc_abi/src/callconv.rs | 2 -- compiler/rustc_abi/src/layout.rs | 23 ++++++------ compiler/rustc_abi/src/lib.rs | 35 +++++++++---------- .../src/value_and_place.rs | 4 +-- .../rustc_codegen_gcc/src/intrinsic/mod.rs | 2 +- compiler/rustc_codegen_gcc/src/type_of.rs | 13 +++---- compiler/rustc_codegen_llvm/src/intrinsic.rs | 2 +- compiler/rustc_codegen_llvm/src/type_of.rs | 13 +++---- compiler/rustc_codegen_ssa/src/mir/operand.rs | 4 +-- .../rustc_const_eval/src/interpret/operand.rs | 2 +- .../src/interpret/validity.rs | 8 ++--- .../src/util/check_validity_requirement.rs | 16 +++++---- compiler/rustc_middle/src/ty/layout.rs | 3 +- compiler/rustc_mir_transform/src/gvn.rs | 5 ++- .../rustc_smir/src/rustc_smir/convert/abi.rs | 1 - .../rustc_target/src/callconv/loongarch.rs | 2 +- compiler/rustc_target/src/callconv/mod.rs | 3 +- compiler/rustc_target/src/callconv/riscv.rs | 2 +- compiler/rustc_target/src/callconv/x86.rs | 4 +-- compiler/rustc_target/src/callconv/x86_64.rs | 2 -- .../rustc_target/src/callconv/x86_win64.rs | 2 +- compiler/rustc_ty_utils/src/abi.rs | 4 +-- compiler/rustc_ty_utils/src/layout.rs | 21 +++++------ .../rustc_ty_utils/src/layout/invariant.rs | 15 ++++---- compiler/stable_mir/src/abi.rs | 6 +--- .../rust-analyzer/crates/hir-ty/src/layout.rs | 12 +++---- 26 files changed, 93 insertions(+), 113 deletions(-) diff --git a/compiler/rustc_abi/src/callconv.rs b/compiler/rustc_abi/src/callconv.rs index 9fb70b80c9efb..4529ab8058e9a 100644 --- a/compiler/rustc_abi/src/callconv.rs +++ b/compiler/rustc_abi/src/callconv.rs @@ -65,8 +65,6 @@ impl<'a, Ty> TyAndLayout<'a, Ty> { Ty: TyAbiInterface<'a, C> + Copy, { match self.backend_repr { - BackendRepr::Uninhabited => Err(Heterogeneous), - // The primitive for this algorithm. BackendRepr::Scalar(scalar) => { let kind = match scalar.primitive() { diff --git a/compiler/rustc_abi/src/layout.rs b/compiler/rustc_abi/src/layout.rs index 45cd0b517f6c7..53243266f992b 100644 --- a/compiler/rustc_abi/src/layout.rs +++ b/compiler/rustc_abi/src/layout.rs @@ -130,6 +130,7 @@ impl LayoutCalculator { }, backend_repr: BackendRepr::ScalarPair(a, b), largest_niche, + uninhabited: false, align, size, max_repr_align: None, @@ -221,8 +222,9 @@ impl LayoutCalculator { LayoutData { variants: Variants::Empty, fields: FieldsShape::Primitive, - backend_repr: BackendRepr::Uninhabited, + backend_repr: BackendRepr::Memory { sized: true }, largest_niche: None, + uninhabited: true, align: dl.i8_align, size: Size::ZERO, max_repr_align: None, @@ -400,6 +402,7 @@ impl LayoutCalculator { fields: FieldsShape::Union(union_field_count), backend_repr: abi, largest_niche: None, + uninhabited: false, align, size: size.align_to(align.abi), max_repr_align, @@ -447,7 +450,6 @@ impl LayoutCalculator { Scalar::Union { .. } => {} }; match &mut st.backend_repr { - BackendRepr::Uninhabited => {} BackendRepr::Scalar(scalar) => hide_niches(scalar), BackendRepr::ScalarPair(a, b) => { hide_niches(a); @@ -639,9 +641,8 @@ impl LayoutCalculator { let same_size = size == variant_layouts[largest_variant_index].size; let same_align = align == variant_layouts[largest_variant_index].align; - let abi = if variant_layouts.iter().all(|v| v.is_uninhabited()) { - BackendRepr::Uninhabited - } else if same_size && same_align && others_zst { + let uninhabited = variant_layouts.iter().all(|v| v.is_uninhabited()); + let abi = if same_size && same_align && others_zst { match variant_layouts[largest_variant_index].backend_repr { // When the total alignment and size match, we can use the // same ABI as the scalar variant with the reserved niche. @@ -683,6 +684,7 @@ impl LayoutCalculator { }, backend_repr: abi, largest_niche, + uninhabited, size, align, max_repr_align, @@ -853,9 +855,8 @@ impl LayoutCalculator { }; let mut abi = BackendRepr::Memory { sized: true }; - if layout_variants.iter().all(|v| v.is_uninhabited()) { - abi = BackendRepr::Uninhabited; - } else if tag.size(dl) == size { + let uninhabited = layout_variants.iter().all(|v| v.is_uninhabited()); + if tag.size(dl) == size { // Make sure we only use scalar layout when the enum is entirely its // own tag (i.e. it has no padding nor any non-ZST variant fields). abi = BackendRepr::Scalar(tag); @@ -995,6 +996,7 @@ impl LayoutCalculator { memory_index: [0].into(), }, largest_niche, + uninhabited, backend_repr: abi, align, size, @@ -1355,9 +1357,7 @@ impl LayoutCalculator { _ => {} } } - if fields.iter().any(|f| f.is_uninhabited()) { - abi = BackendRepr::Uninhabited; - } + let uninhabited = fields.iter().any(|f| f.is_uninhabited()); let unadjusted_abi_align = if repr.transparent() { match layout_of_single_non_zst_field { @@ -1378,6 +1378,7 @@ impl LayoutCalculator { fields: FieldsShape::Arbitrary { offsets, memory_index }, backend_repr: abi, largest_niche, + uninhabited, align, size, max_repr_align, diff --git a/compiler/rustc_abi/src/lib.rs b/compiler/rustc_abi/src/lib.rs index dbb4bed5cdd99..14a8a57920049 100644 --- a/compiler/rustc_abi/src/lib.rs +++ b/compiler/rustc_abi/src/lib.rs @@ -1404,7 +1404,6 @@ impl AddressSpace { #[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)] #[cfg_attr(feature = "nightly", derive(HashStable_Generic))] pub enum BackendRepr { - Uninhabited, Scalar(Scalar), ScalarPair(Scalar, Scalar), Vector { @@ -1423,10 +1422,9 @@ impl BackendRepr { #[inline] pub fn is_unsized(&self) -> bool { match *self { - BackendRepr::Uninhabited - | BackendRepr::Scalar(_) - | BackendRepr::ScalarPair(..) - | BackendRepr::Vector { .. } => false, + BackendRepr::Scalar(_) | BackendRepr::ScalarPair(..) | BackendRepr::Vector { .. } => { + false + } BackendRepr::Memory { sized } => !sized, } } @@ -1445,12 +1443,6 @@ impl BackendRepr { } } - /// Returns `true` if this is an uninhabited type - #[inline] - pub fn is_uninhabited(&self) -> bool { - matches!(*self, BackendRepr::Uninhabited) - } - /// Returns `true` if this is a scalar type #[inline] pub fn is_scalar(&self) -> bool { @@ -1471,7 +1463,7 @@ impl BackendRepr { BackendRepr::Vector { element, count } => { cx.data_layout().vector_align(element.size(cx) * count) } - BackendRepr::Uninhabited | BackendRepr::Memory { .. } => return None, + BackendRepr::Memory { .. } => return None, }) } @@ -1492,7 +1484,7 @@ impl BackendRepr { // to make the size a multiple of align (e.g. for vectors of size 3). (element.size(cx) * count).align_to(self.inherent_align(cx)?.abi) } - BackendRepr::Uninhabited | BackendRepr::Memory { .. } => return None, + BackendRepr::Memory { .. } => return None, }) } @@ -1506,9 +1498,7 @@ impl BackendRepr { BackendRepr::Vector { element, count } => { BackendRepr::Vector { element: element.to_union(), count } } - BackendRepr::Uninhabited | BackendRepr::Memory { .. } => { - BackendRepr::Memory { sized: true } - } + BackendRepr::Memory { .. } => BackendRepr::Memory { sized: true }, } } @@ -1704,6 +1694,11 @@ pub struct LayoutData { /// The leaf scalar with the largest number of invalid values /// (i.e. outside of its `valid_range`), if it exists. pub largest_niche: Option, + /// Is this type known to be uninhabted? + /// + /// This is separate from BackendRepr, because an uninhabited return type may require special + /// consideration based on its size or other attributes. + pub uninhabited: bool, pub align: AbiAndPrefAlign, pub size: Size, @@ -1735,14 +1730,14 @@ impl LayoutData { /// Returns `true` if this is an aggregate type (including a ScalarPair!) pub fn is_aggregate(&self) -> bool { match self.backend_repr { - BackendRepr::Uninhabited | BackendRepr::Scalar(_) | BackendRepr::Vector { .. } => false, + BackendRepr::Scalar(_) | BackendRepr::Vector { .. } => false, BackendRepr::ScalarPair(..) | BackendRepr::Memory { .. } => true, } } /// Returns `true` if this is an uninhabited type pub fn is_uninhabited(&self) -> bool { - self.backend_repr.is_uninhabited() + self.uninhabited } pub fn scalar(cx: &C, scalar: Scalar) -> Self { @@ -1778,6 +1773,7 @@ impl LayoutData { fields: FieldsShape::Primitive, backend_repr: BackendRepr::Scalar(scalar), largest_niche, + uninhabited: false, size, align, max_repr_align: None, @@ -1802,6 +1798,7 @@ where backend_repr, fields, largest_niche, + uninhabited, variants, max_repr_align, unadjusted_abi_align, @@ -1813,6 +1810,7 @@ where .field("abi", backend_repr) .field("fields", fields) .field("largest_niche", largest_niche) + .field("uninhabited", uninhabited) .field("variants", variants) .field("max_repr_align", max_repr_align) .field("unadjusted_abi_align", unadjusted_abi_align) @@ -1877,7 +1875,6 @@ impl LayoutData { BackendRepr::Scalar(_) | BackendRepr::ScalarPair(..) | BackendRepr::Vector { .. } => { false } - BackendRepr::Uninhabited => self.size.bytes() == 0, BackendRepr::Memory { sized } => sized && self.size.bytes() == 0, } } diff --git a/compiler/rustc_codegen_cranelift/src/value_and_place.rs b/compiler/rustc_codegen_cranelift/src/value_and_place.rs index a9b8e1bd39353..1b3f86c8405de 100644 --- a/compiler/rustc_codegen_cranelift/src/value_and_place.rs +++ b/compiler/rustc_codegen_cranelift/src/value_and_place.rs @@ -638,9 +638,7 @@ impl<'tcx> CPlace<'tcx> { } CPlaceInner::Addr(_, Some(_)) => bug!("Can't write value to unsized place {:?}", self), CPlaceInner::Addr(to_ptr, None) => { - if dst_layout.size == Size::ZERO - || dst_layout.backend_repr == BackendRepr::Uninhabited - { + if dst_layout.size == Size::ZERO { return; } diff --git a/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs b/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs index 5322b731d8bb5..433868e238a4c 100644 --- a/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs +++ b/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs @@ -315,7 +315,7 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tc let layout = self.layout_of(tp_ty).layout; let _use_integer_compare = match layout.backend_repr() { Scalar(_) | ScalarPair(_, _) => true, - Uninhabited | Vector { .. } => false, + Vector { .. } => false, Memory { .. } => { // For rusty ABIs, small aggregates are actually passed // as `RegKind::Integer` (see `FnAbi::adjust_for_abi`), diff --git a/compiler/rustc_codegen_gcc/src/type_of.rs b/compiler/rustc_codegen_gcc/src/type_of.rs index 8b8b54753e7fd..bac4fc51300a2 100644 --- a/compiler/rustc_codegen_gcc/src/type_of.rs +++ b/compiler/rustc_codegen_gcc/src/type_of.rs @@ -84,7 +84,7 @@ fn uncached_gcc_type<'gcc, 'tcx>( false, ); } - BackendRepr::Uninhabited | BackendRepr::Memory { .. } => {} + BackendRepr::Memory { .. } => {} } let name = match *layout.ty.kind() { @@ -179,19 +179,16 @@ impl<'tcx> LayoutGccExt<'tcx> for TyAndLayout<'tcx> { fn is_gcc_immediate(&self) -> bool { match self.backend_repr { BackendRepr::Scalar(_) | BackendRepr::Vector { .. } => true, - BackendRepr::ScalarPair(..) | BackendRepr::Uninhabited | BackendRepr::Memory { .. } => { - false - } + BackendRepr::ScalarPair(..) | BackendRepr::Memory { .. } => false, } } fn is_gcc_scalar_pair(&self) -> bool { match self.backend_repr { BackendRepr::ScalarPair(..) => true, - BackendRepr::Uninhabited - | BackendRepr::Scalar(_) - | BackendRepr::Vector { .. } - | BackendRepr::Memory { .. } => false, + BackendRepr::Scalar(_) | BackendRepr::Vector { .. } | BackendRepr::Memory { .. } => { + false + } } } diff --git a/compiler/rustc_codegen_llvm/src/intrinsic.rs b/compiler/rustc_codegen_llvm/src/intrinsic.rs index 7e1a9d361e6fb..f68365f6c69bc 100644 --- a/compiler/rustc_codegen_llvm/src/intrinsic.rs +++ b/compiler/rustc_codegen_llvm/src/intrinsic.rs @@ -476,7 +476,7 @@ impl<'ll, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> { let layout = self.layout_of(tp_ty).layout; let use_integer_compare = match layout.backend_repr() { Scalar(_) | ScalarPair(_, _) => true, - Uninhabited | Vector { .. } => false, + Vector { .. } => false, Memory { .. } => { // For rusty ABIs, small aggregates are actually passed // as `RegKind::Integer` (see `FnAbi::adjust_for_abi`), diff --git a/compiler/rustc_codegen_llvm/src/type_of.rs b/compiler/rustc_codegen_llvm/src/type_of.rs index b0b6da869da68..ba01fbff38539 100644 --- a/compiler/rustc_codegen_llvm/src/type_of.rs +++ b/compiler/rustc_codegen_llvm/src/type_of.rs @@ -23,7 +23,7 @@ fn uncached_llvm_type<'a, 'tcx>( let element = layout.scalar_llvm_type_at(cx, element); return cx.type_vector(element, count); } - BackendRepr::Uninhabited | BackendRepr::Memory { .. } | BackendRepr::ScalarPair(..) => {} + BackendRepr::Memory { .. } | BackendRepr::ScalarPair(..) => {} } let name = match layout.ty.kind() { @@ -172,19 +172,16 @@ impl<'tcx> LayoutLlvmExt<'tcx> for TyAndLayout<'tcx> { fn is_llvm_immediate(&self) -> bool { match self.backend_repr { BackendRepr::Scalar(_) | BackendRepr::Vector { .. } => true, - BackendRepr::ScalarPair(..) | BackendRepr::Uninhabited | BackendRepr::Memory { .. } => { - false - } + BackendRepr::ScalarPair(..) | BackendRepr::Memory { .. } => false, } } fn is_llvm_scalar_pair(&self) -> bool { match self.backend_repr { BackendRepr::ScalarPair(..) => true, - BackendRepr::Uninhabited - | BackendRepr::Scalar(_) - | BackendRepr::Vector { .. } - | BackendRepr::Memory { .. } => false, + BackendRepr::Scalar(_) | BackendRepr::Vector { .. } | BackendRepr::Memory { .. } => { + false + } } } diff --git a/compiler/rustc_codegen_ssa/src/mir/operand.rs b/compiler/rustc_codegen_ssa/src/mir/operand.rs index 958a52a2cb1dc..faf1300e4731e 100644 --- a/compiler/rustc_codegen_ssa/src/mir/operand.rs +++ b/compiler/rustc_codegen_ssa/src/mir/operand.rs @@ -422,9 +422,7 @@ impl<'a, 'tcx, V: CodegenObject> OperandRef<'tcx, V> { See ", ); } - BackendRepr::Uninhabited - | BackendRepr::ScalarPair(_, _) - | BackendRepr::Memory { sized: false } => bug!(), + BackendRepr::ScalarPair(_, _) | BackendRepr::Memory { sized: false } => bug!(), }) }; diff --git a/compiler/rustc_const_eval/src/interpret/operand.rs b/compiler/rustc_const_eval/src/interpret/operand.rs index 5d905cff1f216..36da9037e43d9 100644 --- a/compiler/rustc_const_eval/src/interpret/operand.rs +++ b/compiler/rustc_const_eval/src/interpret/operand.rs @@ -385,7 +385,7 @@ impl<'tcx, Prov: Provenance> ImmTy<'tcx, Prov> { (Immediate::Uninit, _) => Immediate::Uninit, // If the field is uninhabited, we can forget the data (can happen in ConstProp). // `enum S { A(!), B, C }` is an example of an enum with Scalar layout that - // has an `Uninhabited` variant, which means this case is possible. + // has an uninhabited variant, which means this case is possible. _ if layout.is_uninhabited() => Immediate::Uninit, // the field contains no information, can be left uninit // (Scalar/ScalarPair can contain even aligned ZST, not just 1-ZST) diff --git a/compiler/rustc_const_eval/src/interpret/validity.rs b/compiler/rustc_const_eval/src/interpret/validity.rs index 0ac34f4633b57..3667cc84d708e 100644 --- a/compiler/rustc_const_eval/src/interpret/validity.rs +++ b/compiler/rustc_const_eval/src/interpret/validity.rs @@ -1274,11 +1274,11 @@ impl<'rt, 'tcx, M: Machine<'tcx>> ValueVisitor<'tcx, M> for ValidityVisitor<'rt, // FIXME: We could avoid some redundant checks here. For newtypes wrapping // scalars, we do the same check on every "level" (e.g., first we check // MyNewtype and then the scalar in there). + if val.layout.is_uninhabited() { + let ty = val.layout.ty; + throw_validation_failure!(self.path, UninhabitedVal { ty }); + } match val.layout.backend_repr { - BackendRepr::Uninhabited => { - let ty = val.layout.ty; - throw_validation_failure!(self.path, UninhabitedVal { ty }); - } BackendRepr::Scalar(scalar_layout) => { if !scalar_layout.is_uninit_valid() { // There is something to check here. diff --git a/compiler/rustc_const_eval/src/util/check_validity_requirement.rs b/compiler/rustc_const_eval/src/util/check_validity_requirement.rs index 79baf91c3ce64..6426bca2332d4 100644 --- a/compiler/rustc_const_eval/src/util/check_validity_requirement.rs +++ b/compiler/rustc_const_eval/src/util/check_validity_requirement.rs @@ -111,13 +111,15 @@ fn check_validity_requirement_lax<'tcx>( }; // Check the ABI. - let valid = match this.backend_repr { - BackendRepr::Uninhabited => false, // definitely UB - BackendRepr::Scalar(s) => scalar_allows_raw_init(s), - BackendRepr::ScalarPair(s1, s2) => scalar_allows_raw_init(s1) && scalar_allows_raw_init(s2), - BackendRepr::Vector { element: s, count } => count == 0 || scalar_allows_raw_init(s), - BackendRepr::Memory { .. } => true, // Fields are checked below. - }; + let valid = !this.is_uninhabited() // definitely UB if uninhabited + && match this.backend_repr { + BackendRepr::Scalar(s) => scalar_allows_raw_init(s), + BackendRepr::ScalarPair(s1, s2) => { + scalar_allows_raw_init(s1) && scalar_allows_raw_init(s2) + } + BackendRepr::Vector { element: s, count } => count == 0 || scalar_allows_raw_init(s), + BackendRepr::Memory { .. } => true, // Fields are checked below. + }; if !valid { // This is definitely not okay. return Ok(false); diff --git a/compiler/rustc_middle/src/ty/layout.rs b/compiler/rustc_middle/src/ty/layout.rs index 19fa832357499..eb14ed20fbace 100644 --- a/compiler/rustc_middle/src/ty/layout.rs +++ b/compiler/rustc_middle/src/ty/layout.rs @@ -794,8 +794,9 @@ where Some(fields) => FieldsShape::Union(fields), None => FieldsShape::Arbitrary { offsets: IndexVec::new(), memory_index: IndexVec::new() }, }, - backend_repr: BackendRepr::Uninhabited, + backend_repr: BackendRepr::Memory { sized: true }, largest_niche: None, + uninhabited: true, align: tcx.data_layout.i8_align, size: Size::ZERO, max_repr_align: None, diff --git a/compiler/rustc_mir_transform/src/gvn.rs b/compiler/rustc_mir_transform/src/gvn.rs index 77a3854ebdef3..2f8a305019999 100644 --- a/compiler/rustc_mir_transform/src/gvn.rs +++ b/compiler/rustc_mir_transform/src/gvn.rs @@ -1558,8 +1558,11 @@ impl<'body, 'tcx> VnState<'body, 'tcx> { return true; }; + if layout.uninhabited { + return true; + } + match layout.backend_repr { - BackendRepr::Uninhabited => true, BackendRepr::Scalar(a) => !a.is_always_valid(&self.ecx), BackendRepr::ScalarPair(a, b) => { !a.is_always_valid(&self.ecx) || !b.is_always_valid(&self.ecx) diff --git a/compiler/rustc_smir/src/rustc_smir/convert/abi.rs b/compiler/rustc_smir/src/rustc_smir/convert/abi.rs index fb2e838cdc998..a627e0e69b62f 100644 --- a/compiler/rustc_smir/src/rustc_smir/convert/abi.rs +++ b/compiler/rustc_smir/src/rustc_smir/convert/abi.rs @@ -202,7 +202,6 @@ impl<'tcx> Stable<'tcx> for rustc_abi::BackendRepr { fn stable(&self, tables: &mut Tables<'_>) -> Self::T { match *self { - rustc_abi::BackendRepr::Uninhabited => ValueAbi::Uninhabited, rustc_abi::BackendRepr::Scalar(scalar) => ValueAbi::Scalar(scalar.stable(tables)), rustc_abi::BackendRepr::ScalarPair(first, second) => { ValueAbi::ScalarPair(first.stable(tables), second.stable(tables)) diff --git a/compiler/rustc_target/src/callconv/loongarch.rs b/compiler/rustc_target/src/callconv/loongarch.rs index 47566bde6b4a4..3fa67c624a7be 100644 --- a/compiler/rustc_target/src/callconv/loongarch.rs +++ b/compiler/rustc_target/src/callconv/loongarch.rs @@ -80,7 +80,7 @@ where } } }, - BackendRepr::Vector { .. } | BackendRepr::Uninhabited => return Err(CannotUseFpConv), + BackendRepr::Vector { .. } => return Err(CannotUseFpConv), BackendRepr::ScalarPair(..) | BackendRepr::Memory { .. } => match arg_layout.fields { FieldsShape::Primitive => { unreachable!("aggregates can't have `FieldsShape::Primitive`") diff --git a/compiler/rustc_target/src/callconv/mod.rs b/compiler/rustc_target/src/callconv/mod.rs index c2a176facdfa1..e5f986269ddc0 100644 --- a/compiler/rustc_target/src/callconv/mod.rs +++ b/compiler/rustc_target/src/callconv/mod.rs @@ -38,7 +38,7 @@ mod xtensa; pub enum PassMode { /// Ignore the argument. /// - /// The argument is either uninhabited or a ZST. + /// The argument is a ZST. Ignore, /// Pass the argument directly. /// @@ -350,7 +350,6 @@ impl<'a, Ty> ArgAbi<'a, Ty> { scalar_attrs: impl Fn(&TyAndLayout<'a, Ty>, Scalar, Size) -> ArgAttributes, ) -> Self { let mode = match layout.backend_repr { - BackendRepr::Uninhabited => PassMode::Ignore, BackendRepr::Scalar(scalar) => { PassMode::Direct(scalar_attrs(&layout, scalar, Size::ZERO)) } diff --git a/compiler/rustc_target/src/callconv/riscv.rs b/compiler/rustc_target/src/callconv/riscv.rs index 265ae20f9919d..785175229b031 100644 --- a/compiler/rustc_target/src/callconv/riscv.rs +++ b/compiler/rustc_target/src/callconv/riscv.rs @@ -86,7 +86,7 @@ where } } }, - BackendRepr::Vector { .. } | BackendRepr::Uninhabited => return Err(CannotUseFpConv), + BackendRepr::Vector { .. } => return Err(CannotUseFpConv), BackendRepr::ScalarPair(..) | BackendRepr::Memory { .. } => match arg_layout.fields { FieldsShape::Primitive => { unreachable!("aggregates can't have `FieldsShape::Primitive`") diff --git a/compiler/rustc_target/src/callconv/x86.rs b/compiler/rustc_target/src/callconv/x86.rs index 5f4f4cd57f654..7e5aab0201b6d 100644 --- a/compiler/rustc_target/src/callconv/x86.rs +++ b/compiler/rustc_target/src/callconv/x86.rs @@ -108,9 +108,7 @@ where Ty: TyAbiInterface<'a, C> + Copy, { match layout.backend_repr { - BackendRepr::Uninhabited - | BackendRepr::Scalar(_) - | BackendRepr::ScalarPair(..) => false, + BackendRepr::Scalar(_) | BackendRepr::ScalarPair(..) => false, BackendRepr::Vector { .. } => true, BackendRepr::Memory { .. } => { for i in 0..layout.fields.count() { diff --git a/compiler/rustc_target/src/callconv/x86_64.rs b/compiler/rustc_target/src/callconv/x86_64.rs index b15d82c26dac2..ab306e202396b 100644 --- a/compiler/rustc_target/src/callconv/x86_64.rs +++ b/compiler/rustc_target/src/callconv/x86_64.rs @@ -51,8 +51,6 @@ where } let mut c = match layout.backend_repr { - BackendRepr::Uninhabited => return Ok(()), - BackendRepr::Scalar(scalar) => match scalar.primitive() { Primitive::Int(..) | Primitive::Pointer(_) => Class::Int, Primitive::Float(_) => Class::Sse, diff --git a/compiler/rustc_target/src/callconv/x86_win64.rs b/compiler/rustc_target/src/callconv/x86_win64.rs index 2ef5127de04ae..4d99a9f9ba064 100644 --- a/compiler/rustc_target/src/callconv/x86_win64.rs +++ b/compiler/rustc_target/src/callconv/x86_win64.rs @@ -8,7 +8,7 @@ use crate::spec::{HasTargetSpec, RustcAbi}; pub(crate) fn compute_abi_info(cx: &impl HasTargetSpec, fn_abi: &mut FnAbi<'_, Ty>) { let fixup = |a: &mut ArgAbi<'_, Ty>, is_ret: bool| { match a.layout.backend_repr { - BackendRepr::Uninhabited | BackendRepr::Memory { sized: false } => {} + BackendRepr::Memory { sized: false } => {} BackendRepr::ScalarPair(..) | BackendRepr::Memory { sized: true } => { match a.layout.size.bits() { 8 => a.cast_to(Reg::i8()), diff --git a/compiler/rustc_ty_utils/src/abi.rs b/compiler/rustc_ty_utils/src/abi.rs index c5d2d0afbfad2..2d20ef3d690dd 100644 --- a/compiler/rustc_ty_utils/src/abi.rs +++ b/compiler/rustc_ty_utils/src/abi.rs @@ -472,9 +472,7 @@ fn fn_abi_sanity_check<'tcx>( // `layout.backend_repr` and ignore everything else. We should just reject //`Aggregate` entirely here, but some targets need to be fixed first. match arg.layout.backend_repr { - BackendRepr::Uninhabited - | BackendRepr::Scalar(_) - | BackendRepr::Vector { .. } => {} + BackendRepr::Scalar(_) | BackendRepr::Vector { .. } => {} BackendRepr::ScalarPair(..) => { panic!("`PassMode::Direct` used for ScalarPair type {}", arg.layout.ty) } diff --git a/compiler/rustc_ty_utils/src/layout.rs b/compiler/rustc_ty_utils/src/layout.rs index 556512e0236e5..b6a14d147cad4 100644 --- a/compiler/rustc_ty_utils/src/layout.rs +++ b/compiler/rustc_ty_utils/src/layout.rs @@ -348,19 +348,17 @@ fn layout_of_uncached<'tcx>( .checked_mul(count, dl) .ok_or_else(|| error(cx, LayoutError::SizeOverflow(ty)))?; - let abi = if count != 0 && ty.is_privately_uninhabited(tcx, cx.typing_env) { - BackendRepr::Uninhabited - } else { - BackendRepr::Memory { sized: true } - }; + let abi = BackendRepr::Memory { sized: true }; let largest_niche = if count != 0 { element.largest_niche } else { None }; + let uninhabited = if count != 0 { element.uninhabited } else { false }; tcx.mk_layout(LayoutData { variants: Variants::Single { index: FIRST_VARIANT }, fields: FieldsShape::Array { stride: element.size, count }, backend_repr: abi, largest_niche, + uninhabited, align: element.align, size, max_repr_align: None, @@ -375,6 +373,7 @@ fn layout_of_uncached<'tcx>( fields: FieldsShape::Array { stride: element.size, count: 0 }, backend_repr: BackendRepr::Memory { sized: false }, largest_niche: None, + uninhabited: false, align: element.align, size: Size::ZERO, max_repr_align: None, @@ -390,6 +389,7 @@ fn layout_of_uncached<'tcx>( fields: FieldsShape::Array { stride: Size::from_bytes(1), count: 0 }, backend_repr: BackendRepr::Memory { sized: false }, largest_niche: None, + uninhabited: false, align: dl.i8_align, size: Size::ZERO, max_repr_align: None, @@ -555,6 +555,7 @@ fn layout_of_uncached<'tcx>( fields, backend_repr: abi, largest_niche: e_ly.largest_niche, + uninhabited: false, size, align, max_repr_align: None, @@ -1014,13 +1015,8 @@ fn coroutine_layout<'tcx>( size = size.align_to(align.abi); - let abi = if prefix.backend_repr.is_uninhabited() - || variants.iter().all(|v| v.backend_repr.is_uninhabited()) - { - BackendRepr::Uninhabited - } else { - BackendRepr::Memory { sized: true } - }; + let uninhabited = prefix.uninhabited || variants.iter().all(|v| v.is_uninhabited()); + let abi = BackendRepr::Memory { sized: true }; // this is similar to how ReprOptions populates its field_shuffle_seed let def_hash = tcx.def_path_hash(def_id).0.to_smaller_hash(); @@ -1041,6 +1037,7 @@ fn coroutine_layout<'tcx>( // See , . // FIXME: Remove when is implemented and aliased coroutine fields are wrapped in `UnsafePinned`. largest_niche: None, + uninhabited, size, align, max_repr_align: None, diff --git a/compiler/rustc_ty_utils/src/layout/invariant.rs b/compiler/rustc_ty_utils/src/layout/invariant.rs index 8d5403ed32468..5ea6716c5ca14 100644 --- a/compiler/rustc_ty_utils/src/layout/invariant.rs +++ b/compiler/rustc_ty_utils/src/layout/invariant.rs @@ -10,7 +10,11 @@ pub(super) fn layout_sanity_check<'tcx>(cx: &LayoutCx<'tcx>, layout: &TyAndLayou // Type-level uninhabitedness should always imply ABI uninhabitedness. if layout.ty.is_privately_uninhabited(tcx, cx.typing_env) { - assert!(layout.is_uninhabited()); + assert!( + layout.is_uninhabited(), + "{:?} is type-level uninhabited but not ABI-uninhabited?", + layout.ty + ); } if layout.size.bytes() % layout.align.abi.bytes() != 0 { @@ -71,7 +75,7 @@ pub(super) fn layout_sanity_check<'tcx>(cx: &LayoutCx<'tcx>, layout: &TyAndLayou let Some((align, size)) = align.zip(size) else { assert_matches!( layout.layout.backend_repr(), - BackendRepr::Uninhabited | BackendRepr::Memory { .. }, + BackendRepr::Memory { .. }, "ABI unexpectedly missing alignment and/or size in {layout:#?}" ); return; @@ -235,7 +239,7 @@ pub(super) fn layout_sanity_check<'tcx>(cx: &LayoutCx<'tcx>, layout: &TyAndLayou assert!(align >= element.align(cx).abi); // just sanity-checking `vector_align`. // FIXME: Do some kind of check of the inner type, like for Scalar and ScalarPair. } - BackendRepr::Uninhabited | BackendRepr::Memory { .. } => {} // Nothing to check. + BackendRepr::Memory { .. } => {} // Nothing to check. } } @@ -291,8 +295,8 @@ pub(super) fn layout_sanity_check<'tcx>(cx: &LayoutCx<'tcx>, layout: &TyAndLayou || variant.is_uninhabited() { // These are never actually accessed anyway, so we can skip the coherence check - // for them. They also fail that check, since they have - // `Aggregate`/`Uninhabited` ABI even when the main type is + // for them. They also fail that check, since they may have + // a different ABI even when the main type is // `Scalar`/`ScalarPair`. (Note that sometimes, variants with fields have size // 0, and sometimes, variants without fields have non-0 size.) continue; @@ -306,7 +310,6 @@ pub(super) fn layout_sanity_check<'tcx>(cx: &LayoutCx<'tcx>, layout: &TyAndLayou (BackendRepr::ScalarPair(a1, b1), BackendRepr::ScalarPair(a2, b2)) => { scalar_coherent(a1, a2) && scalar_coherent(b1, b2) } - (BackendRepr::Uninhabited, _) => true, (BackendRepr::Memory { .. }, _) => true, _ => false, }; diff --git a/compiler/stable_mir/src/abi.rs b/compiler/stable_mir/src/abi.rs index 861b6692b5367..091f3e1a95e95 100644 --- a/compiler/stable_mir/src/abi.rs +++ b/compiler/stable_mir/src/abi.rs @@ -227,7 +227,6 @@ pub enum TagEncoding { /// in terms of categories of C types there are ABI rules for. #[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize)] pub enum ValueAbi { - Uninhabited, Scalar(Scalar), ScalarPair(Scalar, Scalar), Vector { @@ -244,10 +243,7 @@ impl ValueAbi { /// Returns `true` if the layout corresponds to an unsized type. pub fn is_unsized(&self) -> bool { match *self { - ValueAbi::Uninhabited - | ValueAbi::Scalar(_) - | ValueAbi::ScalarPair(..) - | ValueAbi::Vector { .. } => false, + ValueAbi::Scalar(_) | ValueAbi::ScalarPair(..) | ValueAbi::Vector { .. } => false, ValueAbi::Aggregate { sized } => !sized, } } diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/layout.rs b/src/tools/rust-analyzer/crates/hir-ty/src/layout.rs index b6f7c44c2aeee..f5a7b6581230f 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/layout.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/layout.rs @@ -194,6 +194,7 @@ fn layout_of_simd_ty( fields, backend_repr: BackendRepr::Vector { element: e_abi, count: e_len }, largest_niche: e_ly.largest_niche, + uninhabited: false, size, align, max_repr_align: None, @@ -297,20 +298,17 @@ pub fn layout_of_ty_query( .checked_mul(count, dl) .ok_or(LayoutError::BadCalc(LayoutCalculatorError::SizeOverflow))?; - let backend_repr = - if count != 0 && matches!(element.backend_repr, BackendRepr::Uninhabited) { - BackendRepr::Uninhabited - } else { - BackendRepr::Memory { sized: true } - }; + let backend_repr = BackendRepr::Memory { sized: true }; let largest_niche = if count != 0 { element.largest_niche } else { None }; + let uninhabited = if count != 0 { element.uninhabited } else { false }; Layout { variants: Variants::Single { index: struct_variant_idx() }, fields: FieldsShape::Array { stride: element.size, count }, backend_repr, largest_niche, + uninhabited, align: element.align, size, max_repr_align: None, @@ -325,6 +323,7 @@ pub fn layout_of_ty_query( fields: FieldsShape::Array { stride: element.size, count: 0 }, backend_repr: BackendRepr::Memory { sized: false }, largest_niche: None, + uninhabited: false, align: element.align, size: Size::ZERO, max_repr_align: None, @@ -337,6 +336,7 @@ pub fn layout_of_ty_query( fields: FieldsShape::Array { stride: Size::from_bytes(1), count: 0 }, backend_repr: BackendRepr::Memory { sized: false }, largest_niche: None, + uninhabited: false, align: dl.i8_align, size: Size::ZERO, max_repr_align: None, From c33fb5ae854e8ac26d75e72b7cb31519730f51d6 Mon Sep 17 00:00:00 2001 From: Zachary S Date: Sat, 25 Jan 2025 21:28:54 -0600 Subject: [PATCH 13/20] Update ui tests with `LayoutData { uninhabited: ... }` etc --- tests/ui/abi/c-zst.aarch64-darwin.stderr | 2 + tests/ui/abi/c-zst.powerpc-linux.stderr | 2 + tests/ui/abi/c-zst.s390x-linux.stderr | 2 + tests/ui/abi/c-zst.sparc64-linux.stderr | 2 + tests/ui/abi/c-zst.x86_64-linux.stderr | 2 + .../ui/abi/c-zst.x86_64-pc-windows-gnu.stderr | 2 + tests/ui/abi/debug.stderr | 24 +++++++++ tests/ui/abi/sysv64-zst.stderr | 2 + tests/ui/layout/debug.stderr | 22 +++++++- tests/ui/layout/hexagon-enum.stderr | 10 ++++ ...-scalarpair-payload-might-be-uninit.stderr | 17 +++++++ .../issue-96185-overaligned-enum.stderr | 6 +++ tests/ui/layout/thumb-enum.stderr | 10 ++++ .../layout/zero-sized-array-enum-niche.stderr | 13 +++++ ...-variants.aarch64-unknown-linux-gnu.stderr | 50 +++++++++++++++++-- ...-c-dead-variants.armebv7r-none-eabi.stderr | 50 +++++++++++++++++-- ...-dead-variants.i686-pc-windows-msvc.stderr | 50 +++++++++++++++++-- ...d-variants.x86_64-unknown-linux-gnu.stderr | 50 +++++++++++++++++-- tests/ui/repr/repr-c-int-dead-variants.stderr | 50 +++++++++++++++++-- .../type/pattern_types/range_patterns.stderr | 9 ++++ 20 files changed, 349 insertions(+), 26 deletions(-) diff --git a/tests/ui/abi/c-zst.aarch64-darwin.stderr b/tests/ui/abi/c-zst.aarch64-darwin.stderr index c8f7d0a517c4c..57cc48aa9cf47 100644 --- a/tests/ui/abi/c-zst.aarch64-darwin.stderr +++ b/tests/ui/abi/c-zst.aarch64-darwin.stderr @@ -17,6 +17,7 @@ error: fn_abi_of(pass_zst) = FnAbi { memory_index: [], }, largest_niche: None, + uninhabited: false, variants: Single { index: 0, }, @@ -45,6 +46,7 @@ error: fn_abi_of(pass_zst) = FnAbi { memory_index: [], }, largest_niche: None, + uninhabited: false, variants: Single { index: 0, }, diff --git a/tests/ui/abi/c-zst.powerpc-linux.stderr b/tests/ui/abi/c-zst.powerpc-linux.stderr index 1015f7d889880..6738017673003 100644 --- a/tests/ui/abi/c-zst.powerpc-linux.stderr +++ b/tests/ui/abi/c-zst.powerpc-linux.stderr @@ -17,6 +17,7 @@ error: fn_abi_of(pass_zst) = FnAbi { memory_index: [], }, largest_niche: None, + uninhabited: false, variants: Single { index: 0, }, @@ -56,6 +57,7 @@ error: fn_abi_of(pass_zst) = FnAbi { memory_index: [], }, largest_niche: None, + uninhabited: false, variants: Single { index: 0, }, diff --git a/tests/ui/abi/c-zst.s390x-linux.stderr b/tests/ui/abi/c-zst.s390x-linux.stderr index 1015f7d889880..6738017673003 100644 --- a/tests/ui/abi/c-zst.s390x-linux.stderr +++ b/tests/ui/abi/c-zst.s390x-linux.stderr @@ -17,6 +17,7 @@ error: fn_abi_of(pass_zst) = FnAbi { memory_index: [], }, largest_niche: None, + uninhabited: false, variants: Single { index: 0, }, @@ -56,6 +57,7 @@ error: fn_abi_of(pass_zst) = FnAbi { memory_index: [], }, largest_niche: None, + uninhabited: false, variants: Single { index: 0, }, diff --git a/tests/ui/abi/c-zst.sparc64-linux.stderr b/tests/ui/abi/c-zst.sparc64-linux.stderr index 1015f7d889880..6738017673003 100644 --- a/tests/ui/abi/c-zst.sparc64-linux.stderr +++ b/tests/ui/abi/c-zst.sparc64-linux.stderr @@ -17,6 +17,7 @@ error: fn_abi_of(pass_zst) = FnAbi { memory_index: [], }, largest_niche: None, + uninhabited: false, variants: Single { index: 0, }, @@ -56,6 +57,7 @@ error: fn_abi_of(pass_zst) = FnAbi { memory_index: [], }, largest_niche: None, + uninhabited: false, variants: Single { index: 0, }, diff --git a/tests/ui/abi/c-zst.x86_64-linux.stderr b/tests/ui/abi/c-zst.x86_64-linux.stderr index c8f7d0a517c4c..57cc48aa9cf47 100644 --- a/tests/ui/abi/c-zst.x86_64-linux.stderr +++ b/tests/ui/abi/c-zst.x86_64-linux.stderr @@ -17,6 +17,7 @@ error: fn_abi_of(pass_zst) = FnAbi { memory_index: [], }, largest_niche: None, + uninhabited: false, variants: Single { index: 0, }, @@ -45,6 +46,7 @@ error: fn_abi_of(pass_zst) = FnAbi { memory_index: [], }, largest_niche: None, + uninhabited: false, variants: Single { index: 0, }, diff --git a/tests/ui/abi/c-zst.x86_64-pc-windows-gnu.stderr b/tests/ui/abi/c-zst.x86_64-pc-windows-gnu.stderr index 1015f7d889880..6738017673003 100644 --- a/tests/ui/abi/c-zst.x86_64-pc-windows-gnu.stderr +++ b/tests/ui/abi/c-zst.x86_64-pc-windows-gnu.stderr @@ -17,6 +17,7 @@ error: fn_abi_of(pass_zst) = FnAbi { memory_index: [], }, largest_niche: None, + uninhabited: false, variants: Single { index: 0, }, @@ -56,6 +57,7 @@ error: fn_abi_of(pass_zst) = FnAbi { memory_index: [], }, largest_niche: None, + uninhabited: false, variants: Single { index: 0, }, diff --git a/tests/ui/abi/debug.stderr b/tests/ui/abi/debug.stderr index e550e5bfcf3c3..5f73ff7d6bd58 100644 --- a/tests/ui/abi/debug.stderr +++ b/tests/ui/abi/debug.stderr @@ -20,6 +20,7 @@ error: fn_abi_of(test) = FnAbi { ), fields: Primitive, largest_niche: None, + uninhabited: false, variants: Single { index: 0, }, @@ -67,6 +68,7 @@ error: fn_abi_of(test) = FnAbi { valid_range: 0..=1, }, ), + uninhabited: false, variants: Single { index: 0, }, @@ -125,6 +127,7 @@ error: fn_abi_of(TestFnPtr) = FnAbi { valid_range: 0..=1, }, ), + uninhabited: false, variants: Single { index: 0, }, @@ -163,6 +166,7 @@ error: fn_abi_of(TestFnPtr) = FnAbi { ), fields: Primitive, largest_niche: None, + uninhabited: false, variants: Single { index: 0, }, @@ -213,6 +217,7 @@ error: fn_abi_of(test_generic) = FnAbi { ), fields: Primitive, largest_niche: None, + uninhabited: false, variants: Single { index: 0, }, @@ -248,6 +253,7 @@ error: fn_abi_of(test_generic) = FnAbi { memory_index: [], }, largest_niche: None, + uninhabited: false, variants: Single { index: 0, }, @@ -297,6 +303,7 @@ error: ABIs are not compatible ), fields: Primitive, largest_niche: None, + uninhabited: false, variants: Single { index: 0, }, @@ -332,6 +339,7 @@ error: ABIs are not compatible memory_index: [], }, largest_niche: None, + uninhabited: false, variants: Single { index: 0, }, @@ -369,6 +377,7 @@ error: ABIs are not compatible ), fields: Primitive, largest_niche: None, + uninhabited: false, variants: Single { index: 0, }, @@ -404,6 +413,7 @@ error: ABIs are not compatible memory_index: [], }, largest_niche: None, + uninhabited: false, variants: Single { index: 0, }, @@ -444,6 +454,7 @@ error: ABIs are not compatible count: 32, }, largest_niche: None, + uninhabited: false, variants: Single { index: 0, }, @@ -483,6 +494,7 @@ error: ABIs are not compatible memory_index: [], }, largest_niche: None, + uninhabited: false, variants: Single { index: 0, }, @@ -517,6 +529,7 @@ error: ABIs are not compatible count: 32, }, largest_niche: None, + uninhabited: false, variants: Single { index: 0, }, @@ -556,6 +569,7 @@ error: ABIs are not compatible memory_index: [], }, largest_niche: None, + uninhabited: false, variants: Single { index: 0, }, @@ -598,6 +612,7 @@ error: ABIs are not compatible ), fields: Primitive, largest_niche: None, + uninhabited: false, variants: Single { index: 0, }, @@ -633,6 +648,7 @@ error: ABIs are not compatible memory_index: [], }, largest_niche: None, + uninhabited: false, variants: Single { index: 0, }, @@ -670,6 +686,7 @@ error: ABIs are not compatible ), fields: Primitive, largest_niche: None, + uninhabited: false, variants: Single { index: 0, }, @@ -705,6 +722,7 @@ error: ABIs are not compatible memory_index: [], }, largest_niche: None, + uninhabited: false, variants: Single { index: 0, }, @@ -748,6 +766,7 @@ error: ABIs are not compatible ), fields: Primitive, largest_niche: None, + uninhabited: false, variants: Single { index: 0, }, @@ -783,6 +802,7 @@ error: ABIs are not compatible memory_index: [], }, largest_niche: None, + uninhabited: false, variants: Single { index: 0, }, @@ -820,6 +840,7 @@ error: ABIs are not compatible ), fields: Primitive, largest_niche: None, + uninhabited: false, variants: Single { index: 0, }, @@ -855,6 +876,7 @@ error: ABIs are not compatible memory_index: [], }, largest_niche: None, + uninhabited: false, variants: Single { index: 0, }, @@ -923,6 +945,7 @@ error: fn_abi_of(assoc_test) = FnAbi { valid_range: $NON_NULL, }, ), + uninhabited: false, variants: Single { index: 0, }, @@ -960,6 +983,7 @@ error: fn_abi_of(assoc_test) = FnAbi { memory_index: [], }, largest_niche: None, + uninhabited: false, variants: Single { index: 0, }, diff --git a/tests/ui/abi/sysv64-zst.stderr b/tests/ui/abi/sysv64-zst.stderr index 781e9b2f4c9d5..ec85030c10686 100644 --- a/tests/ui/abi/sysv64-zst.stderr +++ b/tests/ui/abi/sysv64-zst.stderr @@ -17,6 +17,7 @@ error: fn_abi_of(pass_zst) = FnAbi { memory_index: [], }, largest_niche: None, + uninhabited: false, variants: Single { index: 0, }, @@ -45,6 +46,7 @@ error: fn_abi_of(pass_zst) = FnAbi { memory_index: [], }, largest_niche: None, + uninhabited: false, variants: Single { index: 0, }, diff --git a/tests/ui/layout/debug.stderr b/tests/ui/layout/debug.stderr index 0daf2d3b9e7f2..07cad7766920f 100644 --- a/tests/ui/layout/debug.stderr +++ b/tests/ui/layout/debug.stderr @@ -31,6 +31,7 @@ error: layout_of(E) = Layout { valid_range: 0..=0, }, ), + uninhabited: false, variants: Multiple { tag: Initialized { value: Int( @@ -56,6 +57,7 @@ error: layout_of(E) = Layout { memory_index: [], }, largest_niche: None, + uninhabited: false, variants: Single { index: 0, }, @@ -69,7 +71,9 @@ error: layout_of(E) = Layout { abi: Align(4 bytes), pref: $SOME_ALIGN, }, - abi: Uninhabited, + abi: Memory { + sized: true, + }, fields: Arbitrary { offsets: [ Size(4 bytes), @@ -83,6 +87,7 @@ error: layout_of(E) = Layout { ], }, largest_niche: None, + uninhabited: true, variants: Single { index: 1, }, @@ -136,6 +141,7 @@ error: layout_of(S) = Layout { ], }, largest_niche: None, + uninhabited: false, variants: Single { index: 0, }, @@ -161,6 +167,7 @@ error: layout_of(U) = Layout { 2, ), largest_niche: None, + uninhabited: false, variants: Single { index: 0, }, @@ -213,6 +220,7 @@ error: layout_of(Result) = Layout { valid_range: 0..=1, }, ), + uninhabited: false, variants: Multiple { tag: Initialized { value: Int( @@ -255,6 +263,7 @@ error: layout_of(Result) = Layout { ], }, largest_niche: None, + uninhabited: false, variants: Single { index: 0, }, @@ -293,6 +302,7 @@ error: layout_of(Result) = Layout { ], }, largest_niche: None, + uninhabited: false, variants: Single { index: 1, }, @@ -328,6 +338,7 @@ error: layout_of(i32) = Layout { ), fields: Primitive, largest_niche: None, + uninhabited: false, variants: Single { index: 0, }, @@ -353,6 +364,7 @@ error: layout_of(V) = Layout { 2, ), largest_niche: None, + uninhabited: false, variants: Single { index: 0, }, @@ -378,6 +390,7 @@ error: layout_of(W) = Layout { 2, ), largest_niche: None, + uninhabited: false, variants: Single { index: 0, }, @@ -403,6 +416,7 @@ error: layout_of(Y) = Layout { 2, ), largest_niche: None, + uninhabited: false, variants: Single { index: 0, }, @@ -428,6 +442,7 @@ error: layout_of(P1) = Layout { 1, ), largest_niche: None, + uninhabited: false, variants: Single { index: 0, }, @@ -453,6 +468,7 @@ error: layout_of(P2) = Layout { 1, ), largest_niche: None, + uninhabited: false, variants: Single { index: 0, }, @@ -478,6 +494,7 @@ error: layout_of(P3) = Layout { 1, ), largest_niche: None, + uninhabited: false, variants: Single { index: 0, }, @@ -503,6 +520,7 @@ error: layout_of(P4) = Layout { 1, ), largest_niche: None, + uninhabited: false, variants: Single { index: 0, }, @@ -533,6 +551,7 @@ error: layout_of(P5) = Layout { 2, ), largest_niche: None, + uninhabited: false, variants: Single { index: 0, }, @@ -563,6 +582,7 @@ error: layout_of(MaybeUninit) = Layout { 2, ), largest_niche: None, + uninhabited: false, variants: Single { index: 0, }, diff --git a/tests/ui/layout/hexagon-enum.stderr b/tests/ui/layout/hexagon-enum.stderr index 96f0a8c874086..90c06ba1f834e 100644 --- a/tests/ui/layout/hexagon-enum.stderr +++ b/tests/ui/layout/hexagon-enum.stderr @@ -31,6 +31,7 @@ error: layout_of(A) = Layout { valid_range: 0..=0, }, ), + uninhabited: false, variants: Multiple { tag: Initialized { value: Int( @@ -56,6 +57,7 @@ error: layout_of(A) = Layout { memory_index: [], }, largest_niche: None, + uninhabited: false, variants: Single { index: 0, }, @@ -107,6 +109,7 @@ error: layout_of(B) = Layout { valid_range: 255..=255, }, ), + uninhabited: false, variants: Multiple { tag: Initialized { value: Int( @@ -132,6 +135,7 @@ error: layout_of(B) = Layout { memory_index: [], }, largest_niche: None, + uninhabited: false, variants: Single { index: 0, }, @@ -183,6 +187,7 @@ error: layout_of(C) = Layout { valid_range: 256..=256, }, ), + uninhabited: false, variants: Multiple { tag: Initialized { value: Int( @@ -208,6 +213,7 @@ error: layout_of(C) = Layout { memory_index: [], }, largest_niche: None, + uninhabited: false, variants: Single { index: 0, }, @@ -259,6 +265,7 @@ error: layout_of(P) = Layout { valid_range: 268435456..=268435456, }, ), + uninhabited: false, variants: Multiple { tag: Initialized { value: Int( @@ -284,6 +291,7 @@ error: layout_of(P) = Layout { memory_index: [], }, largest_niche: None, + uninhabited: false, variants: Single { index: 0, }, @@ -335,6 +343,7 @@ error: layout_of(T) = Layout { valid_range: 2164260864..=2164260864, }, ), + uninhabited: false, variants: Multiple { tag: Initialized { value: Int( @@ -360,6 +369,7 @@ error: layout_of(T) = Layout { memory_index: [], }, largest_niche: None, + uninhabited: false, variants: Single { index: 0, }, diff --git a/tests/ui/layout/issue-96158-scalarpair-payload-might-be-uninit.stderr b/tests/ui/layout/issue-96158-scalarpair-payload-might-be-uninit.stderr index cd9e4c0278150..3bdb9c5c143e4 100644 --- a/tests/ui/layout/issue-96158-scalarpair-payload-might-be-uninit.stderr +++ b/tests/ui/layout/issue-96158-scalarpair-payload-might-be-uninit.stderr @@ -37,6 +37,7 @@ error: layout_of(MissingPayloadField) = Layout { valid_range: 0..=1, }, ), + uninhabited: false, variants: Multiple { tag: Initialized { value: Int( @@ -78,6 +79,7 @@ error: layout_of(MissingPayloadField) = Layout { ], }, largest_niche: None, + uninhabited: false, variants: Single { index: 0, }, @@ -99,6 +101,7 @@ error: layout_of(MissingPayloadField) = Layout { memory_index: [], }, largest_niche: None, + uninhabited: false, variants: Single { index: 1, }, @@ -157,6 +160,7 @@ error: layout_of(CommonPayloadField) = Layout { valid_range: 0..=1, }, ), + uninhabited: false, variants: Multiple { tag: Initialized { value: Int( @@ -199,6 +203,7 @@ error: layout_of(CommonPayloadField) = Layout { ], }, largest_niche: None, + uninhabited: false, variants: Single { index: 0, }, @@ -237,6 +242,7 @@ error: layout_of(CommonPayloadField) = Layout { ], }, largest_niche: None, + uninhabited: false, variants: Single { index: 1, }, @@ -294,6 +300,7 @@ error: layout_of(CommonPayloadFieldIsMaybeUninit) = Layout { valid_range: 0..=1, }, ), + uninhabited: false, variants: Multiple { tag: Initialized { value: Int( @@ -335,6 +342,7 @@ error: layout_of(CommonPayloadFieldIsMaybeUninit) = Layout { ], }, largest_niche: None, + uninhabited: false, variants: Single { index: 0, }, @@ -372,6 +380,7 @@ error: layout_of(CommonPayloadFieldIsMaybeUninit) = Layout { ], }, largest_niche: None, + uninhabited: false, variants: Single { index: 1, }, @@ -429,6 +438,7 @@ error: layout_of(NicheFirst) = Layout { valid_range: 0..=4, }, ), + uninhabited: false, variants: Multiple { tag: Initialized { value: Int( @@ -486,6 +496,7 @@ error: layout_of(NicheFirst) = Layout { valid_range: 0..=2, }, ), + uninhabited: false, variants: Single { index: 0, }, @@ -507,6 +518,7 @@ error: layout_of(NicheFirst) = Layout { memory_index: [], }, largest_niche: None, + uninhabited: false, variants: Single { index: 1, }, @@ -528,6 +540,7 @@ error: layout_of(NicheFirst) = Layout { memory_index: [], }, largest_niche: None, + uninhabited: false, variants: Single { index: 2, }, @@ -585,6 +598,7 @@ error: layout_of(NicheSecond) = Layout { valid_range: 0..=4, }, ), + uninhabited: false, variants: Multiple { tag: Initialized { value: Int( @@ -642,6 +656,7 @@ error: layout_of(NicheSecond) = Layout { valid_range: 0..=2, }, ), + uninhabited: false, variants: Single { index: 0, }, @@ -663,6 +678,7 @@ error: layout_of(NicheSecond) = Layout { memory_index: [], }, largest_niche: None, + uninhabited: false, variants: Single { index: 1, }, @@ -684,6 +700,7 @@ error: layout_of(NicheSecond) = Layout { memory_index: [], }, largest_niche: None, + uninhabited: false, variants: Single { index: 2, }, diff --git a/tests/ui/layout/issue-96185-overaligned-enum.stderr b/tests/ui/layout/issue-96185-overaligned-enum.stderr index 15a3f6004f50f..1d4e443644826 100644 --- a/tests/ui/layout/issue-96185-overaligned-enum.stderr +++ b/tests/ui/layout/issue-96185-overaligned-enum.stderr @@ -25,6 +25,7 @@ error: layout_of(Aligned1) = Layout { valid_range: 0..=1, }, ), + uninhabited: false, variants: Multiple { tag: Initialized { value: Int( @@ -50,6 +51,7 @@ error: layout_of(Aligned1) = Layout { memory_index: [], }, largest_niche: None, + uninhabited: false, variants: Single { index: 0, }, @@ -73,6 +75,7 @@ error: layout_of(Aligned1) = Layout { memory_index: [], }, largest_niche: None, + uninhabited: false, variants: Single { index: 1, }, @@ -128,6 +131,7 @@ error: layout_of(Aligned2) = Layout { valid_range: 0..=1, }, ), + uninhabited: false, variants: Multiple { tag: Initialized { value: Int( @@ -153,6 +157,7 @@ error: layout_of(Aligned2) = Layout { memory_index: [], }, largest_niche: None, + uninhabited: false, variants: Single { index: 0, }, @@ -176,6 +181,7 @@ error: layout_of(Aligned2) = Layout { memory_index: [], }, largest_niche: None, + uninhabited: false, variants: Single { index: 1, }, diff --git a/tests/ui/layout/thumb-enum.stderr b/tests/ui/layout/thumb-enum.stderr index 120081d193c69..0c34331856474 100644 --- a/tests/ui/layout/thumb-enum.stderr +++ b/tests/ui/layout/thumb-enum.stderr @@ -31,6 +31,7 @@ error: layout_of(A) = Layout { valid_range: 0..=0, }, ), + uninhabited: false, variants: Multiple { tag: Initialized { value: Int( @@ -56,6 +57,7 @@ error: layout_of(A) = Layout { memory_index: [], }, largest_niche: None, + uninhabited: false, variants: Single { index: 0, }, @@ -107,6 +109,7 @@ error: layout_of(B) = Layout { valid_range: 255..=255, }, ), + uninhabited: false, variants: Multiple { tag: Initialized { value: Int( @@ -132,6 +135,7 @@ error: layout_of(B) = Layout { memory_index: [], }, largest_niche: None, + uninhabited: false, variants: Single { index: 0, }, @@ -183,6 +187,7 @@ error: layout_of(C) = Layout { valid_range: 256..=256, }, ), + uninhabited: false, variants: Multiple { tag: Initialized { value: Int( @@ -208,6 +213,7 @@ error: layout_of(C) = Layout { memory_index: [], }, largest_niche: None, + uninhabited: false, variants: Single { index: 0, }, @@ -259,6 +265,7 @@ error: layout_of(P) = Layout { valid_range: 268435456..=268435456, }, ), + uninhabited: false, variants: Multiple { tag: Initialized { value: Int( @@ -284,6 +291,7 @@ error: layout_of(P) = Layout { memory_index: [], }, largest_niche: None, + uninhabited: false, variants: Single { index: 0, }, @@ -335,6 +343,7 @@ error: layout_of(T) = Layout { valid_range: 2164260864..=2164260864, }, ), + uninhabited: false, variants: Multiple { tag: Initialized { value: Int( @@ -360,6 +369,7 @@ error: layout_of(T) = Layout { memory_index: [], }, largest_niche: None, + uninhabited: false, variants: Single { index: 0, }, diff --git a/tests/ui/layout/zero-sized-array-enum-niche.stderr b/tests/ui/layout/zero-sized-array-enum-niche.stderr index b6fcc14c063c5..33d2eede22090 100644 --- a/tests/ui/layout/zero-sized-array-enum-niche.stderr +++ b/tests/ui/layout/zero-sized-array-enum-niche.stderr @@ -25,6 +25,7 @@ error: layout_of(Result<[u32; 0], bool>) = Layout { valid_range: 0..=1, }, ), + uninhabited: false, variants: Multiple { tag: Initialized { value: Int( @@ -54,6 +55,7 @@ error: layout_of(Result<[u32; 0], bool>) = Layout { ], }, largest_niche: None, + uninhabited: false, variants: Single { index: 0, }, @@ -88,6 +90,7 @@ error: layout_of(Result<[u32; 0], bool>) = Layout { valid_range: 0..=1, }, ), + uninhabited: false, variants: Single { index: 1, }, @@ -133,6 +136,7 @@ error: layout_of(MultipleAlignments) = Layout { valid_range: 0..=2, }, ), + uninhabited: false, variants: Multiple { tag: Initialized { value: Int( @@ -162,6 +166,7 @@ error: layout_of(MultipleAlignments) = Layout { ], }, largest_niche: None, + uninhabited: false, variants: Single { index: 0, }, @@ -187,6 +192,7 @@ error: layout_of(MultipleAlignments) = Layout { ], }, largest_niche: None, + uninhabited: false, variants: Single { index: 1, }, @@ -221,6 +227,7 @@ error: layout_of(MultipleAlignments) = Layout { valid_range: 0..=1, }, ), + uninhabited: false, variants: Single { index: 2, }, @@ -266,6 +273,7 @@ error: layout_of(Result<[u32; 0], Packed>>) = Layout { valid_range: 0..=1, }, ), + uninhabited: false, variants: Multiple { tag: Initialized { value: Int( @@ -295,6 +303,7 @@ error: layout_of(Result<[u32; 0], Packed>>) = Layout { ], }, largest_niche: None, + uninhabited: false, variants: Single { index: 0, }, @@ -329,6 +338,7 @@ error: layout_of(Result<[u32; 0], Packed>>) = Layout { valid_range: 1..=65535, }, ), + uninhabited: false, variants: Single { index: 1, }, @@ -374,6 +384,7 @@ error: layout_of(Result<[u32; 0], Packed>) = Layout { valid_range: 0..=1, }, ), + uninhabited: false, variants: Multiple { tag: Initialized { value: Int( @@ -407,6 +418,7 @@ error: layout_of(Result<[u32; 0], Packed>) = Layout { ], }, largest_niche: None, + uninhabited: false, variants: Single { index: 0, }, @@ -441,6 +453,7 @@ error: layout_of(Result<[u32; 0], Packed>) = Layout { valid_range: 0..=0, }, ), + uninhabited: false, variants: Single { index: 1, }, diff --git a/tests/ui/repr/repr-c-dead-variants.aarch64-unknown-linux-gnu.stderr b/tests/ui/repr/repr-c-dead-variants.aarch64-unknown-linux-gnu.stderr index 8e8f1d159b740..204db30786ee3 100644 --- a/tests/ui/repr/repr-c-dead-variants.aarch64-unknown-linux-gnu.stderr +++ b/tests/ui/repr/repr-c-dead-variants.aarch64-unknown-linux-gnu.stderr @@ -4,7 +4,15 @@ error: layout_of(Univariant) = Layout { abi: Align(4 bytes), pref: $SOME_ALIGN, }, - abi: Uninhabited, + abi: Scalar( + Initialized { + value: Int( + I32, + false, + ), + valid_range: 0..=0, + }, + ), fields: Arbitrary { offsets: [ Size(0 bytes), @@ -23,6 +31,7 @@ error: layout_of(Univariant) = Layout { valid_range: 0..=0, }, ), + uninhabited: true, variants: Multiple { tag: Initialized { value: Int( @@ -40,7 +49,15 @@ error: layout_of(Univariant) = Layout { abi: Align(4 bytes), pref: $SOME_ALIGN, }, - abi: Uninhabited, + abi: Scalar( + Initialized { + value: Int( + I32, + false, + ), + valid_range: 0..=0, + }, + ), fields: Arbitrary { offsets: [ Size(4 bytes), @@ -50,6 +67,7 @@ error: layout_of(Univariant) = Layout { ], }, largest_niche: None, + uninhabited: true, variants: Single { index: 0, }, @@ -107,6 +125,7 @@ error: layout_of(TwoVariants) = Layout { valid_range: 0..=1, }, ), + uninhabited: false, variants: Multiple { tag: Initialized { value: Int( @@ -119,12 +138,26 @@ error: layout_of(TwoVariants) = Layout { tag_field: 0, variants: [ Layout { - size: Size(4 bytes), + size: Size(8 bytes), align: AbiAndPrefAlign { abi: Align(4 bytes), pref: $SOME_ALIGN, }, - abi: Uninhabited, + abi: ScalarPair( + Initialized { + value: Int( + I32, + false, + ), + valid_range: 0..=1, + }, + Union { + value: Int( + I8, + false, + ), + }, + ), fields: Arbitrary { offsets: [ Size(4 bytes), @@ -134,6 +167,7 @@ error: layout_of(TwoVariants) = Layout { ], }, largest_niche: None, + uninhabited: true, variants: Single { index: 0, }, @@ -171,6 +205,7 @@ error: layout_of(TwoVariants) = Layout { ], }, largest_niche: None, + uninhabited: false, variants: Single { index: 1, }, @@ -216,6 +251,7 @@ error: layout_of(DeadBranchHasOtherField) = Layout { valid_range: 0..=1, }, ), + uninhabited: false, variants: Multiple { tag: Initialized { value: Int( @@ -233,7 +269,9 @@ error: layout_of(DeadBranchHasOtherField) = Layout { abi: Align(8 bytes), pref: $SOME_ALIGN, }, - abi: Uninhabited, + abi: Memory { + sized: true, + }, fields: Arbitrary { offsets: [ Size(8 bytes), @@ -245,6 +283,7 @@ error: layout_of(DeadBranchHasOtherField) = Layout { ], }, largest_niche: None, + uninhabited: true, variants: Single { index: 0, }, @@ -272,6 +311,7 @@ error: layout_of(DeadBranchHasOtherField) = Layout { ], }, largest_niche: None, + uninhabited: false, variants: Single { index: 1, }, diff --git a/tests/ui/repr/repr-c-dead-variants.armebv7r-none-eabi.stderr b/tests/ui/repr/repr-c-dead-variants.armebv7r-none-eabi.stderr index 2cd0960ce3eec..1fab00bf50c49 100644 --- a/tests/ui/repr/repr-c-dead-variants.armebv7r-none-eabi.stderr +++ b/tests/ui/repr/repr-c-dead-variants.armebv7r-none-eabi.stderr @@ -4,7 +4,15 @@ error: layout_of(Univariant) = Layout { abi: Align(1 bytes), pref: $SOME_ALIGN, }, - abi: Uninhabited, + abi: Scalar( + Initialized { + value: Int( + I8, + false, + ), + valid_range: 0..=0, + }, + ), fields: Arbitrary { offsets: [ Size(0 bytes), @@ -23,6 +31,7 @@ error: layout_of(Univariant) = Layout { valid_range: 0..=0, }, ), + uninhabited: true, variants: Multiple { tag: Initialized { value: Int( @@ -40,7 +49,15 @@ error: layout_of(Univariant) = Layout { abi: Align(1 bytes), pref: $SOME_ALIGN, }, - abi: Uninhabited, + abi: Scalar( + Initialized { + value: Int( + I8, + false, + ), + valid_range: 0..=0, + }, + ), fields: Arbitrary { offsets: [ Size(1 bytes), @@ -50,6 +67,7 @@ error: layout_of(Univariant) = Layout { ], }, largest_niche: None, + uninhabited: true, variants: Single { index: 0, }, @@ -107,6 +125,7 @@ error: layout_of(TwoVariants) = Layout { valid_range: 0..=1, }, ), + uninhabited: false, variants: Multiple { tag: Initialized { value: Int( @@ -119,12 +138,26 @@ error: layout_of(TwoVariants) = Layout { tag_field: 0, variants: [ Layout { - size: Size(1 bytes), + size: Size(2 bytes), align: AbiAndPrefAlign { abi: Align(1 bytes), pref: $SOME_ALIGN, }, - abi: Uninhabited, + abi: ScalarPair( + Initialized { + value: Int( + I8, + false, + ), + valid_range: 0..=1, + }, + Union { + value: Int( + I8, + false, + ), + }, + ), fields: Arbitrary { offsets: [ Size(1 bytes), @@ -134,6 +167,7 @@ error: layout_of(TwoVariants) = Layout { ], }, largest_niche: None, + uninhabited: true, variants: Single { index: 0, }, @@ -171,6 +205,7 @@ error: layout_of(TwoVariants) = Layout { ], }, largest_niche: None, + uninhabited: false, variants: Single { index: 1, }, @@ -216,6 +251,7 @@ error: layout_of(DeadBranchHasOtherField) = Layout { valid_range: 0..=1, }, ), + uninhabited: false, variants: Multiple { tag: Initialized { value: Int( @@ -233,7 +269,9 @@ error: layout_of(DeadBranchHasOtherField) = Layout { abi: Align(8 bytes), pref: $SOME_ALIGN, }, - abi: Uninhabited, + abi: Memory { + sized: true, + }, fields: Arbitrary { offsets: [ Size(8 bytes), @@ -245,6 +283,7 @@ error: layout_of(DeadBranchHasOtherField) = Layout { ], }, largest_niche: None, + uninhabited: true, variants: Single { index: 0, }, @@ -272,6 +311,7 @@ error: layout_of(DeadBranchHasOtherField) = Layout { ], }, largest_niche: None, + uninhabited: false, variants: Single { index: 1, }, diff --git a/tests/ui/repr/repr-c-dead-variants.i686-pc-windows-msvc.stderr b/tests/ui/repr/repr-c-dead-variants.i686-pc-windows-msvc.stderr index 8e8f1d159b740..204db30786ee3 100644 --- a/tests/ui/repr/repr-c-dead-variants.i686-pc-windows-msvc.stderr +++ b/tests/ui/repr/repr-c-dead-variants.i686-pc-windows-msvc.stderr @@ -4,7 +4,15 @@ error: layout_of(Univariant) = Layout { abi: Align(4 bytes), pref: $SOME_ALIGN, }, - abi: Uninhabited, + abi: Scalar( + Initialized { + value: Int( + I32, + false, + ), + valid_range: 0..=0, + }, + ), fields: Arbitrary { offsets: [ Size(0 bytes), @@ -23,6 +31,7 @@ error: layout_of(Univariant) = Layout { valid_range: 0..=0, }, ), + uninhabited: true, variants: Multiple { tag: Initialized { value: Int( @@ -40,7 +49,15 @@ error: layout_of(Univariant) = Layout { abi: Align(4 bytes), pref: $SOME_ALIGN, }, - abi: Uninhabited, + abi: Scalar( + Initialized { + value: Int( + I32, + false, + ), + valid_range: 0..=0, + }, + ), fields: Arbitrary { offsets: [ Size(4 bytes), @@ -50,6 +67,7 @@ error: layout_of(Univariant) = Layout { ], }, largest_niche: None, + uninhabited: true, variants: Single { index: 0, }, @@ -107,6 +125,7 @@ error: layout_of(TwoVariants) = Layout { valid_range: 0..=1, }, ), + uninhabited: false, variants: Multiple { tag: Initialized { value: Int( @@ -119,12 +138,26 @@ error: layout_of(TwoVariants) = Layout { tag_field: 0, variants: [ Layout { - size: Size(4 bytes), + size: Size(8 bytes), align: AbiAndPrefAlign { abi: Align(4 bytes), pref: $SOME_ALIGN, }, - abi: Uninhabited, + abi: ScalarPair( + Initialized { + value: Int( + I32, + false, + ), + valid_range: 0..=1, + }, + Union { + value: Int( + I8, + false, + ), + }, + ), fields: Arbitrary { offsets: [ Size(4 bytes), @@ -134,6 +167,7 @@ error: layout_of(TwoVariants) = Layout { ], }, largest_niche: None, + uninhabited: true, variants: Single { index: 0, }, @@ -171,6 +205,7 @@ error: layout_of(TwoVariants) = Layout { ], }, largest_niche: None, + uninhabited: false, variants: Single { index: 1, }, @@ -216,6 +251,7 @@ error: layout_of(DeadBranchHasOtherField) = Layout { valid_range: 0..=1, }, ), + uninhabited: false, variants: Multiple { tag: Initialized { value: Int( @@ -233,7 +269,9 @@ error: layout_of(DeadBranchHasOtherField) = Layout { abi: Align(8 bytes), pref: $SOME_ALIGN, }, - abi: Uninhabited, + abi: Memory { + sized: true, + }, fields: Arbitrary { offsets: [ Size(8 bytes), @@ -245,6 +283,7 @@ error: layout_of(DeadBranchHasOtherField) = Layout { ], }, largest_niche: None, + uninhabited: true, variants: Single { index: 0, }, @@ -272,6 +311,7 @@ error: layout_of(DeadBranchHasOtherField) = Layout { ], }, largest_niche: None, + uninhabited: false, variants: Single { index: 1, }, diff --git a/tests/ui/repr/repr-c-dead-variants.x86_64-unknown-linux-gnu.stderr b/tests/ui/repr/repr-c-dead-variants.x86_64-unknown-linux-gnu.stderr index 8e8f1d159b740..204db30786ee3 100644 --- a/tests/ui/repr/repr-c-dead-variants.x86_64-unknown-linux-gnu.stderr +++ b/tests/ui/repr/repr-c-dead-variants.x86_64-unknown-linux-gnu.stderr @@ -4,7 +4,15 @@ error: layout_of(Univariant) = Layout { abi: Align(4 bytes), pref: $SOME_ALIGN, }, - abi: Uninhabited, + abi: Scalar( + Initialized { + value: Int( + I32, + false, + ), + valid_range: 0..=0, + }, + ), fields: Arbitrary { offsets: [ Size(0 bytes), @@ -23,6 +31,7 @@ error: layout_of(Univariant) = Layout { valid_range: 0..=0, }, ), + uninhabited: true, variants: Multiple { tag: Initialized { value: Int( @@ -40,7 +49,15 @@ error: layout_of(Univariant) = Layout { abi: Align(4 bytes), pref: $SOME_ALIGN, }, - abi: Uninhabited, + abi: Scalar( + Initialized { + value: Int( + I32, + false, + ), + valid_range: 0..=0, + }, + ), fields: Arbitrary { offsets: [ Size(4 bytes), @@ -50,6 +67,7 @@ error: layout_of(Univariant) = Layout { ], }, largest_niche: None, + uninhabited: true, variants: Single { index: 0, }, @@ -107,6 +125,7 @@ error: layout_of(TwoVariants) = Layout { valid_range: 0..=1, }, ), + uninhabited: false, variants: Multiple { tag: Initialized { value: Int( @@ -119,12 +138,26 @@ error: layout_of(TwoVariants) = Layout { tag_field: 0, variants: [ Layout { - size: Size(4 bytes), + size: Size(8 bytes), align: AbiAndPrefAlign { abi: Align(4 bytes), pref: $SOME_ALIGN, }, - abi: Uninhabited, + abi: ScalarPair( + Initialized { + value: Int( + I32, + false, + ), + valid_range: 0..=1, + }, + Union { + value: Int( + I8, + false, + ), + }, + ), fields: Arbitrary { offsets: [ Size(4 bytes), @@ -134,6 +167,7 @@ error: layout_of(TwoVariants) = Layout { ], }, largest_niche: None, + uninhabited: true, variants: Single { index: 0, }, @@ -171,6 +205,7 @@ error: layout_of(TwoVariants) = Layout { ], }, largest_niche: None, + uninhabited: false, variants: Single { index: 1, }, @@ -216,6 +251,7 @@ error: layout_of(DeadBranchHasOtherField) = Layout { valid_range: 0..=1, }, ), + uninhabited: false, variants: Multiple { tag: Initialized { value: Int( @@ -233,7 +269,9 @@ error: layout_of(DeadBranchHasOtherField) = Layout { abi: Align(8 bytes), pref: $SOME_ALIGN, }, - abi: Uninhabited, + abi: Memory { + sized: true, + }, fields: Arbitrary { offsets: [ Size(8 bytes), @@ -245,6 +283,7 @@ error: layout_of(DeadBranchHasOtherField) = Layout { ], }, largest_niche: None, + uninhabited: true, variants: Single { index: 0, }, @@ -272,6 +311,7 @@ error: layout_of(DeadBranchHasOtherField) = Layout { ], }, largest_niche: None, + uninhabited: false, variants: Single { index: 1, }, diff --git a/tests/ui/repr/repr-c-int-dead-variants.stderr b/tests/ui/repr/repr-c-int-dead-variants.stderr index fa08b323dec2a..f852212deb908 100644 --- a/tests/ui/repr/repr-c-int-dead-variants.stderr +++ b/tests/ui/repr/repr-c-int-dead-variants.stderr @@ -4,7 +4,15 @@ error: layout_of(UnivariantU8) = Layout { abi: Align(1 bytes), pref: $SOME_ALIGN, }, - abi: Uninhabited, + abi: Scalar( + Initialized { + value: Int( + I8, + false, + ), + valid_range: 0..=0, + }, + ), fields: Arbitrary { offsets: [ Size(0 bytes), @@ -23,6 +31,7 @@ error: layout_of(UnivariantU8) = Layout { valid_range: 0..=0, }, ), + uninhabited: true, variants: Multiple { tag: Initialized { value: Int( @@ -40,7 +49,15 @@ error: layout_of(UnivariantU8) = Layout { abi: Align(1 bytes), pref: $SOME_ALIGN, }, - abi: Uninhabited, + abi: Scalar( + Initialized { + value: Int( + I8, + false, + ), + valid_range: 0..=0, + }, + ), fields: Arbitrary { offsets: [ Size(1 bytes), @@ -50,6 +67,7 @@ error: layout_of(UnivariantU8) = Layout { ], }, largest_niche: None, + uninhabited: true, variants: Single { index: 0, }, @@ -107,6 +125,7 @@ error: layout_of(TwoVariantsU8) = Layout { valid_range: 0..=1, }, ), + uninhabited: false, variants: Multiple { tag: Initialized { value: Int( @@ -119,12 +138,26 @@ error: layout_of(TwoVariantsU8) = Layout { tag_field: 0, variants: [ Layout { - size: Size(1 bytes), + size: Size(2 bytes), align: AbiAndPrefAlign { abi: Align(1 bytes), pref: $SOME_ALIGN, }, - abi: Uninhabited, + abi: ScalarPair( + Initialized { + value: Int( + I8, + false, + ), + valid_range: 0..=1, + }, + Union { + value: Int( + I8, + false, + ), + }, + ), fields: Arbitrary { offsets: [ Size(1 bytes), @@ -134,6 +167,7 @@ error: layout_of(TwoVariantsU8) = Layout { ], }, largest_niche: None, + uninhabited: true, variants: Single { index: 0, }, @@ -171,6 +205,7 @@ error: layout_of(TwoVariantsU8) = Layout { ], }, largest_niche: None, + uninhabited: false, variants: Single { index: 1, }, @@ -216,6 +251,7 @@ error: layout_of(DeadBranchHasOtherFieldU8) = Layout { valid_range: 0..=1, }, ), + uninhabited: false, variants: Multiple { tag: Initialized { value: Int( @@ -233,7 +269,9 @@ error: layout_of(DeadBranchHasOtherFieldU8) = Layout { abi: Align(8 bytes), pref: $SOME_ALIGN, }, - abi: Uninhabited, + abi: Memory { + sized: true, + }, fields: Arbitrary { offsets: [ Size(8 bytes), @@ -245,6 +283,7 @@ error: layout_of(DeadBranchHasOtherFieldU8) = Layout { ], }, largest_niche: None, + uninhabited: true, variants: Single { index: 0, }, @@ -272,6 +311,7 @@ error: layout_of(DeadBranchHasOtherFieldU8) = Layout { ], }, largest_niche: None, + uninhabited: false, variants: Single { index: 1, }, diff --git a/tests/ui/type/pattern_types/range_patterns.stderr b/tests/ui/type/pattern_types/range_patterns.stderr index 7da8cfd4dbc2d..690592ba0b8da 100644 --- a/tests/ui/type/pattern_types/range_patterns.stderr +++ b/tests/ui/type/pattern_types/range_patterns.stderr @@ -31,6 +31,7 @@ error: layout_of(NonZero) = Layout { valid_range: 1..=4294967295, }, ), + uninhabited: false, variants: Single { index: 0, }, @@ -69,6 +70,7 @@ error: layout_of((u32) is 1..=) = Layout { valid_range: 1..=4294967295, }, ), + uninhabited: false, variants: Single { index: 0, }, @@ -105,6 +107,7 @@ error: layout_of(Option<(u32) is 1..=>) = Layout { ], }, largest_niche: None, + uninhabited: false, variants: Multiple { tag: Initialized { value: Int( @@ -134,6 +137,7 @@ error: layout_of(Option<(u32) is 1..=>) = Layout { memory_index: [], }, largest_niche: None, + uninhabited: false, variants: Single { index: 0, }, @@ -174,6 +178,7 @@ error: layout_of(Option<(u32) is 1..=>) = Layout { valid_range: 1..=4294967295, }, ), + uninhabited: false, variants: Single { index: 1, }, @@ -216,6 +221,7 @@ error: layout_of(Option>) = Layout { ], }, largest_niche: None, + uninhabited: false, variants: Multiple { tag: Initialized { value: Int( @@ -245,6 +251,7 @@ error: layout_of(Option>) = Layout { memory_index: [], }, largest_niche: None, + uninhabited: false, variants: Single { index: 0, }, @@ -285,6 +292,7 @@ error: layout_of(Option>) = Layout { valid_range: 1..=4294967295, }, ), + uninhabited: false, variants: Single { index: 1, }, @@ -336,6 +344,7 @@ error: layout_of(NonZeroU32New) = Layout { valid_range: 1..=4294967295, }, ), + uninhabited: false, variants: Single { index: 0, }, From bcfde13d51229e5ba4cb324194561b18e9326680 Mon Sep 17 00:00:00 2001 From: Zachary S Date: Tue, 28 Jan 2025 01:29:37 -0600 Subject: [PATCH 14/20] Update check to reflect that non-ZST uninhabited types should not be PassMode::Ignore. --- compiler/rustc_ty_utils/src/abi.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_ty_utils/src/abi.rs b/compiler/rustc_ty_utils/src/abi.rs index 2d20ef3d690dd..0ff82f0c256de 100644 --- a/compiler/rustc_ty_utils/src/abi.rs +++ b/compiler/rustc_ty_utils/src/abi.rs @@ -464,7 +464,7 @@ fn fn_abi_sanity_check<'tcx>( match &arg.mode { PassMode::Ignore => { - assert!(arg.layout.is_zst() || arg.layout.is_uninhabited()); + assert!(arg.layout.is_zst()); } PassMode::Direct(_) => { // Here the Rust type is used to determine the actual ABI, so we have to be very From 58ebf6afdd01d32f9f6d22d2e788c0dc10bc65a5 Mon Sep 17 00:00:00 2001 From: Zachary S Date: Thu, 13 Feb 2025 13:17:39 -0600 Subject: [PATCH 15/20] Add test that uninhabited repr(transparent) type has same function return ABI as wrapped type. Fix codegen of uninhabited PassMode::Indirect return types. Add codegen test for uninhabited PassMode::Indirect return types. Enable optimizations for uninhabited return type codegen test --- compiler/rustc_codegen_ssa/src/mir/block.rs | 28 +++--------- .../uninhabited-transparent-return-abi.rs | 44 +++++++++++++++++++ .../uninhabited-transparent-return-abi.rs | 33 ++++++++++++++ 3 files changed, 84 insertions(+), 21 deletions(-) create mode 100644 tests/codegen/uninhabited-transparent-return-abi.rs create mode 100644 tests/ui/uninhabited/uninhabited-transparent-return-abi.rs diff --git a/compiler/rustc_codegen_ssa/src/mir/block.rs b/compiler/rustc_codegen_ssa/src/mir/block.rs index 0620f08fc731b..49074996174a7 100644 --- a/compiler/rustc_codegen_ssa/src/mir/block.rs +++ b/compiler/rustc_codegen_ssa/src/mir/block.rs @@ -4,9 +4,7 @@ use rustc_abi::{BackendRepr, ExternAbi, HasDataLayout, Reg, WrappingRange}; use rustc_ast as ast; use rustc_ast::{InlineAsmOptions, InlineAsmTemplatePiece}; use rustc_hir::lang_items::LangItem; -use rustc_middle::mir::{ - self, AssertKind, BasicBlock, InlineAsmMacro, SwitchTargets, UnwindTerminateReason, -}; +use rustc_middle::mir::{self, AssertKind, InlineAsmMacro, SwitchTargets, UnwindTerminateReason}; use rustc_middle::ty::layout::{HasTyCtxt, LayoutOf, ValidityRequirement}; use rustc_middle::ty::print::{with_no_trimmed_paths, with_no_visible_paths}; use rustc_middle::ty::{self, Instance, Ty}; @@ -942,7 +940,6 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { &fn_abi.ret, &mut llargs, Some(intrinsic), - target, ); let dest = match ret_dest { _ if fn_abi.ret.is_indirect() => llargs[0], @@ -998,19 +995,12 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { }; let mut llargs = Vec::with_capacity(arg_count); - let destination = target.as_ref().map(|&target| { - ( - self.make_return_dest( - bx, - destination, - &fn_abi.ret, - &mut llargs, - None, - Some(target), - ), - target, - ) - }); + + // We still need to call `make_return_dest` even if there's no `target`, since + // `fn_abi.ret` could be `PassMode::Indirect`, even if it is uninhabited, + // and `make_return_dest` adds the return-place indirect pointer to `llargs`. + let return_dest = self.make_return_dest(bx, destination, &fn_abi.ret, &mut llargs, None); + let destination = target.map(|target| (return_dest, target)); // Split the rust-call tupled arguments off. let (first_args, untuple) = if abi == ExternAbi::RustCall && !args.is_empty() { @@ -1813,11 +1803,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { fn_ret: &ArgAbi<'tcx, Ty<'tcx>>, llargs: &mut Vec, intrinsic: Option, - target: Option, ) -> ReturnDest<'tcx, Bx::Value> { - if target.is_none() { - return ReturnDest::Nothing; - } // If the return is ignored, we can just return a do-nothing `ReturnDest`. if fn_ret.is_ignore() { return ReturnDest::Nothing; diff --git a/tests/codegen/uninhabited-transparent-return-abi.rs b/tests/codegen/uninhabited-transparent-return-abi.rs new file mode 100644 index 0000000000000..6e8b1683163ef --- /dev/null +++ b/tests/codegen/uninhabited-transparent-return-abi.rs @@ -0,0 +1,44 @@ +//@ compile-flags: -Copt-level=3 + +// See https://github.com/rust-lang/rust/issues/135802 + +#![crate_type = "lib"] + +enum Void {} + +// Should be ABI-compatible with T, but wasn't prior to the PR adding this test. +#[repr(transparent)] +struct NoReturn(T, Void); + +// Returned by invisible reference (in most ABIs) +#[allow(dead_code)] +struct Large(u64, u64, u64); + +extern "Rust" { + fn opaque() -> NoReturn; + fn opaque_with_arg(rsi: u32) -> NoReturn; +} + +// CHECK-LABEL: @test_uninhabited_ret_by_ref +#[no_mangle] +pub fn test_uninhabited_ret_by_ref() { + // CHECK: %_1 = alloca [24 x i8], align {{8|4}} + // CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 24, ptr nonnull %_1) + // CHECK-NEXT: call void @opaque(ptr noalias nocapture noundef nonnull sret([24 x i8]) align {{8|4}} dereferenceable(24) %_1) #2 + // CHECK-NEXT: unreachable + unsafe { + opaque(); + } +} + +// CHECK-LABEL: @test_uninhabited_ret_by_ref_with_arg +#[no_mangle] +pub fn test_uninhabited_ret_by_ref_with_arg(rsi: u32) { + // CHECK: %_2 = alloca [24 x i8], align {{8|4}} + // CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 24, ptr nonnull %_2) + // CHECK-NEXT: call void @opaque_with_arg(ptr noalias nocapture noundef nonnull sret([24 x i8]) align {{8|4}} dereferenceable(24) %_2, i32 noundef %rsi) #2 + // CHECK-NEXT: unreachable + unsafe { + opaque_with_arg(rsi); + } +} diff --git a/tests/ui/uninhabited/uninhabited-transparent-return-abi.rs b/tests/ui/uninhabited/uninhabited-transparent-return-abi.rs new file mode 100644 index 0000000000000..2c2788a3e5642 --- /dev/null +++ b/tests/ui/uninhabited/uninhabited-transparent-return-abi.rs @@ -0,0 +1,33 @@ +//@ run-pass +//@ needs-unwind +// See https://github.com/rust-lang/rust/issues/135802 + +enum Void {} + +// Should be ABI-compatible with T, but wasn't prior to the PR adding this test. +#[repr(transparent)] +struct NoReturn(T, Void); + +// Returned by invisible reference (in most ABIs) +#[allow(dead_code)] +struct Large(u64, u64, u64); + +// Prior to the PR adding this test, this function had a different ABI than +// `fn() -> Large` (on `x86_64-unknown-linux-gnu` at least), so calling it as `fn() -> Large` +// would pass the return place pointer in rdi and `correct` in rsi, but the function +// would expect `correct` in rdi. +fn never(correct: &mut bool) -> NoReturn { + *correct = true; + panic!("catch this") +} + +fn main() { + let mut correct = false; + let never: fn(&mut bool) -> NoReturn = never; + // Safety: `NoReturn` is a `repr(transparent)` wrapper around `Large`, + // so they should be ABI-compatible. + let never: fn(&mut bool) -> Large = unsafe { std::mem::transmute(never) }; + let result = std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| never(&mut correct))); + assert!(result.is_err(), "function should have panicked"); + assert!(correct, "function should have stored `true` into `correct`"); +} From 6493cd8699cc6d55a38b5187ff4cc731f969c483 Mon Sep 17 00:00:00 2001 From: zachs18 <8355914+zachs18@users.noreply.github.com> Date: Mon, 17 Feb 2025 18:49:18 -0600 Subject: [PATCH 16/20] Adjust LayoutData::uninhabited doc comment. Co-authored-by: Jubilee --- compiler/rustc_abi/src/lib.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_abi/src/lib.rs b/compiler/rustc_abi/src/lib.rs index 14a8a57920049..098638b6bcfa7 100644 --- a/compiler/rustc_abi/src/lib.rs +++ b/compiler/rustc_abi/src/lib.rs @@ -1696,8 +1696,8 @@ pub struct LayoutData { pub largest_niche: Option, /// Is this type known to be uninhabted? /// - /// This is separate from BackendRepr, because an uninhabited return type may require special - /// consideration based on its size or other attributes. + /// This is separate from BackendRepr because uninhabited return types can affect ABI, + /// especially in the case of by-pointer struct returns, which allocate stack even when unused. pub uninhabited: bool, pub align: AbiAndPrefAlign, From e3f5db07e0daa833c51c335fa07d87affd8a8bf9 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Tue, 18 Feb 2025 11:31:38 +0100 Subject: [PATCH 17/20] fine-tune comment --- compiler/rustc_const_eval/src/interpret/validity.rs | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/compiler/rustc_const_eval/src/interpret/validity.rs b/compiler/rustc_const_eval/src/interpret/validity.rs index 3667cc84d708e..40dec0cb39e7b 100644 --- a/compiler/rustc_const_eval/src/interpret/validity.rs +++ b/compiler/rustc_const_eval/src/interpret/validity.rs @@ -1264,12 +1264,11 @@ impl<'rt, 'tcx, M: Machine<'tcx>> ValueVisitor<'tcx, M> for ValidityVisitor<'rt, } } - // *After* all of this, check the ABI. We need to check the ABI to handle - // types like `NonNull` where the `Scalar` info is more restrictive than what - // the fields say (`rustc_layout_scalar_valid_range_start`). - // But in most cases, this will just propagate what the fields say, - // and then we want the error to point at the field -- so, first recurse, - // then check ABI. + // *After* all of this, check further information stored in the layout. We need to check + // this to handle types like `NonNull` where the `Scalar` info is more restrictive than what + // the fields say (`rustc_layout_scalar_valid_range_start`). But in most cases, this will + // just propagate what the fields say, and then we want the error to point at the field -- + // so, we first recurse, then we do this check. // // FIXME: We could avoid some redundant checks here. For newtypes wrapping // scalars, we do the same check on every "level" (e.g., first we check From 953515131b32deaf26410cb78b7eb6fe93d4d9b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Thu, 20 Feb 2025 20:43:57 +0100 Subject: [PATCH 18/20] Improve error message when a submodule directory is missing completely --- src/bootstrap/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/bootstrap/src/lib.rs b/src/bootstrap/src/lib.rs index dfaf0418d9a2b..c41be41219e0f 100644 --- a/src/bootstrap/src/lib.rs +++ b/src/bootstrap/src/lib.rs @@ -488,7 +488,7 @@ impl Build { } self.config.update_submodule(submodule); let absolute_path = self.config.src.join(submodule); - if dir_is_empty(&absolute_path) { + if !absolute_path.exists() || dir_is_empty(&absolute_path) { let maybe_enable = if !self.config.submodules() && self.config.rust_info.is_managed_git_subrepository() { From d2203ad59c67a6acb2968ea77e1e9dea5530e518 Mon Sep 17 00:00:00 2001 From: onur-ozkan Date: Thu, 20 Feb 2025 22:48:39 +0300 Subject: [PATCH 19/20] skip submodule updating logics on tarballs Signed-off-by: onur-ozkan --- src/bootstrap/src/core/config/config.rs | 2 +- src/bootstrap/src/lib.rs | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/bootstrap/src/core/config/config.rs b/src/bootstrap/src/core/config/config.rs index 64a510240f837..172b8d787640d 100644 --- a/src/bootstrap/src/core/config/config.rs +++ b/src/bootstrap/src/core/config/config.rs @@ -2767,7 +2767,7 @@ impl Config { ), )] pub(crate) fn update_submodule(&self, relative_path: &str) { - if !self.submodules() { + if self.rust_info.is_from_tarball() || !self.submodules() { return; } diff --git a/src/bootstrap/src/lib.rs b/src/bootstrap/src/lib.rs index dfaf0418d9a2b..a0934a8d55663 100644 --- a/src/bootstrap/src/lib.rs +++ b/src/bootstrap/src/lib.rs @@ -481,6 +481,10 @@ impl Build { ), )] pub fn require_submodule(&self, submodule: &str, err_hint: Option<&str>) { + if self.rust_info().is_from_tarball() { + return; + } + // When testing bootstrap itself, it is much faster to ignore // submodules. Almost all Steps work fine without their submodules. if cfg!(test) && !self.config.submodules() { From c0bea5d92d69c93ec8b6d4374df6863ff312e20f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Thu, 20 Feb 2025 21:06:25 +0100 Subject: [PATCH 20/20] Add a notice about missing GCC sources in source tarballs --- src/bootstrap/src/core/build_steps/dist.rs | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/bootstrap/src/core/build_steps/dist.rs b/src/bootstrap/src/core/build_steps/dist.rs index 85b224771bb31..795f9506a259b 100644 --- a/src/bootstrap/src/core/build_steps/dist.rs +++ b/src/bootstrap/src/core/build_steps/dist.rs @@ -1029,6 +1029,17 @@ impl Step for PlainSourceTarball { ], plain_dst_src, ); + // We keep something in src/gcc because it is a registered submodule, + // and if it misses completely it can cause issues elsewhere + // (see https://github.com/rust-lang/rust/issues/137332). + // We can also let others know why is the source code missing. + if !builder.config.dry_run() { + builder.create_dir(&plain_dst_src.join("src/gcc")); + t!(std::fs::write( + plain_dst_src.join("src/gcc/notice.txt"), + "The GCC source code is not included due to unclear licensing implications\n" + )); + } // Copy the files normally for item in &src_files {