diff --git a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs index 2587e89417a6a..e872f8434e56e 100644 --- a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs +++ b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs @@ -630,7 +630,17 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { OperandRef { val: OperandValue::Immediate(static_), layout } } mir::Rvalue::Use(ref operand) => self.codegen_operand(bx, operand), - mir::Rvalue::Repeat(..) => bug!("{rvalue:?} in codegen_rvalue_operand"), + mir::Rvalue::Repeat(ref elem, len_const) => { + // All arrays have `BackendRepr::Memory`, so only the ZST cases + // end up here. Anything else forces the destination local to be + // `Memory`, and thus ends up handled in `codegen_rvalue` instead. + let operand = self.codegen_operand(bx, elem); + let array_ty = Ty::new_array_with_const_len(bx.tcx(), operand.layout.ty, len_const); + let array_ty = self.monomorphize(array_ty); + let array_layout = bx.layout_of(array_ty); + assert!(array_layout.is_zst()); + OperandRef { val: OperandValue::ZeroSized, layout: array_layout } + } mir::Rvalue::Aggregate(ref kind, ref fields) => { let (variant_index, active_field_index) = match **kind { mir::AggregateKind::Adt(_, variant_index, _, _, active_field_index) => { @@ -1000,12 +1010,10 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { mir::Rvalue::NullaryOp(..) | mir::Rvalue::ThreadLocalRef(_) | mir::Rvalue::Use(..) | + mir::Rvalue::Repeat(..) | // (*) mir::Rvalue::Aggregate(..) | // (*) mir::Rvalue::WrapUnsafeBinder(..) => // (*) true, - // Arrays are always aggregates, so it's not worth checking anything here. - // (If it's really `[(); N]` or `[T; 0]` and we use the place path, fine.) - mir::Rvalue::Repeat(..) => false, } // (*) this is only true if the type is suitable diff --git a/compiler/rustc_codegen_ssa/src/target_features.rs b/compiler/rustc_codegen_ssa/src/target_features.rs index 53df99993f06b..def4ec13e87b5 100644 --- a/compiler/rustc_codegen_ssa/src/target_features.rs +++ b/compiler/rustc_codegen_ssa/src/target_features.rs @@ -149,14 +149,14 @@ fn parse_rust_feature_flag<'a>( if let Some(base_feature) = feature.strip_prefix('+') { // Skip features that are not target features, but rustc features. if RUSTC_SPECIFIC_FEATURES.contains(&base_feature) { - return; + continue; } callback(base_feature, sess.target.implied_target_features(base_feature), true) } else if let Some(base_feature) = feature.strip_prefix('-') { // Skip features that are not target features, but rustc features. if RUSTC_SPECIFIC_FEATURES.contains(&base_feature) { - return; + continue; } // If `f1` implies `f2`, then `!f2` implies `!f1` -- this is standard logical diff --git a/compiler/rustc_mir_transform/src/validate.rs b/compiler/rustc_mir_transform/src/validate.rs index cbb9bbfd12f9f..659ca4df159d0 100644 --- a/compiler/rustc_mir_transform/src/validate.rs +++ b/compiler/rustc_mir_transform/src/validate.rs @@ -119,14 +119,16 @@ impl<'a, 'tcx> CfgChecker<'a, 'tcx> { #[track_caller] fn fail(&self, location: Location, msg: impl AsRef) { // We might see broken MIR when other errors have already occurred. - assert!( - self.tcx.dcx().has_errors().is_some(), - "broken MIR in {:?} ({}) at {:?}:\n{}", - self.body.source.instance, - self.when, - location, - msg.as_ref(), - ); + if self.tcx.dcx().has_errors().is_none() { + span_bug!( + self.body.source_info(location).span, + "broken MIR in {:?} ({}) at {:?}:\n{}", + self.body.source.instance, + self.when, + location, + msg.as_ref(), + ); + } } fn check_edge(&mut self, location: Location, bb: BasicBlock, edge_kind: EdgeKind) { diff --git a/library/core/src/async_iter/async_iter.rs b/library/core/src/async_iter/async_iter.rs index 069c50c2531b0..c21c08320bef6 100644 --- a/library/core/src/async_iter/async_iter.rs +++ b/library/core/src/async_iter/async_iter.rs @@ -28,15 +28,15 @@ pub trait AsyncIterator { /// async iterator state: /// /// - `Poll::Pending` means that this async iterator's next value is not ready - /// yet. Implementations will ensure that the current task will be notified - /// when the next value may be ready. + /// yet. Implementations will ensure that the current task will be notified + /// when the next value may be ready. /// /// - `Poll::Ready(Some(val))` means that the async iterator has successfully - /// produced a value, `val`, and may produce further values on subsequent - /// `poll_next` calls. + /// produced a value, `val`, and may produce further values on subsequent + /// `poll_next` calls. /// /// - `Poll::Ready(None)` means that the async iterator has terminated, and - /// `poll_next` should not be invoked again. + /// `poll_next` should not be invoked again. /// /// # Panics /// diff --git a/library/core/src/cmp.rs b/library/core/src/cmp.rs index 6419ae9911359..1b9af10a6fda5 100644 --- a/library/core/src/cmp.rs +++ b/library/core/src/cmp.rs @@ -1482,13 +1482,14 @@ pub trait PartialOrd: PartialEq + PointeeSized { } } -fn default_chaining_impl( +fn default_chaining_impl( lhs: &T, rhs: &U, p: impl FnOnce(Ordering) -> bool, ) -> ControlFlow where - T: PartialOrd, + T: PartialOrd + PointeeSized, + U: PointeeSized, { // It's important that this only call `partial_cmp` once, not call `eq` then // one of the relational operators. We don't want to `bcmp`-then-`memcp` a diff --git a/library/core/src/fmt/mod.rs b/library/core/src/fmt/mod.rs index 228a331e1da4d..8ac29e5b07638 100644 --- a/library/core/src/fmt/mod.rs +++ b/library/core/src/fmt/mod.rs @@ -854,7 +854,6 @@ impl Display for Arguments<'_> { /// }"; /// assert_eq!(format!("The origin is: {origin:#?}"), expected); /// ``` - #[stable(feature = "rust1", since = "1.0.0")] #[rustc_on_unimplemented( on( diff --git a/library/core/src/iter/traits/collect.rs b/library/core/src/iter/traits/collect.rs index 3bc9cff8072bf..ab27650067980 100644 --- a/library/core/src/iter/traits/collect.rs +++ b/library/core/src/iter/traits/collect.rs @@ -436,7 +436,6 @@ pub trait Extend { /// **For implementors:** For a collection to unsafely rely on this method's safety precondition (that is, /// invoke UB if they are violated), it must implement `extend_reserve` correctly. In other words, /// callers may assume that if they `extend_reserve`ed enough space they can call this method. - // This method is for internal usage only. It is only on the trait because of specialization's limitations. #[unstable(feature = "extend_one_unchecked", issue = "none")] #[doc(hidden)] diff --git a/library/core/src/iter/traits/iterator.rs b/library/core/src/iter/traits/iterator.rs index f296792b1dcb2..10f9d464f7d7f 100644 --- a/library/core/src/iter/traits/iterator.rs +++ b/library/core/src/iter/traits/iterator.rs @@ -3414,10 +3414,10 @@ pub trait Iterator { /// ``` #[stable(feature = "iter_copied", since = "1.36.0")] #[rustc_diagnostic_item = "iter_copied"] - fn copied<'a, T: 'a>(self) -> Copied + fn copied<'a, T>(self) -> Copied where + T: Copy + 'a, Self: Sized + Iterator, - T: Copy, { Copied::new(self) } @@ -3462,10 +3462,10 @@ pub trait Iterator { /// ``` #[stable(feature = "rust1", since = "1.0.0")] #[rustc_diagnostic_item = "iter_cloned"] - fn cloned<'a, T: 'a>(self) -> Cloned + fn cloned<'a, T>(self) -> Cloned where + T: Clone + 'a, Self: Sized + Iterator, - T: Clone, { Cloned::new(self) } diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs index 729de5ffc8f6e..3c33f4b136844 100644 --- a/library/core/src/lib.rs +++ b/library/core/src/lib.rs @@ -39,9 +39,9 @@ //! return. You should mark your implementation using `#[panic_handler]`. //! //! * `rust_eh_personality` - is used by the failure mechanisms of the -//! compiler. This is often mapped to GCC's personality function, but crates -//! which do not trigger a panic can be assured that this function is never -//! called. The `lang` attribute is called `eh_personality`. +//! compiler. This is often mapped to GCC's personality function, but crates +//! which do not trigger a panic can be assured that this function is never +//! called. The `lang` attribute is called `eh_personality`. #![stable(feature = "core", since = "1.6.0")] #![doc( diff --git a/library/core/src/mem/mod.rs b/library/core/src/mem/mod.rs index 1bd12d818cfe6..2198d098c4be9 100644 --- a/library/core/src/mem/mod.rs +++ b/library/core/src/mem/mod.rs @@ -36,7 +36,7 @@ pub use crate::intrinsics::transmute; /// * If you want to leak memory, see [`Box::leak`]. /// * If you want to obtain a raw pointer to the memory, see [`Box::into_raw`]. /// * If you want to dispose of a value properly, running its destructor, see -/// [`mem::drop`]. +/// [`mem::drop`]. /// /// # Safety /// diff --git a/library/core/src/net/ip_addr.rs b/library/core/src/net/ip_addr.rs index aaa68e8d7d1ad..49a7ae5de5c8f 100644 --- a/library/core/src/net/ip_addr.rs +++ b/library/core/src/net/ip_addr.rs @@ -787,7 +787,6 @@ impl Ipv4Addr { /// [IANA IPv4 Special-Purpose Address Registry]: https://www.iana.org/assignments/iana-ipv4-special-registry/iana-ipv4-special-registry.xhtml /// [unspecified address]: Ipv4Addr::UNSPECIFIED /// [broadcast address]: Ipv4Addr::BROADCAST - /// /// # Examples /// diff --git a/library/core/src/num/int_log10.rs b/library/core/src/num/int_log10.rs index 28a3f5d880ad7..649a736b6e7b5 100644 --- a/library/core/src/num/int_log10.rs +++ b/library/core/src/num/int_log10.rs @@ -1,5 +1,5 @@ -/// These functions compute the integer logarithm of their type, assuming -/// that someone has already checked that the value is strictly positive. +//! These functions compute the integer logarithm of their type, assuming +//! that someone has already checked that the value is strictly positive. // 0 < val <= u8::MAX #[inline] diff --git a/library/core/src/num/uint_macros.rs b/library/core/src/num/uint_macros.rs index ab6823249c3eb..584cd60fbe5cc 100644 --- a/library/core/src/num/uint_macros.rs +++ b/library/core/src/num/uint_macros.rs @@ -556,7 +556,7 @@ macro_rules! uint_impl { pub const fn strict_add(self, rhs: Self) -> Self { let (a, b) = self.overflowing_add(rhs); if b { overflow_panic::add() } else { a } - } + } /// Unchecked integer addition. Computes `self + rhs`, assuming overflow /// cannot occur. @@ -653,7 +653,7 @@ macro_rules! uint_impl { pub const fn strict_add_signed(self, rhs: $SignedT) -> Self { let (a, b) = self.overflowing_add_signed(rhs); if b { overflow_panic::add() } else { a } - } + } /// Checked integer subtraction. Computes `self - rhs`, returning /// `None` if overflow occurred. @@ -713,7 +713,7 @@ macro_rules! uint_impl { pub const fn strict_sub(self, rhs: Self) -> Self { let (a, b) = self.overflowing_sub(rhs); if b { overflow_panic::sub() } else { a } - } + } /// Unchecked integer subtraction. Computes `self - rhs`, assuming overflow /// cannot occur. @@ -805,6 +805,43 @@ macro_rules! uint_impl { } } + /// Strict subtraction with a signed integer. Computes `self - rhs`, + /// panicking if overflow occurred. + /// + /// # Panics + /// + /// ## Overflow behavior + /// + /// This function will always panic on overflow, regardless of whether overflow checks are enabled. + /// + /// # Examples + /// + /// ``` + /// #![feature(strict_overflow_ops)] + #[doc = concat!("assert_eq!(3", stringify!($SelfT), ".strict_sub_signed(2), 1);")] + /// ``` + /// + /// The following panic because of overflow: + /// + /// ```should_panic + /// #![feature(strict_overflow_ops)] + #[doc = concat!("let _ = 1", stringify!($SelfT), ".strict_sub_signed(2);")] + /// ``` + /// + /// ```should_panic + /// #![feature(strict_overflow_ops)] + #[doc = concat!("let _ = (", stringify!($SelfT), "::MAX).strict_sub_signed(-1);")] + /// ``` + #[unstable(feature = "strict_overflow_ops", issue = "118260")] + #[must_use = "this returns the result of the operation, \ + without modifying the original"] + #[inline] + #[track_caller] + pub const fn strict_sub_signed(self, rhs: $SignedT) -> Self { + let (a, b) = self.overflowing_sub_signed(rhs); + if b { overflow_panic::sub() } else { a } + } + #[doc = concat!( "Checked integer subtraction. Computes `self - rhs` and checks if the result fits into an [`", stringify!($SignedT), "`], returning `None` if overflow occurred." @@ -913,7 +950,7 @@ macro_rules! uint_impl { pub const fn strict_mul(self, rhs: Self) -> Self { let (a, b) = self.overflowing_mul(rhs); if b { overflow_panic::mul() } else { a } - } + } /// Unchecked integer multiplication. Computes `self * rhs`, assuming overflow /// cannot occur. diff --git a/library/core/src/primitive_docs.rs b/library/core/src/primitive_docs.rs index 5bd80149a1d6e..9a1ba7d1728cb 100644 --- a/library/core/src/primitive_docs.rs +++ b/library/core/src/primitive_docs.rs @@ -1363,7 +1363,6 @@ mod prim_f16 {} /// x = a + b + c + d; // As written /// x = (a + c) + (b + d); // Reordered to shorten critical path and enable vectorization /// ``` - #[stable(feature = "rust1", since = "1.0.0")] mod prim_f32 {} diff --git a/library/core/src/ptr/docs/as_uninit_slice.md b/library/core/src/ptr/docs/as_uninit_slice.md index c80c04058838f..1113f4748c2df 100644 --- a/library/core/src/ptr/docs/as_uninit_slice.md +++ b/library/core/src/ptr/docs/as_uninit_slice.md @@ -10,24 +10,24 @@ When calling this method, you have to ensure that *either* the pointer is null * all of the following is true: * The pointer must be [valid] for reads for `ptr.len() * size_of::()` many bytes, -and it must be properly aligned. This means in particular: + and it must be properly aligned. This means in particular: * The entire memory range of this slice must be contained within a single [allocation]! -Slices can never span across multiple allocations. + Slices can never span across multiple allocations. * The pointer must be aligned even for zero-length slices. One -reason for this is that enum layout optimizations may rely on references -(including slices of any length) being aligned and non-null to distinguish -them from other data. You can obtain a pointer that is usable as `data` -for zero-length slices using [`NonNull::dangling()`]. + reason for this is that enum layout optimizations may rely on references + (including slices of any length) being aligned and non-null to distinguish + them from other data. You can obtain a pointer that is usable as `data` + for zero-length slices using [`NonNull::dangling()`]. * The total size `ptr.len() * size_of::()` of the slice must be no larger than `isize::MAX`. -See the safety documentation of [`pointer::offset`]. + See the safety documentation of [`pointer::offset`]. * You must enforce Rust's aliasing rules, since the returned lifetime `'a` is -arbitrarily chosen and does not necessarily reflect the actual lifetime of the data. -In particular, while this reference exists, the memory the pointer points to must -not get mutated (except inside `UnsafeCell`). + arbitrarily chosen and does not necessarily reflect the actual lifetime of the data. + In particular, while this reference exists, the memory the pointer points to must + not get mutated (except inside `UnsafeCell`). This applies even if the result of this method is unused! diff --git a/library/core/src/str/mod.rs b/library/core/src/str/mod.rs index 18a516c0f608c..029abf1753913 100644 --- a/library/core/src/str/mod.rs +++ b/library/core/src/str/mod.rs @@ -2651,7 +2651,6 @@ impl str { /// you're trying to parse into. /// /// `parse` can parse into any type that implements the [`FromStr`] trait. - /// /// # Errors /// diff --git a/src/bootstrap/src/core/build_steps/check.rs b/src/bootstrap/src/core/build_steps/check.rs index 1d30886a86aa4..f0acb7f71411a 100644 --- a/src/bootstrap/src/core/build_steps/check.rs +++ b/src/bootstrap/src/core/build_steps/check.rs @@ -355,7 +355,7 @@ impl Step for CodegenBackend { cargo .arg("--manifest-path") .arg(builder.src.join(format!("compiler/rustc_codegen_{backend}/Cargo.toml"))); - rustc_cargo_env(builder, &mut cargo, target, build_compiler.stage); + rustc_cargo_env(builder, &mut cargo, target); let _guard = builder.msg_check(format!("rustc_codegen_{backend}"), target, None); diff --git a/src/bootstrap/src/core/build_steps/compile.rs b/src/bootstrap/src/core/build_steps/compile.rs index 85847cac44632..c7e7b0160b10c 100644 --- a/src/bootstrap/src/core/build_steps/compile.rs +++ b/src/bootstrap/src/core/build_steps/compile.rs @@ -1316,15 +1316,10 @@ pub fn rustc_cargo( cargo.env("RUSTC_WRAPPER", ccache); } - rustc_cargo_env(builder, cargo, target, build_compiler.stage); + rustc_cargo_env(builder, cargo, target); } -pub fn rustc_cargo_env( - builder: &Builder<'_>, - cargo: &mut Cargo, - target: TargetSelection, - build_stage: u32, -) { +pub fn rustc_cargo_env(builder: &Builder<'_>, cargo: &mut Cargo, target: TargetSelection) { // Set some configuration variables picked up by build scripts and // the compiler alike cargo @@ -1379,18 +1374,24 @@ pub fn rustc_cargo_env( cargo.rustflag("--cfg=llvm_enzyme"); } - // Note that this is disabled if LLVM itself is disabled or we're in a check - // build. If we are in a check build we still go ahead here presuming we've - // detected that LLVM is already built and good to go which helps prevent - // busting caches (e.g. like #71152). + // These conditionals represent a tension between three forces: + // - For non-check builds, we need to define some LLVM-related environment + // variables, requiring LLVM to have been built. + // - For check builds, we want to avoid building LLVM if possible. + // - Check builds and non-check builds should have the same environment if + // possible, to avoid unnecessary rebuilds due to cache-busting. + // + // Therefore we try to avoid building LLVM for check builds, but only if + // building LLVM would be expensive. If "building" LLVM is cheap + // (i.e. it's already built or is downloadable), we prefer to maintain a + // consistent environment between check and non-check builds. if builder.config.llvm_enabled(target) { - let building_is_expensive = + let building_llvm_is_expensive = crate::core::build_steps::llvm::prebuilt_llvm_config(builder, target, false) .should_build(); - // `top_stage == stage` might be false for `check --stage 1`, if we are building the stage 1 compiler - let can_skip_build = builder.kind == Kind::Check && builder.top_stage == build_stage; - let should_skip_build = building_is_expensive && can_skip_build; - if !should_skip_build { + + let skip_llvm = (builder.kind == Kind::Check) && building_llvm_is_expensive; + if !skip_llvm { rustc_llvm_env(builder, cargo, target) } } @@ -1407,6 +1408,9 @@ pub fn rustc_cargo_env( /// Pass down configuration from the LLVM build into the build of /// rustc_llvm and rustc_codegen_llvm. +/// +/// Note that this has the side-effect of _building LLVM_, which is sometimes +/// unwanted (e.g. for check builds). fn rustc_llvm_env(builder: &Builder<'_>, cargo: &mut Cargo, target: TargetSelection) { if builder.config.is_rust_llvm(target) { cargo.env("LLVM_RUSTLLVM", "1"); @@ -1665,7 +1669,7 @@ impl Step for CodegenBackend { cargo .arg("--manifest-path") .arg(builder.src.join(format!("compiler/rustc_codegen_{backend}/Cargo.toml"))); - rustc_cargo_env(builder, &mut cargo, target, compiler.stage); + rustc_cargo_env(builder, &mut cargo, target); // Ideally, we'd have a separate step for the individual codegen backends, // like we have in tests (test::CodegenGCC) but that would require a lot of restructuring. diff --git a/src/bootstrap/src/core/build_steps/test.rs b/src/bootstrap/src/core/build_steps/test.rs index 98f1111627949..00134177966bb 100644 --- a/src/bootstrap/src/core/build_steps/test.rs +++ b/src/bootstrap/src/core/build_steps/test.rs @@ -1810,7 +1810,24 @@ NOTE: if you're sure you want to do this, please open an issue as to why. In the } let mut flags = if is_rustdoc { Vec::new() } else { vec!["-Crpath".to_string()] }; - flags.push(format!("-Cdebuginfo={}", builder.config.rust_debuginfo_level_tests)); + flags.push(format!( + "-Cdebuginfo={}", + if suite == "codegen" { + // codegen tests typically check LLVM IR and are sensitive to additional debuginfo. + // So do not apply `rust.debuginfo-level-tests` for codegen tests. + if builder.config.rust_debuginfo_level_tests + != crate::core::config::DebuginfoLevel::None + { + println!( + "NOTE: ignoring `rust.debuginfo-level-tests={}` for codegen tests", + builder.config.rust_debuginfo_level_tests + ); + } + crate::core::config::DebuginfoLevel::None + } else { + builder.config.rust_debuginfo_level_tests + } + )); flags.extend(builder.config.cmd.compiletest_rustc_args().iter().map(|s| s.to_string())); if suite != "mir-opt" { @@ -3387,7 +3404,7 @@ impl Step for CodegenCranelift { cargo .arg("--manifest-path") .arg(builder.src.join("compiler/rustc_codegen_cranelift/build_system/Cargo.toml")); - compile::rustc_cargo_env(builder, &mut cargo, target, compiler.stage); + compile::rustc_cargo_env(builder, &mut cargo, target); // Avoid incremental cache issues when changing rustc cargo.env("CARGO_BUILD_INCREMENTAL", "false"); @@ -3519,7 +3536,7 @@ impl Step for CodegenGCC { cargo .arg("--manifest-path") .arg(builder.src.join("compiler/rustc_codegen_gcc/build_system/Cargo.toml")); - compile::rustc_cargo_env(builder, &mut cargo, target, compiler.stage); + compile::rustc_cargo_env(builder, &mut cargo, target); add_cg_gcc_cargo_flags(&mut cargo, &gcc); // Avoid incremental cache issues when changing rustc diff --git a/src/bootstrap/src/core/builder/tests.rs b/src/bootstrap/src/core/builder/tests.rs index 2f8cdd2f8c88f..e60a115b19d68 100644 --- a/src/bootstrap/src/core/builder/tests.rs +++ b/src/bootstrap/src/core/builder/tests.rs @@ -712,7 +712,11 @@ mod snapshot { [build] llvm [build] rustc 0 -> rustc 1 "); + } + #[test] + fn build_rustc_no_explicit_stage() { + let ctx = TestCtx::new(); insta::assert_snapshot!( ctx.config("build") .path("rustc") @@ -1303,17 +1307,19 @@ mod snapshot { ctx.config("check") .path("compiler") .render_steps(), @r" - [build] llvm [check] rustc 0 -> rustc 1 [check] rustc 0 -> cranelift 1 [check] rustc 0 -> gcc 1 "); + } + #[test] + fn check_rustc_no_explicit_stage() { + let ctx = TestCtx::new(); insta::assert_snapshot!( ctx.config("check") .path("rustc") .render_steps(), @r" - [build] llvm [check] rustc 0 -> rustc 1 "); } @@ -1333,7 +1339,6 @@ mod snapshot { .path("compiler") .stage(1) .render_steps(), @r" - [build] llvm [check] rustc 0 -> rustc 1 [check] rustc 0 -> cranelift 1 [check] rustc 0 -> gcc 1 @@ -1465,7 +1470,6 @@ mod snapshot { .paths(&["library", "compiler"]) .args(&args) .render_steps(), @r" - [build] llvm [check] rustc 0 -> rustc 1 [check] rustc 0 -> cranelift 1 [check] rustc 0 -> gcc 1 @@ -1479,7 +1483,6 @@ mod snapshot { ctx.config("check") .path("miri") .render_steps(), @r" - [build] llvm [check] rustc 0 -> rustc 1 [check] rustc 0 -> Miri 1 "); @@ -1500,7 +1503,6 @@ mod snapshot { .path("miri") .stage(1) .render_steps(), @r" - [build] llvm [check] rustc 0 -> rustc 1 [check] rustc 0 -> Miri 1 "); @@ -1553,7 +1555,6 @@ mod snapshot { ctx.config("check") .path("rustc_codegen_cranelift") .render_steps(), @r" - [build] llvm [check] rustc 0 -> rustc 1 [check] rustc 0 -> cranelift 1 [check] rustc 0 -> gcc 1 @@ -1567,7 +1568,6 @@ mod snapshot { ctx.config("check") .path("rust-analyzer") .render_steps(), @r" - [build] llvm [check] rustc 0 -> rustc 1 [check] rustc 0 -> rust-analyzer 1 "); diff --git a/src/tools/miri/tests/panic/mir-validation.stderr b/src/tools/miri/tests/panic/mir-validation.stderr index dc70d129da3c3..f801ac907e6b8 100644 --- a/src/tools/miri/tests/panic/mir-validation.stderr +++ b/src/tools/miri/tests/panic/mir-validation.stderr @@ -1,11 +1,15 @@ +error: internal compiler error: compiler/rustc_mir_transform/src/validate.rs:LL:CC: broken MIR in Item(DefId) (after phase change to runtime-optimized) at bb0[1]: + place (*(_2.0: *mut i32)) has deref as a later projection (it is only permitted as the first projection) + --> tests/panic/mir-validation.rs:LL:CC + | +LL | *(tuple.0) = 1; + | ^^^^^^^^^^^^^^ + thread 'rustc' panicked at compiler/rustc_mir_transform/src/validate.rs:LL:CC: -broken MIR in Item(DefId) (after phase change to runtime-optimized) at bb0[1]: -place (*(_2.0: *mut i32)) has deref as a later projection (it is only permitted as the first projection) +Box stack backtrace: -error: the compiler unexpectedly panicked. this is a bug. - @@ -20,3 +24,5 @@ LL | extern "rust-call" fn call_once(self, args: Args) -> Self::Output; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | +error: aborting due to 1 previous error + diff --git a/tests/assembly/cstring-merging.rs b/tests/assembly/cstring-merging.rs index f7d0775f7affd..03688e0068b79 100644 --- a/tests/assembly/cstring-merging.rs +++ b/tests/assembly/cstring-merging.rs @@ -2,7 +2,7 @@ // other architectures (including ARM and x86-64) use the prefix `.Lanon.` //@ only-linux //@ assembly-output: emit-asm -//@ compile-flags: --crate-type=lib -Copt-level=3 +//@ compile-flags: --crate-type=lib -Copt-level=3 -Cllvm-args=-enable-global-merge=0 //@ edition: 2024 use std::ffi::CStr; diff --git a/tests/codegen/repeat-operand-zero-len.rs b/tests/codegen/repeat-operand-zero-len.rs new file mode 100644 index 0000000000000..b4cec42a07c5c --- /dev/null +++ b/tests/codegen/repeat-operand-zero-len.rs @@ -0,0 +1,28 @@ +//@ compile-flags: -Copt-level=1 -Cno-prepopulate-passes + +// This test is here to hit the `Rvalue::Repeat` case in `codegen_rvalue_operand`. +// It only applies when the resulting array is a ZST, so the test is written in +// such a way as to keep MIR optimizations from seeing that fact and removing +// the local and statement altogether. (At the time of writing, no other codegen +// test hit that code path, nor did a stage 2 build of the compiler.) + +#![crate_type = "lib"] + +#[repr(transparent)] +pub struct Wrapper([T; N]); + +// CHECK-LABEL: define {{.+}}do_repeat{{.+}}(i32 noundef %x) +// CHECK-NEXT: start: +// CHECK-NOT: alloca +// CHECK-NEXT: ret void +#[inline(never)] +pub fn do_repeat(x: T) -> Wrapper { + Wrapper([x; N]) +} + +// CHECK-LABEL: @trigger_repeat_zero_len +#[no_mangle] +pub fn trigger_repeat_zero_len() -> Wrapper { + // CHECK: call void {{.+}}do_repeat{{.+}}(i32 noundef 4) + do_repeat(4) +} diff --git a/tests/codegen/repeat-operand-zst-elem.rs b/tests/codegen/repeat-operand-zst-elem.rs new file mode 100644 index 0000000000000..c3637759afa34 --- /dev/null +++ b/tests/codegen/repeat-operand-zst-elem.rs @@ -0,0 +1,28 @@ +//@ compile-flags: -Copt-level=1 -Cno-prepopulate-passes + +// This test is here to hit the `Rvalue::Repeat` case in `codegen_rvalue_operand`. +// It only applies when the resulting array is a ZST, so the test is written in +// such a way as to keep MIR optimizations from seeing that fact and removing +// the local and statement altogether. (At the time of writing, no other codegen +// test hit that code path, nor did a stage 2 build of the compiler.) + +#![crate_type = "lib"] + +#[repr(transparent)] +pub struct Wrapper([T; N]); + +// CHECK-LABEL: define {{.+}}do_repeat{{.+}}() +// CHECK-NEXT: start: +// CHECK-NOT: alloca +// CHECK-NEXT: ret void +#[inline(never)] +pub fn do_repeat(x: T) -> Wrapper { + Wrapper([x; N]) +} + +// CHECK-LABEL: @trigger_repeat_zst_elem +#[no_mangle] +pub fn trigger_repeat_zst_elem() -> Wrapper<(), 8> { + // CHECK: call void {{.+}}do_repeat{{.+}}() + do_repeat(()) +} diff --git a/tests/ui/cfg/crt-static-with-target-features-works.rs b/tests/ui/cfg/crt-static-with-target-features-works.rs new file mode 100644 index 0000000000000..bce022296245f --- /dev/null +++ b/tests/ui/cfg/crt-static-with-target-features-works.rs @@ -0,0 +1,24 @@ +// Test to ensure that specifying a value for crt-static in target features +// does not result in skipping the features following it. +// This is a regression test for #144143 + +//@ add-core-stubs +//@ needs-llvm-components: x86 +//@ compile-flags: --target=x86_64-unknown-linux-gnu +//@ compile-flags: -Ctarget-feature=+crt-static,+avx2 + +#![crate_type = "rlib"] +#![feature(no_core, rustc_attrs, lang_items)] +#![no_core] + +extern crate minicore; +use minicore::*; + +#[rustc_builtin_macro] +macro_rules! compile_error { + () => {}; +} + +#[cfg(target_feature = "avx2")] +compile_error!("+avx2"); +//~^ ERROR: +avx2 diff --git a/tests/ui/cfg/crt-static-with-target-features-works.stderr b/tests/ui/cfg/crt-static-with-target-features-works.stderr new file mode 100644 index 0000000000000..6f265c685bb9f --- /dev/null +++ b/tests/ui/cfg/crt-static-with-target-features-works.stderr @@ -0,0 +1,8 @@ +error: +avx2 + --> $DIR/crt-static-with-target-features-works.rs:23:1 + | +LL | compile_error!("+avx2"); + | ^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 1 previous error + diff --git a/tests/ui/mir/validate/critical-edge.rs b/tests/ui/mir/validate/critical-edge.rs index 2a3bf6a6181b4..7fe3891d6424e 100644 --- a/tests/ui/mir/validate/critical-edge.rs +++ b/tests/ui/mir/validate/critical-edge.rs @@ -21,6 +21,8 @@ pub fn f(a: u32) -> u32 { } bb1 = { Call(RET = f(1), ReturnTo(bb2), UnwindTerminate(ReasonAbi)) +//~^ ERROR broken MIR in Item +//~| ERROR encountered critical edge in `Call` terminator } bb2 = { @@ -29,5 +31,3 @@ pub fn f(a: u32) -> u32 { } } } - -//~? RAW encountered critical edge in `Call` terminator