From eb729380499b12cb539d665221d5930a06467024 Mon Sep 17 00:00:00 2001 From: Markus Mayer Date: Wed, 22 May 2024 11:07:08 +0200 Subject: [PATCH 01/50] Add FRAC_1_SQRT_2PI constant to f16/f32/f64/f128 --- library/core/src/num/f128.rs | 6 ++++++ library/core/src/num/f16.rs | 5 +++++ library/core/src/num/f32.rs | 4 ++++ library/core/src/num/f64.rs | 4 ++++ 4 files changed, 19 insertions(+) diff --git a/library/core/src/num/f128.rs b/library/core/src/num/f128.rs index 9362dc876549..75eed2648588 100644 --- a/library/core/src/num/f128.rs +++ b/library/core/src/num/f128.rs @@ -68,6 +68,12 @@ pub mod consts { pub const FRAC_1_SQRT_PI: f128 = 0.564189583547756286948079451560772585844050629328998856844086_f128; + /// 1/sqrt(2π) + #[unstable(feature = "f128", issue = "116909")] + // Also, #[unstable(feature = "more_float_constants", issue = "103883")] + pub const FRAC_1_SQRT_2PI: f128 = + 0.398942280401432677939946059934381868475858631164934657665926_f128; + /// 2/π #[unstable(feature = "f128", issue = "116909")] pub const FRAC_2_PI: f128 = 0.636619772367581343075535053490057448137838582961825794990669_f128; diff --git a/library/core/src/num/f16.rs b/library/core/src/num/f16.rs index c4d4584544ba..955314516a4a 100644 --- a/library/core/src/num/f16.rs +++ b/library/core/src/num/f16.rs @@ -67,6 +67,11 @@ pub mod consts { // Also, #[unstable(feature = "more_float_constants", issue = "103883")] pub const FRAC_1_SQRT_PI: f16 = 0.564189583547756286948079451560772586_f16; + /// 1/sqrt(2π) + #[unstable(feature = "f16", issue = "116909")] + // Also, #[unstable(feature = "more_float_constants", issue = "103883")] + pub const FRAC_1_SQRT_2PI: f16 = 0.398942280401432677939946059934381868_f16; + /// 2/π #[unstable(feature = "f16", issue = "116909")] pub const FRAC_2_PI: f16 = 0.636619772367581343075535053490057448_f16; diff --git a/library/core/src/num/f32.rs b/library/core/src/num/f32.rs index 2e715fb0bdde..8c591af3c0d0 100644 --- a/library/core/src/num/f32.rs +++ b/library/core/src/num/f32.rs @@ -327,6 +327,10 @@ pub mod consts { #[unstable(feature = "more_float_constants", issue = "103883")] pub const FRAC_1_SQRT_PI: f32 = 0.564189583547756286948079451560772586_f32; + /// 1/sqrt(2π) + #[unstable(feature = "more_float_constants", issue = "103883")] + pub const FRAC_1_SQRT_2PI: f32 = 0.398942280401432677939946059934381868_f32; + /// 2/π #[stable(feature = "rust1", since = "1.0.0")] pub const FRAC_2_PI: f32 = 0.636619772367581343075535053490057448_f32; diff --git a/library/core/src/num/f64.rs b/library/core/src/num/f64.rs index db8e1f318adb..db458c4375ce 100644 --- a/library/core/src/num/f64.rs +++ b/library/core/src/num/f64.rs @@ -327,6 +327,10 @@ pub mod consts { #[unstable(feature = "more_float_constants", issue = "103883")] pub const FRAC_1_SQRT_PI: f64 = 0.564189583547756286948079451560772586_f64; + /// 1/sqrt(2π) + #[unstable(feature = "more_float_constants", issue = "103883")] + pub const FRAC_1_SQRT_2PI: f64 = 0.398942280401432677939946059934381868_f64; + /// 2/π #[stable(feature = "rust1", since = "1.0.0")] pub const FRAC_2_PI: f64 = 0.636619772367581343075535053490057448_f64; From 54bb08d53881da7c43b91fd5a6bd8ef9a3b754e6 Mon Sep 17 00:00:00 2001 From: Markus Mayer Date: Wed, 29 May 2024 14:58:34 +0200 Subject: [PATCH 02/50] Add FRAC_1_SQRT_2PI doc alias to FRAC_1_SQRT_TAU This is create symmetry between the already existing TAU constant (2pi) and the newly-introduced FRAC_1_SQRT_2PI, keeping the more common name while increasing visibility. --- library/core/src/num/f128.rs | 1 + library/core/src/num/f16.rs | 1 + library/core/src/num/f32.rs | 1 + library/core/src/num/f64.rs | 1 + 4 files changed, 4 insertions(+) diff --git a/library/core/src/num/f128.rs b/library/core/src/num/f128.rs index 75eed2648588..129f62fb43d1 100644 --- a/library/core/src/num/f128.rs +++ b/library/core/src/num/f128.rs @@ -69,6 +69,7 @@ pub mod consts { 0.564189583547756286948079451560772585844050629328998856844086_f128; /// 1/sqrt(2π) + #[doc(alias = "FRAC_1_SQRT_TAU")] #[unstable(feature = "f128", issue = "116909")] // Also, #[unstable(feature = "more_float_constants", issue = "103883")] pub const FRAC_1_SQRT_2PI: f128 = diff --git a/library/core/src/num/f16.rs b/library/core/src/num/f16.rs index 955314516a4a..7a488cd6bf6f 100644 --- a/library/core/src/num/f16.rs +++ b/library/core/src/num/f16.rs @@ -68,6 +68,7 @@ pub mod consts { pub const FRAC_1_SQRT_PI: f16 = 0.564189583547756286948079451560772586_f16; /// 1/sqrt(2π) + #[doc(alias = "FRAC_1_SQRT_TAU")] #[unstable(feature = "f16", issue = "116909")] // Also, #[unstable(feature = "more_float_constants", issue = "103883")] pub const FRAC_1_SQRT_2PI: f16 = 0.398942280401432677939946059934381868_f16; diff --git a/library/core/src/num/f32.rs b/library/core/src/num/f32.rs index 8c591af3c0d0..8e9c7b4d11f3 100644 --- a/library/core/src/num/f32.rs +++ b/library/core/src/num/f32.rs @@ -328,6 +328,7 @@ pub mod consts { pub const FRAC_1_SQRT_PI: f32 = 0.564189583547756286948079451560772586_f32; /// 1/sqrt(2π) + #[doc(alias = "FRAC_1_SQRT_TAU")] #[unstable(feature = "more_float_constants", issue = "103883")] pub const FRAC_1_SQRT_2PI: f32 = 0.398942280401432677939946059934381868_f32; diff --git a/library/core/src/num/f64.rs b/library/core/src/num/f64.rs index db458c4375ce..5247897437a0 100644 --- a/library/core/src/num/f64.rs +++ b/library/core/src/num/f64.rs @@ -328,6 +328,7 @@ pub mod consts { pub const FRAC_1_SQRT_PI: f64 = 0.564189583547756286948079451560772586_f64; /// 1/sqrt(2π) + #[doc(alias = "FRAC_1_SQRT_TAU")] #[unstable(feature = "more_float_constants", issue = "103883")] pub const FRAC_1_SQRT_2PI: f64 = 0.398942280401432677939946059934381868_f64; From fb6fbf02a65ad1fc766aeee7c7698907d56f8e12 Mon Sep 17 00:00:00 2001 From: Jubilee Young Date: Tue, 4 Jun 2024 01:22:46 -0700 Subject: [PATCH 03/50] Use FileCheck to parameterize codegen tests over hashes When things like our internal hashing or representations change, it is inappropriate for these tests to suddenly fail for no reason. The chance of error is reduced if we instead pattern-match. --- tests/assembly/asm/global_asm.rs | 4 ++-- tests/codegen/consts.rs | 4 ++-- tests/codegen/pattern_type_symbols.rs | 4 ++-- tests/codegen/virtual-function-elimination.rs | 4 ++-- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/tests/assembly/asm/global_asm.rs b/tests/assembly/asm/global_asm.rs index 8f824563e8ae..22cf4bdb15b7 100644 --- a/tests/assembly/asm/global_asm.rs +++ b/tests/assembly/asm/global_asm.rs @@ -25,9 +25,9 @@ global_asm!("movl ${}, %ecx", const 5, options(att_syntax)); global_asm!("call {}", sym my_func); // CHECK: lea rax, [rip + MY_STATIC] global_asm!("lea rax, [rip + {}]", sym MY_STATIC); -// CHECK: call _RNvCsddMtV7nAi4C_10global_asm6foobar +// CHECK: call _RNvC[[CRATE_IDENT:[a-zA-Z0-9]{12}]]_10global_asm6foobar global_asm!("call {}", sym foobar); -// CHECK: _RNvCsddMtV7nAi4C_10global_asm6foobar: +// CHECK: _RNvC[[CRATE_IDENT]]_10global_asm6foobar: fn foobar() { loop {} } diff --git a/tests/codegen/consts.rs b/tests/codegen/consts.rs index 93c58c37c287..42ce7679d1ac 100644 --- a/tests/codegen/consts.rs +++ b/tests/codegen/consts.rs @@ -9,11 +9,11 @@ // CHECK: @STATIC = {{.*}}, align 4 // This checks the constants from inline_enum_const -// CHECK: @alloc_af1f8e8e6f4b341431a1d405e652df2d = {{.*}}, align 2 +// CHECK: @alloc_[[INLINE_ENUM_HASH:[a-f0-9]{32}]] = {{.*}}, align 2 // This checks the constants from {low,high}_align_const, they share the same // constant, but the alignment differs, so the higher one should be used -// CHECK: [[LOW_HIGH:@alloc_[a-f0-9]+]] = {{.*}}, align 4 +// CHECK: [[LOW_HIGH:@alloc_[a-f0-9]{32}]] = {{.*}}, align 4 #[derive(Copy, Clone)] // repr(i16) is required for the {low,high}_align_const test diff --git a/tests/codegen/pattern_type_symbols.rs b/tests/codegen/pattern_type_symbols.rs index dfe834433487..a99b3efca415 100644 --- a/tests/codegen/pattern_type_symbols.rs +++ b/tests/codegen/pattern_type_symbols.rs @@ -15,9 +15,9 @@ fn foo() {} pub fn bar() { // CHECK: call pattern_type_symbols::foo:: - // CHECK: call void @_RINvCs3QvG2ESzx2Q_20pattern_type_symbols3foomEB2_ + // CHECK: call void @_RINvC[[CRATE_IDENT:[a-zA-Z0-9]{12}]]_20pattern_type_symbols3foomEB2_ foo::(); // CHECK: call pattern_type_symbols::foo::<(u32, [(); 0], [(); 999999999], [(); true])> - // CHECK: call void @_RINvCs3QvG2ESzx2Q_20pattern_type_symbols3fooTmAum0_Aum3b9ac9ff_Aub1_EEB2_ + // CHECK: call void @_RINvC[[CRATE_IDENT]]_20pattern_type_symbols3fooTmAum0_Aum3b9ac9ff_Aub1_EEB2_ foo::(); } diff --git a/tests/codegen/virtual-function-elimination.rs b/tests/codegen/virtual-function-elimination.rs index 6c391d9114b4..23d7657baa99 100644 --- a/tests/codegen/virtual-function-elimination.rs +++ b/tests/codegen/virtual-function-elimination.rs @@ -81,7 +81,7 @@ fn taking_u(u: &dyn U) -> i32 { } pub fn taking_v(v: &dyn V) -> i32 { - // CHECK: @llvm.type.checked.load({{.*}}, i32 24, metadata !"NtCs64ITQYi9761_28virtual_function_elimination1V") + // CHECK: @llvm.type.checked.load({{.*}}, i32 24, metadata !"NtC[[CRATE_IDENT:[a-zA-Z0-9]{12}]]_28virtual_function_elimination1V") v.public_function() } @@ -96,5 +96,5 @@ pub fn main() { // CHECK: ![[TYPE0]] = !{i64 0, !"[[MANGLED_TYPE0]]"} // CHECK: ![[VCALL_VIS0]] = !{i64 2} // CHECK: ![[TYPE1]] = !{i64 0, !"[[MANGLED_TYPE1]]"} -// CHECK: ![[TYPE2]] = !{i64 0, !"NtCs64ITQYi9761_28virtual_function_elimination1V"} +// CHECK: ![[TYPE2]] = !{i64 0, !"NtC[[CRATE_IDENT]]_28virtual_function_elimination1V"} // CHECK: ![[VCALL_VIS2]] = !{i64 1} From dca68e93908ab3a3e0277b198a32bff33e847788 Mon Sep 17 00:00:00 2001 From: Alan Wu Date: Tue, 4 Jun 2024 12:19:17 -0400 Subject: [PATCH 04/50] ci: use GCC 13 as cross compiler in `dist-aarch64-linux` I'm proposing this GCC upgrade since it addresses bug #125619. The regression in question affects stable release consumers who tend to have no exposure to Rust build tools, so if at all possible, I would like to have it resolved in the next stable release. I have tried to fix the bug in `compiler-builtins`, which led to submitting a PR for `compiler-rt` in upstream LLVM, but it may take a long time before these upstreams address this regression. A summary of why upgrading GCC solves the regression follows. `__multc3()` is a builtin function `compiler-builtins` exposes for specifically aarch64, non-Windows targets [1]. The object file for it is included in `staticlib` archives through `libstd`. The implementation for `__multc3()` is from `multc3.c`, part of LLVM's `compiler-rt`. Upstream `compiler-rt` normally builds the C file using the Clang from the same LLVM version. On the other hand, `compiler-builtins` builds the C file using GCC, outside of the usual LLVM build system. The upstream implementation doesn't have feature detection which works for GCC version older than 10, and ends up producing an unlinkable object. Upstream LLVM might be slow to respond to this issue as they might deem `compiler-builtin` as doing something out of the ordinary from their perspective. They might reasonably assume everyone builds `compiler-rt` through LLVM's build system. I have done the following to test this change: - verified that a local build without this patch exhibits the regression. - verified that with this patch, the object for `__multc3()` has no reference to undefined functions in the symbol table. - verified that with this patch, `rustc` is usable to build Ruby with YJIT, and that the reported regression is resolved. [1]: https://github.com/rust-lang/compiler-builtins/blob/c04eb9e1afb72bdf943f5e5d77b3812f40526602/build.rs#L524-L539 --- src/ci/docker/README.md | 2 +- .../host-x86_64/dist-aarch64-linux/aarch64-linux-gnu.defconfig | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/src/ci/docker/README.md b/src/ci/docker/README.md index 9af368ef4450..824c904e17f7 100644 --- a/src/ci/docker/README.md +++ b/src/ci/docker/README.md @@ -233,7 +233,7 @@ For targets: `aarch64-unknown-linux-gnu` - Operating System > Linux kernel version = 4.1.49 - Binary utilities > Version of binutils = 2.29.1 - C-library > glibc version = 2.17 -- aarch64 support was introduced in this version -- C compiler > gcc version = 8.5.0 +- C compiler > gcc version = 13.2.0 - C compiler > C++ = ENABLE -- to cross compile LLVM ### `i586-linux-gnu.defconfig` diff --git a/src/ci/docker/host-x86_64/dist-aarch64-linux/aarch64-linux-gnu.defconfig b/src/ci/docker/host-x86_64/dist-aarch64-linux/aarch64-linux-gnu.defconfig index 47e984ef85a2..520b1667c8be 100644 --- a/src/ci/docker/host-x86_64/dist-aarch64-linux/aarch64-linux-gnu.defconfig +++ b/src/ci/docker/host-x86_64/dist-aarch64-linux/aarch64-linux-gnu.defconfig @@ -6,7 +6,5 @@ CT_ARCH_ARM=y CT_ARCH_64=y CT_KERNEL_LINUX=y CT_LINUX_V_4_1=y -CT_BINUTILS_V_2_29=y CT_GLIBC_V_2_17=y -CT_GCC_V_8=y CT_CC_LANG_CXX=y From 8a0f1957982a6042ec550147243f811f25889d9c Mon Sep 17 00:00:00 2001 From: Weihang Lo Date: Thu, 23 May 2024 16:48:52 -0400 Subject: [PATCH 05/50] docs: add README.md for build_helper --- src/tools/build_helper/README.md | 1 + src/tools/build_helper/src/lib.rs | 2 ++ 2 files changed, 3 insertions(+) create mode 100644 src/tools/build_helper/README.md diff --git a/src/tools/build_helper/README.md b/src/tools/build_helper/README.md new file mode 100644 index 000000000000..f81b631c3fdb --- /dev/null +++ b/src/tools/build_helper/README.md @@ -0,0 +1 @@ +Types and functions shared across tools in this workspace. diff --git a/src/tools/build_helper/src/lib.rs b/src/tools/build_helper/src/lib.rs index 2abda5d3ebf2..d831cfa0d79a 100644 --- a/src/tools/build_helper/src/lib.rs +++ b/src/tools/build_helper/src/lib.rs @@ -1,3 +1,5 @@ +//! Types and functions shared across tools in this workspace. + pub mod ci; pub mod git; pub mod metrics; From 021ccf6c4ed0ae32f66b06a06f542c83f4e81670 Mon Sep 17 00:00:00 2001 From: Scott McMurray Date: Sun, 12 May 2024 00:22:42 -0700 Subject: [PATCH 06/50] Enable GVN for `AggregateKind::RawPtr` & `UnOp::PtrMetadata` --- compiler/rustc_mir_transform/src/gvn.rs | 99 ++++++++++++++++--- ...ore_aggregate_raw_ptr.GVN.panic-abort.diff | 60 +++++++++++ ...re_aggregate_raw_ptr.GVN.panic-unwind.diff | 60 +++++++++++ ....meta_of_ref_to_slice.GVN.panic-abort.diff | 32 ++++++ ...meta_of_ref_to_slice.GVN.panic-unwind.diff | 32 ++++++ tests/mir-opt/gvn.rs | 40 ++++++++ ...vn.slice_const_length.GVN.panic-abort.diff | 48 +++++++++ ...n.slice_const_length.GVN.panic-unwind.diff | 48 +++++++++ ...from_raw_parts_as_ptr.GVN.panic-abort.diff | 51 ++++++++++ ...rom_raw_parts_as_ptr.GVN.panic-unwind.diff | 51 ++++++++++ ...e_add_fat.PreCodegen.after.panic-abort.mir | 10 +- ..._add_fat.PreCodegen.after.panic-unwind.mir | 10 +- ..._add_thin.PreCodegen.after.panic-abort.mir | 2 + ...add_thin.PreCodegen.after.panic-unwind.mir | 2 + 14 files changed, 519 insertions(+), 26 deletions(-) create mode 100644 tests/mir-opt/gvn.casts_before_aggregate_raw_ptr.GVN.panic-abort.diff create mode 100644 tests/mir-opt/gvn.casts_before_aggregate_raw_ptr.GVN.panic-unwind.diff create mode 100644 tests/mir-opt/gvn.meta_of_ref_to_slice.GVN.panic-abort.diff create mode 100644 tests/mir-opt/gvn.meta_of_ref_to_slice.GVN.panic-unwind.diff create mode 100644 tests/mir-opt/gvn.slice_const_length.GVN.panic-abort.diff create mode 100644 tests/mir-opt/gvn.slice_const_length.GVN.panic-unwind.diff create mode 100644 tests/mir-opt/gvn.slice_from_raw_parts_as_ptr.GVN.panic-abort.diff create mode 100644 tests/mir-opt/gvn.slice_from_raw_parts_as_ptr.GVN.panic-unwind.diff diff --git a/compiler/rustc_mir_transform/src/gvn.rs b/compiler/rustc_mir_transform/src/gvn.rs index acde16fcb757..aba5ec8813a6 100644 --- a/compiler/rustc_mir_transform/src/gvn.rs +++ b/compiler/rustc_mir_transform/src/gvn.rs @@ -83,8 +83,8 @@ //! that contain `AllocId`s. use rustc_const_eval::const_eval::DummyMachine; -use rustc_const_eval::interpret::{intern_const_alloc_for_constprop, MemoryKind}; -use rustc_const_eval::interpret::{ImmTy, InterpCx, OpTy, Projectable, Scalar}; +use rustc_const_eval::interpret::{intern_const_alloc_for_constprop, MemPlaceMeta, MemoryKind}; +use rustc_const_eval::interpret::{ImmTy, Immediate, InterpCx, OpTy, Projectable, Scalar}; use rustc_data_structures::fx::FxIndexSet; use rustc_data_structures::graph::dominators::Dominators; use rustc_hir::def::DefKind; @@ -99,7 +99,7 @@ use rustc_middle::ty::layout::LayoutOf; use rustc_middle::ty::{self, Ty, TyCtxt}; use rustc_span::def_id::DefId; use rustc_span::DUMMY_SP; -use rustc_target::abi::{self, Abi, Size, VariantIdx, FIRST_VARIANT}; +use rustc_target::abi::{self, Abi, FieldIdx, Size, VariantIdx, FIRST_VARIANT}; use smallvec::SmallVec; use std::borrow::Cow; @@ -177,6 +177,12 @@ enum AggregateTy<'tcx> { Array, Tuple, Def(DefId, ty::GenericArgsRef<'tcx>), + RawPtr { + /// Needed for cast propagation. + data_pointer_ty: Ty<'tcx>, + /// The data pointer can be anything thin, so doesn't determine the output. + output_pointer_ty: Ty<'tcx>, + }, } #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] @@ -385,11 +391,22 @@ impl<'body, 'tcx> VnState<'body, 'tcx> { AggregateTy::Def(def_id, args) => { self.tcx.type_of(def_id).instantiate(self.tcx, args) } + AggregateTy::RawPtr { output_pointer_ty, .. } => output_pointer_ty, }; let variant = if ty.is_enum() { Some(variant) } else { None }; let ty = self.ecx.layout_of(ty).ok()?; if ty.is_zst() { ImmTy::uninit(ty).into() + } else if matches!(kind, AggregateTy::RawPtr { .. }) { + // Pointers don't have fields, so don't `project_field` them. + let data = self.ecx.read_pointer(fields[0]).ok()?; + let meta = if fields[1].layout.is_zst() { + MemPlaceMeta::None + } else { + MemPlaceMeta::Meta(self.ecx.read_scalar(fields[1]).ok()?) + }; + let ptr_imm = Immediate::new_pointer_with_meta(data, meta, &self.ecx); + ImmTy::from_immediate(ptr_imm, ty).into() } else if matches!(ty.abi, Abi::Scalar(..) | Abi::ScalarPair(..)) { let dest = self.ecx.allocate(ty, MemoryKind::Stack).ok()?; let variant_dest = if let Some(variant) = variant { @@ -862,10 +879,10 @@ impl<'body, 'tcx> VnState<'body, 'tcx> { rvalue: &mut Rvalue<'tcx>, location: Location, ) -> Option { - let Rvalue::Aggregate(box ref kind, ref mut fields) = *rvalue else { bug!() }; + let Rvalue::Aggregate(box ref kind, ref mut field_ops) = *rvalue else { bug!() }; let tcx = self.tcx; - if fields.is_empty() { + if field_ops.is_empty() { let is_zst = match *kind { AggregateKind::Array(..) | AggregateKind::Tuple @@ -884,13 +901,13 @@ impl<'body, 'tcx> VnState<'body, 'tcx> { } } - let (ty, variant_index) = match *kind { + let (mut ty, variant_index) = match *kind { AggregateKind::Array(..) => { - assert!(!fields.is_empty()); + assert!(!field_ops.is_empty()); (AggregateTy::Array, FIRST_VARIANT) } AggregateKind::Tuple => { - assert!(!fields.is_empty()); + assert!(!field_ops.is_empty()); (AggregateTy::Tuple, FIRST_VARIANT) } AggregateKind::Closure(did, args) @@ -901,15 +918,49 @@ impl<'body, 'tcx> VnState<'body, 'tcx> { } // Do not track unions. AggregateKind::Adt(_, _, _, _, Some(_)) => return None, - // FIXME: Do the extra work to GVN `from_raw_parts` - AggregateKind::RawPtr(..) => return None, + AggregateKind::RawPtr(pointee_ty, mtbl) => { + assert_eq!(field_ops.len(), 2); + let data_pointer_ty = field_ops[FieldIdx::ZERO].ty(self.local_decls, self.tcx); + let output_pointer_ty = Ty::new_ptr(self.tcx, pointee_ty, mtbl); + (AggregateTy::RawPtr { data_pointer_ty, output_pointer_ty }, FIRST_VARIANT) + } }; - let fields: Option> = fields + let fields: Option> = field_ops .iter_mut() .map(|op| self.simplify_operand(op, location).or_else(|| self.new_opaque())) .collect(); - let fields = fields?; + let mut fields = fields?; + + if let AggregateTy::RawPtr { data_pointer_ty, output_pointer_ty } = &mut ty { + let mut was_updated = false; + + // Any thin pointer of matching mutability is fine as the data pointer. + while let Value::Cast { + kind: CastKind::PtrToPtr, + value: cast_value, + from: cast_from, + to: _, + } = self.get(fields[0]) + && let ty::RawPtr(from_pointee_ty, from_mtbl) = cast_from.kind() + && let ty::RawPtr(_, output_mtbl) = output_pointer_ty.kind() + && from_mtbl == output_mtbl + && from_pointee_ty.is_sized(self.tcx, self.param_env) + { + fields[0] = *cast_value; + *data_pointer_ty = *cast_from; + was_updated = true; + } + + if was_updated { + if let Some(const_) = self.try_as_constant(fields[0]) { + field_ops[FieldIdx::ZERO] = Operand::Constant(Box::new(const_)); + } else if let Some(local) = self.try_as_local(fields[0], location) { + field_ops[FieldIdx::ZERO] = Operand::Copy(Place::from(local)); + self.reused_locals.insert(local); + } + } + } if let AggregateTy::Array = ty && fields.len() > 4 @@ -941,6 +992,9 @@ impl<'body, 'tcx> VnState<'body, 'tcx> { (UnOp::Not, Value::BinaryOp(BinOp::Ne, lhs, rhs)) => { Value::BinaryOp(BinOp::Eq, *lhs, *rhs) } + (UnOp::PtrMetadata, Value::Aggregate(AggregateTy::RawPtr { .. }, _, fields)) => { + return Some(fields[1]); + } _ => return None, }; @@ -1092,6 +1146,23 @@ impl<'body, 'tcx> VnState<'body, 'tcx> { return self.new_opaque(); } + let mut was_updated = false; + + // If that cast just casts away the metadata again, + if let PtrToPtr = kind + && let Value::Aggregate(AggregateTy::RawPtr { data_pointer_ty, .. }, _, fields) = + self.get(value) + && let ty::RawPtr(to_pointee, _) = to.kind() + && to_pointee.is_sized(self.tcx, self.param_env) + { + from = *data_pointer_ty; + value = fields[0]; + was_updated = true; + if *data_pointer_ty == to { + return Some(fields[0]); + } + } + if let PtrToPtr | PointerCoercion(MutToConstPointer) = kind && let Value::Cast { kind: inner_kind, value: inner_value, from: inner_from, to: _ } = *self.get(value) @@ -1100,9 +1171,13 @@ impl<'body, 'tcx> VnState<'body, 'tcx> { from = inner_from; value = inner_value; *kind = PtrToPtr; + was_updated = true; if inner_from == to { return Some(inner_value); } + } + + if was_updated { if let Some(const_) = self.try_as_constant(value) { *operand = Operand::Constant(Box::new(const_)); } else if let Some(local) = self.try_as_local(value, location) { diff --git a/tests/mir-opt/gvn.casts_before_aggregate_raw_ptr.GVN.panic-abort.diff b/tests/mir-opt/gvn.casts_before_aggregate_raw_ptr.GVN.panic-abort.diff new file mode 100644 index 000000000000..6e5bdb16595b --- /dev/null +++ b/tests/mir-opt/gvn.casts_before_aggregate_raw_ptr.GVN.panic-abort.diff @@ -0,0 +1,60 @@ +- // MIR for `casts_before_aggregate_raw_ptr` before GVN ++ // MIR for `casts_before_aggregate_raw_ptr` after GVN + + fn casts_before_aggregate_raw_ptr(_1: *const u32) -> *const [u8] { + debug x => _1; + let mut _0: *const [u8]; + let _2: *const [u8; 4]; + let mut _3: *const u32; + let mut _5: *const [u8; 4]; + let mut _7: *const u8; + let mut _8: *const (); + scope 1 { + debug x => _2; + let _4: *const u8; + scope 2 { + debug x => _4; + let _6: *const (); + scope 3 { + debug x => _6; + } + } + } + + bb0: { +- StorageLive(_2); ++ nop; + StorageLive(_3); + _3 = _1; +- _2 = move _3 as *const [u8; 4] (PtrToPtr); ++ _2 = _1 as *const [u8; 4] (PtrToPtr); + StorageDead(_3); +- StorageLive(_4); ++ nop; + StorageLive(_5); + _5 = _2; +- _4 = move _5 as *const u8 (PtrToPtr); ++ _4 = _1 as *const u8 (PtrToPtr); + StorageDead(_5); +- StorageLive(_6); ++ nop; + StorageLive(_7); + _7 = _4; +- _6 = move _7 as *const () (PtrToPtr); ++ _6 = _1 as *const () (PtrToPtr); + StorageDead(_7); + StorageLive(_8); + _8 = _6; +- _0 = *const [u8] from (move _8, const 4_usize); ++ _0 = *const [u8] from (_1, const 4_usize); + StorageDead(_8); +- StorageDead(_6); +- StorageDead(_4); +- StorageDead(_2); ++ nop; ++ nop; ++ nop; + return; + } + } + diff --git a/tests/mir-opt/gvn.casts_before_aggregate_raw_ptr.GVN.panic-unwind.diff b/tests/mir-opt/gvn.casts_before_aggregate_raw_ptr.GVN.panic-unwind.diff new file mode 100644 index 000000000000..6e5bdb16595b --- /dev/null +++ b/tests/mir-opt/gvn.casts_before_aggregate_raw_ptr.GVN.panic-unwind.diff @@ -0,0 +1,60 @@ +- // MIR for `casts_before_aggregate_raw_ptr` before GVN ++ // MIR for `casts_before_aggregate_raw_ptr` after GVN + + fn casts_before_aggregate_raw_ptr(_1: *const u32) -> *const [u8] { + debug x => _1; + let mut _0: *const [u8]; + let _2: *const [u8; 4]; + let mut _3: *const u32; + let mut _5: *const [u8; 4]; + let mut _7: *const u8; + let mut _8: *const (); + scope 1 { + debug x => _2; + let _4: *const u8; + scope 2 { + debug x => _4; + let _6: *const (); + scope 3 { + debug x => _6; + } + } + } + + bb0: { +- StorageLive(_2); ++ nop; + StorageLive(_3); + _3 = _1; +- _2 = move _3 as *const [u8; 4] (PtrToPtr); ++ _2 = _1 as *const [u8; 4] (PtrToPtr); + StorageDead(_3); +- StorageLive(_4); ++ nop; + StorageLive(_5); + _5 = _2; +- _4 = move _5 as *const u8 (PtrToPtr); ++ _4 = _1 as *const u8 (PtrToPtr); + StorageDead(_5); +- StorageLive(_6); ++ nop; + StorageLive(_7); + _7 = _4; +- _6 = move _7 as *const () (PtrToPtr); ++ _6 = _1 as *const () (PtrToPtr); + StorageDead(_7); + StorageLive(_8); + _8 = _6; +- _0 = *const [u8] from (move _8, const 4_usize); ++ _0 = *const [u8] from (_1, const 4_usize); + StorageDead(_8); +- StorageDead(_6); +- StorageDead(_4); +- StorageDead(_2); ++ nop; ++ nop; ++ nop; + return; + } + } + diff --git a/tests/mir-opt/gvn.meta_of_ref_to_slice.GVN.panic-abort.diff b/tests/mir-opt/gvn.meta_of_ref_to_slice.GVN.panic-abort.diff new file mode 100644 index 000000000000..73dbabb56b35 --- /dev/null +++ b/tests/mir-opt/gvn.meta_of_ref_to_slice.GVN.panic-abort.diff @@ -0,0 +1,32 @@ +- // MIR for `meta_of_ref_to_slice` before GVN ++ // MIR for `meta_of_ref_to_slice` after GVN + + fn meta_of_ref_to_slice(_1: *const i32) -> usize { + debug x => _1; + let mut _0: usize; + let _2: *const [i32]; + let mut _3: *const i32; + let mut _4: *const [i32]; + scope 1 { + debug ptr => _2; + } + + bb0: { +- StorageLive(_2); ++ nop; + StorageLive(_3); + _3 = _1; +- _2 = *const [i32] from (move _3, const 1_usize); ++ _2 = *const [i32] from (_1, const 1_usize); + StorageDead(_3); + StorageLive(_4); + _4 = _2; +- _0 = PtrMetadata(move _4); ++ _0 = const 1_usize; + StorageDead(_4); +- StorageDead(_2); ++ nop; + return; + } + } + diff --git a/tests/mir-opt/gvn.meta_of_ref_to_slice.GVN.panic-unwind.diff b/tests/mir-opt/gvn.meta_of_ref_to_slice.GVN.panic-unwind.diff new file mode 100644 index 000000000000..73dbabb56b35 --- /dev/null +++ b/tests/mir-opt/gvn.meta_of_ref_to_slice.GVN.panic-unwind.diff @@ -0,0 +1,32 @@ +- // MIR for `meta_of_ref_to_slice` before GVN ++ // MIR for `meta_of_ref_to_slice` after GVN + + fn meta_of_ref_to_slice(_1: *const i32) -> usize { + debug x => _1; + let mut _0: usize; + let _2: *const [i32]; + let mut _3: *const i32; + let mut _4: *const [i32]; + scope 1 { + debug ptr => _2; + } + + bb0: { +- StorageLive(_2); ++ nop; + StorageLive(_3); + _3 = _1; +- _2 = *const [i32] from (move _3, const 1_usize); ++ _2 = *const [i32] from (_1, const 1_usize); + StorageDead(_3); + StorageLive(_4); + _4 = _2; +- _0 = PtrMetadata(move _4); ++ _0 = const 1_usize; + StorageDead(_4); +- StorageDead(_2); ++ nop; + return; + } + } + diff --git a/tests/mir-opt/gvn.rs b/tests/mir-opt/gvn.rs index 315377e4356f..720018f112e5 100644 --- a/tests/mir-opt/gvn.rs +++ b/tests/mir-opt/gvn.rs @@ -783,6 +783,39 @@ fn non_freeze(x: T) { } } +// Check that we can const-prop into `from_raw_parts` +fn slice_const_length(x: &[i32]) -> *const [i32] { + // CHECK-LABEL: fn slice_const_length( + // CHECK: _0 = *const [i32] from ({{_[0-9]+}}, const 123_usize); + let ptr = x.as_ptr(); + let len = 123; + std::intrinsics::aggregate_raw_ptr(ptr, len) +} + +fn meta_of_ref_to_slice(x: *const i32) -> usize { + // CHECK-LABEL: fn meta_of_ref_to_slice + // CHECK: _0 = const 1_usize + let ptr: *const [i32] = std::intrinsics::aggregate_raw_ptr(x, 1); + std::intrinsics::ptr_metadata(ptr) +} + +fn slice_from_raw_parts_as_ptr(x: *const u16, n: usize) -> (*const u16, *const f32) { + // CHECK-LABEL: fn slice_from_raw_parts_as_ptr + // CHECK: _8 = _1 as *const f32 (PtrToPtr); + // CHECK: _0 = (_1, move _8); + let ptr: *const [u16] = std::intrinsics::aggregate_raw_ptr(x, n); + (ptr as *const u16, ptr as *const f32) +} + +fn casts_before_aggregate_raw_ptr(x: *const u32) -> *const [u8] { + // CHECK-LABEL: fn casts_before_aggregate_raw_ptr + // CHECK: _0 = *const [u8] from (_1, const 4_usize); + let x = x as *const [u8; 4]; + let x = x as *const u8; + let x = x as *const (); + std::intrinsics::aggregate_raw_ptr(x, 4) +} + fn main() { subexpression_elimination(2, 4, 5); wrap_unwrap(5); @@ -807,6 +840,9 @@ fn main() { wide_ptr_integer(); borrowed(5); non_freeze(5); + slice_const_length(&[1]); + meta_of_ref_to_slice(&42); + slice_from_raw_parts_as_ptr(&123, 456); } #[inline(never)] @@ -840,3 +876,7 @@ fn identity(x: T) -> T { // EMIT_MIR gvn.wide_ptr_integer.GVN.diff // EMIT_MIR gvn.borrowed.GVN.diff // EMIT_MIR gvn.non_freeze.GVN.diff +// EMIT_MIR gvn.slice_const_length.GVN.diff +// EMIT_MIR gvn.meta_of_ref_to_slice.GVN.diff +// EMIT_MIR gvn.slice_from_raw_parts_as_ptr.GVN.diff +// EMIT_MIR gvn.casts_before_aggregate_raw_ptr.GVN.diff diff --git a/tests/mir-opt/gvn.slice_const_length.GVN.panic-abort.diff b/tests/mir-opt/gvn.slice_const_length.GVN.panic-abort.diff new file mode 100644 index 000000000000..fd5fa035d816 --- /dev/null +++ b/tests/mir-opt/gvn.slice_const_length.GVN.panic-abort.diff @@ -0,0 +1,48 @@ +- // MIR for `slice_const_length` before GVN ++ // MIR for `slice_const_length` after GVN + + fn slice_const_length(_1: &[i32]) -> *const [i32] { + debug x => _1; + let mut _0: *const [i32]; + let _2: *const i32; + let mut _3: &[i32]; + let mut _5: *const i32; + let mut _6: usize; + scope 1 { + debug ptr => _2; + let _4: usize; + scope 2 { + debug len => _4; + } + } + + bb0: { +- StorageLive(_2); ++ nop; + StorageLive(_3); + _3 = &(*_1); + _2 = core::slice::::as_ptr(move _3) -> [return: bb1, unwind unreachable]; + } + + bb1: { + StorageDead(_3); +- StorageLive(_4); ++ nop; + _4 = const 123_usize; + StorageLive(_5); + _5 = _2; + StorageLive(_6); +- _6 = _4; +- _0 = *const [i32] from (move _5, move _6); ++ _6 = const 123_usize; ++ _0 = *const [i32] from (_2, const 123_usize); + StorageDead(_6); + StorageDead(_5); +- StorageDead(_4); +- StorageDead(_2); ++ nop; ++ nop; + return; + } + } + diff --git a/tests/mir-opt/gvn.slice_const_length.GVN.panic-unwind.diff b/tests/mir-opt/gvn.slice_const_length.GVN.panic-unwind.diff new file mode 100644 index 000000000000..98945cf9724d --- /dev/null +++ b/tests/mir-opt/gvn.slice_const_length.GVN.panic-unwind.diff @@ -0,0 +1,48 @@ +- // MIR for `slice_const_length` before GVN ++ // MIR for `slice_const_length` after GVN + + fn slice_const_length(_1: &[i32]) -> *const [i32] { + debug x => _1; + let mut _0: *const [i32]; + let _2: *const i32; + let mut _3: &[i32]; + let mut _5: *const i32; + let mut _6: usize; + scope 1 { + debug ptr => _2; + let _4: usize; + scope 2 { + debug len => _4; + } + } + + bb0: { +- StorageLive(_2); ++ nop; + StorageLive(_3); + _3 = &(*_1); + _2 = core::slice::::as_ptr(move _3) -> [return: bb1, unwind continue]; + } + + bb1: { + StorageDead(_3); +- StorageLive(_4); ++ nop; + _4 = const 123_usize; + StorageLive(_5); + _5 = _2; + StorageLive(_6); +- _6 = _4; +- _0 = *const [i32] from (move _5, move _6); ++ _6 = const 123_usize; ++ _0 = *const [i32] from (_2, const 123_usize); + StorageDead(_6); + StorageDead(_5); +- StorageDead(_4); +- StorageDead(_2); ++ nop; ++ nop; + return; + } + } + diff --git a/tests/mir-opt/gvn.slice_from_raw_parts_as_ptr.GVN.panic-abort.diff b/tests/mir-opt/gvn.slice_from_raw_parts_as_ptr.GVN.panic-abort.diff new file mode 100644 index 000000000000..75bcd2a8d72c --- /dev/null +++ b/tests/mir-opt/gvn.slice_from_raw_parts_as_ptr.GVN.panic-abort.diff @@ -0,0 +1,51 @@ +- // MIR for `slice_from_raw_parts_as_ptr` before GVN ++ // MIR for `slice_from_raw_parts_as_ptr` after GVN + + fn slice_from_raw_parts_as_ptr(_1: *const u16, _2: usize) -> (*const u16, *const f32) { + debug x => _1; + debug n => _2; + let mut _0: (*const u16, *const f32); + let _3: *const [u16]; + let mut _4: *const u16; + let mut _5: usize; + let mut _6: *const u16; + let mut _7: *const [u16]; + let mut _8: *const f32; + let mut _9: *const [u16]; + scope 1 { + debug ptr => _3; + } + + bb0: { +- StorageLive(_3); ++ nop; + StorageLive(_4); + _4 = _1; + StorageLive(_5); + _5 = _2; +- _3 = *const [u16] from (move _4, move _5); ++ _3 = *const [u16] from (_1, _2); + StorageDead(_5); + StorageDead(_4); + StorageLive(_6); + StorageLive(_7); + _7 = _3; +- _6 = move _7 as *const u16 (PtrToPtr); ++ _6 = _1; + StorageDead(_7); + StorageLive(_8); + StorageLive(_9); + _9 = _3; +- _8 = move _9 as *const f32 (PtrToPtr); ++ _8 = _1 as *const f32 (PtrToPtr); + StorageDead(_9); +- _0 = (move _6, move _8); ++ _0 = (_1, move _8); + StorageDead(_8); + StorageDead(_6); +- StorageDead(_3); ++ nop; + return; + } + } + diff --git a/tests/mir-opt/gvn.slice_from_raw_parts_as_ptr.GVN.panic-unwind.diff b/tests/mir-opt/gvn.slice_from_raw_parts_as_ptr.GVN.panic-unwind.diff new file mode 100644 index 000000000000..75bcd2a8d72c --- /dev/null +++ b/tests/mir-opt/gvn.slice_from_raw_parts_as_ptr.GVN.panic-unwind.diff @@ -0,0 +1,51 @@ +- // MIR for `slice_from_raw_parts_as_ptr` before GVN ++ // MIR for `slice_from_raw_parts_as_ptr` after GVN + + fn slice_from_raw_parts_as_ptr(_1: *const u16, _2: usize) -> (*const u16, *const f32) { + debug x => _1; + debug n => _2; + let mut _0: (*const u16, *const f32); + let _3: *const [u16]; + let mut _4: *const u16; + let mut _5: usize; + let mut _6: *const u16; + let mut _7: *const [u16]; + let mut _8: *const f32; + let mut _9: *const [u16]; + scope 1 { + debug ptr => _3; + } + + bb0: { +- StorageLive(_3); ++ nop; + StorageLive(_4); + _4 = _1; + StorageLive(_5); + _5 = _2; +- _3 = *const [u16] from (move _4, move _5); ++ _3 = *const [u16] from (_1, _2); + StorageDead(_5); + StorageDead(_4); + StorageLive(_6); + StorageLive(_7); + _7 = _3; +- _6 = move _7 as *const u16 (PtrToPtr); ++ _6 = _1; + StorageDead(_7); + StorageLive(_8); + StorageLive(_9); + _9 = _3; +- _8 = move _9 as *const f32 (PtrToPtr); ++ _8 = _1 as *const f32 (PtrToPtr); + StorageDead(_9); +- _0 = (move _6, move _8); ++ _0 = (_1, move _8); + StorageDead(_8); + StorageDead(_6); +- StorageDead(_3); ++ nop; + return; + } + } + diff --git a/tests/mir-opt/pre-codegen/ptr_offset.demo_byte_add_fat.PreCodegen.after.panic-abort.mir b/tests/mir-opt/pre-codegen/ptr_offset.demo_byte_add_fat.PreCodegen.after.panic-abort.mir index 2c6d93e10c11..2f6139712ffc 100644 --- a/tests/mir-opt/pre-codegen/ptr_offset.demo_byte_add_fat.PreCodegen.after.panic-abort.mir +++ b/tests/mir-opt/pre-codegen/ptr_offset.demo_byte_add_fat.PreCodegen.after.panic-abort.mir @@ -12,8 +12,7 @@ fn demo_byte_add_fat(_1: *const [u32], _2: usize) -> *const [u32] { scope 3 (inlined std::ptr::const_ptr::::add) { } scope 4 (inlined std::ptr::const_ptr::::with_metadata_of::<[u32]>) { - let mut _5: *const (); - let mut _6: usize; + let mut _5: usize; scope 5 (inlined std::ptr::metadata::<[u32]>) { } scope 6 (inlined std::ptr::from_raw_parts::<[u32], ()>) { @@ -28,11 +27,8 @@ fn demo_byte_add_fat(_1: *const [u32], _2: usize) -> *const [u32] { _4 = Offset(_3, _2); StorageDead(_3); StorageLive(_5); - _5 = _4 as *const () (PtrToPtr); - StorageLive(_6); - _6 = PtrMetadata(_1); - _0 = *const [u32] from (_5, _6); - StorageDead(_6); + _5 = PtrMetadata(_1); + _0 = *const [u32] from (_4, _5); StorageDead(_5); StorageDead(_4); return; diff --git a/tests/mir-opt/pre-codegen/ptr_offset.demo_byte_add_fat.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/pre-codegen/ptr_offset.demo_byte_add_fat.PreCodegen.after.panic-unwind.mir index 2c6d93e10c11..2f6139712ffc 100644 --- a/tests/mir-opt/pre-codegen/ptr_offset.demo_byte_add_fat.PreCodegen.after.panic-unwind.mir +++ b/tests/mir-opt/pre-codegen/ptr_offset.demo_byte_add_fat.PreCodegen.after.panic-unwind.mir @@ -12,8 +12,7 @@ fn demo_byte_add_fat(_1: *const [u32], _2: usize) -> *const [u32] { scope 3 (inlined std::ptr::const_ptr::::add) { } scope 4 (inlined std::ptr::const_ptr::::with_metadata_of::<[u32]>) { - let mut _5: *const (); - let mut _6: usize; + let mut _5: usize; scope 5 (inlined std::ptr::metadata::<[u32]>) { } scope 6 (inlined std::ptr::from_raw_parts::<[u32], ()>) { @@ -28,11 +27,8 @@ fn demo_byte_add_fat(_1: *const [u32], _2: usize) -> *const [u32] { _4 = Offset(_3, _2); StorageDead(_3); StorageLive(_5); - _5 = _4 as *const () (PtrToPtr); - StorageLive(_6); - _6 = PtrMetadata(_1); - _0 = *const [u32] from (_5, _6); - StorageDead(_6); + _5 = PtrMetadata(_1); + _0 = *const [u32] from (_4, _5); StorageDead(_5); StorageDead(_4); return; diff --git a/tests/mir-opt/pre-codegen/ptr_offset.demo_byte_add_thin.PreCodegen.after.panic-abort.mir b/tests/mir-opt/pre-codegen/ptr_offset.demo_byte_add_thin.PreCodegen.after.panic-abort.mir index 04fb6b838f02..8d47e63eff2a 100644 --- a/tests/mir-opt/pre-codegen/ptr_offset.demo_byte_add_thin.PreCodegen.after.panic-abort.mir +++ b/tests/mir-opt/pre-codegen/ptr_offset.demo_byte_add_thin.PreCodegen.after.panic-abort.mir @@ -20,11 +20,13 @@ fn demo_byte_add_thin(_1: *const u32, _2: usize) -> *const u32 { } bb0: { + StorageLive(_4); StorageLive(_3); _3 = _1 as *const u8 (PtrToPtr); _4 = Offset(_3, _2); StorageDead(_3); _0 = _4 as *const u32 (PtrToPtr); + StorageDead(_4); return; } } diff --git a/tests/mir-opt/pre-codegen/ptr_offset.demo_byte_add_thin.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/pre-codegen/ptr_offset.demo_byte_add_thin.PreCodegen.after.panic-unwind.mir index 04fb6b838f02..8d47e63eff2a 100644 --- a/tests/mir-opt/pre-codegen/ptr_offset.demo_byte_add_thin.PreCodegen.after.panic-unwind.mir +++ b/tests/mir-opt/pre-codegen/ptr_offset.demo_byte_add_thin.PreCodegen.after.panic-unwind.mir @@ -20,11 +20,13 @@ fn demo_byte_add_thin(_1: *const u32, _2: usize) -> *const u32 { } bb0: { + StorageLive(_4); StorageLive(_3); _3 = _1 as *const u8 (PtrToPtr); _4 = Offset(_3, _2); StorageDead(_3); _0 = _4 as *const u32 (PtrToPtr); + StorageDead(_4); return; } } From 6d87fc8747bc341088cc9831e24c50b8894918e6 Mon Sep 17 00:00:00 2001 From: Gurinder Singh Date: Sat, 8 Jun 2024 08:43:08 +0530 Subject: [PATCH 07/50] Fix ICE due to `unwrap` in `probe_for_name_many` --- compiler/rustc_hir_typeck/src/demand.rs | 15 +++++-- compiler/rustc_hir_typeck/src/method/probe.rs | 3 +- .../rustc_hir_typeck/src/method/suggest.rs | 14 ++++--- .../ice-unwrap-probe-many-result-125876.rs | 11 +++++ ...ice-unwrap-probe-many-result-125876.stderr | 40 +++++++++++++++++++ 5 files changed, 72 insertions(+), 11 deletions(-) create mode 100644 tests/ui/suggestions/ice-unwrap-probe-many-result-125876.rs create mode 100644 tests/ui/suggestions/ice-unwrap-probe-many-result-125876.stderr diff --git a/compiler/rustc_hir_typeck/src/demand.rs b/compiler/rustc_hir_typeck/src/demand.rs index 5d30b2a71e09..d2a5924c8bbb 100644 --- a/compiler/rustc_hir_typeck/src/demand.rs +++ b/compiler/rustc_hir_typeck/src/demand.rs @@ -827,7 +827,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ) else { return; }; - let in_scope_methods = self.probe_for_name_many( + + let Ok(in_scope_methods) = self.probe_for_name_many( probe::Mode::MethodCall, path.ident, Some(expected), @@ -835,11 +836,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self_ty, deref.hir_id, probe::ProbeScope::TraitsInScope, - ); + ) else { + return; + }; + let other_methods_in_scope: Vec<_> = in_scope_methods.iter().filter(|c| c.item.def_id != pick.item.def_id).collect(); - let all_methods = self.probe_for_name_many( + let Ok(all_methods) = self.probe_for_name_many( probe::Mode::MethodCall, path.ident, Some(expected), @@ -847,7 +851,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self_ty, deref.hir_id, probe::ProbeScope::AllTraits, - ); + ) else { + return; + }; + let suggestions: Vec<_> = all_methods .into_iter() .filter(|c| c.item.def_id != pick.item.def_id) diff --git a/compiler/rustc_hir_typeck/src/method/probe.rs b/compiler/rustc_hir_typeck/src/method/probe.rs index ab0f16bd87d0..e842bba34bf8 100644 --- a/compiler/rustc_hir_typeck/src/method/probe.rs +++ b/compiler/rustc_hir_typeck/src/method/probe.rs @@ -306,7 +306,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self_ty: Ty<'tcx>, scope_expr_id: HirId, scope: ProbeScope, - ) -> Vec> { + ) -> Result>, MethodError<'tcx>> { self.probe_op( item_name.span, mode, @@ -324,7 +324,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { .collect()) }, ) - .unwrap() } pub(crate) fn probe_op( diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs index c1e14f7fb753..bbe4a8791c69 100644 --- a/compiler/rustc_hir_typeck/src/method/suggest.rs +++ b/compiler/rustc_hir_typeck/src/method/suggest.rs @@ -1640,10 +1640,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { .unwrap_or(Ty::new_misc_error(self.tcx)), ); - // FIXME: `probe_for_name_many` searches for methods in inherent implementations, - // so it may return a candidate that doesn't belong to this `revr_ty`. We need to - // check whether the instantiated type matches the received one. - for _matched_method in self.probe_for_name_many( + let Ok(candidates) = self.probe_for_name_many( Mode::MethodCall, item_name, None, @@ -1651,7 +1648,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { rcvr_ty, source_expr.hir_id, ProbeScope::TraitsInScope, - ) { + ) else { + return; + }; + + // FIXME: `probe_for_name_many` searches for methods in inherent implementations, + // so it may return a candidate that doesn't belong to this `revr_ty`. We need to + // check whether the instantiated type matches the received one. + for _matched_method in candidates { // found a match, push to stack stack_methods.push(rcvr_ty); } diff --git a/tests/ui/suggestions/ice-unwrap-probe-many-result-125876.rs b/tests/ui/suggestions/ice-unwrap-probe-many-result-125876.rs new file mode 100644 index 000000000000..efa296db47cf --- /dev/null +++ b/tests/ui/suggestions/ice-unwrap-probe-many-result-125876.rs @@ -0,0 +1,11 @@ +// Regression test for ICE #125876 + +fn main() { + std::ptr::from_ref(num).cast_mut().as_deref(); + //~^ ERROR cannot find value `num` in this scope + //~| ERROR no method named `as_deref` found for raw pointer `*mut _` in the current scope + //~| WARN type annotations needed + //~| WARN this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! + //~| WARN type annotations needed + //~| WARN this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! +} diff --git a/tests/ui/suggestions/ice-unwrap-probe-many-result-125876.stderr b/tests/ui/suggestions/ice-unwrap-probe-many-result-125876.stderr new file mode 100644 index 000000000000..d610a3b7cadd --- /dev/null +++ b/tests/ui/suggestions/ice-unwrap-probe-many-result-125876.stderr @@ -0,0 +1,40 @@ +error[E0425]: cannot find value `num` in this scope + --> $DIR/ice-unwrap-probe-many-result-125876.rs:4:24 + | +LL | std::ptr::from_ref(num).cast_mut().as_deref(); + | ^^^ not found in this scope + +warning: type annotations needed + --> $DIR/ice-unwrap-probe-many-result-125876.rs:4:29 + | +LL | std::ptr::from_ref(num).cast_mut().as_deref(); + | ^^^^^^^^ + | + = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! + = note: for more information, see issue #46906 + = note: `#[warn(tyvar_behind_raw_pointer)]` on by default + +warning: type annotations needed + --> $DIR/ice-unwrap-probe-many-result-125876.rs:4:40 + | +LL | std::ptr::from_ref(num).cast_mut().as_deref(); + | ^^^^^^^^ + | + = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! + = note: for more information, see issue #46906 + +error[E0599]: no method named `as_deref` found for raw pointer `*mut _` in the current scope + --> $DIR/ice-unwrap-probe-many-result-125876.rs:4:40 + | +LL | std::ptr::from_ref(num).cast_mut().as_deref(); + | ^^^^^^^^ + | +help: there is a method `as_ref` with a similar name + | +LL | std::ptr::from_ref(num).cast_mut().as_ref(); + | ~~~~~~ + +error: aborting due to 2 previous errors; 2 warnings emitted + +Some errors have detailed explanations: E0425, E0599. +For more information about an error, try `rustc --explain E0425`. From cf3966dd9c1e175a0c0e1186616708ab4878896b Mon Sep 17 00:00:00 2001 From: David Carlier Date: Sat, 8 Jun 2024 08:31:35 +0100 Subject: [PATCH 08/50] std::unix::process adding few specific freebsd signals to be able to id. --- library/std/src/sys/pal/unix/process/process_unix.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/library/std/src/sys/pal/unix/process/process_unix.rs b/library/std/src/sys/pal/unix/process/process_unix.rs index e2fca8c7e63d..72bda90a9ba7 100644 --- a/library/std/src/sys/pal/unix/process/process_unix.rs +++ b/library/std/src/sys/pal/unix/process/process_unix.rs @@ -1053,6 +1053,10 @@ fn signal_string(signal: i32) -> &'static str { libc::SIGINFO => " (SIGINFO)", #[cfg(target_os = "hurd")] libc::SIGLOST => " (SIGLOST)", + #[cfg(target_os = "freebsd")] + libc::SIGTHR => " (SIGTHR)", + #[cfg(target_os = "freebsd")] + libc::SIGLIBRT => " (SIGLIBRT)", _ => "", } } From 1293ef735e251f8062d0a34a737fc675486afb74 Mon Sep 17 00:00:00 2001 From: Martin Nordholts Date: Fri, 7 Jun 2024 20:59:31 +0200 Subject: [PATCH 09/50] tests: Add ui/higher-ranked/trait-bounds/normalize-generic-arg.rs --- ...-in-higher-ranked-fn-signature.next.stderr | 9 ++++++ ...ojections-in-higher-ranked-fn-signature.rs | 30 +++++++++++++++++++ 2 files changed, 39 insertions(+) create mode 100644 tests/ui/higher-ranked/trait-bounds/rigid-equate-projections-in-higher-ranked-fn-signature.next.stderr create mode 100644 tests/ui/higher-ranked/trait-bounds/rigid-equate-projections-in-higher-ranked-fn-signature.rs diff --git a/tests/ui/higher-ranked/trait-bounds/rigid-equate-projections-in-higher-ranked-fn-signature.next.stderr b/tests/ui/higher-ranked/trait-bounds/rigid-equate-projections-in-higher-ranked-fn-signature.next.stderr new file mode 100644 index 000000000000..14a3d5e178d4 --- /dev/null +++ b/tests/ui/higher-ranked/trait-bounds/rigid-equate-projections-in-higher-ranked-fn-signature.next.stderr @@ -0,0 +1,9 @@ +error[E0284]: type annotations needed: cannot satisfy `for<'a> <_ as Trait<'a>>::Assoc <: >::Assoc` + --> $DIR/rigid-equate-projections-in-higher-ranked-fn-signature.rs:27:50 + | +LL | let _: for<'a> fn(<_ as Trait<'a>>::Assoc) = foo::(); + | ^^^^^^^^^^ cannot satisfy `for<'a> <_ as Trait<'a>>::Assoc <: >::Assoc` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0284`. diff --git a/tests/ui/higher-ranked/trait-bounds/rigid-equate-projections-in-higher-ranked-fn-signature.rs b/tests/ui/higher-ranked/trait-bounds/rigid-equate-projections-in-higher-ranked-fn-signature.rs new file mode 100644 index 000000000000..10dbc2a4a825 --- /dev/null +++ b/tests/ui/higher-ranked/trait-bounds/rigid-equate-projections-in-higher-ranked-fn-signature.rs @@ -0,0 +1,30 @@ +//@ revisions: current next +//@[current] check-pass +//@[next] compile-flags: -Znext-solver +//@[next] check-fail +//@ ignore-compare-mode-next-solver (explicit revisions) + +/// This triggers an ICE with (and without) `--emit metadata` using the old +/// trait solver: +/// ``` +/// rustc +nightly-2023-01-09 \ +/// tests/ui/higher-ranked/trait-bounds/rigid-equate-projections-in-higher-ranked-fn-signature.rs +/// ``` +/// The ICE was unknowingly fixed by +/// in `nightly-2023-01-10`. +/// This is a regression test for that fixed ICE. For the next solver we simply +/// make sure there is a compiler error. + +trait Trait<'a> { + type Assoc; +} + +fn foo Trait<'a>>() -> for<'a> fn(>::Assoc) { + todo!() +} + +fn bar Trait<'a>>() { + let _: for<'a> fn(<_ as Trait<'a>>::Assoc) = foo::(); //[next]~ ERROR type annotations needed +} + +fn main() {} From eb584a23bfba55512af0a223cf4133b806ede178 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sat, 8 Jun 2024 11:26:56 +0200 Subject: [PATCH 10/50] offset_of: allow (unstably) taking the offset of slice tail fields --- compiler/rustc_codegen_cranelift/src/base.rs | 7 ++-- compiler/rustc_codegen_ssa/src/mir/rvalue.rs | 5 ++- .../rustc_const_eval/src/interpret/step.rs | 5 ++- compiler/rustc_feature/src/unstable.rs | 2 ++ compiler/rustc_hir_typeck/src/expr.rs | 35 +++++++++++++++---- .../rustc_hir_typeck/src/fn_ctxt/_impl.rs | 20 +++++++++++ compiler/rustc_middle/src/ty/layout.rs | 34 ++++++++++++++++++ .../src/dataflow_const_prop.rs | 10 +++--- compiler/rustc_mir_transform/src/gvn.rs | 10 +++--- .../src/known_panics_lint.rs | 7 ++-- compiler/rustc_span/src/symbol.rs | 1 + compiler/rustc_target/src/abi/mod.rs | 23 ------------ .../feature-gate-offset-of-slice.rs | 26 ++++++++++++++ .../feature-gate-offset-of-slice.stderr | 35 +++++++++++++++++++ tests/ui/offset-of/offset-of-dst-field.rs | 4 +++ tests/ui/offset-of/offset-of-dst-field.stderr | 11 +++++- tests/ui/offset-of/offset-of-slice.rs | 26 ++++++++++++++ 17 files changed, 215 insertions(+), 46 deletions(-) create mode 100644 tests/ui/feature-gates/feature-gate-offset-of-slice.rs create mode 100644 tests/ui/feature-gates/feature-gate-offset-of-slice.stderr create mode 100644 tests/ui/offset-of/offset-of-slice.rs diff --git a/compiler/rustc_codegen_cranelift/src/base.rs b/compiler/rustc_codegen_cranelift/src/base.rs index 963e5de91cef..6d26ca0b899b 100644 --- a/compiler/rustc_codegen_cranelift/src/base.rs +++ b/compiler/rustc_codegen_cranelift/src/base.rs @@ -832,9 +832,10 @@ fn codegen_stmt<'tcx>( let val = match null_op { NullOp::SizeOf => layout.size.bytes(), NullOp::AlignOf => layout.align.abi.bytes(), - NullOp::OffsetOf(fields) => { - layout.offset_of_subfield(fx, fields.iter()).bytes() - } + NullOp::OffsetOf(fields) => fx + .tcx + .offset_of_subfield(ParamEnv::reveal_all(), layout, fields.iter()) + .bytes(), NullOp::UbChecks => { let val = fx.tcx.sess.ub_checks(); let val = CValue::by_val( diff --git a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs index c23867be3a10..ad6b3f1159de 100644 --- a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs +++ b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs @@ -680,7 +680,10 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { bx.cx().const_usize(val) } mir::NullOp::OffsetOf(fields) => { - let val = layout.offset_of_subfield(bx.cx(), fields.iter()).bytes(); + let val = bx + .tcx() + .offset_of_subfield(bx.param_env(), layout, fields.iter()) + .bytes(); bx.cx().const_usize(val) } mir::NullOp::UbChecks => { diff --git a/compiler/rustc_const_eval/src/interpret/step.rs b/compiler/rustc_const_eval/src/interpret/step.rs index d0bb821862aa..1baf62baa816 100644 --- a/compiler/rustc_const_eval/src/interpret/step.rs +++ b/compiler/rustc_const_eval/src/interpret/step.rs @@ -253,7 +253,10 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { Scalar::from_target_usize(val, self) } mir::NullOp::OffsetOf(fields) => { - let val = layout.offset_of_subfield(self, fields.iter()).bytes(); + let val = self + .tcx + .offset_of_subfield(self.param_env, layout, fields.iter()) + .bytes(); Scalar::from_target_usize(val, self) } mir::NullOp::UbChecks => Scalar::from_bool(self.tcx.sess.ub_checks()), diff --git a/compiler/rustc_feature/src/unstable.rs b/compiler/rustc_feature/src/unstable.rs index d67422849d8a..2410019868a1 100644 --- a/compiler/rustc_feature/src/unstable.rs +++ b/compiler/rustc_feature/src/unstable.rs @@ -559,6 +559,8 @@ declare_features! ( (unstable, offset_of_enum, "1.75.0", Some(120141)), /// Allows using multiple nested field accesses in offset_of! (unstable, offset_of_nested, "1.77.0", Some(120140)), + /// Allows using fields with slice type in offset_of! + (unstable, offset_of_slice, "CURRENT_RUSTC_VERSION", Some(126151)), /// Allows using `#[optimize(X)]`. (unstable, optimize_attribute, "1.34.0", Some(54882)), /// Allows postfix match `expr.match { ... }` diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs index d5d360ca0479..5b27ebe3416a 100644 --- a/compiler/rustc_hir_typeck/src/expr.rs +++ b/compiler/rustc_hir_typeck/src/expr.rs @@ -3363,7 +3363,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let field_ty = self.field_ty(expr.span, field, args); - // FIXME: DSTs with static alignment should be allowed + // Enums are anyway always sized. But just to safeguard against future + // language extensions, let's double-check. self.require_type_is_sized(field_ty, expr.span, ObligationCauseCode::Misc); if field.vis.is_accessible_from(sub_def_scope, self.tcx) { @@ -3391,8 +3392,19 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { { let field_ty = self.field_ty(expr.span, field, args); - // FIXME: DSTs with static alignment should be allowed - self.require_type_is_sized(field_ty, expr.span, ObligationCauseCode::Misc); + if self.tcx.features().offset_of_slice { + self.require_type_has_static_alignment( + field_ty, + expr.span, + ObligationCauseCode::Misc, + ); + } else { + self.require_type_is_sized( + field_ty, + expr.span, + ObligationCauseCode::Misc, + ); + } if field.vis.is_accessible_from(def_scope, self.tcx) { self.tcx.check_stability(field.did, Some(expr.hir_id), expr.span, None); @@ -3412,10 +3424,21 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { if let Ok(index) = field.as_str().parse::() && field.name == sym::integer(index) { - for ty in tys.iter().take(index + 1) { - self.require_type_is_sized(ty, expr.span, ObligationCauseCode::Misc); - } if let Some(&field_ty) = tys.get(index) { + if self.tcx.features().offset_of_slice { + self.require_type_has_static_alignment( + field_ty, + expr.span, + ObligationCauseCode::Misc, + ); + } else { + self.require_type_is_sized( + field_ty, + expr.span, + ObligationCauseCode::Misc, + ); + } + field_indices.push((FIRST_VARIANT, index.into())); current_container = field_ty; diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs index 85c6d4dc12c5..e354e1ec59c6 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs @@ -386,6 +386,26 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } + pub fn require_type_has_static_alignment( + &self, + ty: Ty<'tcx>, + span: Span, + code: traits::ObligationCauseCode<'tcx>, + ) { + if !ty.references_error() { + let tail = + self.tcx.struct_tail_with_normalize(ty, |ty| self.normalize(span, ty), || {}); + // Sized types have static alignment, and so do slices. + if tail.is_trivially_sized(self.tcx) || matches!(tail.kind(), ty::Slice(..)) { + // Nothing else is required here. + } else { + // We can't be sure, let's required full `Sized`. + let lang_item = self.tcx.require_lang_item(LangItem::Sized, None); + self.require_type_meets(ty, span, code, lang_item); + } + } + } + pub fn register_bound( &self, ty: Ty<'tcx>, diff --git a/compiler/rustc_middle/src/ty/layout.rs b/compiler/rustc_middle/src/ty/layout.rs index 142872009bf2..56945bf6be4f 100644 --- a/compiler/rustc_middle/src/ty/layout.rs +++ b/compiler/rustc_middle/src/ty/layout.rs @@ -1351,3 +1351,37 @@ pub trait FnAbiOf<'tcx>: FnAbiOfHelpers<'tcx> { } impl<'tcx, C: FnAbiOfHelpers<'tcx>> FnAbiOf<'tcx> for C {} + +impl<'tcx> TyCtxt<'tcx> { + pub fn offset_of_subfield( + self, + param_env: ty::ParamEnv<'tcx>, + mut layout: TyAndLayout<'tcx>, + indices: I, + ) -> Size + where + I: Iterator, + { + let cx = LayoutCx { tcx: self, param_env }; + let mut offset = Size::ZERO; + + for (variant, field) in indices { + layout = layout.for_variant(&cx, variant); + let index = field.index(); + offset += layout.fields.offset(index); + layout = layout.field(&cx, index); + if !layout.is_sized() { + // If it is not sized, then the tail must still have at least a known static alignment. + let tail = self.struct_tail_erasing_lifetimes(layout.ty, param_env); + if !matches!(tail.kind(), ty::Slice(..)) { + bug!( + "offset of not-statically-aligned field (type {:?}) cannot be computed statically", + layout.ty + ); + } + } + } + + offset + } +} diff --git a/compiler/rustc_mir_transform/src/dataflow_const_prop.rs b/compiler/rustc_mir_transform/src/dataflow_const_prop.rs index a8caead46f2f..eba5d13d33f6 100644 --- a/compiler/rustc_mir_transform/src/dataflow_const_prop.rs +++ b/compiler/rustc_mir_transform/src/dataflow_const_prop.rs @@ -10,7 +10,7 @@ use rustc_middle::bug; use rustc_middle::mir::interpret::{InterpResult, Scalar}; use rustc_middle::mir::visit::{MutVisitor, PlaceContext, Visitor}; use rustc_middle::mir::*; -use rustc_middle::ty::layout::LayoutOf; +use rustc_middle::ty::layout::{HasParamEnv, LayoutOf}; use rustc_middle::ty::{self, Ty, TyCtxt}; use rustc_mir_dataflow::value_analysis::{ Map, PlaceIndex, State, TrackElem, ValueAnalysis, ValueAnalysisWrapper, ValueOrPlace, @@ -285,9 +285,11 @@ impl<'tcx> ValueAnalysis<'tcx> for ConstAnalysis<'_, 'tcx> { let val = match null_op { NullOp::SizeOf if layout.is_sized() => layout.size.bytes(), NullOp::AlignOf if layout.is_sized() => layout.align.abi.bytes(), - NullOp::OffsetOf(fields) => { - layout.offset_of_subfield(&self.ecx, fields.iter()).bytes() - } + NullOp::OffsetOf(fields) => self + .ecx + .tcx + .offset_of_subfield(self.ecx.param_env(), layout, fields.iter()) + .bytes(), _ => return ValueOrPlace::Value(FlatSet::Top), }; FlatSet::Elem(Scalar::from_target_usize(val, &self.tcx)) diff --git a/compiler/rustc_mir_transform/src/gvn.rs b/compiler/rustc_mir_transform/src/gvn.rs index acde16fcb757..ebfb372329ee 100644 --- a/compiler/rustc_mir_transform/src/gvn.rs +++ b/compiler/rustc_mir_transform/src/gvn.rs @@ -95,7 +95,7 @@ use rustc_middle::bug; use rustc_middle::mir::interpret::GlobalAlloc; use rustc_middle::mir::visit::*; use rustc_middle::mir::*; -use rustc_middle::ty::layout::LayoutOf; +use rustc_middle::ty::layout::{HasParamEnv, LayoutOf}; use rustc_middle::ty::{self, Ty, TyCtxt}; use rustc_span::def_id::DefId; use rustc_span::DUMMY_SP; @@ -484,9 +484,11 @@ impl<'body, 'tcx> VnState<'body, 'tcx> { let val = match null_op { NullOp::SizeOf => layout.size.bytes(), NullOp::AlignOf => layout.align.abi.bytes(), - NullOp::OffsetOf(fields) => { - layout.offset_of_subfield(&self.ecx, fields.iter()).bytes() - } + NullOp::OffsetOf(fields) => self + .ecx + .tcx + .offset_of_subfield(self.ecx.param_env(), layout, fields.iter()) + .bytes(), NullOp::UbChecks => return None, }; let usize_layout = self.ecx.layout_of(self.tcx.types.usize).unwrap(); diff --git a/compiler/rustc_mir_transform/src/known_panics_lint.rs b/compiler/rustc_mir_transform/src/known_panics_lint.rs index 8b46658b3225..47bbddbc31d4 100644 --- a/compiler/rustc_mir_transform/src/known_panics_lint.rs +++ b/compiler/rustc_mir_transform/src/known_panics_lint.rs @@ -625,9 +625,10 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> { let val = match null_op { NullOp::SizeOf => op_layout.size.bytes(), NullOp::AlignOf => op_layout.align.abi.bytes(), - NullOp::OffsetOf(fields) => { - op_layout.offset_of_subfield(self, fields.iter()).bytes() - } + NullOp::OffsetOf(fields) => self + .tcx + .offset_of_subfield(self.param_env, op_layout, fields.iter()) + .bytes(), NullOp::UbChecks => return None, }; ImmTy::from_scalar(Scalar::from_target_usize(val, self), layout).into() diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 935942641677..e245dfb9f5d7 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -1304,6 +1304,7 @@ symbols! { offset_of, offset_of_enum, offset_of_nested, + offset_of_slice, ok_or_else, omit_gdb_pretty_printer_section, on, diff --git a/compiler/rustc_target/src/abi/mod.rs b/compiler/rustc_target/src/abi/mod.rs index 666efd9deca2..737e9a8eab02 100644 --- a/compiler/rustc_target/src/abi/mod.rs +++ b/compiler/rustc_target/src/abi/mod.rs @@ -256,29 +256,6 @@ impl<'a, Ty> TyAndLayout<'a, Ty> { Ty::is_transparent(self) } - pub fn offset_of_subfield(self, cx: &C, indices: I) -> Size - where - Ty: TyAbiInterface<'a, C>, - I: Iterator, - { - let mut layout = self; - let mut offset = Size::ZERO; - - for (variant, field) in indices { - layout = layout.for_variant(cx, variant); - let index = field.index(); - offset += layout.fields.offset(index); - layout = layout.field(cx, index); - assert!( - layout.is_sized(), - "offset of unsized field (type {:?}) cannot be computed statically", - layout.ty - ); - } - - offset - } - /// Finds the one field that is not a 1-ZST. /// Returns `None` if there are multiple non-1-ZST fields or only 1-ZST-fields. pub fn non_1zst_field(&self, cx: &C) -> Option<(usize, Self)> diff --git a/tests/ui/feature-gates/feature-gate-offset-of-slice.rs b/tests/ui/feature-gates/feature-gate-offset-of-slice.rs new file mode 100644 index 000000000000..23e8668bc685 --- /dev/null +++ b/tests/ui/feature-gates/feature-gate-offset-of-slice.rs @@ -0,0 +1,26 @@ +use std::mem::offset_of; + +struct S { + a: u8, + b: (u8, u8), + c: [i32], +} + +struct T { + x: i32, + y: S, +} + +type Tup = (i32, [i32]); + +fn main() { + offset_of!(S, c); //~ ERROR size for values of type `[i32]` cannot be known at compilation time +} + +fn other() { + offset_of!(T, y); //~ ERROR size for values of type `[i32]` cannot be known at compilation time +} + +fn tuple() { + offset_of!(Tup, 1); //~ ERROR size for values of type `[i32]` cannot be known at compilation time +} diff --git a/tests/ui/feature-gates/feature-gate-offset-of-slice.stderr b/tests/ui/feature-gates/feature-gate-offset-of-slice.stderr new file mode 100644 index 000000000000..5cf34a897f4d --- /dev/null +++ b/tests/ui/feature-gates/feature-gate-offset-of-slice.stderr @@ -0,0 +1,35 @@ +error[E0277]: the size for values of type `[i32]` cannot be known at compilation time + --> $DIR/feature-gate-offset-of-slice.rs:17:5 + | +LL | offset_of!(S, c); + | ^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `[i32]` + = note: this error originates in the macro `offset_of` (in Nightly builds, run with -Z macro-backtrace for more info) + +error[E0277]: the size for values of type `[i32]` cannot be known at compilation time + --> $DIR/feature-gate-offset-of-slice.rs:21:5 + | +LL | offset_of!(T, y); + | ^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time + | + = help: within `S`, the trait `Sized` is not implemented for `[i32]`, which is required by `S: Sized` +note: required because it appears within the type `S` + --> $DIR/feature-gate-offset-of-slice.rs:3:8 + | +LL | struct S { + | ^ + = note: this error originates in the macro `offset_of` (in Nightly builds, run with -Z macro-backtrace for more info) + +error[E0277]: the size for values of type `[i32]` cannot be known at compilation time + --> $DIR/feature-gate-offset-of-slice.rs:25:5 + | +LL | offset_of!(Tup, 1); + | ^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `[i32]` + = note: this error originates in the macro `offset_of` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/offset-of/offset-of-dst-field.rs b/tests/ui/offset-of/offset-of-dst-field.rs index 016ebfadd142..5ae15f323577 100644 --- a/tests/ui/offset-of/offset-of-dst-field.rs +++ b/tests/ui/offset-of/offset-of-dst-field.rs @@ -49,3 +49,7 @@ fn delta() { fn generic_with_maybe_sized() -> usize { offset_of!(Delta, z) //~ ERROR the size for values of type } + +fn illformed_tuple() { + offset_of!(([u8], u8), 1); //~ ERROR the size for values of type +} diff --git a/tests/ui/offset-of/offset-of-dst-field.stderr b/tests/ui/offset-of/offset-of-dst-field.stderr index adfd16c6f2b9..bcfe796897e0 100644 --- a/tests/ui/offset-of/offset-of-dst-field.stderr +++ b/tests/ui/offset-of/offset-of-dst-field.stderr @@ -81,6 +81,15 @@ LL - fn generic_with_maybe_sized() -> usize { LL + fn generic_with_maybe_sized() -> usize { | -error: aborting due to 8 previous errors +error[E0277]: the size for values of type `[u8]` cannot be known at compilation time + --> $DIR/offset-of-dst-field.rs:54:16 + | +LL | offset_of!(([u8], u8), 1); + | ^^^^^^^^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `[u8]` + = note: only the last element of a tuple may have a dynamically sized type + +error: aborting due to 9 previous errors For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/offset-of/offset-of-slice.rs b/tests/ui/offset-of/offset-of-slice.rs new file mode 100644 index 000000000000..a0fe3198f686 --- /dev/null +++ b/tests/ui/offset-of/offset-of-slice.rs @@ -0,0 +1,26 @@ +//@run-pass +#![feature(offset_of_slice, offset_of_nested)] + +use std::mem::offset_of; + +#[repr(C)] +struct S { + a: u8, + b: (u8, u8), + c: [i32], +} + +#[repr(C)] +struct T { + x: i8, + y: S, +} + +type Tup = (i16, [i32]); + +fn main() { + assert_eq!(offset_of!(S, c), 4); + assert_eq!(offset_of!(T, y), 4); + assert_eq!(offset_of!(T, y.c), 8); + assert_eq!(offset_of!(Tup, 1), 4); +} From 75607b7a5aed2c585df06c28e8473f503ffd6eb0 Mon Sep 17 00:00:00 2001 From: David Carlier Date: Sat, 8 Jun 2024 17:12:17 +0000 Subject: [PATCH 11/50] std::unix::os current_exe implementation simplification for haiku. _get_net_image_info is a bit overkill as it allows to get broader informations about the process. --- library/std/src/sys/pal/unix/os.rs | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/library/std/src/sys/pal/unix/os.rs b/library/std/src/sys/pal/unix/os.rs index b5c7d30da7bc..ae1e42c419b9 100644 --- a/library/std/src/sys/pal/unix/os.rs +++ b/library/std/src/sys/pal/unix/os.rs @@ -462,21 +462,21 @@ pub fn current_exe() -> io::Result { #[cfg(target_os = "haiku")] pub fn current_exe() -> io::Result { + let mut name = vec![0; libc::PATH_MAX as usize]; unsafe { - let mut info: mem::MaybeUninit = mem::MaybeUninit::uninit(); - let mut cookie: i32 = 0; - // the executable can be found at team id 0 - let result = libc::_get_next_image_info( - 0, - &mut cookie, - info.as_mut_ptr(), - mem::size_of::(), + let result = libc::find_path( + std::ptr::null_mut(), + libc::path_base_directory::B_FIND_PATH_IMAGE_PATH, + std::ptr::null_mut(), + name.as_mut_ptr(), + name.len(), ); - if result != 0 { + if result != libc::B_OK { use crate::io::ErrorKind; Err(io::const_io_error!(ErrorKind::Uncategorized, "Error getting executable path")) } else { - let name = CStr::from_ptr((*info.as_ptr()).name.as_ptr()).to_bytes(); + // find_path adds the null terminator. + let name = CStr::from_ptr(name.as_ptr()).to_bytes(); Ok(PathBuf::from(OsStr::from_bytes(name))) } } From 18ae9afa826006cf2f78a0defda286fcaf4bee99 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Fri, 7 Jun 2024 14:50:03 +0200 Subject: [PATCH 12/50] Introduce a custom `Command` wrapper in `run-make-support` --- src/tools/run-make-support/src/cc.rs | 2 +- src/tools/run-make-support/src/clang.rs | 7 +- src/tools/run-make-support/src/command.rs | 91 +++++++++++++++++++ src/tools/run-make-support/src/lib.rs | 38 ++++---- .../run-make-support/src/llvm_readobj.rs | 8 +- src/tools/run-make-support/src/run.rs | 14 +-- src/tools/run-make-support/src/rustc.rs | 46 +--------- src/tools/run-make-support/src/rustdoc.rs | 45 +-------- 8 files changed, 129 insertions(+), 122 deletions(-) create mode 100644 src/tools/run-make-support/src/command.rs diff --git a/src/tools/run-make-support/src/cc.rs b/src/tools/run-make-support/src/cc.rs index b33004974bf3..bfed6d922abe 100644 --- a/src/tools/run-make-support/src/cc.rs +++ b/src/tools/run-make-support/src/cc.rs @@ -1,7 +1,7 @@ use std::path::Path; -use std::process::Command; use crate::{bin_name, cygpath_windows, env_var, handle_failed_output, is_msvc, is_windows, uname}; +use crate::command::Command; /// Construct a new platform-specific C compiler invocation. /// diff --git a/src/tools/run-make-support/src/clang.rs b/src/tools/run-make-support/src/clang.rs index 7d9246b52227..2ceea3df95eb 100644 --- a/src/tools/run-make-support/src/clang.rs +++ b/src/tools/run-make-support/src/clang.rs @@ -1,7 +1,7 @@ use std::path::Path; -use std::process::Command; use crate::{bin_name, env_var, handle_failed_output}; +use crate::command::Command; /// Construct a new `clang` invocation. `clang` is not always available for all targets. pub fn clang() -> Clang { @@ -68,9 +68,4 @@ impl Clang { self.cmd.arg(format!("-fuse-ld={ld}")); self } - - /// Get the [`Output`][::std::process::Output] of the finished process. - pub fn command_output(&mut self) -> ::std::process::Output { - self.cmd.output().expect("failed to get output of finished process") - } } diff --git a/src/tools/run-make-support/src/command.rs b/src/tools/run-make-support/src/command.rs new file mode 100644 index 000000000000..c142c80024ba --- /dev/null +++ b/src/tools/run-make-support/src/command.rs @@ -0,0 +1,91 @@ +use std::ffi::OsStr; +use std::io::Write; +use std::ops::{Deref, DerefMut}; +use std::process::{Command as StdCommand, ExitStatus, Output, Stdio}; + +#[derive(Debug)] +pub struct Command { + cmd: StdCommand, + stdin: Option>, +} + +impl Command { + pub fn new>(program: S) -> Self { + Self { + cmd: StdCommand::new(program), + stdin: None, + } + } + + pub fn set_stdin(&mut self, stdin: Box<[u8]>) { + self.stdin = Some(stdin); + } + + #[track_caller] + pub(crate) fn command_output(&mut self) -> CompletedProcess { + // let's make sure we piped all the input and outputs + self.cmd.stdin(Stdio::piped()); + self.cmd.stdout(Stdio::piped()); + self.cmd.stderr(Stdio::piped()); + + let output = if let Some(input) = &self.stdin { + let mut child = self.cmd.spawn().unwrap(); + + { + let mut stdin = child.stdin.take().unwrap(); + stdin.write_all(input.as_ref()).unwrap(); + } + + child.wait_with_output().expect("failed to get output of finished process") + } else { + self.cmd.output().expect("failed to get output of finished process") + }; + output.into() + } +} + +impl Deref for Command { + type Target = StdCommand; + + fn deref(&self) -> &Self::Target { + &self.cmd + } +} + +impl DerefMut for Command { + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.cmd + } +} + +/// Represents the result of an executed process. +pub struct CompletedProcess { + output: Output, +} + +impl CompletedProcess { + pub fn stdout_utf8(&self) -> String { + String::from_utf8(self.output.stdout.clone()).expect("stdout is not valid UTF-8") + } + + pub fn stderr_utf8(&self) -> String { + String::from_utf8(self.output.stderr.clone()).expect("stderr is not valid UTF-8") + } + + pub fn status(&self) -> ExitStatus { + self.output.status + } + + #[track_caller] + pub fn assert_exit_code(&self, code: i32) { + assert!(self.output.status.code() == Some(code)); + } +} + +impl From for CompletedProcess { + fn from(output: Output) -> Self { + Self { + output + } + } +} diff --git a/src/tools/run-make-support/src/lib.rs b/src/tools/run-make-support/src/lib.rs index 0d167960c162..c22ff12814b7 100644 --- a/src/tools/run-make-support/src/lib.rs +++ b/src/tools/run-make-support/src/lib.rs @@ -10,13 +10,13 @@ pub mod llvm_readobj; pub mod run; pub mod rustc; pub mod rustdoc; +mod command; use std::env; use std::ffi::OsString; use std::fs; use std::io; use std::path::{Path, PathBuf}; -use std::process::{Command, Output}; pub use gimli; pub use object; @@ -167,13 +167,12 @@ pub fn cygpath_windows>(path: P) -> String { let mut cygpath = Command::new("cygpath"); cygpath.arg("-w"); cygpath.arg(path.as_ref()); - let output = cygpath.output().unwrap(); - if !output.status.success() { + let output = cygpath.command_output(); + if !output.status().success() { handle_failed_output(&cygpath, output, caller_line_number); } - let s = String::from_utf8(output.stdout).unwrap(); // cygpath -w can attach a newline - s.trim().to_string() + output.stdout_utf8().trim().to_string() } /// Run `uname`. This assumes that `uname` is available on the platform! @@ -183,23 +182,23 @@ pub fn uname() -> String { let caller_line_number = caller_location.line(); let mut uname = Command::new("uname"); - let output = uname.output().unwrap(); - if !output.status.success() { + let output = uname.command_output(); + if !output.status().success() { handle_failed_output(&uname, output, caller_line_number); } - String::from_utf8(output.stdout).unwrap() + output.stdout_utf8() } -fn handle_failed_output(cmd: &Command, output: Output, caller_line_number: u32) -> ! { - if output.status.success() { +fn handle_failed_output(cmd: &Command, output: CompletedProcess, caller_line_number: u32) -> ! { + if output.status().success() { eprintln!("command unexpectedly succeeded at line {caller_line_number}"); } else { eprintln!("command failed at line {caller_line_number}"); } eprintln!("{cmd:?}"); - eprintln!("output status: `{}`", output.status); - eprintln!("=== STDOUT ===\n{}\n\n", String::from_utf8(output.stdout).unwrap()); - eprintln!("=== STDERR ===\n{}\n\n", String::from_utf8(output.stderr).unwrap()); + eprintln!("output status: `{}`", output.status()); + eprintln!("=== STDOUT ===\n{}\n\n", output.stdout_utf8()); + eprintln!("=== STDERR ===\n{}\n\n", output.stderr_utf8()); std::process::exit(1) } @@ -412,12 +411,12 @@ macro_rules! impl_common_helpers { /// Run the constructed command and assert that it is successfully run. #[track_caller] - pub fn run(&mut self) -> ::std::process::Output { + pub fn run(&mut self) -> crate::command::CompletedProcess { let caller_location = ::std::panic::Location::caller(); let caller_line_number = caller_location.line(); - let output = self.command_output(); - if !output.status.success() { + let output = self.cmd.command_output(); + if !output.status().success() { handle_failed_output(&self.cmd, output, caller_line_number); } output @@ -425,12 +424,12 @@ macro_rules! impl_common_helpers { /// Run the constructed command and assert that it does not successfully run. #[track_caller] - pub fn run_fail(&mut self) -> ::std::process::Output { + pub fn run_fail(&mut self) -> crate::command::CompletedProcess { let caller_location = ::std::panic::Location::caller(); let caller_line_number = caller_location.line(); - let output = self.command_output(); - if output.status.success() { + let output = self.cmd.command_output(); + if output.status().success() { handle_failed_output(&self.cmd, output, caller_line_number); } output @@ -446,3 +445,4 @@ macro_rules! impl_common_helpers { } pub(crate) use impl_common_helpers; +use crate::command::{Command, CompletedProcess}; diff --git a/src/tools/run-make-support/src/llvm_readobj.rs b/src/tools/run-make-support/src/llvm_readobj.rs index 77aaadfe18c4..a834d3a2e19d 100644 --- a/src/tools/run-make-support/src/llvm_readobj.rs +++ b/src/tools/run-make-support/src/llvm_readobj.rs @@ -1,7 +1,7 @@ use std::path::{Path, PathBuf}; -use std::process::Command; use crate::{env_var, handle_failed_output}; +use crate::command::Command; /// Construct a new `llvm-readobj` invocation. This assumes that `llvm-readobj` is available /// at `$LLVM_BIN_DIR/llvm-readobj`. @@ -39,10 +39,4 @@ impl LlvmReadobj { self.cmd.arg("--file-header"); self } - - /// Get the [`Output`][::std::process::Output] of the finished process. - #[track_caller] - pub fn command_output(&mut self) -> ::std::process::Output { - self.cmd.output().expect("failed to get output of finished process") - } } diff --git a/src/tools/run-make-support/src/run.rs b/src/tools/run-make-support/src/run.rs index b607c583e328..09ad98c24517 100644 --- a/src/tools/run-make-support/src/run.rs +++ b/src/tools/run-make-support/src/run.rs @@ -1,12 +1,12 @@ use std::env; use std::path::{Path, PathBuf}; -use std::process::{Command, Output}; use crate::{cwd, env_var, is_windows}; +use crate::command::{Command, CompletedProcess}; use super::handle_failed_output; -fn run_common(name: &str) -> (Command, Output) { +fn run_common(name: &str) -> (Command, CompletedProcess) { let mut bin_path = PathBuf::new(); bin_path.push(cwd()); bin_path.push(name); @@ -33,18 +33,18 @@ fn run_common(name: &str) -> (Command, Output) { cmd.env("PATH", env::join_paths(paths.iter()).unwrap()); } - let output = cmd.output().unwrap(); + let output = cmd.command_output(); (cmd, output) } /// Run a built binary and make sure it succeeds. #[track_caller] -pub fn run(name: &str) -> Output { +pub fn run(name: &str) -> CompletedProcess { let caller_location = std::panic::Location::caller(); let caller_line_number = caller_location.line(); let (cmd, output) = run_common(name); - if !output.status.success() { + if !output.status().success() { handle_failed_output(&cmd, output, caller_line_number); } output @@ -52,12 +52,12 @@ pub fn run(name: &str) -> Output { /// Run a built binary and make sure it fails. #[track_caller] -pub fn run_fail(name: &str) -> Output { +pub fn run_fail(name: &str) -> CompletedProcess { let caller_location = std::panic::Location::caller(); let caller_line_number = caller_location.line(); let (cmd, output) = run_common(name); - if output.status.success() { + if output.status().success() { handle_failed_output(&cmd, output, caller_line_number); } output diff --git a/src/tools/run-make-support/src/rustc.rs b/src/tools/run-make-support/src/rustc.rs index a64dd9d30cf5..9bbe30bcb2d9 100644 --- a/src/tools/run-make-support/src/rustc.rs +++ b/src/tools/run-make-support/src/rustc.rs @@ -1,9 +1,8 @@ use std::ffi::{OsStr, OsString}; -use std::io::Write; use std::path::Path; -use std::process::{Command, Output, Stdio}; +use command::Command; -use crate::{cwd, env_var, handle_failed_output, set_host_rpath}; +use crate::{command, cwd, env_var, handle_failed_output, set_host_rpath}; /// Construct a new `rustc` invocation. pub fn rustc() -> Rustc { @@ -19,7 +18,6 @@ pub fn aux_build() -> Rustc { #[derive(Debug)] pub struct Rustc { cmd: Command, - stdin: Option>, } crate::impl_common_helpers!(Rustc); @@ -38,14 +36,14 @@ impl Rustc { /// Construct a new `rustc` invocation. pub fn new() -> Self { let cmd = setup_common(); - Self { cmd, stdin: None } + Self { cmd } } /// Construct a new `rustc` invocation with `aux_build` preset (setting `--crate-type=lib`). pub fn new_aux_build() -> Self { let mut cmd = setup_common(); cmd.arg("--crate-type=lib"); - Self { cmd, stdin: None } + Self { cmd } } // Argument provider methods @@ -197,7 +195,7 @@ impl Rustc { /// Specify a stdin input pub fn stdin>(&mut self, input: I) -> &mut Self { - self.stdin = Some(input.as_ref().to_vec().into_boxed_slice()); + self.cmd.set_stdin(input.as_ref().to_vec().into_boxed_slice()); self } @@ -213,38 +211,4 @@ impl Rustc { self.cmd.arg(format!("-Clinker={linker}")); self } - - /// Get the [`Output`] of the finished process. - #[track_caller] - pub fn command_output(&mut self) -> Output { - // let's make sure we piped all the input and outputs - self.cmd.stdin(Stdio::piped()); - self.cmd.stdout(Stdio::piped()); - self.cmd.stderr(Stdio::piped()); - - if let Some(input) = &self.stdin { - let mut child = self.cmd.spawn().unwrap(); - - { - let mut stdin = child.stdin.take().unwrap(); - stdin.write_all(input.as_ref()).unwrap(); - } - - child.wait_with_output().expect("failed to get output of finished process") - } else { - self.cmd.output().expect("failed to get output of finished process") - } - } - - #[track_caller] - pub fn run_fail_assert_exit_code(&mut self, code: i32) -> Output { - let caller_location = std::panic::Location::caller(); - let caller_line_number = caller_location.line(); - - let output = self.command_output(); - if output.status.code().unwrap() != code { - handle_failed_output(&self.cmd, output, caller_line_number); - } - output - } } diff --git a/src/tools/run-make-support/src/rustdoc.rs b/src/tools/run-make-support/src/rustdoc.rs index 34d32992e65e..c75bb1d1196a 100644 --- a/src/tools/run-make-support/src/rustdoc.rs +++ b/src/tools/run-make-support/src/rustdoc.rs @@ -1,9 +1,8 @@ use std::ffi::OsStr; -use std::io::Write; use std::path::Path; -use std::process::{Command, Output, Stdio}; use crate::{env_var, env_var_os, handle_failed_output, set_host_rpath}; +use crate::command::Command; /// Construct a plain `rustdoc` invocation with no flags set. pub fn bare_rustdoc() -> Rustdoc { @@ -18,7 +17,6 @@ pub fn rustdoc() -> Rustdoc { #[derive(Debug)] pub struct Rustdoc { cmd: Command, - stdin: Option>, } crate::impl_common_helpers!(Rustdoc); @@ -34,7 +32,7 @@ impl Rustdoc { /// Construct a bare `rustdoc` invocation. pub fn bare() -> Self { let cmd = setup_common(); - Self { cmd, stdin: None } + Self { cmd } } /// Construct a `rustdoc` invocation with `-L $(TARGET_RPATH_DIR)` set. @@ -42,7 +40,7 @@ impl Rustdoc { let mut cmd = setup_common(); let target_rpath_dir = env_var_os("TARGET_RPATH_DIR"); cmd.arg(format!("-L{}", target_rpath_dir.to_string_lossy())); - Self { cmd, stdin: None } + Self { cmd } } /// Specify where an external library is located. @@ -88,33 +86,10 @@ impl Rustdoc { /// Specify a stdin input pub fn stdin>(&mut self, input: I) -> &mut Self { - self.cmd.stdin(Stdio::piped()); - self.stdin = Some(input.as_ref().to_vec().into_boxed_slice()); + self.cmd.set_stdin(input.as_ref().to_vec().into_boxed_slice()); self } - /// Get the [`Output`] of the finished process. - #[track_caller] - pub fn command_output(&mut self) -> ::std::process::Output { - // let's make sure we piped all the input and outputs - self.cmd.stdin(Stdio::piped()); - self.cmd.stdout(Stdio::piped()); - self.cmd.stderr(Stdio::piped()); - - if let Some(input) = &self.stdin { - let mut child = self.cmd.spawn().unwrap(); - - { - let mut stdin = child.stdin.take().unwrap(); - stdin.write_all(input.as_ref()).unwrap(); - } - - child.wait_with_output().expect("failed to get output of finished process") - } else { - self.cmd.output().expect("failed to get output of finished process") - } - } - /// Specify the edition year. pub fn edition(&mut self, edition: &str) -> &mut Self { self.cmd.arg("--edition"); @@ -156,16 +131,4 @@ impl Rustdoc { self.cmd.arg(format); self } - - #[track_caller] - pub fn run_fail_assert_exit_code(&mut self, code: i32) -> Output { - let caller_location = std::panic::Location::caller(); - let caller_line_number = caller_location.line(); - - let output = self.command_output(); - if output.status.code().unwrap() != code { - handle_failed_output(&self.cmd, output, caller_line_number); - } - output - } } From 0a190e8d2d9bbe0b417b6f160042b816b31cec7b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Fri, 7 Jun 2024 15:23:10 +0200 Subject: [PATCH 13/50] Migrate runmake tests away from custom commands and `command_output` --- src/tools/run-make-support/src/cc.rs | 2 +- src/tools/run-make-support/src/clang.rs | 2 +- src/tools/run-make-support/src/command.rs | 76 +++++++++++++++++-- src/tools/run-make-support/src/lib.rs | 25 ++---- .../run-make-support/src/llvm_readobj.rs | 2 +- src/tools/run-make-support/src/run.rs | 11 ++- src/tools/run-make-support/src/rustc.rs | 4 +- src/tools/run-make-support/src/rustdoc.rs | 2 +- tests/run-make/CURRENT_RUSTC_VERSION/rmake.rs | 10 +-- .../allow-warnings-cmdline-stability/rmake.rs | 12 +-- tests/run-make/compiler-builtins/rmake.rs | 9 +-- tests/run-make/const-prop-lint/rmake.rs | 2 +- tests/run-make/crate-data-smoke/rmake.rs | 35 +++++---- tests/run-make/exit-code/rmake.rs | 13 ++-- tests/run-make/mixing-formats/rmake.rs | 4 +- .../no-input-file/no-input-file.stderr | 2 - tests/run-make/no-input-file/rmake.rs | 10 ++- tests/run-make/non-unicode-env/rmake.rs | 3 +- .../notify-all-emit-artifacts/rmake.rs | 4 +- tests/run-make/print-cfg/rmake.rs | 5 +- tests/run-make/print-check-cfg/rmake.rs | 2 +- .../print-native-static-libs/rmake.rs | 4 +- tests/run-make/print-to-output/rmake.rs | 8 +- tests/run-make/rust-lld-by-default/rmake.rs | 11 ++- .../run-make/rust-lld-custom-target/rmake.rs | 11 ++- tests/run-make/rust-lld/rmake.rs | 15 ++-- tests/run-make/rustdoc-error-lines/rmake.rs | 4 +- .../rustdoc-scrape-examples-macros/rmake.rs | 19 ++--- tests/run-make/rustdoc-shared-flags/rmake.rs | 4 +- tests/run-make/stdin-rustc/rmake.rs | 6 +- 30 files changed, 176 insertions(+), 141 deletions(-) delete mode 100644 tests/run-make/no-input-file/no-input-file.stderr diff --git a/src/tools/run-make-support/src/cc.rs b/src/tools/run-make-support/src/cc.rs index bfed6d922abe..5c0158d75470 100644 --- a/src/tools/run-make-support/src/cc.rs +++ b/src/tools/run-make-support/src/cc.rs @@ -1,7 +1,7 @@ use std::path::Path; -use crate::{bin_name, cygpath_windows, env_var, handle_failed_output, is_msvc, is_windows, uname}; use crate::command::Command; +use crate::{bin_name, cygpath_windows, env_var, is_msvc, is_windows, uname}; /// Construct a new platform-specific C compiler invocation. /// diff --git a/src/tools/run-make-support/src/clang.rs b/src/tools/run-make-support/src/clang.rs index 2ceea3df95eb..d2ebed7ab067 100644 --- a/src/tools/run-make-support/src/clang.rs +++ b/src/tools/run-make-support/src/clang.rs @@ -1,7 +1,7 @@ use std::path::Path; -use crate::{bin_name, env_var, handle_failed_output}; use crate::command::Command; +use crate::{bin_name, env_var}; /// Construct a new `clang` invocation. `clang` is not always available for all targets. pub fn clang() -> Clang { diff --git a/src/tools/run-make-support/src/command.rs b/src/tools/run-make-support/src/command.rs index c142c80024ba..b9e56ab632ad 100644 --- a/src/tools/run-make-support/src/command.rs +++ b/src/tools/run-make-support/src/command.rs @@ -1,8 +1,12 @@ +use crate::{assert_not_contains, handle_failed_output}; use std::ffi::OsStr; use std::io::Write; use std::ops::{Deref, DerefMut}; use std::process::{Command as StdCommand, ExitStatus, Output, Stdio}; +/// This is a custom command wrapper that simplifies working with commands +/// and makes it easier to ensure that we check the exit status of executed +/// processes. #[derive(Debug)] pub struct Command { cmd: StdCommand, @@ -11,16 +15,39 @@ pub struct Command { impl Command { pub fn new>(program: S) -> Self { - Self { - cmd: StdCommand::new(program), - stdin: None, - } + Self { cmd: StdCommand::new(program), stdin: None } } pub fn set_stdin(&mut self, stdin: Box<[u8]>) { self.stdin = Some(stdin); } + /// Run the constructed command and assert that it is successfully run. + #[track_caller] + pub fn run(&mut self) -> CompletedProcess { + let caller_location = std::panic::Location::caller(); + let caller_line_number = caller_location.line(); + + let output = self.command_output(); + if !output.status().success() { + handle_failed_output(&self, output, caller_line_number); + } + output + } + + /// Run the constructed command and assert that it does not successfully run. + #[track_caller] + pub fn run_fail(&mut self) -> CompletedProcess { + let caller_location = std::panic::Location::caller(); + let caller_line_number = caller_location.line(); + + let output = self.command_output(); + if output.status().success() { + handle_failed_output(&self, output, caller_line_number); + } + output + } + #[track_caller] pub(crate) fn command_output(&mut self) -> CompletedProcess { // let's make sure we piped all the input and outputs @@ -59,6 +86,8 @@ impl DerefMut for Command { } /// Represents the result of an executed process. +/// The various `assert_` helper methods should preferably be used for +/// checking the contents of stdout/stderr. pub struct CompletedProcess { output: Output, } @@ -76,16 +105,47 @@ impl CompletedProcess { self.output.status } + /// Checks that trimmed `stdout` matches trimmed `content`. #[track_caller] - pub fn assert_exit_code(&self, code: i32) { + pub fn assert_stdout_equals>(self, content: S) -> Self { + assert_eq!(self.stdout_utf8().trim(), content.as_ref().trim()); + self + } + + #[track_caller] + pub fn assert_stdout_not_contains>(self, needle: S) -> Self { + assert_not_contains(&self.stdout_utf8(), needle.as_ref()); + self + } + + /// Checks that trimmed `stderr` matches trimmed `content`. + #[track_caller] + pub fn assert_stderr_equals>(self, content: S) -> Self { + assert_eq!(self.stderr_utf8().trim(), content.as_ref().trim()); + self + } + + #[track_caller] + pub fn assert_stderr_contains>(self, needle: S) -> Self { + assert!(self.stderr_utf8().contains(needle.as_ref())); + self + } + + #[track_caller] + pub fn assert_stderr_not_contains>(self, needle: S) -> Self { + assert_not_contains(&self.stdout_utf8(), needle.as_ref()); + self + } + + #[track_caller] + pub fn assert_exit_code(self, code: i32) -> Self { assert!(self.output.status.code() == Some(code)); + self } } impl From for CompletedProcess { fn from(output: Output) -> Self { - Self { - output - } + Self { output } } } diff --git a/src/tools/run-make-support/src/lib.rs b/src/tools/run-make-support/src/lib.rs index c22ff12814b7..b17f217c133b 100644 --- a/src/tools/run-make-support/src/lib.rs +++ b/src/tools/run-make-support/src/lib.rs @@ -5,12 +5,12 @@ pub mod cc; pub mod clang; +mod command; pub mod diff; pub mod llvm_readobj; pub mod run; pub mod rustc; pub mod rustdoc; -mod command; use std::env; use std::ffi::OsString; @@ -27,7 +27,7 @@ pub use cc::{cc, extra_c_flags, extra_cxx_flags, Cc}; pub use clang::{clang, Clang}; pub use diff::{diff, Diff}; pub use llvm_readobj::{llvm_readobj, LlvmReadobj}; -pub use run::{run, run_fail}; +pub use run::{cmd, run, run_fail}; pub use rustc::{aux_build, rustc, Rustc}; pub use rustdoc::{bare_rustdoc, rustdoc, Rustdoc}; @@ -285,6 +285,7 @@ pub fn read_dir(dir: impl AsRef, callback: F) { } /// Check that `haystack` does not contain `needle`. Panic otherwise. +#[track_caller] pub fn assert_not_contains(haystack: &str, needle: &str) { if haystack.contains(needle) { eprintln!("=== HAYSTACK ==="); @@ -412,27 +413,13 @@ macro_rules! impl_common_helpers { /// Run the constructed command and assert that it is successfully run. #[track_caller] pub fn run(&mut self) -> crate::command::CompletedProcess { - let caller_location = ::std::panic::Location::caller(); - let caller_line_number = caller_location.line(); - - let output = self.cmd.command_output(); - if !output.status().success() { - handle_failed_output(&self.cmd, output, caller_line_number); - } - output + self.cmd.run() } /// Run the constructed command and assert that it does not successfully run. #[track_caller] pub fn run_fail(&mut self) -> crate::command::CompletedProcess { - let caller_location = ::std::panic::Location::caller(); - let caller_line_number = caller_location.line(); - - let output = self.cmd.command_output(); - if output.status().success() { - handle_failed_output(&self.cmd, output, caller_line_number); - } - output + self.cmd.run_fail() } /// Set the path where the command will be run. @@ -444,5 +431,5 @@ macro_rules! impl_common_helpers { }; } -pub(crate) use impl_common_helpers; use crate::command::{Command, CompletedProcess}; +pub(crate) use impl_common_helpers; diff --git a/src/tools/run-make-support/src/llvm_readobj.rs b/src/tools/run-make-support/src/llvm_readobj.rs index a834d3a2e19d..db2f9db6e41f 100644 --- a/src/tools/run-make-support/src/llvm_readobj.rs +++ b/src/tools/run-make-support/src/llvm_readobj.rs @@ -1,7 +1,7 @@ use std::path::{Path, PathBuf}; -use crate::{env_var, handle_failed_output}; use crate::command::Command; +use crate::env_var; /// Construct a new `llvm-readobj` invocation. This assumes that `llvm-readobj` is available /// at `$LLVM_BIN_DIR/llvm-readobj`. diff --git a/src/tools/run-make-support/src/run.rs b/src/tools/run-make-support/src/run.rs index 09ad98c24517..4a6fd7c432e5 100644 --- a/src/tools/run-make-support/src/run.rs +++ b/src/tools/run-make-support/src/run.rs @@ -1,8 +1,9 @@ use std::env; +use std::ffi::OsStr; use std::path::{Path, PathBuf}; -use crate::{cwd, env_var, is_windows}; use crate::command::{Command, CompletedProcess}; +use crate::{cwd, env_var, is_windows, set_host_rpath}; use super::handle_failed_output; @@ -62,3 +63,11 @@ pub fn run_fail(name: &str) -> CompletedProcess { } output } + +/// Create a new custom Command. +/// This should be preferred to creating `std::process::Command` directly. +pub fn cmd>(program: S) -> Command { + let mut command = Command::new(program); + set_host_rpath(&mut command); + command +} diff --git a/src/tools/run-make-support/src/rustc.rs b/src/tools/run-make-support/src/rustc.rs index 9bbe30bcb2d9..d4c00d23b8b1 100644 --- a/src/tools/run-make-support/src/rustc.rs +++ b/src/tools/run-make-support/src/rustc.rs @@ -1,8 +1,8 @@ +use command::Command; use std::ffi::{OsStr, OsString}; use std::path::Path; -use command::Command; -use crate::{command, cwd, env_var, handle_failed_output, set_host_rpath}; +use crate::{command, cwd, env_var, set_host_rpath}; /// Construct a new `rustc` invocation. pub fn rustc() -> Rustc { diff --git a/src/tools/run-make-support/src/rustdoc.rs b/src/tools/run-make-support/src/rustdoc.rs index c75bb1d1196a..39a698a47b43 100644 --- a/src/tools/run-make-support/src/rustdoc.rs +++ b/src/tools/run-make-support/src/rustdoc.rs @@ -1,8 +1,8 @@ use std::ffi::OsStr; use std::path::Path; -use crate::{env_var, env_var_os, handle_failed_output, set_host_rpath}; use crate::command::Command; +use crate::{env_var, env_var_os, set_host_rpath}; /// Construct a plain `rustdoc` invocation with no flags set. pub fn bare_rustdoc() -> Rustdoc { diff --git a/tests/run-make/CURRENT_RUSTC_VERSION/rmake.rs b/tests/run-make/CURRENT_RUSTC_VERSION/rmake.rs index b56f8dd7acb2..f913aedcde75 100644 --- a/tests/run-make/CURRENT_RUSTC_VERSION/rmake.rs +++ b/tests/run-make/CURRENT_RUSTC_VERSION/rmake.rs @@ -10,14 +10,10 @@ use run_make_support::{aux_build, rustc, source_root}; fn main() { aux_build().input("stable.rs").emit("metadata").run(); - let output = rustc() - .input("main.rs") - .emit("metadata") - .extern_("stable", "libstable.rmeta") - .command_output(); + let output = + rustc().input("main.rs").emit("metadata").extern_("stable", "libstable.rmeta").run(); - let stderr = String::from_utf8_lossy(&output.stderr); let version = std::fs::read_to_string(source_root().join("src/version")).unwrap(); let expected_string = format!("stable since {}", version.trim()); - assert!(stderr.contains(&expected_string)); + output.assert_stderr_contains(expected_string); } diff --git a/tests/run-make/allow-warnings-cmdline-stability/rmake.rs b/tests/run-make/allow-warnings-cmdline-stability/rmake.rs index 8f6fe6bd0b66..22a31266176b 100644 --- a/tests/run-make/allow-warnings-cmdline-stability/rmake.rs +++ b/tests/run-make/allow-warnings-cmdline-stability/rmake.rs @@ -1,11 +1,13 @@ // Test that `-Awarnings` suppresses warnings for unstable APIs. -use run_make_support::{assert_not_contains, rustc}; +use run_make_support::rustc; fn main() { rustc().input("bar.rs").run(); - let output = rustc().input("foo.rs").arg("-Awarnings").run(); - - assert_not_contains(&String::from_utf8(output.stdout).unwrap(), "warning"); - assert_not_contains(&String::from_utf8(output.stderr).unwrap(), "warning"); + rustc() + .input("foo.rs") + .arg("-Awarnings") + .run() + .assert_stdout_not_contains("warning") + .assert_stderr_not_contains("warning"); } diff --git a/tests/run-make/compiler-builtins/rmake.rs b/tests/run-make/compiler-builtins/rmake.rs index 309d3a04b21c..a2c0ad5f6def 100644 --- a/tests/run-make/compiler-builtins/rmake.rs +++ b/tests/run-make/compiler-builtins/rmake.rs @@ -19,8 +19,7 @@ use run_make_support::object::read::Object; use run_make_support::object::ObjectSection; use run_make_support::object::ObjectSymbol; use run_make_support::object::RelocationTarget; -use run_make_support::set_host_rpath; -use run_make_support::{env_var, object}; +use run_make_support::{cmd, env_var, object}; use std::collections::HashSet; use std::path::PathBuf; @@ -35,7 +34,7 @@ fn main() { let path = env_var("PATH"); let rustc = env_var("RUSTC"); let bootstrap_cargo = env_var("BOOTSTRAP_CARGO"); - let mut cmd = std::process::Command::new(bootstrap_cargo); + let mut cmd = cmd(bootstrap_cargo); cmd.args([ "build", "--manifest-path", @@ -52,10 +51,8 @@ fn main() { // Visual Studio 2022 requires that the LIB env var be set so it can // find the Windows SDK. .env("LIB", std::env::var("LIB").unwrap_or_default()); - set_host_rpath(&mut cmd); - let status = cmd.status().unwrap(); - assert!(status.success()); + cmd.run(); let rlibs_path = target_dir.join(target).join("debug").join("deps"); let compiler_builtins_rlib = std::fs::read_dir(rlibs_path) diff --git a/tests/run-make/const-prop-lint/rmake.rs b/tests/run-make/const-prop-lint/rmake.rs index 6d0069a84d7a..c35294f2f5af 100644 --- a/tests/run-make/const-prop-lint/rmake.rs +++ b/tests/run-make/const-prop-lint/rmake.rs @@ -5,7 +5,7 @@ use std::fs; use run_make_support::{cwd, rustc}; fn main() { - rustc().input("input.rs").run_fail_assert_exit_code(1); + rustc().input("input.rs").run_fail().assert_exit_code(1); for entry in fs::read_dir(cwd()).unwrap() { let entry = entry.unwrap(); diff --git a/tests/run-make/crate-data-smoke/rmake.rs b/tests/run-make/crate-data-smoke/rmake.rs index 86fe5593e661..70f8e46b6d92 100644 --- a/tests/run-make/crate-data-smoke/rmake.rs +++ b/tests/run-make/crate-data-smoke/rmake.rs @@ -1,22 +1,21 @@ -use std::process::Output; - use run_make_support::{bin_name, rust_lib_name, rustc}; -fn compare_stdout>(output: Output, expected: S) { - assert_eq!(String::from_utf8(output.stdout).unwrap().trim(), expected.as_ref()); -} - fn main() { - compare_stdout(rustc().print("crate-name").input("crate.rs").run(), "foo"); - compare_stdout(rustc().print("file-names").input("crate.rs").run(), bin_name("foo")); - compare_stdout( - rustc().print("file-names").crate_type("lib").arg("--test").input("crate.rs").run(), - bin_name("foo"), - ); - compare_stdout( - rustc().print("file-names").arg("--test").input("lib.rs").run(), - bin_name("mylib"), - ); - compare_stdout(rustc().print("file-names").input("lib.rs").run(), rust_lib_name("mylib")); - compare_stdout(rustc().print("file-names").input("rlib.rs").run(), rust_lib_name("mylib")); + rustc().print("crate-name").input("crate.rs").run().assert_stdout_equals("foo"); + rustc().print("file-names").input("crate.rs").run().assert_stdout_equals(bin_name("foo")); + rustc() + .print("file-names") + .crate_type("lib") + .arg("--test") + .input("crate.rs") + .run() + .assert_stdout_equals(bin_name("foo")); + rustc() + .print("file-names") + .arg("--test") + .input("lib.rs") + .run() + .assert_stdout_equals(bin_name("mylib")); + rustc().print("file-names").input("lib.rs").run().assert_stdout_equals(rust_lib_name("mylib")); + rustc().print("file-names").input("rlib.rs").run().assert_stdout_equals(rust_lib_name("mylib")); } diff --git a/tests/run-make/exit-code/rmake.rs b/tests/run-make/exit-code/rmake.rs index 6bf7a232642d..f290554831db 100644 --- a/tests/run-make/exit-code/rmake.rs +++ b/tests/run-make/exit-code/rmake.rs @@ -5,21 +5,22 @@ use run_make_support::{rustc, rustdoc}; fn main() { rustc().arg("success.rs").run(); - rustc().arg("--invalid-arg-foo").run_fail_assert_exit_code(1); + rustc().arg("--invalid-arg-foo").run_fail().assert_exit_code(1); - rustc().arg("compile-error.rs").run_fail_assert_exit_code(1); + rustc().arg("compile-error.rs").run_fail().assert_exit_code(1); rustc() .env("RUSTC_ICE", "0") .arg("-Ztreat-err-as-bug") .arg("compile-error.rs") - .run_fail_assert_exit_code(101); + .run_fail() + .assert_exit_code(101); rustdoc().arg("success.rs").output("exit-code").run(); - rustdoc().arg("--invalid-arg-foo").run_fail_assert_exit_code(1); + rustdoc().arg("--invalid-arg-foo").run_fail().assert_exit_code(1); - rustdoc().arg("compile-error.rs").run_fail_assert_exit_code(1); + rustdoc().arg("compile-error.rs").run_fail().assert_exit_code(1); - rustdoc().arg("lint-failure.rs").run_fail_assert_exit_code(1); + rustdoc().arg("lint-failure.rs").run_fail().assert_exit_code(1); } diff --git a/tests/run-make/mixing-formats/rmake.rs b/tests/run-make/mixing-formats/rmake.rs index 444751419d74..9cbff94f6701 100644 --- a/tests/run-make/mixing-formats/rmake.rs +++ b/tests/run-make/mixing-formats/rmake.rs @@ -34,8 +34,8 @@ fn main() { rustc().crate_type("rlib").input("foo.rs").run(); rustc().crate_type("dylib").input("bar1.rs").arg("-Cprefer-dynamic").run(); rustc().crate_type("dylib").input("bar2.rs").arg("-Cprefer-dynamic").run(); - rustc().crate_type("dylib").input("baz2.rs").run_fail_assert_exit_code(1); - rustc().crate_type("bin").input("baz2.rs").run_fail_assert_exit_code(1); + rustc().crate_type("dylib").input("baz2.rs").run_fail().assert_exit_code(1); + rustc().crate_type("bin").input("baz2.rs").run_fail().assert_exit_code(1); }); run_in_tmpdir(|| { rustc().crate_type("rlib").input("foo.rs").run(); diff --git a/tests/run-make/no-input-file/no-input-file.stderr b/tests/run-make/no-input-file/no-input-file.stderr deleted file mode 100644 index b843eb524f3d..000000000000 --- a/tests/run-make/no-input-file/no-input-file.stderr +++ /dev/null @@ -1,2 +0,0 @@ -error: no input filename given - diff --git a/tests/run-make/no-input-file/rmake.rs b/tests/run-make/no-input-file/rmake.rs index 15e582311f09..fc558b22fb49 100644 --- a/tests/run-make/no-input-file/rmake.rs +++ b/tests/run-make/no-input-file/rmake.rs @@ -1,7 +1,9 @@ -use run_make_support::{diff, rustc}; +use run_make_support::rustc; fn main() { - let output = rustc().print("crate-name").run_fail_assert_exit_code(1); - - diff().expected_file("no-input-file.stderr").actual_text("output", output.stderr).run(); + rustc() + .print("crate-name") + .run_fail() + .assert_exit_code(1) + .assert_stderr_equals("error: no input filename given"); } diff --git a/tests/run-make/non-unicode-env/rmake.rs b/tests/run-make/non-unicode-env/rmake.rs index a4843a52efd5..ed40d7a6d7f0 100644 --- a/tests/run-make/non-unicode-env/rmake.rs +++ b/tests/run-make/non-unicode-env/rmake.rs @@ -6,7 +6,6 @@ fn main() { #[cfg(windows)] let non_unicode: std::ffi::OsString = std::os::windows::ffi::OsStringExt::from_wide(&[0xD800]); let output = rustc().input("non_unicode_env.rs").env("NON_UNICODE_VAR", non_unicode).run_fail(); - let actual = std::str::from_utf8(&output.stderr).unwrap(); let expected = std::fs::read_to_string("non_unicode_env.stderr").unwrap(); - assert_eq!(actual, expected); + output.assert_stderr_equals(expected); } diff --git a/tests/run-make/notify-all-emit-artifacts/rmake.rs b/tests/run-make/notify-all-emit-artifacts/rmake.rs index 1c2e08ca8f53..321eda489410 100644 --- a/tests/run-make/notify-all-emit-artifacts/rmake.rs +++ b/tests/run-make/notify-all-emit-artifacts/rmake.rs @@ -19,7 +19,7 @@ fn main() { .error_format("json") .incremental(cwd()) .run(); - let stderr = String::from_utf8_lossy(&output.stderr); + let stderr = output.stderr_utf8(); for file in &["lib.o", "lib.ll", "lib.bc", "lib.s"] { assert!(stderr.contains(file), "No {:?} in {:?}", file, stderr); } @@ -35,7 +35,7 @@ fn main() { .error_format("json") .incremental(cwd()) .run(); - let stderr = String::from_utf8_lossy(&output.stderr); + let stderr = output.stderr_utf8(); for file in &["rcgu.o", "rcgu.ll", "rcgu.bc", "rcgu.s"] { assert!(stderr.contains(file), "No {:?} in {:?}", file, stderr); } diff --git a/tests/run-make/print-cfg/rmake.rs b/tests/run-make/print-cfg/rmake.rs index 29cf0ba1b3fd..f382d952db47 100644 --- a/tests/run-make/print-cfg/rmake.rs +++ b/tests/run-make/print-cfg/rmake.rs @@ -83,8 +83,7 @@ fn check(PrintCfg { target, includes, disallow }: PrintCfg) { // --print=cfg { let output = rustc().target(target).print("cfg").run(); - - let stdout = String::from_utf8(output.stdout).unwrap(); + let stdout = output.stdout_utf8(); check_(&stdout, includes, disallow); } @@ -95,7 +94,7 @@ fn check(PrintCfg { target, includes, disallow }: PrintCfg) { let mut print_arg = OsString::from("--print=cfg="); print_arg.push(tmp_path.as_os_str()); - let output = rustc().target(target).arg(print_arg).run(); + rustc().target(target).arg(print_arg).run(); let output = std::fs::read_to_string(&tmp_path).unwrap(); diff --git a/tests/run-make/print-check-cfg/rmake.rs b/tests/run-make/print-check-cfg/rmake.rs index a0aa95c8abcf..f4b02b5e265b 100644 --- a/tests/run-make/print-check-cfg/rmake.rs +++ b/tests/run-make/print-check-cfg/rmake.rs @@ -93,7 +93,7 @@ fn check(CheckCfg { args, contains }: CheckCfg) { .args(&*args) .run(); - let stdout = String::from_utf8(output.stdout).unwrap(); + let stdout = output.stdout_utf8(); let mut found = HashSet::::new(); diff --git a/tests/run-make/print-native-static-libs/rmake.rs b/tests/run-make/print-native-static-libs/rmake.rs index edb85d568c67..b4e7c0e17ff8 100644 --- a/tests/run-make/print-native-static-libs/rmake.rs +++ b/tests/run-make/print-native-static-libs/rmake.rs @@ -30,9 +30,7 @@ fn main() { .run(); let mut found_note = false; - for l in output.stderr.lines() { - let l = l.expect("utf-8 string"); - + for l in output.stderr_utf8().lines() { let Some(args) = l.strip_prefix("note: native-static-libs:") else { continue; }; diff --git a/tests/run-make/print-to-output/rmake.rs b/tests/run-make/print-to-output/rmake.rs index b3f77e0633c4..ff5e6cacf4fa 100644 --- a/tests/run-make/print-to-output/rmake.rs +++ b/tests/run-make/print-to-output/rmake.rs @@ -39,11 +39,7 @@ fn check(args: Option) { } // --print={option} - let stdout = { - let output = rustc().target(args.target).print(args.option).run(); - - String::from_utf8(output.stdout).unwrap() - }; + let stdout = rustc().target(args.target).print(args.option).run().stdout_utf8(); // --print={option}=PATH let output = { @@ -51,7 +47,7 @@ fn check(args: Option) { let mut print_arg = OsString::from(format!("--print={}=", args.option)); print_arg.push(tmp_path.as_os_str()); - let _output = rustc().target(args.target).arg(print_arg).run(); + rustc().target(args.target).arg(print_arg).run(); std::fs::read_to_string(&tmp_path).unwrap() }; diff --git a/tests/run-make/rust-lld-by-default/rmake.rs b/tests/run-make/rust-lld-by-default/rmake.rs index 8ab16394a915..5b065f86f53f 100644 --- a/tests/run-make/rust-lld-by-default/rmake.rs +++ b/tests/run-make/rust-lld-by-default/rmake.rs @@ -17,9 +17,9 @@ fn main() { .input("main.rs") .run(); assert!( - find_lld_version_in_logs(&output), + find_lld_version_in_logs(output.stderr_utf8()), "the LLD version string should be present in the output logs:\n{}", - std::str::from_utf8(&output.stderr).unwrap() + output.stderr_utf8() ); // But it can still be disabled by turning the linker feature off. @@ -30,14 +30,13 @@ fn main() { .input("main.rs") .run(); assert!( - !find_lld_version_in_logs(&output), + !find_lld_version_in_logs(output.stderr_utf8()), "the LLD version string should not be present in the output logs:\n{}", - std::str::from_utf8(&output.stderr).unwrap() + output.stderr_utf8() ); } -fn find_lld_version_in_logs(output: &Output) -> bool { +fn find_lld_version_in_logs(stderr: String) -> bool { let lld_version_re = Regex::new(r"^LLD [0-9]+\.[0-9]+\.[0-9]+").unwrap(); - let stderr = std::str::from_utf8(&output.stderr).unwrap(); stderr.lines().any(|line| lld_version_re.is_match(line.trim())) } diff --git a/tests/run-make/rust-lld-custom-target/rmake.rs b/tests/run-make/rust-lld-custom-target/rmake.rs index e6c4a321d000..f3dc2275f625 100644 --- a/tests/run-make/rust-lld-custom-target/rmake.rs +++ b/tests/run-make/rust-lld-custom-target/rmake.rs @@ -23,9 +23,9 @@ fn main() { .input("lib.rs") .run(); assert!( - find_lld_version_in_logs(&output), + find_lld_version_in_logs(output.stderr_utf8()), "the LLD version string should be present in the output logs:\n{}", - std::str::from_utf8(&output.stderr).unwrap() + output.stderr_utf8() ); // But it can also be disabled via linker features. @@ -38,14 +38,13 @@ fn main() { .input("lib.rs") .run(); assert!( - !find_lld_version_in_logs(&output), + !find_lld_version_in_logs(output.stderr_utf8()), "the LLD version string should not be present in the output logs:\n{}", - std::str::from_utf8(&output.stderr).unwrap() + output.stderr_utf8() ); } -fn find_lld_version_in_logs(output: &Output) -> bool { +fn find_lld_version_in_logs(stderr: String) -> bool { let lld_version_re = Regex::new(r"^LLD [0-9]+\.[0-9]+\.[0-9]+").unwrap(); - let stderr = std::str::from_utf8(&output.stderr).unwrap(); stderr.lines().any(|line| lld_version_re.is_match(line.trim())) } diff --git a/tests/run-make/rust-lld/rmake.rs b/tests/run-make/rust-lld/rmake.rs index a74e858045d4..3eb60367c7f9 100644 --- a/tests/run-make/rust-lld/rmake.rs +++ b/tests/run-make/rust-lld/rmake.rs @@ -21,9 +21,9 @@ fn main() { .input("main.rs") .run(); assert!( - find_lld_version_in_logs(&output), + find_lld_version_in_logs(output.stderr_utf8()), "the LLD version string should be present in the output logs:\n{}", - std::str::from_utf8(&output.stderr).unwrap() + output.stderr_utf8() ); // It should not be used when we explictly opt-out of lld. @@ -34,9 +34,9 @@ fn main() { .input("main.rs") .run(); assert!( - !find_lld_version_in_logs(&output), + !find_lld_version_in_logs(output.stderr_utf8()), "the LLD version string should not be present in the output logs:\n{}", - std::str::from_utf8(&output.stderr).unwrap() + output.stderr_utf8() ); // While we're here, also check that the last linker feature flag "wins" when passed multiple @@ -52,14 +52,13 @@ fn main() { .input("main.rs") .run(); assert!( - find_lld_version_in_logs(&output), + find_lld_version_in_logs(output.stderr_utf8()), "the LLD version string should be present in the output logs:\n{}", - std::str::from_utf8(&output.stderr).unwrap() + output.stderr_utf8() ); } -fn find_lld_version_in_logs(output: &Output) -> bool { +fn find_lld_version_in_logs(stderr: String) -> bool { let lld_version_re = Regex::new(r"^LLD [0-9]+\.[0-9]+\.[0-9]+").unwrap(); - let stderr = std::str::from_utf8(&output.stderr).unwrap(); stderr.lines().any(|line| lld_version_re.is_match(line.trim())) } diff --git a/tests/run-make/rustdoc-error-lines/rmake.rs b/tests/run-make/rustdoc-error-lines/rmake.rs index db6e28e4feb7..ea5ec2faed95 100644 --- a/tests/run-make/rustdoc-error-lines/rmake.rs +++ b/tests/run-make/rustdoc-error-lines/rmake.rs @@ -4,9 +4,7 @@ use run_make_support::rustdoc; fn main() { - let output = - String::from_utf8(rustdoc().input("input.rs").arg("--test").command_output().stdout) - .unwrap(); + let output = rustdoc().input("input.rs").arg("--test").run_fail().stdout_utf8(); let should_contain = &[ "input.rs - foo (line 5)", diff --git a/tests/run-make/rustdoc-scrape-examples-macros/rmake.rs b/tests/run-make/rustdoc-scrape-examples-macros/rmake.rs index a6d08f28cda3..c9650def347d 100644 --- a/tests/run-make/rustdoc-scrape-examples-macros/rmake.rs +++ b/tests/run-make/rustdoc-scrape-examples-macros/rmake.rs @@ -8,17 +8,14 @@ fn main() { let proc_crate_name = "foobar_macro"; let crate_name = "foobar"; - let dylib_name = String::from_utf8( - rustc() - .crate_name(proc_crate_name) - .crate_type("dylib") - .arg("--print") - .arg("file-names") - .arg("-") - .command_output() - .stdout, - ) - .unwrap(); + let dylib_name = rustc() + .crate_name(proc_crate_name) + .crate_type("dylib") + .arg("--print") + .arg("file-names") + .arg("-") + .run() + .stdout_utf8(); rustc() .input("src/proc.rs") diff --git a/tests/run-make/rustdoc-shared-flags/rmake.rs b/tests/run-make/rustdoc-shared-flags/rmake.rs index 2db613f78176..d9a16d78a342 100644 --- a/tests/run-make/rustdoc-shared-flags/rmake.rs +++ b/tests/run-make/rustdoc-shared-flags/rmake.rs @@ -1,8 +1,8 @@ use run_make_support::{rustc, rustdoc, Diff}; fn compare_outputs(args: &[&str]) { - let rustc_output = String::from_utf8(rustc().args(args).command_output().stdout).unwrap(); - let rustdoc_output = String::from_utf8(rustdoc().args(args).command_output().stdout).unwrap(); + let rustc_output = rustc().args(args).run().stdout_utf8(); + let rustdoc_output = rustdoc().args(args).run().stdout_utf8(); Diff::new().expected_text("rustc", rustc_output).actual_text("rustdoc", rustdoc_output).run(); } diff --git a/tests/run-make/stdin-rustc/rmake.rs b/tests/run-make/stdin-rustc/rmake.rs index 1869b1dcb8c0..d599f813563c 100644 --- a/tests/run-make/stdin-rustc/rmake.rs +++ b/tests/run-make/stdin-rustc/rmake.rs @@ -21,7 +21,7 @@ fn main() { ); // echo $NOT_UTF8 | rustc - - let output = rustc().arg("-").stdin(NOT_UTF8).run_fail(); - let stderr = String::from_utf8(output.stderr).unwrap(); - assert!(stderr.contains("error: couldn't read from stdin, as it did not contain valid UTF-8")); + rustc().arg("-").stdin(NOT_UTF8).run_fail().assert_stderr_contains( + "error: couldn't read from stdin, as it did not contain valid UTF-8", + ); } From e7409d2130b3065169ab3933fb7fb515ef0303a6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=AE=B8=E6=9D=B0=E5=8F=8B=20Jieyou=20Xu=20=28Joe=29?= Date: Thu, 6 Jun 2024 17:14:51 +0000 Subject: [PATCH 14/50] run-make: add some basic docs about the test suite's setup --- tests/run-make/README.md | 43 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 tests/run-make/README.md diff --git a/tests/run-make/README.md b/tests/run-make/README.md new file mode 100644 index 000000000000..a6c1b4b7db76 --- /dev/null +++ b/tests/run-make/README.md @@ -0,0 +1,43 @@ +# The `run-make` test suite + +The `run-make` test suite contains tests which are the most flexible out of all +the [rust-lang/rust](https://github.com/rust-lang/rust) test suites. `run-make` +tests can basically contain arbitrary code, and are supported by the +[`run_make_support`] library. + +## Infrastructure + +There are two kinds of run-make tests: + +1. The new `rmake.rs` version: this allows run-make tests to be written in Rust + (with `rmake.rs` as the main test file). +2. The legacy `Makefile` version: this is what run-make tests were written with + before support for `rmake.rs` was introduced. + +The implementation for collecting and building the `rmake.rs` recipes (or +`Makefile`s) are in +[`src/tools/compiletest/src/runtest.rs`](../../src/tools/compiletest/src/runtest.rs), +in `run_rmake_v2_test` and `run_rmake_legacy_test`. + +### Rust-based `run-make` tests: `rmake.rs` + +The setup for the `rmake.rs` version is a 3-stage process: + +1. First, we build the [`run_make_support`] library in bootstrap as a tool lib. +2. Then, we compile the `rmake.rs` "recipe" linking the support library and its + dependencies in, and provide a bunch of env vars. We setup a directory + structure within `build//test/run-make/` + + ``` + / + rmake.exe # recipe binary + rmake_out/ # sources from test sources copied over + ``` + + and copy non-`rmake.rs` input support files over to `rmake_out/`. The + support library is made available as an [*extern prelude*][extern_prelude]. +3. Finally, we run the recipe binary and set `rmake_out/` as the working + directory. + +[`run_make_support`]: ../../src/tools/run-make-support +[extern_prelude]: https://doc.rust-lang.org/reference/names/preludes.html#extern-prelude From 9cd6c3244577b21b60d30711aa976333ef05bea0 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Sat, 8 Jun 2024 21:25:49 +0200 Subject: [PATCH 15/50] Don't disable codegen tests in PR CI --- src/ci/docker/scripts/x86_64-gnu-llvm.sh | 16 ++-------------- 1 file changed, 2 insertions(+), 14 deletions(-) diff --git a/src/ci/docker/scripts/x86_64-gnu-llvm.sh b/src/ci/docker/scripts/x86_64-gnu-llvm.sh index 876b300d35c6..b3921f114217 100755 --- a/src/ci/docker/scripts/x86_64-gnu-llvm.sh +++ b/src/ci/docker/scripts/x86_64-gnu-llvm.sh @@ -4,13 +4,7 @@ set -ex # Only run the stage 1 tests on merges, not on PR CI jobs. if [[ -z "${PR_CI_JOB}" ]]; then - # When running gcc backend tests, we need to install `libgccjit` and to not run llvm codegen - # tests as it will fail them. - if [[ "${ENABLE_GCC_CODEGEN}" == "1" ]]; then - ../x.py --stage 1 test --skip src/tools/tidy --skip tests/codegen - else - ../x.py --stage 1 test --skip src/tools/tidy - fi + ../x.py --stage 1 test --skip src/tools/tidy # Run the `mir-opt` tests again but this time for a 32-bit target. # This enforces that tests using `// EMIT_MIR_FOR_EACH_BIT_WIDTH` have @@ -29,14 +23,8 @@ if [[ -z "${PR_CI_JOB}" ]]; then --rustc-args "--cfg feature=\"optimize_for_size\"" fi -# When running gcc backend tests, we need to install `libgccjit` and to not run llvm codegen -# tests as it will fail them. # NOTE: intentionally uses all of `x.py`, `x`, and `x.ps1` to make sure they all work on Linux. -if [[ "${ENABLE_GCC_CODEGEN}" == "1" ]]; then - ../x.py --stage 2 test --skip src/tools/tidy --skip tests/codegen -else - ../x.py --stage 2 test --skip src/tools/tidy -fi +../x.py --stage 2 test --skip src/tools/tidy # Run the `mir-opt` tests again but this time for a 32-bit target. # This enforces that tests using `// EMIT_MIR_FOR_EACH_BIT_WIDTH` have From 2f2031d2b22d64d015625db2dd11e44e7ab37091 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sat, 8 Jun 2024 18:05:44 +0200 Subject: [PATCH 16/50] simd packed types: update outdated check, extend codegen test --- compiler/rustc_codegen_llvm/src/intrinsic.rs | 10 +++++---- tests/codegen/simd/packed-simd.rs | 23 ++++++++++++++++---- 2 files changed, 25 insertions(+), 8 deletions(-) diff --git a/compiler/rustc_codegen_llvm/src/intrinsic.rs b/compiler/rustc_codegen_llvm/src/intrinsic.rs index 7b1038d56176..ad4e753fe9d7 100644 --- a/compiler/rustc_codegen_llvm/src/intrinsic.rs +++ b/compiler/rustc_codegen_llvm/src/intrinsic.rs @@ -1109,10 +1109,12 @@ fn generic_simd_intrinsic<'ll, 'tcx>( tcx.normalize_erasing_late_bound_regions(ty::ParamEnv::reveal_all(), callee_ty.fn_sig(tcx)); let arg_tys = sig.inputs(); - // Vectors must be immediates (non-power-of-2 #[repr(packed)] are not) - for (ty, arg) in arg_tys.iter().zip(args) { - if ty.is_simd() && !matches!(arg.val, OperandValue::Immediate(_)) { - return_error!(InvalidMonomorphization::SimdArgument { span, name, ty: *ty }); + // Sanity-check: all vector arguments must be immediates. + if cfg!(debug_assertions) { + for (ty, arg) in arg_tys.iter().zip(args) { + if ty.is_simd() { + assert!(matches!(arg.val, OperandValue::Immediate(_))); + } } } diff --git a/tests/codegen/simd/packed-simd.rs b/tests/codegen/simd/packed-simd.rs index f0911b6e3602..1df09c96e6cc 100644 --- a/tests/codegen/simd/packed-simd.rs +++ b/tests/codegen/simd/packed-simd.rs @@ -9,10 +9,11 @@ use core::intrinsics::simd as intrinsics; use core::{mem, ptr}; // Test codegen for not only "packed" but also "fully aligned" SIMD types, and conversion between -// A repr(packed,simd) type with 3 elements can't exceed its element alignment, -// whereas the same type as repr(simd) will instead have padding. +// them. A repr(packed,simd) type with 3 elements can't exceed its element alignment, whereas the +// same type as repr(simd) will instead have padding. #[repr(simd, packed)] +#[derive(Copy, Clone)] pub struct Simd([T; N]); #[repr(simd)] @@ -28,11 +29,11 @@ fn load(v: Simd) -> FullSimd { } } -// CHECK-LABEL: square_packed +// CHECK-LABEL: square_packed_full // CHECK-SAME: ptr{{[a-z_ ]*}} sret([[RET_TYPE:[^)]+]]) [[RET_ALIGN:align (8|16)]]{{[^%]*}} [[RET_VREG:%[_0-9]*]] // CHECK-SAME: ptr{{[a-z_ ]*}} align 4 #[no_mangle] -pub fn square_packed(x: Simd) -> FullSimd { +pub fn square_packed_full(x: Simd) -> FullSimd { // CHECK-NEXT: start // noopt: alloca [[RET_TYPE]], [[RET_ALIGN]] // CHECK: load <3 x float> @@ -42,3 +43,17 @@ pub fn square_packed(x: Simd) -> FullSimd { // CHECK-NEXT: ret void unsafe { intrinsics::simd_mul(x, x) } } + +// CHECK-LABEL: square_packed +// CHECK-SAME: ptr{{[a-z_ ]*}} sret([[RET_TYPE:[^)]+]]) [[RET_ALIGN:align 4]]{{[^%]*}} [[RET_VREG:%[_0-9]*]] +// CHECK-SAME: ptr{{[a-z_ ]*}} align 4 +#[no_mangle] +pub fn square_packed(x: Simd) -> Simd { + // CHECK-NEXT: start + // CHECK-NEXT: load <3 x float> + // noopt-NEXT: load <3 x float> + // CHECK-NEXT: [[VREG:%[a-z0-9_]+]] = fmul <3 x float> + // CHECK-NEXT: store <3 x float> [[VREG]], ptr [[RET_VREG]], [[RET_ALIGN]] + // CHECK-NEXT: ret void + unsafe { intrinsics::simd_mul(x, x) } +} From 1ade7cbe4185bcd302b3774b00c0b4011f43d165 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Sat, 8 Jun 2024 23:25:43 +0200 Subject: [PATCH 17/50] Use --quiet flag when installing pip dependencies --- src/tools/tidy/src/ext_tool_checks.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/tidy/src/ext_tool_checks.rs b/src/tools/tidy/src/ext_tool_checks.rs index 40e75d1d3fac..2c97a39f1008 100644 --- a/src/tools/tidy/src/ext_tool_checks.rs +++ b/src/tools/tidy/src/ext_tool_checks.rs @@ -320,7 +320,7 @@ fn install_requirements( } let stat = Command::new(py_path) - .args(["-m", "pip", "install", "--require-hashes", "-r"]) + .args(["-m", "pip", "install", "--quiet", "--require-hashes", "-r"]) .arg(src_reqs_path) .status()?; if !stat.success() { From b8e734a8ca552eadaf45d62d9ea2a98364c6e957 Mon Sep 17 00:00:00 2001 From: Zalathar Date: Fri, 7 Jun 2024 16:33:35 +1000 Subject: [PATCH 18/50] Identify run-make tests by mode name instead of suite name --- src/bootstrap/src/core/build_steps/test.rs | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/bootstrap/src/core/build_steps/test.rs b/src/bootstrap/src/core/build_steps/test.rs index aaedee65ed75..38eabfb5945f 100644 --- a/src/bootstrap/src/core/build_steps/test.rs +++ b/src/bootstrap/src/core/build_steps/test.rs @@ -1973,9 +1973,7 @@ NOTE: if you're sure you want to do this, please open an issue as to why. In the add_link_lib_path(vec![llvm_libdir.trim().into()], &mut cmd); } - if !builder.config.dry_run() - && (matches!(suite, "run-make" | "run-make-fulldeps") || mode == "coverage-run") - { + if !builder.config.dry_run() && matches!(mode, "run-make" | "coverage-run") { // The llvm/bin directory contains many useful cross-platform // tools. Pass the path to run-make tests so they can use them. // (The coverage-run tests also need these tools to process @@ -1987,7 +1985,7 @@ NOTE: if you're sure you want to do this, please open an issue as to why. In the cmd.arg("--llvm-bin-dir").arg(llvm_bin_path); } - if !builder.config.dry_run() && matches!(suite, "run-make" | "run-make-fulldeps") { + if !builder.config.dry_run() && mode == "run-make" { // If LLD is available, add it to the PATH if builder.config.lld_enabled { let lld_install_root = @@ -2007,7 +2005,7 @@ NOTE: if you're sure you want to do this, please open an issue as to why. In the // Only pass correct values for these flags for the `run-make` suite as it // requires that a C++ compiler was configured which isn't always the case. - if !builder.config.dry_run() && matches!(suite, "run-make" | "run-make-fulldeps") { + if !builder.config.dry_run() && mode == "run-make" { cmd.arg("--cc") .arg(builder.cc(target)) .arg("--cxx") From 92a56ff2919df7ad58d410be1629903b65283db9 Mon Sep 17 00:00:00 2001 From: Zalathar Date: Fri, 7 Jun 2024 16:43:26 +1000 Subject: [PATCH 19/50] Remove useless feature gate test for `#[feature(extern_prelude)]` This test never actually checked anything useful, so presumably it only existed to silence the tidy check for feature gate tests, with the real checks being performed elsewhere (in tests that have since been deleted). --- tests/ui/feature-gates/feature-gate-extern_prelude.rs | 1 - tests/ui/feature-gates/feature-gate-extern_prelude.stderr | 8 -------- 2 files changed, 9 deletions(-) delete mode 100644 tests/ui/feature-gates/feature-gate-extern_prelude.rs delete mode 100644 tests/ui/feature-gates/feature-gate-extern_prelude.stderr diff --git a/tests/ui/feature-gates/feature-gate-extern_prelude.rs b/tests/ui/feature-gates/feature-gate-extern_prelude.rs deleted file mode 100644 index 237099e79010..000000000000 --- a/tests/ui/feature-gates/feature-gate-extern_prelude.rs +++ /dev/null @@ -1 +0,0 @@ -can-only-test-this-in-run-make-fulldeps //~ ERROR expected one of `!` or `::`, found `-` diff --git a/tests/ui/feature-gates/feature-gate-extern_prelude.stderr b/tests/ui/feature-gates/feature-gate-extern_prelude.stderr deleted file mode 100644 index 3b0ffae86965..000000000000 --- a/tests/ui/feature-gates/feature-gate-extern_prelude.stderr +++ /dev/null @@ -1,8 +0,0 @@ -error: expected one of `!` or `::`, found `-` - --> $DIR/feature-gate-extern_prelude.rs:1:4 - | -LL | can-only-test-this-in-run-make-fulldeps - | ^ expected one of `!` or `::` - -error: aborting due to 1 previous error - From 0f8c3adc687a727fe1cbb4f3e83d68cec95b2ace Mon Sep 17 00:00:00 2001 From: Zalathar Date: Sun, 9 Jun 2024 13:02:05 +1000 Subject: [PATCH 20/50] Make job `x86_64-gnu-debug` run a subset of run-make tests It looks like this job was intending to run all of the `needs-matching-clang` tests (since they don't run without `RUSTBUILD_FORCE_CLANG_BASED_TESTS`), but over time developed two problems: - The tests it cares about were moved from run-make-fulldeps to run-make. - Some of the relevant tests don't actually have "clang" in their name. Switching to run-make solves the first problem, but we still don't run the tests without "clang" in their name, because some of them are currently broken. --- src/ci/docker/host-x86_64/x86_64-gnu-debug/Dockerfile | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/ci/docker/host-x86_64/x86_64-gnu-debug/Dockerfile b/src/ci/docker/host-x86_64/x86_64-gnu-debug/Dockerfile index e4534d0f8408..64a1fb093b49 100644 --- a/src/ci/docker/host-x86_64/x86_64-gnu-debug/Dockerfile +++ b/src/ci/docker/host-x86_64/x86_64-gnu-debug/Dockerfile @@ -44,6 +44,14 @@ ENV RUST_CONFIGURE_ARGS \ --set target.x86_64-unknown-linux-gnu.cc=clang \ --set target.x86_64-unknown-linux-gnu.cxx=clang++ +# This job appears to be checking two separate things: +# - That we can build the compiler with `--enable-debug` +# (without necessarily testing the result). +# - That the tests with `//@ needs-matching-clang` pass, since they +# don't run by default unless RUSTBUILD_FORCE_CLANG_BASED_TESTS is set. +# - FIXME(https://github.com/rust-lang/rust/pull/126155#issuecomment-2156314273): +# Currently we only run the subset of tests with "clang" in their name. + ENV SCRIPT \ python3 ../x.py --stage 2 build && \ - python3 ../x.py --stage 2 test tests/run-make-fulldeps --test-args clang + python3 ../x.py --stage 2 test tests/run-make --test-args clang From 5223bf4474b02bd6925c5b516a8a0efd5ec4ec20 Mon Sep 17 00:00:00 2001 From: Zalathar Date: Wed, 5 Jun 2024 21:54:55 +1000 Subject: [PATCH 21/50] Remove empty test suite `tests/run-make-fulldeps` --- src/bootstrap/src/core/build_steps/test.rs | 6 ------ src/bootstrap/src/core/builder.rs | 2 -- src/ci/github-actions/jobs.yml | 4 ++-- src/doc/rustc/src/platform-support/nto-qnx.md | 3 +-- tests/run-make-fulldeps/README.md | 4 ---- 5 files changed, 3 insertions(+), 16 deletions(-) delete mode 100644 tests/run-make-fulldeps/README.md diff --git a/src/bootstrap/src/core/build_steps/test.rs b/src/bootstrap/src/core/build_steps/test.rs index 38eabfb5945f..fb7b40b73212 100644 --- a/src/bootstrap/src/core/build_steps/test.rs +++ b/src/bootstrap/src/core/build_steps/test.rs @@ -1487,12 +1487,6 @@ impl Step for RunMake { } } -host_test!(RunMakeFullDeps { - path: "tests/run-make-fulldeps", - mode: "run-make", - suite: "run-make-fulldeps" -}); - default_test!(Assembly { path: "tests/assembly", mode: "assembly", suite: "assembly" }); /// Coverage tests are a bit more complicated than other test suites, because diff --git a/src/bootstrap/src/core/builder.rs b/src/bootstrap/src/core/builder.rs index b3d8465cda98..7189cd695fa7 100644 --- a/src/bootstrap/src/core/builder.rs +++ b/src/bootstrap/src/core/builder.rs @@ -332,7 +332,6 @@ const PATH_REMAP: &[(&str, &[&str])] = &[ "tests/mir-opt", "tests/pretty", "tests/run-make", - "tests/run-make-fulldeps", "tests/run-pass-valgrind", "tests/rustdoc", "tests/rustdoc-gui", @@ -828,7 +827,6 @@ impl<'a> Builder<'a> { test::RustAnalyzer, test::ErrorIndex, test::Distcheck, - test::RunMakeFullDeps, test::Nomicon, test::Reference, test::RustdocBook, diff --git a/src/ci/github-actions/jobs.yml b/src/ci/github-actions/jobs.yml index 8c84e721f5de..48c39d2c33e5 100644 --- a/src/ci/github-actions/jobs.yml +++ b/src/ci/github-actions/jobs.yml @@ -37,7 +37,7 @@ runners: envs: env-x86_64-apple-tests: &env-x86_64-apple-tests - SCRIPT: ./x.py --stage 2 test --skip tests/ui --skip tests/rustdoc --skip tests/run-make-fulldeps + SCRIPT: ./x.py --stage 2 test --skip tests/ui --skip tests/rustdoc RUST_CONFIGURE_ARGS: --build=x86_64-apple-darwin --enable-sanitizers --enable-profiler --set rust.jemalloc RUSTC_RETRY_LINKER_ON_SEGFAULT: 1 MACOSX_DEPLOYMENT_TARGET: 10.12 @@ -294,7 +294,7 @@ auto: - image: x86_64-apple-2 env: - SCRIPT: ./x.py --stage 2 test tests/ui tests/rustdoc tests/run-make-fulldeps + SCRIPT: ./x.py --stage 2 test tests/ui tests/rustdoc <<: *env-x86_64-apple-tests <<: *job-macos-xl diff --git a/src/doc/rustc/src/platform-support/nto-qnx.md b/src/doc/rustc/src/platform-support/nto-qnx.md index 56070c2ec34e..51a397a38d20 100644 --- a/src/doc/rustc/src/platform-support/nto-qnx.md +++ b/src/doc/rustc/src/platform-support/nto-qnx.md @@ -160,8 +160,7 @@ export exclude_tests=' --exclude src/tools/linkchecker --exclude tests/ui-fulldeps --exclude rustc - --exclude rustdoc - --exclude tests/run-make-fulldeps' + --exclude rustdoc' env $build_env \ ./x.py test \ diff --git a/tests/run-make-fulldeps/README.md b/tests/run-make-fulldeps/README.md deleted file mode 100644 index dd1788390220..000000000000 --- a/tests/run-make-fulldeps/README.md +++ /dev/null @@ -1,4 +0,0 @@ -If this directory is empty, Git won't create it, and compiletest will complain -that it can't find a nonexistent test suite directory. - -FIXME(#126111): Remove `run-make-fulldeps` from bootstrap. From 9d85dfc3e652d38b986e4f0f21318f5f2d748bd4 Mon Sep 17 00:00:00 2001 From: clubby789 Date: Sat, 8 Jun 2024 20:18:31 +0100 Subject: [PATCH 22/50] Update `icu4x` dependencies --- Cargo.lock | 68 ++++++++++++------------ src/tools/clippy/tests/ui/unicode.stderr | 2 +- src/tools/tidy/src/deps.rs | 33 +----------- 3 files changed, 37 insertions(+), 66 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 54b1bf593e0a..52448e154c12 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1800,9 +1800,9 @@ dependencies = [ [[package]] name = "icu_list" -version = "1.4.0" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe6c04ec71ad1bacdbfb47164d4801f80a0533d9340f94f1a880f521eff59f54" +checksum = "bbfeda1d7775b6548edd4e8b7562304a559a91ed56ab56e18961a053f367c365" dependencies = [ "displaydoc", "icu_list_data", @@ -1814,15 +1814,15 @@ dependencies = [ [[package]] name = "icu_list_data" -version = "1.4.0" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42f6afcf7a9a7fedece70b7f17d7a7ecdfb8df145d37ae46d0277cd1e3932532" +checksum = "e1825170d2c6679cb20dbd96a589d034e49f698aed9a2ef4fafc9a0101ed298f" [[package]] name = "icu_locid" -version = "1.4.0" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c0aa2536adc14c07e2a521e95512b75ed8ef832f0fdf9299d4a0a45d2be2a9d" +checksum = "13acbb8371917fc971be86fc8057c41a64b521c184808a698c02acc242dbf637" dependencies = [ "displaydoc", "litemap", @@ -1833,9 +1833,9 @@ dependencies = [ [[package]] name = "icu_locid_transform" -version = "1.4.0" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57c17d8f6524fdca4471101dd71f0a132eb6382b5d6d7f2970441cb25f6f435a" +checksum = "01d11ac35de8e40fdeda00d9e1e9d92525f3f9d887cdd7aa81d727596788b54e" dependencies = [ "displaydoc", "icu_locid", @@ -1847,15 +1847,15 @@ dependencies = [ [[package]] name = "icu_locid_transform_data" -version = "1.4.0" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "545c6c3e8bf9580e2dafee8de6f9ec14826aaf359787789c7724f1f85f47d3dc" +checksum = "fdc8ff3388f852bede6b579ad4e978ab004f139284d7b28715f773507b946f6e" [[package]] name = "icu_provider" -version = "1.4.0" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba58e782287eb6950247abbf11719f83f5d4e4a5c1f2cd490d30a334bc47c2f4" +checksum = "6ed421c8a8ef78d3e2dbc98a973be2f3770cb42b606e3ab18d6237c4dfde68d9" dependencies = [ "displaydoc", "icu_locid", @@ -1870,9 +1870,9 @@ dependencies = [ [[package]] name = "icu_provider_adapters" -version = "1.4.0" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a229f978260da7c3aabb68cb7dc7316589936680570fe55e50fdd3f97711a4dd" +checksum = "d6324dfd08348a8e0374a447ebd334044d766b1839bb8d5ccf2482a99a77c0bc" dependencies = [ "icu_locid", "icu_locid_transform", @@ -1883,9 +1883,9 @@ dependencies = [ [[package]] name = "icu_provider_macros" -version = "1.4.0" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2abdd3a62551e8337af119c5899e600ca0c88ec8f23a46c60ba216c803dcf1a" +checksum = "1ec89e9337638ecdc08744df490b221a7399bf8d164eb52a665454e60e075ad6" dependencies = [ "proc-macro2", "quote", @@ -2252,9 +2252,9 @@ checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" [[package]] name = "litemap" -version = "0.7.2" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9d642685b028806386b2b6e75685faadd3eb65a85fff7df711ce18446a422da" +checksum = "643cb0b8d4fcc284004d5fd0d67ccf61dfffadb7f75e1e71bc420f4688a3a704" [[package]] name = "lld-wrapper" @@ -5744,9 +5744,9 @@ dependencies = [ [[package]] name = "tinystr" -version = "0.7.5" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83c02bf3c538ab32ba913408224323915f4ef9a6d61c0e85d493f355921c0ece" +checksum = "9117f5d4db391c1cf6927e7bea3db74b9a1c1add8f7eda9ffd5364f40f57b82f" dependencies = [ "displaydoc", "zerovec", @@ -6585,9 +6585,9 @@ dependencies = [ [[package]] name = "writeable" -version = "0.5.4" +version = "0.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dad7bb64b8ef9c0aa27b6da38b452b0ee9fd82beaf276a87dd796fb55cbae14e" +checksum = "1e9df38ee2d2c3c5948ea468a8406ff0db0b29ae1ffde1bcf20ef305bcc95c51" [[package]] name = "xattr" @@ -6635,9 +6635,9 @@ dependencies = [ [[package]] name = "yoke" -version = "0.7.3" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "65e71b2e4f287f467794c671e2b8f8a5f3716b3c829079a1c44740148eff07e4" +checksum = "6c5b1314b079b0930c31e3af543d8ee1757b1951ae1e1565ec704403a7240ca5" dependencies = [ "serde", "stable_deref_trait", @@ -6647,9 +6647,9 @@ dependencies = [ [[package]] name = "yoke-derive" -version = "0.7.3" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e6936f0cce458098a201c245a11bef556c6a0181129c7034d10d76d1ec3a2b8" +checksum = "28cc31741b18cb6f1d5ff12f5b7523e3d6eb0852bbbad19d73905511d9849b95" dependencies = [ "proc-macro2", "quote", @@ -6679,18 +6679,18 @@ dependencies = [ [[package]] name = "zerofrom" -version = "0.1.3" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "655b0814c5c0b19ade497851070c640773304939a6c0fd5f5fb43da0696d05b7" +checksum = "91ec111ce797d0e0784a1116d0ddcdbea84322cd79e5d5ad173daeba4f93ab55" dependencies = [ "zerofrom-derive", ] [[package]] name = "zerofrom-derive" -version = "0.1.3" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6a647510471d372f2e6c2e6b7219e44d8c574d24fdc11c610a61455782f18c3" +checksum = "0ea7b4a3637ea8669cedf0f1fd5c286a17f3de97b8dd5a70a6c167a1730e63a5" dependencies = [ "proc-macro2", "quote", @@ -6700,9 +6700,9 @@ dependencies = [ [[package]] name = "zerovec" -version = "0.10.1" +version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eff4439ae91fb5c72b8abc12f3f2dbf51bd27e6eadb9f8a5bc8898dddb0e27ea" +checksum = "bb2cc8827d6c0994478a15c53f374f46fbd41bea663d809b14744bc42e6b109c" dependencies = [ "yoke", "zerofrom", @@ -6711,9 +6711,9 @@ dependencies = [ [[package]] name = "zerovec-derive" -version = "0.10.1" +version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b4e5997cbf58990550ef1f0e5124a05e47e1ebd33a84af25739be6031a62c20" +checksum = "97cf56601ee5052b4417d90c8755c6683473c926039908196cf35d99f893ebe7" dependencies = [ "proc-macro2", "quote", diff --git a/src/tools/clippy/tests/ui/unicode.stderr b/src/tools/clippy/tests/ui/unicode.stderr index 9c365e1097db..b004493300ee 100644 --- a/src/tools/clippy/tests/ui/unicode.stderr +++ b/src/tools/clippy/tests/ui/unicode.stderr @@ -11,7 +11,7 @@ error: invisible character detected --> tests/ui/unicode.rs:7:12 | LL | print!("Here >­< is a SHY, and ­another"); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider replacing the string with: `"Here >\u{AD}< is a SHY, and \u{AD}another"` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider replacing the string with: `"Here >\u{AD}< is a SHY, and \u{AD}another"` error: invisible character detected --> tests/ui/unicode.rs:9:12 diff --git a/src/tools/tidy/src/deps.rs b/src/tools/tidy/src/deps.rs index efcd2a181ffa..cf89149dd5bd 100644 --- a/src/tools/tidy/src/deps.rs +++ b/src/tools/tidy/src/deps.rs @@ -27,7 +27,8 @@ const LICENSES: &[&str] = &[ "MIT OR Zlib OR Apache-2.0", // miniz_oxide "MIT", "MIT/Apache-2.0", - "Unicode-DFS-2016", // tinystr and icu4x + "Unicode-3.0", // icu4x + "Unicode-DFS-2016", // tinystr "Unlicense OR MIT", "Unlicense/MIT", "Zlib OR Apache-2.0 OR MIT", // tinyvec @@ -411,32 +412,6 @@ const PERMITTED_RUSTC_DEPENDENCIES: &[&str] = &[ // tidy-alphabetical-end ]; -// These crates come from ICU4X and are licensed under the unicode license. -// It currently doesn't have an SPDX identifier, so they cannot put one there. -// See https://github.com/unicode-org/icu4x/pull/3875 -// FIXME: This should be removed once ICU4X crates update. -const ICU4X_UNICODE_LICENSE_DEPENDENCIES: &[&str] = &[ - // tidy-alphabetical-start - "icu_list", - "icu_list_data", - "icu_locid", - "icu_locid_transform", - "icu_locid_transform_data", - "icu_provider", - "icu_provider_adapters", - "icu_provider_macros", - "litemap", - "tinystr", - "writeable", - "yoke", - "yoke-derive", - "zerofrom", - "zerofrom-derive", - "zerovec", - "zerovec-derive", - // tidy-alphabetical-end -]; - const PERMITTED_CRANELIFT_DEPENDENCIES: &[&str] = &[ // tidy-alphabetical-start "ahash", @@ -642,10 +617,6 @@ fn check_license_exceptions(metadata: &Metadata, exceptions: &[(&str, &str)], ba let license = match &pkg.license { Some(license) => license, None => { - if ICU4X_UNICODE_LICENSE_DEPENDENCIES.contains(&pkg.name.as_str()) { - // See the comment on ICU4X_UNICODE_LICENSE_DEPENDENCIES. - continue; - } tidy_error!(bad, "dependency `{}` does not define a license expression", pkg.id); continue; } From dcd03aadd2e653e6cc432db0b430b55af300c2b1 Mon Sep 17 00:00:00 2001 From: clubby789 Date: Sat, 8 Jun 2024 20:19:39 +0100 Subject: [PATCH 23/50] Update `r-efi` --- Cargo.lock | 4 ++-- .../docker/host-x86_64/test-various/uefi_qemu_test/Cargo.lock | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 52448e154c12..801579865ae8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3246,9 +3246,9 @@ dependencies = [ [[package]] name = "r-efi" -version = "4.4.0" +version = "4.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c47196f636c4cc0634b73b0405323d177753c2e15e866952c64ea22902567a34" +checksum = "e9e935efc5854715dfc0a4c9ef18dc69dee0ec3bf9cc3ab740db831c0fdd86a3" dependencies = [ "compiler_builtins", "rustc-std-workspace-core", diff --git a/src/ci/docker/host-x86_64/test-various/uefi_qemu_test/Cargo.lock b/src/ci/docker/host-x86_64/test-various/uefi_qemu_test/Cargo.lock index b0c17d9a296c..dacf531e4048 100644 --- a/src/ci/docker/host-x86_64/test-various/uefi_qemu_test/Cargo.lock +++ b/src/ci/docker/host-x86_64/test-various/uefi_qemu_test/Cargo.lock @@ -4,9 +4,9 @@ version = 3 [[package]] name = "r-efi" -version = "4.4.0" +version = "4.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c47196f636c4cc0634b73b0405323d177753c2e15e866952c64ea22902567a34" +checksum = "e9e935efc5854715dfc0a4c9ef18dc69dee0ec3bf9cc3ab740db831c0fdd86a3" [[package]] name = "uefi_qemu_test" From d42c9607f87269a8ee1e664a82809a707d8ff5a6 Mon Sep 17 00:00:00 2001 From: clubby789 Date: Sat, 8 Jun 2024 20:22:16 +0100 Subject: [PATCH 24/50] Run `cargo update` --- Cargo.lock | 186 ++++++++++++++++++++++++++--------------------------- 1 file changed, 93 insertions(+), 93 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 801579865ae8..58d95f927bf9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -131,9 +131,9 @@ dependencies = [ [[package]] name = "annotate-snippets" -version = "0.11.2" +version = "0.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a5a59f105fb9635e9eebdc1e29d53e764fa5795b9cf899a638a53e61567ef61" +checksum = "086b0afab3b349e5691143adbfb26983821e3eec4ba4c51957104d372c2e1b7d" dependencies = [ "anstyle", "unicode-width", @@ -189,9 +189,9 @@ dependencies = [ [[package]] name = "anstyle-query" -version = "1.0.3" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a64c907d4e79225ac72e2a354c9ce84d50ebb4586dee56c82b3ee73004f537f5" +checksum = "ad186efb764318d35165f1758e7dcef3b10628e26d41a44bc5550652e6804391" dependencies = [ "windows-sys 0.52.0", ] @@ -266,7 +266,7 @@ dependencies = [ "proc-macro2", "quote", "serde", - "syn 2.0.64", + "syn 2.0.66", ] [[package]] @@ -501,9 +501,9 @@ version = "0.1.0" [[package]] name = "cc" -version = "1.0.97" +version = "1.0.99" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "099a5357d84c4c61eb35fc8eafa9a79a902c2f76911e5747ced4e032edd8d9b4" +checksum = "96c51067fd44124faa7f870b4b1c969379ad32b2ba805aa959430ceaa384f695" [[package]] name = "cfg-if" @@ -568,9 +568,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.4" +version = "4.5.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90bc066a67923782aa8515dbaea16946c5bcc5addbd668bb80af688e53e548a0" +checksum = "a9689a29b593160de5bc4aacab7b5d54fb52231de70122626c178e6a368994c7" dependencies = [ "clap_builder", "clap_derive", @@ -588,9 +588,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.2" +version = "4.5.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae129e2e766ae0ec03484e609954119f123cc1fe650337e155d03b022f24f7b4" +checksum = "2e5387378c84f6faa26890ebf9f0a92989f8873d4d380467bcd0d8d8620424df" dependencies = [ "anstream", "anstyle", @@ -601,30 +601,30 @@ dependencies = [ [[package]] name = "clap_complete" -version = "4.5.2" +version = "4.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd79504325bf38b10165b02e89b4347300f855f273c4cb30c4a3209e6583275e" +checksum = "d2020fa13af48afc65a9a87335bda648309ab3d154cd03c7ff95b378c7ed39c4" dependencies = [ "clap", ] [[package]] name = "clap_derive" -version = "4.5.4" +version = "4.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "528131438037fd55894f62d6e9f068b8f45ac57ffa77517819645d10aed04f64" +checksum = "c780290ccf4fb26629baa7a1081e68ced113f1d3ec302fa5948f1c381ebf06c6" dependencies = [ "heck 0.5.0", "proc-macro2", "quote", - "syn 2.0.64", + "syn 2.0.66", ] [[package]] name = "clap_lex" -version = "0.7.0" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "98cc8fbded0c607b7ba9dd60cd98df59af97e84d24e49c8557331cfc26d301ce" +checksum = "4b82cf0babdbd58558212896d1a4272303a57bdb245c2bf1147185fb45640e70" [[package]] name = "clippy" @@ -644,7 +644,7 @@ dependencies = [ "regex", "rustc_tools_util", "serde", - "syn 2.0.64", + "syn 2.0.66", "tempfile", "termize", "tokio", @@ -754,7 +754,7 @@ dependencies = [ "nom", "proc-macro2", "quote", - "syn 2.0.64", + "syn 2.0.66", ] [[package]] @@ -878,18 +878,18 @@ dependencies = [ [[package]] name = "crc32fast" -version = "1.4.0" +version = "1.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3855a8a784b474f333699ef2bbca9db2c4a1f6d9088a90a2d25b1eb53111eaa" +checksum = "a97769d94ddab943e4510d138150169a2758b5ef3eb191a9ee688de3e23ef7b3" dependencies = [ "cfg-if", ] [[package]] name = "crossbeam-channel" -version = "0.5.12" +version = "0.5.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab3db02a9c5b5121e1e42fbdb1aeb65f5e02624cc58c43f2884c6ccac0b82f95" +checksum = "33480d6946193aa8033910124896ca395333cae7e2d1113d1fef6c3272217df2" dependencies = [ "crossbeam-utils", ] @@ -915,9 +915,9 @@ dependencies = [ [[package]] name = "crossbeam-utils" -version = "0.8.19" +version = "0.8.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "248e3bacc7dc6baa3b21e405ee045c3047101a49145e7e9eca583ab4c2ca5345" +checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80" [[package]] name = "crypto-common" @@ -990,7 +990,7 @@ dependencies = [ "proc-macro2", "quote", "strsim", - "syn 2.0.64", + "syn 2.0.66", ] [[package]] @@ -1001,7 +1001,7 @@ checksum = "733cabb43482b1a1b53eee8583c2b9e8684d592215ea83efd305dd31bc2f0178" dependencies = [ "darling_core", "quote", - "syn 2.0.64", + "syn 2.0.66", ] [[package]] @@ -1027,7 +1027,7 @@ version = "0.1.80" dependencies = [ "itertools 0.12.1", "quote", - "syn 2.0.64", + "syn 2.0.66", ] [[package]] @@ -1068,7 +1068,7 @@ dependencies = [ "darling", "proc-macro2", "quote", - "syn 2.0.64", + "syn 2.0.66", ] [[package]] @@ -1078,7 +1078,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "206868b8242f27cecce124c19fd88157fbd0dd334df2587f36417bafbc85097b" dependencies = [ "derive_builder_core", - "syn 2.0.64", + "syn 2.0.66", ] [[package]] @@ -1101,7 +1101,7 @@ dependencies = [ "darling", "proc-macro2", "quote", - "syn 2.0.64", + "syn 2.0.66", ] [[package]] @@ -1196,7 +1196,7 @@ checksum = "487585f4d0c6655fe74905e2504d8ad6908e4db67f744eb140876906c2f3175d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.64", + "syn 2.0.66", ] [[package]] @@ -1516,7 +1516,7 @@ checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" dependencies = [ "proc-macro2", "quote", - "syn 2.0.64", + "syn 2.0.66", ] [[package]] @@ -1588,9 +1588,9 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.14" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94b22e06ecb0110981051723910cbf0b5f5e09a2062dd7663334ee79a9d1286c" +checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" dependencies = [ "cfg-if", "libc", @@ -1757,7 +1757,7 @@ dependencies = [ "markup5ever 0.12.1", "proc-macro2", "quote", - "syn 2.0.64", + "syn 2.0.66", ] [[package]] @@ -1889,7 +1889,7 @@ checksum = "1ec89e9337638ecdc08744df490b221a7399bf8d164eb52a665454e60e075ad6" dependencies = [ "proc-macro2", "quote", - "syn 2.0.64", + "syn 2.0.66", ] [[package]] @@ -2196,9 +2196,9 @@ dependencies = [ [[package]] name = "libz-sys" -version = "1.1.16" +version = "1.1.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e143b5e666b2695d28f6bca6497720813f699c9602dd7f5cac91008b8ada7f9" +checksum = "c15da26e5af7e25c90b37a2d75cdbf940cf4a55316de9d84c679c9b8bfabf82e" dependencies = [ "cc", "libc", @@ -2415,7 +2415,7 @@ dependencies = [ "pulldown-cmark-to-cmark", "serde_json", "thiserror", - "toml 0.8.13", + "toml 0.8.14", "xmlparser", ] @@ -2608,9 +2608,9 @@ dependencies = [ [[package]] name = "nu-ansi-term" -version = "0.49.0" +version = "0.50.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c073d3c1930d0751774acf49e66653acecb416c3a54c6ec095a9b11caddb5a68" +checksum = "dd2800e1520bdc966782168a627aa5d1ad92e33b984bf7c7615d31280c83ff14" dependencies = [ "windows-sys 0.48.0", ] @@ -2849,9 +2849,9 @@ dependencies = [ [[package]] name = "parking_lot" -version = "0.12.2" +version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e4af0ca4f6caed20e900d564c242b8e5d4903fdacf31d3daf527b66fe6f42fb" +checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27" dependencies = [ "lock_api", "parking_lot_core", @@ -2931,7 +2931,7 @@ dependencies = [ "pest_meta", "proc-macro2", "quote", - "syn 2.0.64", + "syn 2.0.66", ] [[package]] @@ -3142,9 +3142,9 @@ checksum = "dc375e1527247fe1a97d8b7156678dfe7c1af2fc075c9a4db3690ecd2a148068" [[package]] name = "proc-macro2" -version = "1.0.82" +version = "1.0.85" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ad3d49ab951a01fbaafe34f2ec74122942fe18a3f9814c3268f1bb72042131b" +checksum = "22244ce15aa966053a896d1accb3a6e68469b97c7f33f284b99f0d576879fc23" dependencies = [ "unicode-ident", ] @@ -4058,7 +4058,7 @@ dependencies = [ "fluent-syntax", "proc-macro2", "quote", - "syn 2.0.64", + "syn 2.0.66", "unic-langid", ] @@ -4192,7 +4192,7 @@ version = "0.0.0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.64", + "syn 2.0.66", "synstructure", ] @@ -4341,7 +4341,7 @@ version = "0.0.0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.64", + "syn 2.0.66", "synstructure", ] @@ -4920,7 +4920,7 @@ version = "0.0.0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.64", + "syn 2.0.66", "synstructure", ] @@ -5018,7 +5018,7 @@ dependencies = [ "proc-macro2", "quote", "serde", - "syn 2.0.64", + "syn 2.0.66", ] [[package]] @@ -5154,22 +5154,22 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.202" +version = "1.0.203" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "226b61a0d411b2ba5ff6d7f73a476ac4f8bb900373459cd00fab8512828ba395" +checksum = "7253ab4de971e72fb7be983802300c30b5a7f0c2e56fab8abfc6a214307c0094" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.202" +version = "1.0.203" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6048858004bcff69094cd972ed40a32500f153bd3be9f716b2eed2e8217c4838" +checksum = "500cbc0ebeb6f46627f50f3f5811ccf6bf00643be300b4c3eabc0ef55dc5b5ba" dependencies = [ "proc-macro2", "quote", - "syn 2.0.64", + "syn 2.0.66", ] [[package]] @@ -5281,9 +5281,9 @@ dependencies = [ [[package]] name = "spanned" -version = "0.2.0" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ccdf4f5590b7e6fbd4f2e80d442789079a6fff7c12ef921a9de358b7b353098e" +checksum = "ed14ba8b4b82241bd5daba2c49185d4a0581a0058355fe96537338f002b8605d" dependencies = [ "bstr", "color-eyre", @@ -5463,9 +5463,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.64" +version = "2.0.66" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ad3dee41f36859875573074334c200d1add8e4a87bb37113ebd31d926b7b11f" +checksum = "c42f3f41a2de00b01c0aaad383c5a45241efc8b2d1eda5661812fda5f3cdcff5" dependencies = [ "proc-macro2", "quote", @@ -5480,7 +5480,7 @@ checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971" dependencies = [ "proc-macro2", "quote", - "syn 2.0.64", + "syn 2.0.66", ] [[package]] @@ -5540,9 +5540,9 @@ dependencies = [ [[package]] name = "tar" -version = "0.4.40" +version = "0.4.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b16afcea1f22891c49a00c751c7b63b2233284064f11a200fc624137c51e2ddb" +checksum = "cb797dad5fb5b76fcf519e702f4a589483b5ef06567f160c392832c1f5e44909" dependencies = [ "filetime", "libc", @@ -5659,7 +5659,7 @@ checksum = "46c3384250002a6d5af4d114f2845d37b57521033f30d5c3f46c4d70e1197533" dependencies = [ "proc-macro2", "quote", - "syn 2.0.64", + "syn 2.0.66", ] [[package]] @@ -5769,9 +5769,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.37.0" +version = "1.38.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1adbebffeca75fcfd058afa480fb6c0b81e165a0323f9c9d39c9697e37c46787" +checksum = "ba4f4a02a7a80d6f274636f0aa95c7e383b912d41fe721a31f29e29698585a4a" dependencies = [ "backtrace", "bytes", @@ -5801,14 +5801,14 @@ dependencies = [ [[package]] name = "toml" -version = "0.8.13" +version = "0.8.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4e43f8cc456c9704c851ae29c67e17ef65d2c30017c17a9765b89c382dc8bba" +checksum = "6f49eb2ab21d2f26bd6db7bf383edc527a7ebaee412d17af4d40fdccd442f335" dependencies = [ "serde", "serde_spanned", "toml_datetime", - "toml_edit 0.22.13", + "toml_edit 0.22.14", ] [[package]] @@ -5835,15 +5835,15 @@ dependencies = [ [[package]] name = "toml_edit" -version = "0.22.13" +version = "0.22.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c127785850e8c20836d49732ae6abfa47616e60bf9d9f57c43c250361a9db96c" +checksum = "f21c7aaf97f1bd9ca9d4f9e73b0a6c74bd5afef56f2bc931943a6e1c37e04e38" dependencies = [ "indexmap", "serde", "serde_spanned", "toml_datetime", - "winnow 0.6.8", + "winnow 0.6.13", ] [[package]] @@ -5872,7 +5872,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.64", + "syn 2.0.66", ] [[package]] @@ -5927,11 +5927,11 @@ dependencies = [ [[package]] name = "tracing-tree" -version = "0.3.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "65139ecd2c3f6484c3b99bc01c77afe21e95473630747c7aca525e78b0666675" +checksum = "b56c62d2c80033cb36fae448730a2f2ef99410fe3ecbffc916681a32f6807dbe" dependencies = [ - "nu-ansi-term 0.49.0", + "nu-ansi-term 0.50.0", "tracing-core", "tracing-log", "tracing-subscriber", @@ -6011,7 +6011,7 @@ version = "0.23.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "29e5f4ffcbab82453958fbf59990e981b8e8a177dcd60c2bd8f9b52c3036a6e1" dependencies = [ - "annotate-snippets 0.11.2", + "annotate-snippets 0.11.3", "anyhow", "bstr", "cargo-platform", @@ -6072,7 +6072,7 @@ checksum = "1ed7f4237ba393424195053097c1516bd4590dc82b84f2f97c5c69e12704555b" dependencies = [ "proc-macro-hack", "quote", - "syn 2.0.64", + "syn 2.0.66", "unic-langid-impl", ] @@ -6143,9 +6143,9 @@ checksum = "d4c87d22b6e3f4a18d4d40ef354e97c90fcb14dd91d7dc0aa9d8a1172ebf7202" [[package]] name = "unicode-width" -version = "0.1.12" +version = "0.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68f5e5f3158ecfd4b8ff6fe086db7c8467a2dfdac97fe420f2b7c4aa97af66d6" +checksum = "0336d538f7abc86d282a4189614dfaa90810dfc2c6f6427eaf88e16311dd225d" dependencies = [ "compiler_builtins", "rustc-std-workspace-core", @@ -6222,9 +6222,9 @@ checksum = "86bd8d4e895da8537e5315b8254664e6b769c4ff3db18321b297a1e7004392e3" [[package]] name = "utf8parse" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" +checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" [[package]] name = "uuid" @@ -6304,7 +6304,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.64", + "syn 2.0.66", "wasm-bindgen-shared", ] @@ -6326,7 +6326,7 @@ checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.64", + "syn 2.0.66", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -6407,7 +6407,7 @@ dependencies = [ "rayon", "serde", "serde_json", - "syn 2.0.64", + "syn 2.0.66", "windows-metadata", ] @@ -6576,9 +6576,9 @@ dependencies = [ [[package]] name = "winnow" -version = "0.6.8" +version = "0.6.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3c52e9c97a68071b23e836c9380edae937f17b9c4667bd021973efc689f618d" +checksum = "59b5e5f6c299a3c7890b876a2a587f3115162487e704907d9b6cd29473052ba1" dependencies = [ "memchr", ] @@ -6653,7 +6653,7 @@ checksum = "28cc31741b18cb6f1d5ff12f5b7523e3d6eb0852bbbad19d73905511d9849b95" dependencies = [ "proc-macro2", "quote", - "syn 2.0.64", + "syn 2.0.66", "synstructure", ] @@ -6674,7 +6674,7 @@ checksum = "15e934569e47891f7d9411f1a451d947a60e000ab3bd24fbb970f000387d1b3b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.64", + "syn 2.0.66", ] [[package]] @@ -6694,7 +6694,7 @@ checksum = "0ea7b4a3637ea8669cedf0f1fd5c286a17f3de97b8dd5a70a6c167a1730e63a5" dependencies = [ "proc-macro2", "quote", - "syn 2.0.64", + "syn 2.0.66", "synstructure", ] @@ -6717,5 +6717,5 @@ checksum = "97cf56601ee5052b4417d90c8755c6683473c926039908196cf35d99f893ebe7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.64", + "syn 2.0.66", ] From 0f8513a51c7560d0e381198d607dfcc91e8ef36d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Kr=C3=BCger?= Date: Sat, 8 Jun 2024 18:36:21 +0200 Subject: [PATCH 25/50] tests: add more crashes --- tests/crashes/125655.rs | 8 ++++++++ tests/crashes/125680.rs | 15 +++++++++++++++ tests/crashes/125758.rs | 26 ++++++++++++++++++++++++++ tests/crashes/125768.rs | 15 +++++++++++++++ tests/crashes/125769.rs | 14 ++++++++++++++ tests/crashes/125772.rs | 17 +++++++++++++++++ tests/crashes/125799.rs | 22 ++++++++++++++++++++++ tests/crashes/125801.rs | 20 ++++++++++++++++++++ tests/crashes/125810.rs | 10 ++++++++++ tests/crashes/125811.rs | 34 ++++++++++++++++++++++++++++++++++ tests/crashes/125841.rs | 14 ++++++++++++++ tests/crashes/125843.rs | 4 ++++ tests/crashes/125874.rs | 22 ++++++++++++++++++++++ tests/crashes/125879.rs | 18 ++++++++++++++++++ tests/crashes/125881.rs | 8 ++++++++ tests/crashes/125888.rs | 17 +++++++++++++++++ tests/crashes/125914.rs | 20 ++++++++++++++++++++ tests/crashes/125957.rs | 20 ++++++++++++++++++++ tests/crashes/125992.rs | 19 +++++++++++++++++++ 19 files changed, 323 insertions(+) create mode 100644 tests/crashes/125655.rs create mode 100644 tests/crashes/125680.rs create mode 100644 tests/crashes/125758.rs create mode 100644 tests/crashes/125768.rs create mode 100644 tests/crashes/125769.rs create mode 100644 tests/crashes/125772.rs create mode 100644 tests/crashes/125799.rs create mode 100644 tests/crashes/125801.rs create mode 100644 tests/crashes/125810.rs create mode 100644 tests/crashes/125811.rs create mode 100644 tests/crashes/125841.rs create mode 100644 tests/crashes/125843.rs create mode 100644 tests/crashes/125874.rs create mode 100644 tests/crashes/125879.rs create mode 100644 tests/crashes/125881.rs create mode 100644 tests/crashes/125888.rs create mode 100644 tests/crashes/125914.rs create mode 100644 tests/crashes/125957.rs create mode 100644 tests/crashes/125992.rs diff --git a/tests/crashes/125655.rs b/tests/crashes/125655.rs new file mode 100644 index 000000000000..fbf92ca22be7 --- /dev/null +++ b/tests/crashes/125655.rs @@ -0,0 +1,8 @@ +//@ known-bug: rust-lang/rust#125655 + +fn main() { + static foo: dyn Fn() -> u32 = || -> u32 { + ... + 0 + }; +} diff --git a/tests/crashes/125680.rs b/tests/crashes/125680.rs new file mode 100644 index 000000000000..09f4f318bddd --- /dev/null +++ b/tests/crashes/125680.rs @@ -0,0 +1,15 @@ +//@ known-bug: rust-lang/rust#125680 +//@ edition:2021 + +#![feature(generic_const_exprs)] + +use core::fmt::Debug; + +struct Inline +where + [(); std::mem::offset_of!((T,), 0)]:, +{} + +fn main() { + let dst = Inline::::new(0); // BANG! +} diff --git a/tests/crashes/125758.rs b/tests/crashes/125758.rs new file mode 100644 index 000000000000..86c3b80abab9 --- /dev/null +++ b/tests/crashes/125758.rs @@ -0,0 +1,26 @@ +//@ known-bug: rust-lang/rust#125758 +#![feature(impl_trait_in_assoc_type)] + +trait Trait: Sized { + type Assoc2; +} + +impl Trait for Bar { + type Assoc2 = impl std::fmt::Debug; +} + +struct Foo { + field: ::Assoc2, +} + +enum Bar { + C = 42, + D = 99, +} + +static BAR: u8 = 42; + +static FOO2: (&Foo, &::Assoc2) = + unsafe { (std::mem::transmute(&BAR), std::mem::transmute(&BAR)) }; + +fn main() {} diff --git a/tests/crashes/125768.rs b/tests/crashes/125768.rs new file mode 100644 index 000000000000..3c04431baa0a --- /dev/null +++ b/tests/crashes/125768.rs @@ -0,0 +1,15 @@ +//@ known-bug: rust-lang/rust#125768 + +#![feature(generic_const_exprs)] + +struct Outer(); +impl Outer +where + [(); A + (B * 2)]:, +{ + fn o() -> Union {} +} + +fn main() { + Outer::<1, 1>::o(); +} diff --git a/tests/crashes/125769.rs b/tests/crashes/125769.rs new file mode 100644 index 000000000000..da19458f7ca7 --- /dev/null +++ b/tests/crashes/125769.rs @@ -0,0 +1,14 @@ +//@ known-bug: rust-lang/rust#125769 + +#![feature(generic_const_exprs)] + +trait Trait {} + +struct HasCastInTraitImpl; +impl Trait for HasCastInTraitImpl {} + +pub fn use_trait_impl() { + fn assert_impl() {} + + assert_impl::>(); +} diff --git a/tests/crashes/125772.rs b/tests/crashes/125772.rs new file mode 100644 index 000000000000..2965cfc9e7c3 --- /dev/null +++ b/tests/crashes/125772.rs @@ -0,0 +1,17 @@ +//@ known-bug: rust-lang/rust#125772 +//@ only-x86_64 +#![feature(generic_const_exprs)] + +struct Outer(); +impl Outer +where + [(); A + (B * 2)]:, +{ + fn i() -> Self { + Self + } +} + +fn main() { + Outer::<1, 1>::o(); +} diff --git a/tests/crashes/125799.rs b/tests/crashes/125799.rs new file mode 100644 index 000000000000..62d5438b4e40 --- /dev/null +++ b/tests/crashes/125799.rs @@ -0,0 +1,22 @@ +//@ known-bug: rust-lang/rust#125799 +//@ only-x86_64 + +trait Trait { + type Assoc; +} + +impl Trait for Vec { + type Assoc = (); +} + +impl Trait for Vec {} + +const BAR: as Trait>::Assoc = 3; + +pub fn main() { + let x: isize = 3; + let _ = match x { + BAR => 2, + _ => 3, + }; +} diff --git a/tests/crashes/125801.rs b/tests/crashes/125801.rs new file mode 100644 index 000000000000..aaa76bd0ba69 --- /dev/null +++ b/tests/crashes/125801.rs @@ -0,0 +1,20 @@ +//@ known-bug: rust-lang/rust#125801 + +#![feature(generic_const_exprs)] +#![allow(incomplete_features)] + +trait Foo { + type Output; +} + +impl Foo for [u8; 3] { + type Output = [u8; 3]; +} + +static A: <[u8; N] as Foo>::Output = [1, 2, 3]; + +fn main() { + || { + let _ = A[1]; + }; +} diff --git a/tests/crashes/125810.rs b/tests/crashes/125810.rs new file mode 100644 index 000000000000..4a152da8ddf3 --- /dev/null +++ b/tests/crashes/125810.rs @@ -0,0 +1,10 @@ +//@ known-bug: rust-lang/rust#125810 +#![feature(arbitrary_self_types, dispatch_from_dyn)] + +use std::ops::{Deref, DispatchFromDyn}; + +trait Trait + DispatchFromDyn> { + fn MONO_BUF(self: T) -> dyn Trait; +} + +fn main() {} diff --git a/tests/crashes/125811.rs b/tests/crashes/125811.rs new file mode 100644 index 000000000000..eb764e8d1522 --- /dev/null +++ b/tests/crashes/125811.rs @@ -0,0 +1,34 @@ +//@ known-bug: rust-lang/rust#125811 +mod assert { + use std::mem::{Assume, BikeshedIntrinsicFrom}; + + pub fn is_transmutable() + where + Dst: BikeshedIntrinsicFrom, + { + } +} + +#[repr(C)] +struct Zst; + +enum V0 { + B(!), +} + +enum V2 { + V = 2, +} + +enum Lopsided { + Smol(Zst), + Lorg(V0), +} + +#[repr(C)] +#[repr(C)] +struct Dst(Lopsided, V2); + +fn should_pad_variants() { + assert::is_transmutable::(); +} diff --git a/tests/crashes/125841.rs b/tests/crashes/125841.rs new file mode 100644 index 000000000000..e2e61071f1df --- /dev/null +++ b/tests/crashes/125841.rs @@ -0,0 +1,14 @@ +//@ known-bug: rust-lang/rust#125841 +#![feature(non_lifetime_binders)] +fn take(id: impl for Fn(T) -> T) { + id(0); + id(""); +} + +fn take2() -> impl for Fn(T) -> T { + |x| x +} + +fn main() { + take(|x| take2) +} diff --git a/tests/crashes/125843.rs b/tests/crashes/125843.rs new file mode 100644 index 000000000000..8b9a3913c7e6 --- /dev/null +++ b/tests/crashes/125843.rs @@ -0,0 +1,4 @@ +//@ known-bug: rust-lang/rust#125843 +#![feature(non_lifetime_binders)] +trait v0<> {} +fn kind :(v3main impl for v0<'_, v2 = impl v0 + '_>) {} diff --git a/tests/crashes/125874.rs b/tests/crashes/125874.rs new file mode 100644 index 000000000000..6a2713cd7c89 --- /dev/null +++ b/tests/crashes/125874.rs @@ -0,0 +1,22 @@ +//@ known-bug: rust-lang/rust#125874 +pub trait A {} + +pub trait Mirror { + type Assoc: ?Sized; +} +impl Mirror for dyn A { + type Assoc = T; +} + +struct Bar { + foo: ::Assoc, +} + +pub fn main() { + let strct = Bar { foo: 3 }; + + match strct { + Bar { foo: 1, .. } => {} + _ => (), + }; +} diff --git a/tests/crashes/125879.rs b/tests/crashes/125879.rs new file mode 100644 index 000000000000..4318842e4551 --- /dev/null +++ b/tests/crashes/125879.rs @@ -0,0 +1,18 @@ +//@ known-bug: rust-lang/rust#125879 +#![feature(inherent_associated_types)] +#![allow(incomplete_features)] + +pub type PubAlias0 = PubTy::PrivAssocTy; + +pub struct PubTy; +impl PubTy { + type PrivAssocTy = (); +} + +pub struct S(pub PubAlias0); + +pub unsafe fn foo(a: S) -> S { + a +} + +fn main() {} diff --git a/tests/crashes/125881.rs b/tests/crashes/125881.rs new file mode 100644 index 000000000000..98331d3c9748 --- /dev/null +++ b/tests/crashes/125881.rs @@ -0,0 +1,8 @@ +//@ known-bug: rust-lang/rust#125881 +#![crate_type = "lib"] +#![feature(transmutability)] +#![feature(unboxed_closures,effects)] + +const fn test() -> impl std::mem::BikeshedIntrinsicFrom() { + || {} +} diff --git a/tests/crashes/125888.rs b/tests/crashes/125888.rs new file mode 100644 index 000000000000..ae8f2d6576b7 --- /dev/null +++ b/tests/crashes/125888.rs @@ -0,0 +1,17 @@ +//@ known-bug: rust-lang/rust#125888 +enum NestedEnum { + First, + Second, +} + +enum Enum { + Variant(*const &'a ()), +} + +fn foo(x: Enum) { + match x { + Enum::Variant(NestedEnum::Second) => {} + } +} + +fn main() {} diff --git a/tests/crashes/125914.rs b/tests/crashes/125914.rs new file mode 100644 index 000000000000..77ccb9fb0978 --- /dev/null +++ b/tests/crashes/125914.rs @@ -0,0 +1,20 @@ +//@ known-bug: rust-lang/rust#125914 +enum AstKind<'ast> { + ExprInt, +} + +enum Foo { + Bar(isize), + Baz, +} + +enum Other { + Other1(Foo), + Other2(AstKind), +} + +fn main() { + match Other::Other1(Foo::Baz) { + ::Other::Other2(::Foo::Bar(..)) => {} + } +} diff --git a/tests/crashes/125957.rs b/tests/crashes/125957.rs new file mode 100644 index 000000000000..e3abe5262eb9 --- /dev/null +++ b/tests/crashes/125957.rs @@ -0,0 +1,20 @@ +//@ known-bug: rust-lang/rust#125957 +#![feature(generic_const_exprs)] +#![allow(incomplete_features)] +#![feature(associated_const_equality)] + +pub struct Equal(); + +pub enum ParseMode { + Raw, +} +pub trait Parse { + const PARSE_MODE: ParseMode; +} +pub trait RenderRaw: Parse {} + +trait GenericVec { + fn unwrap() -> dyn RenderRaw; +} + +fn main() {} diff --git a/tests/crashes/125992.rs b/tests/crashes/125992.rs new file mode 100644 index 000000000000..d78f28ce6de4 --- /dev/null +++ b/tests/crashes/125992.rs @@ -0,0 +1,19 @@ +//@ known-bug: rust-lang/rust#125992 +//@ compile-flags: -Zpolonius=next + +#![feature(inherent_associated_types)] + +type Function = for<'a> fn(&'a i32) -> S<'a>::P; + +struct S<'a>(&'a ()); + +impl<'a> S { + type P = &'a i32; +} + +fn ret_ref_local<'e>() -> &'e i32 { + let f: Function = |x| x; + + let local = 0; + f(&local) +} From fbe5015480f44cad99f9005a48f9699a3f633a96 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Sun, 9 Jun 2024 11:52:16 +0200 Subject: [PATCH 26/50] Fix documentation for `impl_common_helpers` in `run-make-support` --- src/tools/run-make-support/src/lib.rs | 20 ++++++-------------- 1 file changed, 6 insertions(+), 14 deletions(-) diff --git a/src/tools/run-make-support/src/lib.rs b/src/tools/run-make-support/src/lib.rs index b17f217c133b..cea1313e29d7 100644 --- a/src/tools/run-make-support/src/lib.rs +++ b/src/tools/run-make-support/src/lib.rs @@ -318,38 +318,30 @@ pub fn run_in_tmpdir(callback: F) { } /// Implement common helpers for command wrappers. This assumes that the command wrapper is a struct -/// containing a `cmd: Command` field and a `output` function. The provided helpers are: +/// containing a `cmd: Command` field. The provided helpers are: /// /// 1. Generic argument acceptors: `arg` and `args` (delegated to [`Command`]). These are intended /// to be *fallback* argument acceptors, when specific helpers don't make sense. Prefer to add /// new specific helper methods over relying on these generic argument providers. /// 2. Environment manipulation methods: `env`, `env_remove` and `env_clear`: these delegate to /// methods of the same name on [`Command`]. -/// 3. Output and execution: `output`, `run` and `run_fail` are provided. `output` waits for the -/// command to finish running and returns the process's [`Output`]. `run` and `run_fail` are -/// higher-level convenience methods which waits for the command to finish running and assert -/// that the command successfully ran or failed as expected. Prefer `run` and `run_fail` when -/// possible. +/// 3. Output and execution: `run` and `run_fail` are provided. These are +/// higher-level convenience methods which wait for the command to finish running and assert +/// that the command successfully ran or failed as expected. They return +/// [`CompletedProcess`], which can be used to assert the stdout/stderr/exit code of the executed +/// process. /// /// Example usage: /// /// ```ignore (illustrative) /// struct CommandWrapper { cmd: Command } // <- required `cmd` field /// -/// impl CommandWrapper { -/// /// Get the [`Output`][::std::process::Output] of the finished process. -/// pub fn command_output(&mut self) -> Output { /* ... */ } // <- required `command_output()` method -/// } -/// /// crate::impl_common_helpers!(CommandWrapper); /// /// impl CommandWrapper { /// // ... additional specific helper methods /// } /// ``` -/// -/// [`Command`]: ::std::process::Command -/// [`Output`]: ::std::process::Output macro_rules! impl_common_helpers { ($wrapper: ident) => { impl $wrapper { From d5fb8257e7533edd1f2699f9b92f80848477c800 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sun, 9 Jun 2024 09:37:15 +0200 Subject: [PATCH 27/50] interpret: do not ICE on padded non-pow2 SIMD vectors --- .../rustc_const_eval/src/interpret/place.rs | 13 ++++++----- .../src/interpret/projection.rs | 2 ++ .../tests/pass/intrinsics/portable-simd.rs | 23 ++++++++++++++++++- 3 files changed, 31 insertions(+), 7 deletions(-) diff --git a/compiler/rustc_const_eval/src/interpret/place.rs b/compiler/rustc_const_eval/src/interpret/place.rs index 4a86ec3f57a4..046ff34e3d07 100644 --- a/compiler/rustc_const_eval/src/interpret/place.rs +++ b/compiler/rustc_const_eval/src/interpret/place.rs @@ -499,13 +499,14 @@ where &self, mplace: &MPlaceTy<'tcx, M::Provenance>, ) -> InterpResult<'tcx, (MPlaceTy<'tcx, M::Provenance>, u64)> { - // Basically we just transmute this place into an array following simd_size_and_type. - // (Transmuting is okay since this is an in-memory place. We also double-check the size - // stays the same.) + // Basically we want to transmute this place into an array following simd_size_and_type. let (len, e_ty) = mplace.layout.ty.simd_size_and_type(*self.tcx); - let array = Ty::new_array(self.tcx.tcx, e_ty, len); - let layout = self.layout_of(array)?; - let mplace = mplace.transmute(layout, self)?; + // Some SIMD types have padding, so `len` many `e_ty` does not cover the entire place. + // Therefore we cannot transmute, and instead we project at offset 0, which side-steps + // the size check. + let array_layout = self.layout_of(Ty::new_array(self.tcx.tcx, e_ty, len))?; + assert!(array_layout.size <= mplace.layout.size); + let mplace = mplace.offset(Size::ZERO, array_layout, self)?; Ok((mplace, len)) } diff --git a/compiler/rustc_const_eval/src/interpret/projection.rs b/compiler/rustc_const_eval/src/interpret/projection.rs index 0e594914c3a7..09e1a59dfa1a 100644 --- a/compiler/rustc_const_eval/src/interpret/projection.rs +++ b/compiler/rustc_const_eval/src/interpret/projection.rs @@ -81,6 +81,8 @@ pub trait Projectable<'tcx, Prov: Provenance>: Sized + std::fmt::Debug { ecx: &InterpCx<'tcx, M>, ) -> InterpResult<'tcx, Self> { assert!(layout.is_sized()); + // We sometimes do pointer arithmetic with this function, disregarding the source type. + // So we don't check the sizes here. self.offset_with_meta(offset, OffsetMode::Inbounds, MemPlaceMeta::None, layout, ecx) } diff --git a/src/tools/miri/tests/pass/intrinsics/portable-simd.rs b/src/tools/miri/tests/pass/intrinsics/portable-simd.rs index 248a57d68504..5250a1138b74 100644 --- a/src/tools/miri/tests/pass/intrinsics/portable-simd.rs +++ b/src/tools/miri/tests/pass/intrinsics/portable-simd.rs @@ -1,5 +1,5 @@ //@compile-flags: -Zmiri-strict-provenance -#![feature(portable_simd, adt_const_params, core_intrinsics)] +#![feature(portable_simd, adt_const_params, core_intrinsics, repr_simd)] #![allow(incomplete_features, internal_features)] use std::intrinsics::simd as intrinsics; use std::ptr; @@ -581,11 +581,32 @@ fn simd_masked_loadstore() { assert_eq!(buf, [2, 3, 4]); } +fn simd_ops_non_pow2() { + // Just a little smoke test for operations on non-power-of-two vectors. + #[repr(simd, packed)] + #[derive(Copy, Clone)] + pub struct SimdPacked([T; N]); + #[repr(simd)] + #[derive(Copy, Clone)] + pub struct SimdPadded([T; N]); + + let x = SimdPacked([1u32; 3]); + let y = SimdPacked([2u32; 3]); + let z = unsafe { intrinsics::simd_add(x, y) }; + assert_eq!({ z.0 }, [3u32; 3]); + + let x = SimdPadded([1u32; 3]); + let y = SimdPadded([2u32; 3]); + let z = unsafe { intrinsics::simd_add(x, y) }; + assert_eq!(z.0, [3u32; 3]); +} + fn main() { simd_mask(); simd_ops_f32(); simd_ops_f64(); simd_ops_i32(); + simd_ops_non_pow2(); simd_cast(); simd_swizzle(); simd_gather_scatter(); From 041e204e0d487e633c40709cb4c1f4535145c016 Mon Sep 17 00:00:00 2001 From: ivan-shrimp <70307174+ivan-shrimp@users.noreply.github.com> Date: Sun, 9 Jun 2024 19:45:12 +0800 Subject: [PATCH 28/50] fix `NonZero` doctest inconsistencies --- library/core/src/num/nonzero.rs | 42 +++++++++++++++++++++++++-------- 1 file changed, 32 insertions(+), 10 deletions(-) diff --git a/library/core/src/num/nonzero.rs b/library/core/src/num/nonzero.rs index fcdd983343d6..863f0d61df37 100644 --- a/library/core/src/num/nonzero.rs +++ b/library/core/src/num/nonzero.rs @@ -517,9 +517,13 @@ macro_rules! nonzero_integer { /// ``` /// # use std::num::NonZero; /// # - #[doc = concat!("let n = NonZero::<", stringify!($Int), ">::new(", $leading_zeros_test, ").unwrap();")] + /// # fn main() { test().unwrap(); } + /// # fn test() -> Option<()> { + #[doc = concat!("let n = NonZero::<", stringify!($Int), ">::new(", $leading_zeros_test, ")?;")] /// /// assert_eq!(n.leading_zeros(), 0); + /// # Some(()) + /// # } /// ``` #[stable(feature = "nonzero_leading_trailing_zeros", since = "1.53.0")] #[rustc_const_stable(feature = "nonzero_leading_trailing_zeros", since = "1.53.0")] @@ -545,9 +549,13 @@ macro_rules! nonzero_integer { /// ``` /// # use std::num::NonZero; /// # - #[doc = concat!("let n = NonZero::<", stringify!($Int), ">::new(0b0101000).unwrap();")] + /// # fn main() { test().unwrap(); } + /// # fn test() -> Option<()> { + #[doc = concat!("let n = NonZero::<", stringify!($Int), ">::new(0b0101000)?;")] /// /// assert_eq!(n.trailing_zeros(), 3); + /// # Some(()) + /// # } /// ``` #[stable(feature = "nonzero_leading_trailing_zeros", since = "1.53.0")] #[rustc_const_stable(feature = "nonzero_leading_trailing_zeros", since = "1.53.0")] @@ -1101,9 +1109,13 @@ macro_rules! nonzero_integer_signedness_dependent_methods { /// ``` /// # use std::num::NonZero; /// # - #[doc = concat!("assert_eq!(NonZero::new(7", stringify!($Int), ").unwrap().ilog2(), 2);")] - #[doc = concat!("assert_eq!(NonZero::new(8", stringify!($Int), ").unwrap().ilog2(), 3);")] - #[doc = concat!("assert_eq!(NonZero::new(9", stringify!($Int), ").unwrap().ilog2(), 3);")] + /// # fn main() { test().unwrap(); } + /// # fn test() -> Option<()> { + #[doc = concat!("assert_eq!(NonZero::new(7", stringify!($Int), ")?.ilog2(), 2);")] + #[doc = concat!("assert_eq!(NonZero::new(8", stringify!($Int), ")?.ilog2(), 3);")] + #[doc = concat!("assert_eq!(NonZero::new(9", stringify!($Int), ")?.ilog2(), 3);")] + /// # Some(()) + /// # } /// ``` #[stable(feature = "int_log", since = "1.67.0")] #[rustc_const_stable(feature = "int_log", since = "1.67.0")] @@ -1126,9 +1138,13 @@ macro_rules! nonzero_integer_signedness_dependent_methods { /// ``` /// # use std::num::NonZero; /// # - #[doc = concat!("assert_eq!(NonZero::new(99", stringify!($Int), ").unwrap().ilog10(), 1);")] - #[doc = concat!("assert_eq!(NonZero::new(100", stringify!($Int), ").unwrap().ilog10(), 2);")] - #[doc = concat!("assert_eq!(NonZero::new(101", stringify!($Int), ").unwrap().ilog10(), 2);")] + /// # fn main() { test().unwrap(); } + /// # fn test() -> Option<()> { + #[doc = concat!("assert_eq!(NonZero::new(99", stringify!($Int), ")?.ilog10(), 1);")] + #[doc = concat!("assert_eq!(NonZero::new(100", stringify!($Int), ")?.ilog10(), 2);")] + #[doc = concat!("assert_eq!(NonZero::new(101", stringify!($Int), ")?.ilog10(), 2);")] + /// # Some(()) + /// # } /// ``` #[stable(feature = "int_log", since = "1.67.0")] #[rustc_const_stable(feature = "int_log", since = "1.67.0")] @@ -1187,10 +1203,16 @@ macro_rules! nonzero_integer_signedness_dependent_methods { /// Basic usage: /// /// ``` - #[doc = concat!("let eight = std::num::NonZero::new(8", stringify!($Int), ").unwrap();")] + /// # use std::num::NonZero; + /// # + /// # fn main() { test().unwrap(); } + /// # fn test() -> Option<()> { + #[doc = concat!("let eight = NonZero::new(8", stringify!($Int), ")?;")] /// assert!(eight.is_power_of_two()); - #[doc = concat!("let ten = std::num::NonZero::new(10", stringify!($Int), ").unwrap();")] + #[doc = concat!("let ten = NonZero::new(10", stringify!($Int), ")?;")] /// assert!(!ten.is_power_of_two()); + /// # Some(()) + /// # } /// ``` #[must_use] #[stable(feature = "nonzero_is_power_of_two", since = "1.59.0")] From 3606818010ac773285e151c9cfaf1d09865f2957 Mon Sep 17 00:00:00 2001 From: Chris Denton Date: Sun, 9 Jun 2024 14:29:28 +0000 Subject: [PATCH 29/50] Migrate more things to WinError --- library/std/src/sys/pal/windows/api.rs | 36 ++++++++++++++++++++++ library/std/src/sys/pal/windows/fs.rs | 30 +++++++++--------- library/std/src/sys/pal/windows/futex.rs | 4 +-- library/std/src/sys/pal/windows/os.rs | 7 +++-- library/std/src/sys/pal/windows/pipe.rs | 10 +++--- library/std/src/sys/pal/windows/process.rs | 8 +++-- library/std/src/sys/pal/windows/stdio.rs | 4 +-- 7 files changed, 69 insertions(+), 30 deletions(-) diff --git a/library/std/src/sys/pal/windows/api.rs b/library/std/src/sys/pal/windows/api.rs index 555ad581b856..17a0e47ad595 100644 --- a/library/std/src/sys/pal/windows/api.rs +++ b/library/std/src/sys/pal/windows/api.rs @@ -251,3 +251,39 @@ pub fn get_last_error() -> WinError { pub struct WinError { pub code: u32, } +impl WinError { + const fn new(code: u32) -> Self { + Self { code } + } +} + +// Error code constants. +// The constant names should be the same as the winapi constants except for the leading `ERROR_`. +// Due to the sheer number of codes, error codes should only be added here on an as-needed basis. +// However, they should never be removed as the assumption is they may be useful again in the future. +#[allow(unused)] +impl WinError { + /// Success is not an error. + /// Some Windows APIs do use this to distinguish between a zero return and an error return + /// but we should never return this to users as an error. + pub const SUCCESS: Self = Self::new(c::ERROR_SUCCESS); + // tidy-alphabetical-start + pub const ACCESS_DENIED: Self = Self::new(c::ERROR_ACCESS_DENIED); + pub const ALREADY_EXISTS: Self = Self::new(c::ERROR_ALREADY_EXISTS); + pub const CANT_ACCESS_FILE: Self = Self::new(c::ERROR_CANT_ACCESS_FILE); + pub const DELETE_PENDING: Self = Self::new(c::ERROR_DELETE_PENDING); + pub const DIRECTORY: Self = Self::new(c::ERROR_DIRECTORY); + pub const FILE_NOT_FOUND: Self = Self::new(c::ERROR_FILE_NOT_FOUND); + pub const INSUFFICIENT_BUFFER: Self = Self::new(c::ERROR_INSUFFICIENT_BUFFER); + pub const INVALID_FUNCTION: Self = Self::new(c::ERROR_INVALID_FUNCTION); + pub const INVALID_HANDLE: Self = Self::new(c::ERROR_INVALID_HANDLE); + pub const INVALID_PARAMETER: Self = Self::new(c::ERROR_INVALID_PARAMETER); + pub const NO_MORE_FILES: Self = Self::new(c::ERROR_NO_MORE_FILES); + pub const NOT_FOUND: Self = Self::new(c::ERROR_NOT_FOUND); + pub const NOT_SUPPORTED: Self = Self::new(c::ERROR_NOT_SUPPORTED); + pub const OPERATION_ABORTED: Self = Self::new(c::ERROR_OPERATION_ABORTED); + pub const PATH_NOT_FOUND: Self = Self::new(c::ERROR_PATH_NOT_FOUND); + pub const SHARING_VIOLATION: Self = Self::new(c::ERROR_SHARING_VIOLATION); + pub const TIMEOUT: Self = Self::new(c::ERROR_TIMEOUT); + // tidy-alphabetical-end +} diff --git a/library/std/src/sys/pal/windows/fs.rs b/library/std/src/sys/pal/windows/fs.rs index e92c5e80eac9..629ff114b5a8 100644 --- a/library/std/src/sys/pal/windows/fs.rs +++ b/library/std/src/sys/pal/windows/fs.rs @@ -18,7 +18,8 @@ use crate::sys::{c, cvt, Align8}; use crate::sys_common::{AsInner, FromInner, IntoInner}; use crate::thread; -use super::{api, to_u16s, IoResult}; +use super::api::{self, WinError}; +use super::{to_u16s, IoResult}; use crate::sys::path::maybe_verbatim; pub struct File { @@ -130,10 +131,11 @@ impl Iterator for ReadDir { let mut wfd = mem::zeroed(); loop { if c::FindNextFileW(self.handle.0, &mut wfd) == 0 { - if api::get_last_error().code == c::ERROR_NO_MORE_FILES { - return None; - } else { - return Some(Err(Error::last_os_error())); + match api::get_last_error() { + WinError::NO_MORE_FILES => return None, + WinError { code } => { + return Some(Err(Error::from_raw_os_error(code as i32))); + } } } if let Some(e) = DirEntry::new(&self.root, &wfd) { @@ -244,8 +246,6 @@ impl OpenOptions { } fn get_access_mode(&self) -> io::Result { - const ERROR_INVALID_PARAMETER: i32 = 87; - match (self.read, self.write, self.append, self.access_mode) { (.., Some(mode)) => Ok(mode), (true, false, false, None) => Ok(c::GENERIC_READ), @@ -255,23 +255,23 @@ impl OpenOptions { (true, _, true, None) => { Ok(c::GENERIC_READ | (c::FILE_GENERIC_WRITE & !c::FILE_WRITE_DATA)) } - (false, false, false, None) => Err(Error::from_raw_os_error(ERROR_INVALID_PARAMETER)), + (false, false, false, None) => { + Err(Error::from_raw_os_error(c::ERROR_INVALID_PARAMETER as i32)) + } } } fn get_creation_mode(&self) -> io::Result { - const ERROR_INVALID_PARAMETER: i32 = 87; - match (self.write, self.append) { (true, false) => {} (false, false) => { if self.truncate || self.create || self.create_new { - return Err(Error::from_raw_os_error(ERROR_INVALID_PARAMETER)); + return Err(Error::from_raw_os_error(c::ERROR_INVALID_PARAMETER as i32)); } } (_, true) => { if self.truncate && !self.create_new { - return Err(Error::from_raw_os_error(ERROR_INVALID_PARAMETER)); + return Err(Error::from_raw_os_error(c::ERROR_INVALID_PARAMETER as i32)); } } } @@ -315,7 +315,7 @@ impl File { // Manual truncation. See #115745. if opts.truncate && creation == c::OPEN_ALWAYS - && unsafe { c::GetLastError() } == c::ERROR_ALREADY_EXISTS + && api::get_last_error() == WinError::ALREADY_EXISTS { unsafe { // This originally used `FileAllocationInfo` instead of @@ -845,7 +845,7 @@ fn open_link_no_reparse(parent: &File, name: &[u16], access: u32) -> io::Result< // We make a special exception for `STATUS_DELETE_PENDING` because // otherwise this will be mapped to `ERROR_ACCESS_DENIED` which is // very unhelpful. - Err(io::Error::from_raw_os_error(c::ERROR_DELETE_PENDING as _)) + Err(io::Error::from_raw_os_error(c::ERROR_DELETE_PENDING as i32)) } else if status == c::STATUS_INVALID_PARAMETER && ATTRIBUTES.load(Ordering::Relaxed) == c::OBJ_DONT_REPARSE { @@ -1097,7 +1097,7 @@ pub fn readdir(p: &Path) -> io::Result { // // See issue #120040: https://github.com/rust-lang/rust/issues/120040. let last_error = api::get_last_error(); - if last_error.code == c::ERROR_FILE_NOT_FOUND { + if last_error == WinError::FILE_NOT_FOUND { return Ok(ReadDir { handle: FindNextFileHandle(find_handle), root: Arc::new(root), diff --git a/library/std/src/sys/pal/windows/futex.rs b/library/std/src/sys/pal/windows/futex.rs index bc19c402d9c1..08b7fe300dc3 100644 --- a/library/std/src/sys/pal/windows/futex.rs +++ b/library/std/src/sys/pal/windows/futex.rs @@ -1,4 +1,4 @@ -use super::api; +use super::api::{self, WinError}; use crate::sys::c; use crate::sys::dur2timeout; use core::ffi::c_void; @@ -72,7 +72,7 @@ pub fn wake_by_address_all(address: &T) { pub fn futex_wait(futex: &W::Atomic, expected: W, timeout: Option) -> bool { // return false only on timeout - wait_on_address(futex, expected, timeout) || api::get_last_error().code != c::ERROR_TIMEOUT + wait_on_address(futex, expected, timeout) || api::get_last_error() != WinError::TIMEOUT } pub fn futex_wake(futex: &T) -> bool { diff --git a/library/std/src/sys/pal/windows/os.rs b/library/std/src/sys/pal/windows/os.rs index 483b8b0072c8..62199c16bfed 100644 --- a/library/std/src/sys/pal/windows/os.rs +++ b/library/std/src/sys/pal/windows/os.rs @@ -17,7 +17,8 @@ use crate::ptr; use crate::slice; use crate::sys::{c, cvt}; -use super::{api, to_u16s}; +use super::api::{self, WinError}; +use super::to_u16s; pub fn errno() -> i32 { api::get_last_error().code as i32 @@ -333,7 +334,7 @@ fn home_dir_crt() -> Option { buf, &mut sz, ) { - 0 if api::get_last_error().code != c::ERROR_INSUFFICIENT_BUFFER => 0, + 0 if api::get_last_error() != WinError::INSUFFICIENT_BUFFER => 0, 0 => sz, _ => sz - 1, // sz includes the null terminator } @@ -358,7 +359,7 @@ fn home_dir_crt() -> Option { super::fill_utf16_buf( |buf, mut sz| { match c::GetUserProfileDirectoryW(token, buf, &mut sz) { - 0 if api::get_last_error().code != c::ERROR_INSUFFICIENT_BUFFER => 0, + 0 if api::get_last_error() != WinError::INSUFFICIENT_BUFFER => 0, 0 => sz, _ => sz - 1, // sz includes the null terminator } diff --git a/library/std/src/sys/pal/windows/pipe.rs b/library/std/src/sys/pal/windows/pipe.rs index dfa938d4d576..67ef3ca82da0 100644 --- a/library/std/src/sys/pal/windows/pipe.rs +++ b/library/std/src/sys/pal/windows/pipe.rs @@ -12,6 +12,7 @@ use crate::sys::c; use crate::sys::fs::{File, OpenOptions}; use crate::sys::handle::Handle; use crate::sys::hashmap_random_keys; +use crate::sys::pal::windows::api::{self, WinError}; use crate::sys_common::{FromInner, IntoInner}; //////////////////////////////////////////////////////////////////////////////// @@ -124,20 +125,19 @@ pub fn anon_pipe(ours_readable: bool, their_handle_inheritable: bool) -> io::Res // testing strategy // For more info, see https://github.com/rust-lang/rust/pull/37677. if handle == c::INVALID_HANDLE_VALUE { - let err = io::Error::last_os_error(); - let raw_os_err = err.raw_os_error(); + let error = api::get_last_error(); if tries < 10 { - if raw_os_err == Some(c::ERROR_ACCESS_DENIED as i32) { + if error == WinError::ACCESS_DENIED { continue; } else if reject_remote_clients_flag != 0 - && raw_os_err == Some(c::ERROR_INVALID_PARAMETER as i32) + && error == WinError::INVALID_PARAMETER { reject_remote_clients_flag = 0; tries -= 1; continue; } } - return Err(err); + return Err(io::Error::from_raw_os_error(error.code as i32)); } ours = Handle::from_raw_handle(handle); break; diff --git a/library/std/src/sys/pal/windows/process.rs b/library/std/src/sys/pal/windows/process.rs index e4ab2ca7da1c..2da986a1494e 100644 --- a/library/std/src/sys/pal/windows/process.rs +++ b/library/std/src/sys/pal/windows/process.rs @@ -31,6 +31,8 @@ use crate::sys_common::IntoInner; use core::ffi::c_void; +use super::api::{self, WinError}; + //////////////////////////////////////////////////////////////////////////////// // Command //////////////////////////////////////////////////////////////////////////////// @@ -645,12 +647,12 @@ impl Process { pub fn kill(&mut self) -> io::Result<()> { let result = unsafe { c::TerminateProcess(self.handle.as_raw_handle(), 1) }; if result == c::FALSE { - let error = unsafe { c::GetLastError() }; + let error = api::get_last_error(); // TerminateProcess returns ERROR_ACCESS_DENIED if the process has already been // terminated (by us, or for any other reason). So check if the process was actually // terminated, and if so, do not return an error. - if error != c::ERROR_ACCESS_DENIED || self.try_wait().is_err() { - return Err(crate::io::Error::from_raw_os_error(error as i32)); + if error != WinError::ACCESS_DENIED || self.try_wait().is_err() { + return Err(crate::io::Error::from_raw_os_error(error.code as i32)); } } Ok(()) diff --git a/library/std/src/sys/pal/windows/stdio.rs b/library/std/src/sys/pal/windows/stdio.rs index 96c23f82aec2..690b60d1decc 100644 --- a/library/std/src/sys/pal/windows/stdio.rs +++ b/library/std/src/sys/pal/windows/stdio.rs @@ -1,6 +1,6 @@ #![unstable(issue = "none", feature = "windows_stdio")] -use super::api; +use super::api::{self, WinError}; use crate::cmp; use crate::io; use crate::mem::MaybeUninit; @@ -370,7 +370,7 @@ fn read_u16s(handle: c::HANDLE, buf: &mut [MaybeUninit]) -> io::Result Date: Sun, 9 Jun 2024 11:52:11 +0000 Subject: [PATCH 30/50] Autolabel run-make tests, remind to update tracking issue - Autolabel PRs modifying `tests/run-make/` and `src/tools/run-make-support/` with `X-run-make` label. - Add reminder to update the tracking issue if applicable when `tests/run-make/` is modified by a PR. --- triagebot.toml | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/triagebot.toml b/triagebot.toml index 55f63ef2567c..3abff0f1c784 100644 --- a/triagebot.toml +++ b/triagebot.toml @@ -429,6 +429,12 @@ trigger_files = [ "tests/ui/stack-protector" ] +[autolabel."A-run-make"] +trigger_files = [ + "tests/run-make", + "src/tools/run-make-support" +] + [notify-zulip."I-prioritize"] zulip_stream = 245100 # #t-compiler/wg-prioritization/alerts topic = "#{number} {title}" @@ -684,7 +690,13 @@ message = "Some changes occurred in GUI tests." cc = ["@GuillaumeGomez"] [mentions."tests/run-make/"] -message = "Some changes occurred in run-make tests." +message = """ +This PR modifies `tests/run-make/`. If this PR is trying to port a Makefile +run-make test to use rmake.rs, please update the +[run-make port tracking issue](https://github.com/rust-lang/rust/issues/121876) +so we can track our progress. You can either modify the tracking issue +directly, or you can comment on the tracking issue and link this PR. +""" cc = ["@jieyouxu"] [mentions."src/librustdoc/html/static/css/themes/ayu.css"] From 4977608f72e97f498d6be312860753d0d131314b Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Thu, 23 May 2024 18:13:50 -0700 Subject: [PATCH 31/50] Add release notes for 1.79.0 --- RELEASES.md | 128 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 128 insertions(+) diff --git a/RELEASES.md b/RELEASES.md index 3080f03c7210..c1311ab14c53 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -1,3 +1,131 @@ +Version 1.79.0 (2024-06-13) +========================== + + + +Language +-------- +- [Stabilize inline `const {}` expressions.](https://github.com/rust-lang/rust/pull/104087/) +- [Prevent opaque types being instantiated twice with different regions within the same function.](https://github.com/rust-lang/rust/pull/116935/) +- [Stabilize WebAssembly target features that are in phase 4 and 5.](https://github.com/rust-lang/rust/pull/117457/) +- [Add the `redundant_lifetimes` lint to detect lifetimes which are semantically redundant.](https://github.com/rust-lang/rust/pull/118391/) +- [Stabilize the `unnameable_types` lint for public types that can't be named.](https://github.com/rust-lang/rust/pull/120144/) +- [Enable debuginfo in macros, and stabilize `-C collapse-macro-debuginfo` and `#[collapse_debuginfo]`.](https://github.com/rust-lang/rust/pull/120845/) +- [Propagate temporary lifetime extension into `if` and `match` expressions.](https://github.com/rust-lang/rust/pull/121346/) +- [Restrict promotion of `const fn` calls.](https://github.com/rust-lang/rust/pull/121557/) +- [Warn against refining impls of crate-private traits with `refining_impl_trait` lint.](https://github.com/rust-lang/rust/pull/121720/) +- [Stabilize associated type bounds (RFC 2289).](https://github.com/rust-lang/rust/pull/122055/) +- [Stabilize importing `main` from other modules or crates.](https://github.com/rust-lang/rust/pull/122060/) +- [Check return types of function types for well-formedness](https://github.com/rust-lang/rust/pull/115538) +- [Rework `impl Trait` lifetime inference](https://github.com/rust-lang/rust/pull/116891/) +- [Change inductive trait solver cycles to be ambiguous](https://github.com/rust-lang/rust/pull/122791) + + + +Compiler +-------- +- [Define `-C strip` to only affect binaries, not artifacts like `.pdb`.](https://github.com/rust-lang/rust/pull/115120/) +- [Stabilize `-Crelro-level` for controlling runtime link hardening.](https://github.com/rust-lang/rust/pull/121694/) +- [Stabilize checking of `cfg` names and values at compile-time with `--check-cfg`.](https://github.com/rust-lang/rust/pull/123501/) + *Note that this only stabilizes the compiler part, the Cargo part is still unstable in this release.* +- [Add `aarch64-apple-visionos` and `aarch64-apple-visionos-sim` tier 3 targets.](https://github.com/rust-lang/rust/pull/121419/) +- [Add `riscv32ima-unknown-none-elf` tier 3 target.](https://github.com/rust-lang/rust/pull/122696/) +- [Promote several Windows targets to tier 2](https://github.com/rust-lang/rust/pull/121712): `aarch64-pc-windows-gnullvm`, `i686-pc-windows-gnullvm`, and `x86_64-pc-windows-gnullvm`. + +Refer to Rust's [platform support page][platform-support-doc] +for more information on Rust's tiered platform support. + + + +Libraries +--------- + +- [Implement `FromIterator` for `(impl Default + Extend, impl Default + Extend)`.](https://github.com/rust-lang/rust/pull/107462/) +- [Implement `{Div,Rem}Assign>` on `X`.](https://github.com/rust-lang/rust/pull/121952/) +- [Document overrides of `clone_from()` in core/std.](https://github.com/rust-lang/rust/pull/122201/) +- [Link MSVC default lib in core.](https://github.com/rust-lang/rust/pull/122268/) +- [Caution against using `transmute` between pointers and integers.](https://github.com/rust-lang/rust/pull/122379/) +- [Enable frame pointers for the standard library.](https://github.com/rust-lang/rust/pull/122646/) + + + +Stabilized APIs +--------------- + +- [`{integer}::unchecked_add`](https://doc.rust-lang.org/stable/core/primitive.i32.html#method.unchecked_add) +- [`{integer}::unchecked_mul`](https://doc.rust-lang.org/stable/core/primitive.i32.html#method.unchecked_mul) +- [`{integer}::unchecked_sub`](https://doc.rust-lang.org/stable/core/primitive.i32.html#method.unchecked_sub) +- [`<[T]>::split_at_unchecked`](https://doc.rust-lang.org/stable/core/primitive.slice.html#method.split_at_unchecked) +- [`<[T]>::split_at_mut_unchecked`](https://doc.rust-lang.org/stable/core/primitive.slice.html#method.split_at_mut_unchecked) +- [`<[u8]>::utf8_chunks`](https://doc.rust-lang.org/stable/core/primitive.slice.html#method.utf8_chunks) +- [`str::Utf8Chunks`](https://doc.rust-lang.org/stable/core/str/struct.Utf8Chunks.html) +- [`str::Utf8Chunk`](https://doc.rust-lang.org/stable/core/str/struct.Utf8Chunk.html) +- [`<*const T>::is_aligned`](https://doc.rust-lang.org/stable/core/primitive.pointer.html#method.is_aligned) +- [`<*mut T>::is_aligned`](https://doc.rust-lang.org/stable/core/primitive.pointer.html#method.is_aligned-1) +- [`NonNull::is_aligned`](https://doc.rust-lang.org/stable/core/ptr/struct.NonNull.html#method.is_aligned) +- [`<*const [T]>::len`](https://doc.rust-lang.org/stable/core/primitive.pointer.html#method.len) +- [`<*mut [T]>::len`](https://doc.rust-lang.org/stable/core/primitive.pointer.html#method.len-1) +- [`<*const [T]>::is_empty`](https://doc.rust-lang.org/stable/core/primitive.pointer.html#method.is_empty) +- [`<*mut [T]>::is_empty`](https://doc.rust-lang.org/stable/core/primitive.pointer.html#method.is_empty-1) +- [`NonNull::<[T]>::is_empty`](https://doc.rust-lang.org/stable/core/ptr/struct.NonNull.html#method.is_empty) +- [`CStr::count_bytes`](https://doc.rust-lang.org/stable/core/ffi/c_str/struct.CStr.html#method.count_bytes) +- [`io::Error::downcast`](https://doc.rust-lang.org/stable/std/io/struct.Error.html#method.downcast) +- [`num::NonZero`](https://doc.rust-lang.org/stable/core/num/struct.NonZero.html) +- [`path::absolute`](https://doc.rust-lang.org/stable/std/path/fn.absolute.html) +- [`proc_macro::Literal::byte_character`](https://doc.rust-lang.org/stable/proc_macro/struct.Literal.html#method.byte_character) +- [`proc_macro::Literal::c_string`](https://doc.rust-lang.org/stable/proc_macro/struct.Literal.html#method.c_string) + +These APIs are now stable in const contexts: + +- [`Atomic*::into_inner`](https://doc.rust-lang.org/stable/core/sync/atomic/struct.AtomicUsize.html#method.into_inner) +- [`io::Cursor::new`](https://doc.rust-lang.org/stable/std/io/struct.Cursor.html#method.new) +- [`io::Cursor::get_ref`](https://doc.rust-lang.org/stable/std/io/struct.Cursor.html#method.get_ref) +- [`io::Cursor::position`](https://doc.rust-lang.org/stable/std/io/struct.Cursor.html#method.position) +- [`io::empty`](https://doc.rust-lang.org/stable/std/io/fn.empty.html) +- [`io::repeat`](https://doc.rust-lang.org/stable/std/io/fn.repeat.html) +- [`io::sink`](https://doc.rust-lang.org/stable/std/io/fn.sink.html) +- [`panic::Location::caller`](https://doc.rust-lang.org/stable/std/panic/struct.Location.html#method.caller) +- [`panic::Location::file`](https://doc.rust-lang.org/stable/std/panic/struct.Location.html#method.file) +- [`panic::Location::line`](https://doc.rust-lang.org/stable/std/panic/struct.Location.html#method.line) +- [`panic::Location::column`](https://doc.rust-lang.org/stable/std/panic/struct.Location.html#method.column) + + + +Cargo +----- + +- [Prevent dashes in `lib.name`, always normalizing to `_`.](https://github.com/rust-lang/cargo/pull/12783/) +- [Stabilize MSRV-aware version requirement selection in `cargo add`.](https://github.com/rust-lang/cargo/pull/13608/) +- [Switch to using `gitoxide` by default for listing files.](https://github.com/rust-lang/cargo/pull/13696/) +- [Error on `[project]` in Edition 2024; `cargo fix --edition` will change it to `[package]`.](https://github.com/rust-lang/cargo/pull/13747/) + + + +Rustdoc +----- + +- [Always display stability version even if it's the same as the containing item.](https://github.com/rust-lang/rust/pull/118441/) +- [Show a single search result for items with multiple paths.](https://github.com/rust-lang/rust/pull/119912/) +- [Support typing `/` in docs to begin a search.](https://github.com/rust-lang/rust/pull/123355/) + + + +Misc +---- + + + +Compatibility Notes +------------------- + +- [Update the minimum external LLVM to 17.](https://github.com/rust-lang/rust/pull/122649/) +- [`RustcEncodable` and `RustcDecodable` are soft-destabilized, to be removed + from the prelude in next edition.](https://github.com/rust-lang/rust/pull/116016/) +- [The `wasm_c_abi` future-incompatibility lint will warn about use of the + non-spec-compliant C ABI.](https://github.com/rust-lang/rust/pull/117918/) + Use `wasm-bindgen v0.2.88` to generate forward-compatible bindings. +- [Check return types of function types for well-formedness](https://github.com/rust-lang/rust/pull/115538) + Version 1.78.0 (2024-05-02) ========================== From e24be071e3bef8dfb84b082f1478e9d33a108901 Mon Sep 17 00:00:00 2001 From: Weihang Lo Date: Thu, 23 May 2024 20:36:39 +0000 Subject: [PATCH 32/50] feat: vendor crates required by opt-dist to collect profiles These are the default package set required by opt-dist to correctly work, hence for people wanting to build a production grade of rustc in a sandboxed / air-gapped environment, these need to be vendored. The size of `rustc-src-nightly.tar.xz` before and after this change: * Before: 298M * After: 323M (+8%) These crates are the default set of packages required by opt-dist to correctly work, hence for people wanting to build a production grade of rustc in an sandboxed / air-gapped environment, these need to be vendored. The size of `rustc-src-nightly.tar.xz` before and after this change: * Before: 298M * After: 323M (+8%) Size change might or might not be a concern. See the previous discussion: https://github.com/rust-lang/rust/pull/125166#issuecomment-2113626468 Previous efforts on making: * https://github.com/rust-lang/rust/pull/125125 * https://github.com/rust-lang/rust/pull/125166 --- Note that extra works still need to be done to make it fully vendored. * The current pinned rustc-perf uses `tempfile::Tempdir` as the working directory when collecting profiles from some of these packages. This "tmp" working directory usage make it impossible for Cargo to pick up the correct vendor sources setting in `.cargo/config.toml` bundled in the rustc-src tarball. [^1] * opt-dist verifies the final built rustc against a subset of rustc test suite. However it rolls out its own `config.toml` without setting `vendor = true`, and that results in `./vendor/` directory removed. [^2] [^1]: https://github.com/rust-lang/rustc-perf/blob/4f313add609f43e928e98132358e8426ed3969ae/collector/src/compile/benchmark/mod.rs#L164-L173 [^2]: https://github.com/rust-lang/rust/blob/606afbb617a2949a4e35c4b0258ff94c980b9451/src/tools/opt-dist/src/tests.rs#L62-L77 --- src/bootstrap/src/core/build_steps/dist.rs | 15 ++++++++++++++ src/tools/build_helper/src/lib.rs | 23 ++++++++++++++++++++++ src/tools/opt-dist/src/training.rs | 22 +-------------------- 3 files changed, 39 insertions(+), 21 deletions(-) diff --git a/src/bootstrap/src/core/build_steps/dist.rs b/src/bootstrap/src/core/build_steps/dist.rs index 91039d0c8dcc..60b1ff3e4413 100644 --- a/src/bootstrap/src/core/build_steps/dist.rs +++ b/src/bootstrap/src/core/build_steps/dist.rs @@ -1041,6 +1041,21 @@ impl Step for PlainSourceTarball { .env("RUSTC_BOOTSTRAP", "1") .current_dir(plain_dst_src); + // Vendor packages that are required by opt-dist to collect PGO profiles. + let pkgs_for_pgo_training = build_helper::LLVM_PGO_CRATES + .iter() + .chain(build_helper::RUSTC_PGO_CRATES) + .map(|pkg| { + let mut manifest_path = + builder.src.join("./src/tools/rustc-perf/collector/compile-benchmarks"); + manifest_path.push(pkg); + manifest_path.push("Cargo.toml"); + manifest_path + }); + for manifest_path in pkgs_for_pgo_training { + cmd.arg("--sync").arg(manifest_path); + } + let config = if !builder.config.dry_run() { t!(String::from_utf8(t!(cmd.output()).stdout)) } else { diff --git a/src/tools/build_helper/src/lib.rs b/src/tools/build_helper/src/lib.rs index d831cfa0d79a..15807d1c0d8f 100644 --- a/src/tools/build_helper/src/lib.rs +++ b/src/tools/build_helper/src/lib.rs @@ -5,3 +5,26 @@ pub mod git; pub mod metrics; pub mod stage0_parser; pub mod util; + +/// The default set of crates for opt-dist to collect LLVM profiles. +pub const LLVM_PGO_CRATES: &[&str] = &[ + "syn-1.0.89", + "cargo-0.60.0", + "serde-1.0.136", + "ripgrep-13.0.0", + "regex-1.5.5", + "clap-3.1.6", + "hyper-0.14.18", +]; + +/// The default set of crates for opt-dist to collect rustc profiles. +pub const RUSTC_PGO_CRATES: &[&str] = &[ + "externs", + "ctfe-stress-5", + "cargo-0.60.0", + "token-stream-stress", + "match-stress", + "tuple-stress", + "diesel-1.4.8", + "bitmaps-3.1.0", +]; diff --git a/src/tools/opt-dist/src/training.rs b/src/tools/opt-dist/src/training.rs index 09263dc645e2..89f4d8957c8b 100644 --- a/src/tools/opt-dist/src/training.rs +++ b/src/tools/opt-dist/src/training.rs @@ -3,30 +3,10 @@ use crate::exec::{cmd, CmdBuilder}; use crate::utils::io::{count_files, delete_directory}; use crate::utils::with_log_group; use anyhow::Context; +use build_helper::{LLVM_PGO_CRATES, RUSTC_PGO_CRATES}; use camino::{Utf8Path, Utf8PathBuf}; use humansize::BINARY; -const LLVM_PGO_CRATES: &[&str] = &[ - "syn-1.0.89", - "cargo-0.60.0", - "serde-1.0.136", - "ripgrep-13.0.0", - "regex-1.5.5", - "clap-3.1.6", - "hyper-0.14.18", -]; - -const RUSTC_PGO_CRATES: &[&str] = &[ - "externs", - "ctfe-stress-5", - "cargo-0.60.0", - "token-stream-stress", - "match-stress", - "tuple-stress", - "diesel-1.4.8", - "bitmaps-3.1.0", -]; - fn init_compiler_benchmarks( env: &Environment, profiles: &[&str], From 377870386f99ee811e8945fade761a3ea8944db1 Mon Sep 17 00:00:00 2001 From: Weihang Lo Date: Sat, 25 May 2024 00:06:00 -0400 Subject: [PATCH 33/50] tidy: add license exceptions for rustc-perf `ring` is included because it is an optional dependency of `hyper`, which is a training data in rustc-pref for optimized build. The license of it is generally `ISC AND MIT AND OpenSSL`, though the `package.license` field is not set. See https://github.com/briansmith/ring/issues/902 `git+https://github.com/rust-lang/team` git source is from `rust_team_data`, which is used by `site` in src/tools/rustc-perf. This doesn't really a part of the compiler, so doesn't really affect the bootstrapping process. See https://github.com/rust-lang/rustc-perf/pull/1914. --- src/tools/tidy/src/deps.rs | 36 +++++++++++++++++++++++++++++++++++ src/tools/tidy/src/extdeps.rs | 6 +++++- 2 files changed, 41 insertions(+), 1 deletion(-) diff --git a/src/tools/tidy/src/deps.rs b/src/tools/tidy/src/deps.rs index efcd2a181ffa..7b93b09dda24 100644 --- a/src/tools/tidy/src/deps.rs +++ b/src/tools/tidy/src/deps.rs @@ -67,6 +67,7 @@ pub(crate) const WORKSPACES: &[(&str, ExceptionList, Option<(&[&str], &[&str])>) //("src/tools/miri/test-cargo-miri", &[], None), // FIXME uncomment once all deps are vendored //("src/tools/miri/test_dependencies", &[], None), // FIXME uncomment once all deps are vendored ("src/tools/rust-analyzer", EXCEPTIONS_RUST_ANALYZER, None), + ("src/tools/rustc-perf", EXCEPTIONS_RUSTC_PERF, None), ("src/tools/x", &[], None), // tidy-alphabetical-end ]; @@ -142,6 +143,22 @@ const EXCEPTIONS_RUST_ANALYZER: ExceptionList = &[ // tidy-alphabetical-end ]; +const EXCEPTIONS_RUSTC_PERF: ExceptionList = &[ + // tidy-alphabetical-start + ("alloc-no-stdlib", "BSD-3-Clause"), + ("alloc-stdlib", "BSD-3-Clause"), + ("brotli", "BSD-3-Clause/MIT"), + ("brotli-decompressor", "BSD-3-Clause/MIT"), + ("encoding_rs", "(Apache-2.0 OR MIT) AND BSD-3-Clause"), + ("inferno", "CDDL-1.0"), + ("instant", "BSD-3-Clause"), + ("ring", NON_STANDARD_LICENSE), // see EXCEPTIONS_NON_STANDARD_LICENSE_DEPS for more. + ("ryu", "Apache-2.0 OR BSL-1.0"), + ("snap", "BSD-3-Clause"), + ("subtle", "BSD-3-Clause"), + // tidy-alphabetical-end +]; + const EXCEPTIONS_CRANELIFT: ExceptionList = &[ // tidy-alphabetical-start ("cranelift-bforest", "Apache-2.0 WITH LLVM-exception"), @@ -178,6 +195,20 @@ const EXCEPTIONS_UEFI_QEMU_TEST: ExceptionList = &[ ("r-efi", "MIT OR Apache-2.0 OR LGPL-2.1-or-later"), // LGPL is not acceptible, but we use it under MIT OR Apache-2.0 ]; +/// Placeholder for non-standard license file. +const NON_STANDARD_LICENSE: &str = "NON_STANDARD_LICENSE"; + +/// These dependencies have non-standard licenses but are genenrally permitted. +const EXCEPTIONS_NON_STANDARD_LICENSE_DEPS: &[&str] = &[ + // `ring` is included because it is an optional dependency of `hyper`, + // which is a training data in rustc-perf for optimized build. + // The license of it is generally `ISC AND MIT AND OpenSSL`, + // though the `package.license` field is not set. + // + // See https://github.com/briansmith/ring/issues/902 + "ring", +]; + /// These are the root crates that are part of the runtime. The licenses for /// these and all their dependencies *must not* be in the exception list. const RUNTIME_CRATES: &[&str] = &["std", "core", "alloc", "test", "panic_abort", "panic_unwind"]; @@ -610,6 +641,11 @@ fn check_license_exceptions(metadata: &Metadata, exceptions: &[(&str, &str)], ba for pkg in metadata.packages.iter().filter(|p| p.name == *name) { match &pkg.license { None => { + if *license == NON_STANDARD_LICENSE + && EXCEPTIONS_NON_STANDARD_LICENSE_DEPS.contains(&pkg.name.as_str()) + { + continue; + } tidy_error!( bad, "dependency exception `{}` does not declare a license expression", diff --git a/src/tools/tidy/src/extdeps.rs b/src/tools/tidy/src/extdeps.rs index ff71ca537256..2118de5f2041 100644 --- a/src/tools/tidy/src/extdeps.rs +++ b/src/tools/tidy/src/extdeps.rs @@ -4,7 +4,11 @@ use std::fs; use std::path::Path; /// List of allowed sources for packages. -const ALLOWED_SOURCES: &[&str] = &["\"registry+https://github.com/rust-lang/crates.io-index\""]; +const ALLOWED_SOURCES: &[&str] = &[ + r#""registry+https://github.com/rust-lang/crates.io-index""#, + // This is `rust_team_data` used by `site` in src/tools/rustc-perf, + r#""git+https://github.com/rust-lang/team#a5260e76d3aa894c64c56e6ddc8545b9a98043ec""#, +]; /// Checks for external package sources. `root` is the path to the directory that contains the /// workspace `Cargo.toml`. From d9f78cb7939b340f72389fbaedfa4d872d0bbe43 Mon Sep 17 00:00:00 2001 From: Edward Shen Date: Sun, 9 Jun 2024 10:17:21 -0700 Subject: [PATCH 34/50] rustdoc: Add support for --remap-path-prefix Adds --remap-path-prefix as an unstable option. This is implemented to mimic the behavior of rustc's --remap-path-prefix but with minor adjustments. This flag similarly takes in two paths, a prefix to replace and a replacement string. --- src/librustdoc/config.rs | 26 +++++++++++++++++++ src/librustdoc/doctest.rs | 4 +-- src/librustdoc/doctest/rust.rs | 12 +++++---- src/librustdoc/lib.rs | 8 ++++++ .../output-default.stdout | 2 ++ ...remap-path-prefix-failed-doctest-output.rs | 14 ++++++++++ ...p-path-prefix-failed-doctest-output.stdout | 21 +++++++++++++++ .../remap-path-prefix-invalid-doctest.rs | 13 ++++++++++ .../remap-path-prefix-invalid-doctest.stdout | 22 ++++++++++++++++ ...remap-path-prefix-passed-doctest-output.rs | 14 ++++++++++ ...p-path-prefix-passed-doctest-output.stdout | 6 +++++ 11 files changed, 135 insertions(+), 7 deletions(-) create mode 100644 tests/rustdoc-ui/remap-path-prefix-failed-doctest-output.rs create mode 100644 tests/rustdoc-ui/remap-path-prefix-failed-doctest-output.stdout create mode 100644 tests/rustdoc-ui/remap-path-prefix-invalid-doctest.rs create mode 100644 tests/rustdoc-ui/remap-path-prefix-invalid-doctest.stdout create mode 100644 tests/rustdoc-ui/remap-path-prefix-passed-doctest-output.rs create mode 100644 tests/rustdoc-ui/remap-path-prefix-passed-doctest-output.stdout diff --git a/src/librustdoc/config.rs b/src/librustdoc/config.rs index 012afada1e5e..78d4129f6422 100644 --- a/src/librustdoc/config.rs +++ b/src/librustdoc/config.rs @@ -128,6 +128,8 @@ pub(crate) struct Options { pub(crate) enable_per_target_ignores: bool, /// Do not run doctests, compile them if should_test is active. pub(crate) no_run: bool, + /// What sources are being mapped. + pub(crate) remap_path_prefix: Vec<(PathBuf, PathBuf)>, /// The path to a rustc-like binary to build tests with. If not set, we /// default to loading from `$sysroot/bin/rustc`. @@ -211,6 +213,7 @@ impl fmt::Debug for Options { .field("run_check", &self.run_check) .field("no_run", &self.no_run) .field("test_builder_wrappers", &self.test_builder_wrappers) + .field("remap-file-prefix", &self.remap_path_prefix) .field("nocapture", &self.nocapture) .field("scrape_examples_options", &self.scrape_examples_options) .field("unstable_features", &self.unstable_features) @@ -372,6 +375,13 @@ impl Options { let codegen_options = CodegenOptions::build(early_dcx, matches); let unstable_opts = UnstableOptions::build(early_dcx, matches); + let remap_path_prefix = match parse_remap_path_prefix(&matches) { + Ok(prefix_mappings) => prefix_mappings, + Err(err) => { + early_dcx.early_fatal(err); + } + }; + let dcx = new_dcx(error_format, None, diagnostic_width, &unstable_opts); // check for deprecated options @@ -772,6 +782,7 @@ impl Options { run_check, no_run, test_builder_wrappers, + remap_path_prefix, nocapture, crate_name, output_format, @@ -820,6 +831,21 @@ impl Options { } } +fn parse_remap_path_prefix( + matches: &getopts::Matches, +) -> Result, &'static str> { + matches + .opt_strs("remap-path-prefix") + .into_iter() + .map(|remap| { + remap + .rsplit_once('=') + .ok_or("--remap-path-prefix must contain '=' between FROM and TO") + .map(|(from, to)| (PathBuf::from(from), PathBuf::from(to))) + }) + .collect() +} + /// Prints deprecation warnings for deprecated options fn check_deprecated_options(matches: &getopts::Matches, dcx: &rustc_errors::DiagCtxt) { let deprecated_flags = []; diff --git a/src/librustdoc/doctest.rs b/src/librustdoc/doctest.rs index a732e645b6ba..81a7463decad 100644 --- a/src/librustdoc/doctest.rs +++ b/src/librustdoc/doctest.rs @@ -129,6 +129,7 @@ pub(crate) fn run( edition: options.edition, target_triple: options.target.clone(), crate_name: options.crate_name.clone(), + remap_path_prefix: options.remap_path_prefix.clone(), ..config::Options::default() }; @@ -572,7 +573,6 @@ fn make_maybe_absolute_path(path: PathBuf) -> PathBuf { std::env::current_dir().map(|c| c.join(&path)).unwrap_or_else(|_| path) } } - struct IndividualTestOptions { outdir: DirState, test_id: String, @@ -651,7 +651,7 @@ impl CreateRunnableDoctests { if !item_path.is_empty() { item_path.push(' '); } - format!("{} - {item_path}(line {line})", filename.prefer_local()) + format!("{} - {item_path}(line {line})", filename.prefer_remapped_unconditionaly()) } fn add_test(&mut self, test: ScrapedDoctest) { diff --git a/src/librustdoc/doctest/rust.rs b/src/librustdoc/doctest/rust.rs index e6bef395fa9c..fc8e119ccc23 100644 --- a/src/librustdoc/doctest/rust.rs +++ b/src/librustdoc/doctest/rust.rs @@ -27,11 +27,13 @@ struct RustCollector { impl RustCollector { fn get_filename(&self) -> FileName { let filename = self.source_map.span_to_filename(self.position); - if let FileName::Real(ref filename) = filename - && let Ok(cur_dir) = env::current_dir() - && let Some(local_path) = filename.local_path() - && let Ok(path) = local_path.strip_prefix(&cur_dir) - { + if let FileName::Real(ref filename) = filename { + let path = filename.remapped_path_if_available(); + // Strip the cwd prefix from the path. This will likely exist if + // the path was not remapped. + let path = env::current_dir() + .map(|cur_dir| path.strip_prefix(&cur_dir).unwrap_or(path)) + .unwrap_or(path); return path.to_owned().into(); } filename diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index 3b6bddf263a9..d6e715d48ea5 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -555,6 +555,14 @@ fn opts() -> Vec { unstable("no-run", |o| { o.optflagmulti("", "no-run", "Compile doctests without running them") }), + unstable("remap-path-prefix", |o| { + o.optmulti( + "", + "remap-path-prefix", + "Remap source names in compiler messages", + "FROM=TO", + ) + }), unstable("show-type-layout", |o| { o.optflagmulti("", "show-type-layout", "Include the memory layout of types in the docs") }), diff --git a/tests/run-make/issue-88756-default-output/output-default.stdout b/tests/run-make/issue-88756-default-output/output-default.stdout index 12c1b389fb34..bc38d9e9dc6b 100644 --- a/tests/run-make/issue-88756-default-output/output-default.stdout +++ b/tests/run-make/issue-88756-default-output/output-default.stdout @@ -157,6 +157,8 @@ Options: Comma separated list of types of output for rustdoc to emit --no-run Compile doctests without running them + --remap-path-prefix FROM=TO + Remap source names in compiler messages --show-type-layout Include the memory layout of types in the docs --nocapture Don't capture stdout and stderr of tests diff --git a/tests/rustdoc-ui/remap-path-prefix-failed-doctest-output.rs b/tests/rustdoc-ui/remap-path-prefix-failed-doctest-output.rs new file mode 100644 index 000000000000..2b220370d77a --- /dev/null +++ b/tests/rustdoc-ui/remap-path-prefix-failed-doctest-output.rs @@ -0,0 +1,14 @@ +// FIXME: if/when the output of the test harness can be tested on its own, this test should be +// adapted to use that, and that normalize line can go away + +//@ failure-status: 101 +//@ compile-flags:--test -Z unstable-options --remap-path-prefix={{src-base}}=remapped_path --test-args --test-threads=1 +//@ rustc-env:RUST_BACKTRACE=0 +//@ normalize-stdout-test "finished in \d+\.\d+s" -> "finished in $$TIME" +//@ normalize-stdout-test "exit (status|code): 101" -> "exit status: 101" + +// doctest fails at runtime +/// ``` +/// panic!("oh no"); +/// ``` +pub struct SomeStruct; diff --git a/tests/rustdoc-ui/remap-path-prefix-failed-doctest-output.stdout b/tests/rustdoc-ui/remap-path-prefix-failed-doctest-output.stdout new file mode 100644 index 000000000000..2102e2c38918 --- /dev/null +++ b/tests/rustdoc-ui/remap-path-prefix-failed-doctest-output.stdout @@ -0,0 +1,21 @@ + +running 1 test +test remapped_path/remap-path-prefix-failed-doctest-output.rs - SomeStruct (line 11) ... FAILED + +failures: + +---- remapped_path/remap-path-prefix-failed-doctest-output.rs - SomeStruct (line 11) stdout ---- +Test executable failed (exit status: 101). + +stderr: +thread 'main' panicked at remapped_path/remap-path-prefix-failed-doctest-output.rs:3:1: +oh no +note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace + + + +failures: + remapped_path/remap-path-prefix-failed-doctest-output.rs - SomeStruct (line 11) + +test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME + diff --git a/tests/rustdoc-ui/remap-path-prefix-invalid-doctest.rs b/tests/rustdoc-ui/remap-path-prefix-invalid-doctest.rs new file mode 100644 index 000000000000..2e023e32d7a7 --- /dev/null +++ b/tests/rustdoc-ui/remap-path-prefix-invalid-doctest.rs @@ -0,0 +1,13 @@ +// FIXME: if/when the output of the test harness can be tested on its own, this test should be +// adapted to use that, and that normalize line can go away + +//@ failure-status: 101 +//@ compile-flags:--test -Z unstable-options --remap-path-prefix={{src-base}}=remapped_path --test-args --test-threads=1 +//@ rustc-env:RUST_BACKTRACE=0 +//@ normalize-stdout-test "finished in \d+\.\d+s" -> "finished in $$TIME" + +// doctest fails to compile +/// ``` +/// this is not real code +/// ``` +pub struct SomeStruct; diff --git a/tests/rustdoc-ui/remap-path-prefix-invalid-doctest.stdout b/tests/rustdoc-ui/remap-path-prefix-invalid-doctest.stdout new file mode 100644 index 000000000000..a05b51699894 --- /dev/null +++ b/tests/rustdoc-ui/remap-path-prefix-invalid-doctest.stdout @@ -0,0 +1,22 @@ + +running 1 test +test remapped_path/remap-path-prefix-invalid-doctest.rs - SomeStruct (line 10) ... FAILED + +failures: + +---- remapped_path/remap-path-prefix-invalid-doctest.rs - SomeStruct (line 10) stdout ---- +error: expected one of `!`, `.`, `::`, `;`, `?`, `{`, `}`, or an operator, found `is` + --> remapped_path/remap-path-prefix-invalid-doctest.rs:11:6 + | +LL | this is not real code + | ^^ expected one of 8 possible tokens + +error: aborting due to 1 previous error + +Couldn't compile the test. + +failures: + remapped_path/remap-path-prefix-invalid-doctest.rs - SomeStruct (line 10) + +test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME + diff --git a/tests/rustdoc-ui/remap-path-prefix-passed-doctest-output.rs b/tests/rustdoc-ui/remap-path-prefix-passed-doctest-output.rs new file mode 100644 index 000000000000..c58f3faeb532 --- /dev/null +++ b/tests/rustdoc-ui/remap-path-prefix-passed-doctest-output.rs @@ -0,0 +1,14 @@ +//@ check-pass +//@ check-run-results + +// FIXME: if/when the output of the test harness can be tested on its own, this test should be +// adapted to use that, and that normalize line can go away + +//@ compile-flags:--test -Z unstable-options --remap-path-prefix={{src-base}}=remapped_path --test-args --test-threads=1 +//@ normalize-stdout-test "finished in \d+\.\d+s" -> "finished in $$TIME" + +// doctest passes at runtime +/// ``` +/// assert!(true); +/// ``` +pub struct SomeStruct; diff --git a/tests/rustdoc-ui/remap-path-prefix-passed-doctest-output.stdout b/tests/rustdoc-ui/remap-path-prefix-passed-doctest-output.stdout new file mode 100644 index 000000000000..8ffb56948856 --- /dev/null +++ b/tests/rustdoc-ui/remap-path-prefix-passed-doctest-output.stdout @@ -0,0 +1,6 @@ + +running 1 test +test remapped_path/remap-path-prefix-passed-doctest-output.rs - SomeStruct (line 11) ... ok + +test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME + From 8865b8c63900acb1834390344fc1cc43ae209f08 Mon Sep 17 00:00:00 2001 From: Michael Howell Date: Sun, 9 Jun 2024 11:56:52 -0700 Subject: [PATCH 35/50] rustdoc-search: use lowercase, non-normalized name for type search The type name ID map has underscores in its names, so the query element should have them, too. --- src/librustdoc/html/static/js/search.js | 12 +++-- tests/rustdoc-js/underscoredtype.js | 62 +++++++++++++++++++++++++ tests/rustdoc-js/underscoredtype.rs | 8 ++++ 3 files changed, 78 insertions(+), 4 deletions(-) create mode 100644 tests/rustdoc-js/underscoredtype.js create mode 100644 tests/rustdoc-js/underscoredtype.rs diff --git a/src/librustdoc/html/static/js/search.js b/src/librustdoc/html/static/js/search.js index 8ac4b53673f4..a0ab262bf0b0 100644 --- a/src/librustdoc/html/static/js/search.js +++ b/src/librustdoc/html/static/js/search.js @@ -2399,15 +2399,19 @@ function initSearch(rawSearchIndex) { * @param {boolean} isAssocType */ function convertNameToId(elem, isAssocType) { - if (typeNameIdMap.has(elem.normalizedPathLast) && - (isAssocType || !typeNameIdMap.get(elem.normalizedPathLast).assocOnly)) { - elem.id = typeNameIdMap.get(elem.normalizedPathLast).id; + const loweredName = elem.pathLast.toLowerCase(); + if (typeNameIdMap.has(loweredName) && + (isAssocType || !typeNameIdMap.get(loweredName).assocOnly)) { + elem.id = typeNameIdMap.get(loweredName).id; } else if (!parsedQuery.literalSearch) { let match = null; let matchDist = maxEditDistance + 1; let matchName = ""; for (const [name, {id, assocOnly}] of typeNameIdMap) { - const dist = editDistance(name, elem.normalizedPathLast, maxEditDistance); + const dist = Math.min( + editDistance(name, loweredName, maxEditDistance), + editDistance(name, elem.normalizedPathLast, maxEditDistance), + ); if (dist <= matchDist && dist <= maxEditDistance && (isAssocType || !assocOnly)) { if (dist === matchDist && matchName > name) { diff --git a/tests/rustdoc-js/underscoredtype.js b/tests/rustdoc-js/underscoredtype.js new file mode 100644 index 000000000000..06e3b07b0960 --- /dev/null +++ b/tests/rustdoc-js/underscoredtype.js @@ -0,0 +1,62 @@ +const EXPECTED = [ + { + 'query': 'pid_t', + 'correction': null, + 'proposeCorrectionFrom': null, + 'proposeCorrectionTo': null, + 'others': [ + { 'path': 'underscoredtype::unix', 'name': 'pid_t' }, + ], + 'returned': [ + { 'path': 'underscoredtype::unix', 'name': 'set_pid' }, + ], + 'returned': [ + { 'path': 'underscoredtype::unix', 'name': 'get_pid' }, + ], + }, + { + 'query': 'pidt', + 'correction': 'pid_t', + 'proposeCorrectionFrom': null, + 'proposeCorrectionTo': null, + 'others': [ + { 'path': 'underscoredtype::unix', 'name': 'pid_t' }, + ], + 'returned': [ + { 'path': 'underscoredtype::unix', 'name': 'set_pid' }, + ], + 'returned': [ + { 'path': 'underscoredtype::unix', 'name': 'get_pid' }, + ], + }, + { + 'query': 'unix::pid_t', + 'correction': null, + 'proposeCorrectionFrom': null, + 'proposeCorrectionTo': null, + 'others': [ + { 'path': 'underscoredtype::unix', 'name': 'pid_t' }, + ], + 'returned': [ + { 'path': 'underscoredtype::unix', 'name': 'set_pid' }, + ], + 'returned': [ + { 'path': 'underscoredtype::unix', 'name': 'get_pid' }, + ], + }, + { + 'query': 'unix::pidt', + 'correction': 'pid_t', + 'proposeCorrectionFrom': null, + 'proposeCorrectionTo': null, + 'others': [ + { 'path': 'underscoredtype::unix', 'name': 'pid_t' }, + ], + 'returned': [ + { 'path': 'underscoredtype::unix', 'name': 'set_pid' }, + ], + 'returned': [ + { 'path': 'underscoredtype::unix', 'name': 'get_pid' }, + ], + }, +]; diff --git a/tests/rustdoc-js/underscoredtype.rs b/tests/rustdoc-js/underscoredtype.rs new file mode 100644 index 000000000000..83c532cf855d --- /dev/null +++ b/tests/rustdoc-js/underscoredtype.rs @@ -0,0 +1,8 @@ +pub mod unix { + #[allow(non_camel_case_types)] + pub type pid_t = i32; + pub fn get_pid() -> pid_t { + 0 + } + pub fn set_pid(_: pid_t) {} +} From e61d3b8372f988ba8b6573deac2290d59d72b76f Mon Sep 17 00:00:00 2001 From: onur-ozkan Date: Sat, 8 Jun 2024 12:48:19 +0300 Subject: [PATCH 36/50] fix `Builder::doc_rust_lang_org_channel` Previously, we were unable to use `rust.download-rustc` with the beta or stable channel settings through `rust.channel` due to breaking rustdoc UI tests. This was because when using a precompiled nightly compiler from CI, we must use the channel of precompiled compiler and ignore `rust.channel` from the configuration. This change addresses that issue in `Builder::doc_rust_lang_org_channel` and allows rustdoc UI tests to work with the precompiled compiler even if the channel specified in config.toml is "beta" or "stable". Signed-off-by: onur-ozkan --- src/bootstrap/src/core/builder.rs | 26 ++++++++++++++++++------- src/bootstrap/src/core/config/config.rs | 26 ++++++++++++++++++------- 2 files changed, 38 insertions(+), 14 deletions(-) diff --git a/src/bootstrap/src/core/builder.rs b/src/bootstrap/src/core/builder.rs index b3d8465cda98..3b890a6516f9 100644 --- a/src/bootstrap/src/core/builder.rs +++ b/src/bootstrap/src/core/builder.rs @@ -1038,14 +1038,26 @@ impl<'a> Builder<'a> { } pub fn doc_rust_lang_org_channel(&self) -> String { - let channel = match &*self.config.channel { - "stable" => &self.version, - "beta" => "beta", - "nightly" | "dev" => "nightly", - // custom build of rustdoc maybe? link to the latest stable docs just in case - _ => "stable", + // When using precompiled compiler from CI, we need to use CI rustc's channel and + // ignore `rust.channel` from the configuration. Otherwise most of the rustdoc tests + // will fail due to incompatible `DOC_RUST_LANG_ORG_CHANNEL`. + let channel = if let Some(commit) = self.config.download_rustc_commit() { + self.config + .read_file_by_commit(&PathBuf::from("src/ci/channel"), commit) + .trim() + .to_owned() + } else { + match &*self.config.channel { + "stable" => &self.version, + "beta" => "beta", + "nightly" | "dev" => "nightly", + // custom build of rustdoc maybe? link to the latest stable docs just in case + _ => "stable", + } + .to_owned() }; - "https://doc.rust-lang.org/".to_owned() + channel + + format!("https://doc.rust-lang.org/{channel}") } fn run_step_descriptions(&self, v: &[StepDescription], paths: &[PathBuf]) { diff --git a/src/bootstrap/src/core/config/config.rs b/src/bootstrap/src/core/config/config.rs index 17e37c1ecd23..2d87fb4aa60f 100644 --- a/src/bootstrap/src/core/config/config.rs +++ b/src/bootstrap/src/core/config/config.rs @@ -2134,17 +2134,29 @@ impl Config { args } + /// Returns the content of the given file at a specific commit. + pub(crate) fn read_file_by_commit(&self, file: &Path, commit: &str) -> String { + assert!( + self.rust_info.is_managed_git_subrepository(), + "`Config::read_file_by_commit` is not supported in non-git sources." + ); + + let mut git = self.git(); + git.arg("show").arg(format!("{commit}:{}", file.to_str().unwrap())); + output(&mut git) + } + /// Bootstrap embeds a version number into the name of shared libraries it uploads in CI. /// Return the version it would have used for the given commit. pub(crate) fn artifact_version_part(&self, commit: &str) -> String { let (channel, version) = if self.rust_info.is_managed_git_subrepository() { - let mut channel = self.git(); - channel.arg("show").arg(format!("{commit}:src/ci/channel")); - let channel = output(&mut channel); - let mut version = self.git(); - version.arg("show").arg(format!("{commit}:src/version")); - let version = output(&mut version); - (channel.trim().to_owned(), version.trim().to_owned()) + let channel = self + .read_file_by_commit(&PathBuf::from("src/ci/channel"), commit) + .trim() + .to_owned(); + let version = + self.read_file_by_commit(&PathBuf::from("src/version"), commit).trim().to_owned(); + (channel, version) } else { let channel = fs::read_to_string(self.src.join("src/ci/channel")); let version = fs::read_to_string(self.src.join("src/version")); From 99c5476edb85f061d960b4c789b4f70ec444864d Mon Sep 17 00:00:00 2001 From: onur-ozkan Date: Sat, 8 Jun 2024 12:59:58 +0300 Subject: [PATCH 37/50] remove the outdated incompatibility check This check is no longer needed as rustdoc ui tests works with any channel + precompiled compiler. Signed-off-by: onur-ozkan --- src/bootstrap/src/core/config/config.rs | 15 ++------------- 1 file changed, 2 insertions(+), 13 deletions(-) diff --git a/src/bootstrap/src/core/config/config.rs b/src/bootstrap/src/core/config/config.rs index 2d87fb4aa60f..36b44d0169c9 100644 --- a/src/bootstrap/src/core/config/config.rs +++ b/src/bootstrap/src/core/config/config.rs @@ -1608,19 +1608,8 @@ impl Config { set(&mut config.channel, channel); config.download_rustc_commit = config.download_ci_rustc_commit(download_rustc); - // This list is incomplete, please help by expanding it! - if config.download_rustc_commit.is_some() { - // We need the channel used by the downloaded compiler to match the one we set for rustdoc; - // otherwise rustdoc-ui tests break. - if config.channel != ci_channel - && !(config.channel == "dev" && ci_channel == "nightly") - { - panic!( - "setting rust.channel={} is incompatible with download-rustc", - config.channel - ); - } - } + + // FIXME: handle download-rustc incompatible options. debug = debug_toml; debug_assertions = debug_assertions_toml; From 5349476a0351f6d97076bc5ac9857994ee0e839b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Sun, 9 Jun 2024 22:10:49 +0200 Subject: [PATCH 38/50] Remove libstdc++ version check --- src/bootstrap/src/core/sanity.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/bootstrap/src/core/sanity.rs b/src/bootstrap/src/core/sanity.rs index e3556cb16b05..b5f17b9f54ed 100644 --- a/src/bootstrap/src/core/sanity.rs +++ b/src/bootstrap/src/core/sanity.rs @@ -128,7 +128,6 @@ pub fn check(build: &mut Build) { eprintln!( "Consider upgrading libstdc++ or disabling the `llvm.download-ci-llvm` option." ); - crate::exit!(1); } } tool::LibcxxVersion::Llvm(_) => { From d5dd2d8284c30f3f79e4beb35246761ed4892c49 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Sun, 3 Mar 2024 15:34:22 +0300 Subject: [PATCH 39/50] rustc_span: Optimize syntax context updates in spans --- compiler/rustc_expand/src/mbe/transcribe.rs | 10 +- compiler/rustc_span/src/lib.rs | 25 +-- compiler/rustc_span/src/span_encoding.rs | 187 ++++++++++++++------ 3 files changed, 149 insertions(+), 73 deletions(-) diff --git a/compiler/rustc_expand/src/mbe/transcribe.rs b/compiler/rustc_expand/src/mbe/transcribe.rs index 3196b8260854..25e961d60090 100644 --- a/compiler/rustc_expand/src/mbe/transcribe.rs +++ b/compiler/rustc_expand/src/mbe/transcribe.rs @@ -30,11 +30,11 @@ impl MutVisitor for Marker { // it's some advanced case with macro-generated macros. So if we cache the marked version // of that context once, we'll typically have a 100% cache hit rate after that. let Marker(expn_id, transparency, ref mut cache) = *self; - let data = span.data(); - let marked_ctxt = *cache - .entry(data.ctxt) - .or_insert_with(|| data.ctxt.apply_mark(expn_id.to_expn_id(), transparency)); - *span = data.with_ctxt(marked_ctxt); + span.update_ctxt(|ctxt| { + *cache + .entry(ctxt) + .or_insert_with(|| ctxt.apply_mark(expn_id.to_expn_id(), transparency)) + }); } } diff --git a/compiler/rustc_span/src/lib.rs b/compiler/rustc_span/src/lib.rs index 82179a4a0586..99fcaf917fe9 100644 --- a/compiler/rustc_span/src/lib.rs +++ b/compiler/rustc_span/src/lib.rs @@ -521,7 +521,7 @@ impl SpanData { Span::new(self.lo, hi, self.ctxt, self.parent) } #[inline] - pub fn with_ctxt(&self, ctxt: SyntaxContext) -> Span { + fn with_ctxt(&self, ctxt: SyntaxContext) -> Span { Span::new(self.lo, self.hi, ctxt, self.parent) } #[inline] @@ -576,8 +576,9 @@ impl Span { self.data().with_hi(hi) } #[inline] - pub fn with_ctxt(self, ctxt: SyntaxContext) -> Span { - self.data_untracked().with_ctxt(ctxt) + pub fn with_ctxt(mut self, ctxt: SyntaxContext) -> Span { + self.update_ctxt(|_| ctxt); + self } #[inline] pub fn parent(self) -> Option { @@ -1058,9 +1059,9 @@ impl Span { } #[inline] - pub fn apply_mark(self, expn_id: ExpnId, transparency: Transparency) -> Span { - let span = self.data(); - span.with_ctxt(span.ctxt.apply_mark(expn_id, transparency)) + pub fn apply_mark(mut self, expn_id: ExpnId, transparency: Transparency) -> Span { + self.update_ctxt(|ctxt| ctxt.apply_mark(expn_id, transparency)); + self } #[inline] @@ -1108,15 +1109,15 @@ impl Span { } #[inline] - pub fn normalize_to_macros_2_0(self) -> Span { - let span = self.data(); - span.with_ctxt(span.ctxt.normalize_to_macros_2_0()) + pub fn normalize_to_macros_2_0(mut self) -> Span { + self.update_ctxt(|ctxt| ctxt.normalize_to_macros_2_0()); + self } #[inline] - pub fn normalize_to_macro_rules(self) -> Span { - let span = self.data(); - span.with_ctxt(span.ctxt.normalize_to_macro_rules()) + pub fn normalize_to_macro_rules(mut self) -> Span { + self.update_ctxt(|ctxt| ctxt.normalize_to_macro_rules()); + self } } diff --git a/compiler/rustc_span/src/span_encoding.rs b/compiler/rustc_span/src/span_encoding.rs index 6a0282266316..52a1267f8918 100644 --- a/compiler/rustc_span/src/span_encoding.rs +++ b/compiler/rustc_span/src/span_encoding.rs @@ -87,6 +87,45 @@ pub struct Span { ctxt_or_parent_or_marker: u16, } +impl Span { + #[inline] + fn data_inline_ctxt(self) -> SpanData { + let len = self.len_with_tag_or_marker as u32; + debug_assert!(len <= MAX_LEN); + SpanData { + lo: BytePos(self.lo_or_index), + hi: BytePos(self.lo_or_index.debug_strict_add(len)), + ctxt: SyntaxContext::from_u32(self.ctxt_or_parent_or_marker as u32), + parent: None, + } + } + #[inline] + fn data_inline_parent(self) -> SpanData { + let len = (self.len_with_tag_or_marker & !PARENT_TAG) as u32; + debug_assert!(len <= MAX_LEN); + let parent = LocalDefId { + local_def_index: DefIndex::from_u32(self.ctxt_or_parent_or_marker as u32), + }; + SpanData { + lo: BytePos(self.lo_or_index), + hi: BytePos(self.lo_or_index.debug_strict_add(len)), + ctxt: SyntaxContext::root(), + parent: Some(parent), + } + } + #[inline] + fn data_partially_interned(self) -> SpanData { + SpanData { + ctxt: SyntaxContext::from_u32(self.ctxt_or_parent_or_marker as u32), + ..with_span_interner(|interner| interner.spans[self.lo_or_index as usize]) + } + } + #[inline] + fn data_interned(self) -> SpanData { + with_span_interner(|interner| interner.spans[self.lo_or_index as usize]) + } +} + // `MAX_LEN` is chosen so that `PARENT_TAG | MAX_LEN` is distinct from // `BASE_LEN_INTERNED_MARKER`. (If `MAX_LEN` was 1 higher, this wouldn't be true.) const MAX_LEN: u32 = 0b0111_1111_1111_1110; @@ -111,42 +150,49 @@ impl Span { std::mem::swap(&mut lo, &mut hi); } - let (lo2, len, ctxt2) = (lo.0, hi.0 - lo.0, ctxt.as_u32()); - + // Small len may enable one of fully inline formats (or may not). + let (len, ctxt32) = (hi.0 - lo.0, ctxt.as_u32()); if len <= MAX_LEN { - if ctxt2 <= MAX_CTXT && parent.is_none() { + if ctxt32 <= MAX_CTXT && parent.is_none() { // Inline-context format. return Span { - lo_or_index: lo2, + lo_or_index: lo.0, len_with_tag_or_marker: len as u16, - ctxt_or_parent_or_marker: ctxt2 as u16, + ctxt_or_parent_or_marker: ctxt32 as u16, }; - } else if ctxt2 == SyntaxContext::root().as_u32() + } else if ctxt32 == 0 && let Some(parent) = parent - && let parent2 = parent.local_def_index.as_u32() - && parent2 <= MAX_CTXT + && let parent32 = parent.local_def_index.as_u32() + && parent32 <= MAX_CTXT { // Inline-parent format. return Span { - lo_or_index: lo2, + lo_or_index: lo.0, len_with_tag_or_marker: PARENT_TAG | len as u16, - ctxt_or_parent_or_marker: parent2 as u16, + ctxt_or_parent_or_marker: parent32 as u16, }; } } - // Partially-interned or fully-interned format. - let index = - with_span_interner(|interner| interner.intern(&SpanData { lo, hi, ctxt, parent })); - let ctxt_or_parent_or_marker = if ctxt2 <= MAX_CTXT { - ctxt2 as u16 // partially-interned - } else { - CTXT_INTERNED_MARKER // fully-interned + // Otherwise small ctxt may enable the partially inline format. + let index = |ctxt| { + with_span_interner(|interner| interner.intern(&SpanData { lo, hi, ctxt, parent })) }; - Span { - lo_or_index: index, - len_with_tag_or_marker: BASE_LEN_INTERNED_MARKER, - ctxt_or_parent_or_marker, + if ctxt32 <= MAX_CTXT { + // Partially-interned format. + Span { + // Interned ctxt should never be read, so it can use any value. + lo_or_index: index(SyntaxContext::from_u32(u32::MAX)), + len_with_tag_or_marker: BASE_LEN_INTERNED_MARKER, + ctxt_or_parent_or_marker: ctxt32 as u16, + } + } else { + // Interned format. + Span { + lo_or_index: index(ctxt), + len_with_tag_or_marker: BASE_LEN_INTERNED_MARKER, + ctxt_or_parent_or_marker: CTXT_INTERNED_MARKER, + } } } @@ -166,34 +212,17 @@ impl Span { if self.len_with_tag_or_marker != BASE_LEN_INTERNED_MARKER { if self.len_with_tag_or_marker & PARENT_TAG == 0 { // Inline-context format. - let len = self.len_with_tag_or_marker as u32; - debug_assert!(len <= MAX_LEN); - SpanData { - lo: BytePos(self.lo_or_index), - hi: BytePos(self.lo_or_index.debug_strict_add(len)), - ctxt: SyntaxContext::from_u32(self.ctxt_or_parent_or_marker as u32), - parent: None, - } + self.data_inline_ctxt() } else { // Inline-parent format. - let len = (self.len_with_tag_or_marker & !PARENT_TAG) as u32; - debug_assert!(len <= MAX_LEN); - let parent = LocalDefId { - local_def_index: DefIndex::from_u32(self.ctxt_or_parent_or_marker as u32), - }; - SpanData { - lo: BytePos(self.lo_or_index), - hi: BytePos(self.lo_or_index.debug_strict_add(len)), - ctxt: SyntaxContext::root(), - parent: Some(parent), - } + self.data_inline_parent() } + } else if self.ctxt_or_parent_or_marker != CTXT_INTERNED_MARKER { + // Partially-interned format. + self.data_partially_interned() } else { - // Fully-interned or partially-interned format. In either case, - // the interned value contains all the data, so we don't need to - // distinguish them. - let index = self.lo_or_index; - with_span_interner(|interner| interner.spans[index as usize]) + // Interned format. + self.data_interned() } } @@ -214,27 +243,73 @@ impl Span { } } + // For optimization we are interested in cases in which the context is inline and the context + // update doesn't change format. All non-inline or format changing scenarios require accessing + // interner and can fall back to `Span::new`. + #[inline] + pub fn update_ctxt(&mut self, update: impl FnOnce(SyntaxContext) -> SyntaxContext) { + let (updated_ctxt32, data); + if self.len_with_tag_or_marker != BASE_LEN_INTERNED_MARKER { + if self.len_with_tag_or_marker & PARENT_TAG == 0 { + // Inline-context format. + updated_ctxt32 = + update(SyntaxContext::from_u32(self.ctxt_or_parent_or_marker as u32)).as_u32(); + // Any small new context including zero will preserve the format. + if updated_ctxt32 <= MAX_CTXT { + self.ctxt_or_parent_or_marker = updated_ctxt32 as u16; + return; + } + data = self.data_inline_ctxt(); + } else { + // Inline-parent format. + updated_ctxt32 = update(SyntaxContext::root()).as_u32(); + // Only if the new context is zero the format will be preserved. + if updated_ctxt32 == 0 { + // Do nothing. + return; + } + data = self.data_inline_parent(); + } + } else if self.ctxt_or_parent_or_marker != CTXT_INTERNED_MARKER { + // Partially-interned format. + updated_ctxt32 = + update(SyntaxContext::from_u32(self.ctxt_or_parent_or_marker as u32)).as_u32(); + // Any small new context excluding zero will preserve the format. + // Zero may change the format to `InlineParent` if parent and len are small enough. + if updated_ctxt32 <= MAX_CTXT && updated_ctxt32 != 0 { + self.ctxt_or_parent_or_marker = updated_ctxt32 as u16; + return; + } + data = self.data_partially_interned(); + } else { + // Interned format. + data = self.data_interned(); + updated_ctxt32 = update(data.ctxt).as_u32(); + } + + // We could not keep the span in the same inline format, fall back to the complete logic. + *self = data.with_ctxt(SyntaxContext::from_u32(updated_ctxt32)); + } + // Returns either syntactic context, if it can be retrieved without taking the interner lock, // or an index into the interner if it cannot. #[inline] fn inline_ctxt(self) -> Result { - Ok(if self.len_with_tag_or_marker != BASE_LEN_INTERNED_MARKER { + if self.len_with_tag_or_marker != BASE_LEN_INTERNED_MARKER { if self.len_with_tag_or_marker & PARENT_TAG == 0 { // Inline-context format. - SyntaxContext::from_u32(self.ctxt_or_parent_or_marker as u32) + Ok(SyntaxContext::from_u32(self.ctxt_or_parent_or_marker as u32)) } else { - // Inline-parent format. We know that the SyntaxContext is root. - SyntaxContext::root() + // Inline-parent format. + Ok(SyntaxContext::root()) } } else if self.ctxt_or_parent_or_marker != CTXT_INTERNED_MARKER { - // Partially-interned format. This path avoids looking up the - // interned value, and is the whole point of the - // partially-interned format. - SyntaxContext::from_u32(self.ctxt_or_parent_or_marker as u32) + // Partially-interned format. + Ok(SyntaxContext::from_u32(self.ctxt_or_parent_or_marker as u32)) } else { - // Fully-interned format. - return Err(self.lo_or_index as usize); - }) + // Interned format. + Err(self.lo_or_index as usize) + } } /// This function is used as a fast path when decoding the full `SpanData` is not necessary. From 63ec8dd24ff4219960435c7dfd2c510c48dcda5c Mon Sep 17 00:00:00 2001 From: Steve Lau Date: Mon, 10 Jun 2024 10:38:00 +0800 Subject: [PATCH 40/50] fix: build on haiku --- library/std/src/sys/pal/unix/os.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/library/std/src/sys/pal/unix/os.rs b/library/std/src/sys/pal/unix/os.rs index ae1e42c419b9..2e71ceceb58b 100644 --- a/library/std/src/sys/pal/unix/os.rs +++ b/library/std/src/sys/pal/unix/os.rs @@ -465,9 +465,9 @@ pub fn current_exe() -> io::Result { let mut name = vec![0; libc::PATH_MAX as usize]; unsafe { let result = libc::find_path( - std::ptr::null_mut(), + crate::ptr::null_mut(), libc::path_base_directory::B_FIND_PATH_IMAGE_PATH, - std::ptr::null_mut(), + crate::ptr::null_mut(), name.as_mut_ptr(), name.len(), ); From a4d0fc39bacbd9520b1ccc3eaa051bd7086ce484 Mon Sep 17 00:00:00 2001 From: Scott McMurray Date: Sun, 2 Jun 2024 19:41:00 -0700 Subject: [PATCH 41/50] Add `SingleUseConsts` mir-opt pass --- .../src/const_debuginfo.rs | 3 +- compiler/rustc_mir_transform/src/lib.rs | 2 + .../src/single_use_consts.rs | 195 ++++++++++++++++++ .../mir-opt/building/match/sort_candidates.rs | 6 +- ...in.DestinationPropagation.panic-abort.diff | 2 +- ...n.DestinationPropagation.panic-unwind.diff | 2 +- ...implifyComparisonIntegral.panic-abort.diff | 4 +- ...mplifyComparisonIntegral.panic-unwind.diff | 4 +- ...d_constant.main.GVN.32bit.panic-abort.diff | 32 ++- ...d_constant.main.GVN.64bit.panic-abort.diff | 32 ++- ...ated_loop.PreCodegen.after.panic-abort.mir | 102 +++++---- ...ted_loop.PreCodegen.after.panic-unwind.mir | 102 +++++---- ...ward_loop.PreCodegen.after.panic-abort.mir | 88 ++++---- ...ard_loop.PreCodegen.after.panic-unwind.mir | 88 ++++---- ...erse_loop.PreCodegen.after.panic-abort.mir | 96 +++++---- ...rse_loop.PreCodegen.after.panic-unwind.mir | 96 +++++---- ...to_return.SingleUseConsts.panic-abort.diff | 12 ++ ...o_return.SingleUseConsts.panic-unwind.diff | 12 ++ ....if_const.SingleUseConsts.panic-abort.diff | 31 +++ ...if_const.SingleUseConsts.panic-unwind.diff | 31 +++ ...nst_debug.SingleUseConsts.panic-abort.diff | 46 +++++ ...st_debug.SingleUseConsts.panic-unwind.diff | 46 +++++ ...parameter.SingleUseConsts.panic-abort.diff | 14 ++ ...arameter.SingleUseConsts.panic-unwind.diff | 14 ++ ...tch_const.SingleUseConsts.panic-abort.diff | 36 ++++ ...ch_const.SingleUseConsts.panic-unwind.diff | 36 ++++ ...nst_debug.SingleUseConsts.panic-abort.diff | 47 +++++ ...st_debug.SingleUseConsts.panic-unwind.diff | 47 +++++ ...sed_debug.SingleUseConsts.panic-abort.diff | 21 ++ ...ed_debug.SingleUseConsts.panic-unwind.diff | 21 ++ tests/mir-opt/single_use_consts.rs | 80 +++++++ 31 files changed, 1004 insertions(+), 344 deletions(-) create mode 100644 compiler/rustc_mir_transform/src/single_use_consts.rs create mode 100644 tests/mir-opt/single_use_consts.assign_const_to_return.SingleUseConsts.panic-abort.diff create mode 100644 tests/mir-opt/single_use_consts.assign_const_to_return.SingleUseConsts.panic-unwind.diff create mode 100644 tests/mir-opt/single_use_consts.if_const.SingleUseConsts.panic-abort.diff create mode 100644 tests/mir-opt/single_use_consts.if_const.SingleUseConsts.panic-unwind.diff create mode 100644 tests/mir-opt/single_use_consts.if_const_debug.SingleUseConsts.panic-abort.diff create mode 100644 tests/mir-opt/single_use_consts.if_const_debug.SingleUseConsts.panic-unwind.diff create mode 100644 tests/mir-opt/single_use_consts.keep_parameter.SingleUseConsts.panic-abort.diff create mode 100644 tests/mir-opt/single_use_consts.keep_parameter.SingleUseConsts.panic-unwind.diff create mode 100644 tests/mir-opt/single_use_consts.match_const.SingleUseConsts.panic-abort.diff create mode 100644 tests/mir-opt/single_use_consts.match_const.SingleUseConsts.panic-unwind.diff create mode 100644 tests/mir-opt/single_use_consts.match_const_debug.SingleUseConsts.panic-abort.diff create mode 100644 tests/mir-opt/single_use_consts.match_const_debug.SingleUseConsts.panic-unwind.diff create mode 100644 tests/mir-opt/single_use_consts.never_used_debug.SingleUseConsts.panic-abort.diff create mode 100644 tests/mir-opt/single_use_consts.never_used_debug.SingleUseConsts.panic-unwind.diff create mode 100644 tests/mir-opt/single_use_consts.rs diff --git a/compiler/rustc_mir_transform/src/const_debuginfo.rs b/compiler/rustc_mir_transform/src/const_debuginfo.rs index e4e4270c4995..c758325fb989 100644 --- a/compiler/rustc_mir_transform/src/const_debuginfo.rs +++ b/compiler/rustc_mir_transform/src/const_debuginfo.rs @@ -16,7 +16,8 @@ pub struct ConstDebugInfo; impl<'tcx> MirPass<'tcx> for ConstDebugInfo { fn is_enabled(&self, sess: &rustc_session::Session) -> bool { - sess.mir_opt_level() > 0 + // Disabled in favour of `SingleUseConsts` + sess.mir_opt_level() > 2 } fn run_pass(&self, _tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { diff --git a/compiler/rustc_mir_transform/src/lib.rs b/compiler/rustc_mir_transform/src/lib.rs index e4670633914e..23e2c1287712 100644 --- a/compiler/rustc_mir_transform/src/lib.rs +++ b/compiler/rustc_mir_transform/src/lib.rs @@ -106,6 +106,7 @@ mod check_alignment; pub mod simplify; mod simplify_branches; mod simplify_comparison_integral; +mod single_use_consts; mod sroa; mod unreachable_enum_branching; mod unreachable_prop; @@ -593,6 +594,7 @@ fn run_optimization_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { &gvn::GVN, &simplify::SimplifyLocals::AfterGVN, &dataflow_const_prop::DataflowConstProp, + &single_use_consts::SingleUseConsts, &const_debuginfo::ConstDebugInfo, &o1(simplify_branches::SimplifyConstCondition::AfterConstProp), &jump_threading::JumpThreading, diff --git a/compiler/rustc_mir_transform/src/single_use_consts.rs b/compiler/rustc_mir_transform/src/single_use_consts.rs new file mode 100644 index 000000000000..864d109e3869 --- /dev/null +++ b/compiler/rustc_mir_transform/src/single_use_consts.rs @@ -0,0 +1,195 @@ +use rustc_index::{bit_set::BitSet, IndexVec}; +use rustc_middle::bug; +use rustc_middle::mir::visit::{MutVisitor, PlaceContext, Visitor}; +use rustc_middle::mir::*; +use rustc_middle::ty::TyCtxt; + +/// Various parts of MIR building introduce temporaries that are commonly not needed. +/// +/// Notably, `if CONST` and `match CONST` end up being used-once temporaries, which +/// obfuscates the structure for other passes and codegen, which would like to always +/// be able to just see the constant directly. +/// +/// At higher optimization levels fancier passes like GVN will take care of this +/// in a more general fashion, but this handles the easy cases so can run in debug. +/// +/// This only removes constants with a single-use because re-evaluating constants +/// isn't always an improvement, especially for large ones. +/// +/// It also removes *never*-used constants, since it had all the information +/// needed to do that too, including updating the debug info. +pub struct SingleUseConsts; + +impl<'tcx> MirPass<'tcx> for SingleUseConsts { + fn is_enabled(&self, sess: &rustc_session::Session) -> bool { + sess.mir_opt_level() > 0 + } + + fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { + let mut finder = SingleUseConstsFinder { + ineligible_locals: BitSet::new_empty(body.local_decls.len()), + locations: IndexVec::new(), + }; + + finder.ineligible_locals.insert_range(..=Local::from_usize(body.arg_count)); + + finder.visit_body(body); + + for (local, locations) in finder.locations.iter_enumerated() { + if finder.ineligible_locals.contains(local) { + continue; + } + + let Some(init_loc) = locations.init_loc else { + continue; + }; + + // We're only changing an operand, not the terminator kinds or successors + let basic_blocks = body.basic_blocks.as_mut_preserves_cfg(); + let init_statement = + basic_blocks[init_loc.block].statements[init_loc.statement_index].replace_nop(); + let StatementKind::Assign(place_and_rvalue) = init_statement.kind else { + bug!("No longer an assign?"); + }; + let (place, rvalue) = *place_and_rvalue; + assert_eq!(place.as_local(), Some(local)); + let Rvalue::Use(operand) = rvalue else { bug!("No longer a use?") }; + + let mut replacer = LocalReplacer { tcx, local, operand: Some(operand) }; + + for var_debug_info in &mut body.var_debug_info { + replacer.visit_var_debug_info(var_debug_info); + } + + let Some(use_loc) = locations.use_loc else { continue }; + + let use_block = &mut basic_blocks[use_loc.block]; + if let Some(use_statement) = use_block.statements.get_mut(use_loc.statement_index) { + replacer.visit_statement(use_statement, use_loc); + } else { + replacer.visit_terminator(use_block.terminator_mut(), use_loc); + } + + if replacer.operand.is_some() { + bug!( + "operand wasn't used replacing local {local:?} with locations {locations:?} in body {body:#?}" + ); + } + } + } +} + +#[derive(Copy, Clone, Debug)] +struct LocationPair { + init_loc: Option, + use_loc: Option, +} + +impl LocationPair { + fn new() -> Self { + Self { init_loc: None, use_loc: None } + } +} + +struct SingleUseConstsFinder { + ineligible_locals: BitSet, + locations: IndexVec, +} + +impl<'tcx> Visitor<'tcx> for SingleUseConstsFinder { + fn visit_assign(&mut self, place: &Place<'tcx>, rvalue: &Rvalue<'tcx>, location: Location) { + if let Some(local) = place.as_local() + && let Rvalue::Use(operand) = rvalue + && let Operand::Constant(_) = operand + { + let locations = self.locations.ensure_contains_elem(local, LocationPair::new); + if locations.init_loc.is_some() { + self.ineligible_locals.insert(local); + } else { + locations.init_loc = Some(location); + } + } else { + self.super_assign(place, rvalue, location); + } + } + + fn visit_operand(&mut self, operand: &Operand<'tcx>, location: Location) { + if let Some(place) = operand.place() + && let Some(local) = place.as_local() + { + let locations = self.locations.ensure_contains_elem(local, LocationPair::new); + if locations.use_loc.is_some() { + self.ineligible_locals.insert(local); + } else { + locations.use_loc = Some(location); + } + } else { + self.super_operand(operand, location); + } + } + + fn visit_statement(&mut self, statement: &Statement<'tcx>, location: Location) { + match &statement.kind { + // Storage markers are irrelevant to this. + StatementKind::StorageLive(_) | StatementKind::StorageDead(_) => {} + _ => self.super_statement(statement, location), + } + } + + fn visit_var_debug_info(&mut self, var_debug_info: &VarDebugInfo<'tcx>) { + if let VarDebugInfoContents::Place(place) = &var_debug_info.value + && let Some(_local) = place.as_local() + { + // It's a simple one that we can easily update + } else { + self.super_var_debug_info(var_debug_info); + } + } + + fn visit_local(&mut self, local: Local, _context: PlaceContext, _location: Location) { + // If there's any path that gets here, rather than being understood elsewhere, + // then we'd better not do anything with this local. + self.ineligible_locals.insert(local); + } +} + +struct LocalReplacer<'tcx> { + tcx: TyCtxt<'tcx>, + local: Local, + operand: Option>, +} + +impl<'tcx> MutVisitor<'tcx> for LocalReplacer<'tcx> { + fn tcx(&self) -> TyCtxt<'tcx> { + self.tcx + } + + fn visit_operand(&mut self, operand: &mut Operand<'tcx>, _location: Location) { + if let Operand::Copy(place) | Operand::Move(place) = operand + && let Some(local) = place.as_local() + && local == self.local + { + *operand = self.operand.take().unwrap_or_else(|| { + bug!("there was a second use of the operand"); + }); + } + } + + fn visit_var_debug_info(&mut self, var_debug_info: &mut VarDebugInfo<'tcx>) { + if let VarDebugInfoContents::Place(place) = &var_debug_info.value + && let Some(local) = place.as_local() + && local == self.local + { + let const_op = self + .operand + .as_ref() + .unwrap_or_else(|| { + bug!("the operand was already stolen"); + }) + .constant() + .unwrap() + .clone(); + var_debug_info.value = VarDebugInfoContents::Const(const_op); + } + } +} diff --git a/tests/mir-opt/building/match/sort_candidates.rs b/tests/mir-opt/building/match/sort_candidates.rs index f207f0b32348..593a975a7a47 100644 --- a/tests/mir-opt/building/match/sort_candidates.rs +++ b/tests/mir-opt/building/match/sort_candidates.rs @@ -5,9 +5,9 @@ fn constant_eq(s: &str, b: bool) -> u32 { // Check that we only test "a" once // CHECK-LABEL: fn constant_eq( - // CHECK: bb0: { - // CHECK: [[a:_.*]] = const "a"; - // CHECK-NOT: {{_.*}} = const "a"; + // CHECK-NOT: const "a" + // CHECK: {{_[0-9]+}} = const "a" as &[u8] (Transmute); + // CHECK-NOT: const "a" match (s, b) { ("a", _) if true => 1, ("b", true) => 2, diff --git a/tests/mir-opt/dest-prop/union.main.DestinationPropagation.panic-abort.diff b/tests/mir-opt/dest-prop/union.main.DestinationPropagation.panic-abort.diff index 570ec129f06e..b596e25ddfdf 100644 --- a/tests/mir-opt/dest-prop/union.main.DestinationPropagation.panic-abort.diff +++ b/tests/mir-opt/dest-prop/union.main.DestinationPropagation.panic-abort.diff @@ -18,7 +18,7 @@ bb0: { StorageLive(_1); StorageLive(_2); - _2 = const 1_u32; + nop; _1 = Un { us: const 1_u32 }; StorageDead(_2); StorageLive(_3); diff --git a/tests/mir-opt/dest-prop/union.main.DestinationPropagation.panic-unwind.diff b/tests/mir-opt/dest-prop/union.main.DestinationPropagation.panic-unwind.diff index 570ec129f06e..b596e25ddfdf 100644 --- a/tests/mir-opt/dest-prop/union.main.DestinationPropagation.panic-unwind.diff +++ b/tests/mir-opt/dest-prop/union.main.DestinationPropagation.panic-unwind.diff @@ -18,7 +18,7 @@ bb0: { StorageLive(_1); StorageLive(_2); - _2 = const 1_u32; + nop; _1 = Un { us: const 1_u32 }; StorageDead(_2); StorageLive(_3); diff --git a/tests/mir-opt/issue_76432.test.SimplifyComparisonIntegral.panic-abort.diff b/tests/mir-opt/issue_76432.test.SimplifyComparisonIntegral.panic-abort.diff index b2539f391d1a..1f88339b5861 100644 --- a/tests/mir-opt/issue_76432.test.SimplifyComparisonIntegral.panic-abort.diff +++ b/tests/mir-opt/issue_76432.test.SimplifyComparisonIntegral.panic-abort.diff @@ -29,8 +29,8 @@ _3 = &_4; _2 = move _3 as &[T] (PointerCoercion(Unsize)); StorageDead(_3); - _5 = const 3_usize; - _6 = const true; + nop; + nop; goto -> bb2; } diff --git a/tests/mir-opt/issue_76432.test.SimplifyComparisonIntegral.panic-unwind.diff b/tests/mir-opt/issue_76432.test.SimplifyComparisonIntegral.panic-unwind.diff index ff7f12c093ce..19a581ba3f09 100644 --- a/tests/mir-opt/issue_76432.test.SimplifyComparisonIntegral.panic-unwind.diff +++ b/tests/mir-opt/issue_76432.test.SimplifyComparisonIntegral.panic-unwind.diff @@ -29,8 +29,8 @@ _3 = &_4; _2 = move _3 as &[T] (PointerCoercion(Unsize)); StorageDead(_3); - _5 = const 3_usize; - _6 = const true; + nop; + nop; goto -> bb2; } diff --git a/tests/mir-opt/pre-codegen/issue_117368_print_invalid_constant.main.GVN.32bit.panic-abort.diff b/tests/mir-opt/pre-codegen/issue_117368_print_invalid_constant.main.GVN.32bit.panic-abort.diff index 17d83752fc13..465cb1a9b1f4 100644 --- a/tests/mir-opt/pre-codegen/issue_117368_print_invalid_constant.main.GVN.32bit.panic-abort.diff +++ b/tests/mir-opt/pre-codegen/issue_117368_print_invalid_constant.main.GVN.32bit.panic-abort.diff @@ -23,16 +23,15 @@ let mut _12: isize; let _13: std::alloc::AllocError; let mut _14: !; - let _15: &str; - let mut _16: &dyn std::fmt::Debug; - let mut _17: &std::alloc::AllocError; + let mut _15: &dyn std::fmt::Debug; + let mut _16: &std::alloc::AllocError; scope 7 { } scope 8 { } } scope 9 (inlined NonNull::<[u8]>::as_ptr) { - let mut _18: *const [u8]; + let mut _17: *const [u8]; } } scope 3 (inlined #[track_caller] Option::::unwrap) { @@ -87,36 +86,33 @@ StorageDead(_8); StorageDead(_7); StorageLive(_12); - StorageLive(_15); _12 = discriminant(_6); switchInt(move _12) -> [0: bb6, 1: bb5, otherwise: bb1]; } bb5: { - _15 = const "called `Result::unwrap()` on an `Err` value"; + StorageLive(_15); StorageLive(_16); - StorageLive(_17); - _17 = &_13; - _16 = move _17 as &dyn std::fmt::Debug (PointerCoercion(Unsize)); - StorageDead(_17); - _14 = result::unwrap_failed(move _15, move _16) -> unwind unreachable; + _16 = &_13; + _15 = move _16 as &dyn std::fmt::Debug (PointerCoercion(Unsize)); + StorageDead(_16); + _14 = result::unwrap_failed(const "called `Result::unwrap()` on an `Err` value", move _15) -> unwind unreachable; } bb6: { _5 = move ((_6 as Ok).0: std::ptr::NonNull<[u8]>); - StorageDead(_15); StorageDead(_12); StorageDead(_6); -- StorageLive(_18); +- StorageLive(_17); + nop; - _18 = (_5.0: *const [u8]); -- _4 = move _18 as *mut [u8] (PtrToPtr); -- StorageDead(_18); -+ _4 = _18 as *mut [u8] (PtrToPtr); + _17 = (_5.0: *const [u8]); +- _4 = move _17 as *mut [u8] (PtrToPtr); +- StorageDead(_17); ++ _4 = _17 as *mut [u8] (PtrToPtr); + nop; StorageDead(_5); - _3 = move _4 as *mut u8 (PtrToPtr); -+ _3 = _18 as *mut u8 (PtrToPtr); ++ _3 = _17 as *mut u8 (PtrToPtr); StorageDead(_4); StorageDead(_3); - StorageDead(_1); diff --git a/tests/mir-opt/pre-codegen/issue_117368_print_invalid_constant.main.GVN.64bit.panic-abort.diff b/tests/mir-opt/pre-codegen/issue_117368_print_invalid_constant.main.GVN.64bit.panic-abort.diff index 1cf950402c36..925d8997b8a5 100644 --- a/tests/mir-opt/pre-codegen/issue_117368_print_invalid_constant.main.GVN.64bit.panic-abort.diff +++ b/tests/mir-opt/pre-codegen/issue_117368_print_invalid_constant.main.GVN.64bit.panic-abort.diff @@ -23,16 +23,15 @@ let mut _12: isize; let _13: std::alloc::AllocError; let mut _14: !; - let _15: &str; - let mut _16: &dyn std::fmt::Debug; - let mut _17: &std::alloc::AllocError; + let mut _15: &dyn std::fmt::Debug; + let mut _16: &std::alloc::AllocError; scope 7 { } scope 8 { } } scope 9 (inlined NonNull::<[u8]>::as_ptr) { - let mut _18: *const [u8]; + let mut _17: *const [u8]; } } scope 3 (inlined #[track_caller] Option::::unwrap) { @@ -87,36 +86,33 @@ StorageDead(_8); StorageDead(_7); StorageLive(_12); - StorageLive(_15); _12 = discriminant(_6); switchInt(move _12) -> [0: bb6, 1: bb5, otherwise: bb1]; } bb5: { - _15 = const "called `Result::unwrap()` on an `Err` value"; + StorageLive(_15); StorageLive(_16); - StorageLive(_17); - _17 = &_13; - _16 = move _17 as &dyn std::fmt::Debug (PointerCoercion(Unsize)); - StorageDead(_17); - _14 = result::unwrap_failed(move _15, move _16) -> unwind unreachable; + _16 = &_13; + _15 = move _16 as &dyn std::fmt::Debug (PointerCoercion(Unsize)); + StorageDead(_16); + _14 = result::unwrap_failed(const "called `Result::unwrap()` on an `Err` value", move _15) -> unwind unreachable; } bb6: { _5 = move ((_6 as Ok).0: std::ptr::NonNull<[u8]>); - StorageDead(_15); StorageDead(_12); StorageDead(_6); -- StorageLive(_18); +- StorageLive(_17); + nop; - _18 = (_5.0: *const [u8]); -- _4 = move _18 as *mut [u8] (PtrToPtr); -- StorageDead(_18); -+ _4 = _18 as *mut [u8] (PtrToPtr); + _17 = (_5.0: *const [u8]); +- _4 = move _17 as *mut [u8] (PtrToPtr); +- StorageDead(_17); ++ _4 = _17 as *mut [u8] (PtrToPtr); + nop; StorageDead(_5); - _3 = move _4 as *mut u8 (PtrToPtr); -+ _3 = _18 as *mut u8 (PtrToPtr); ++ _3 = _17 as *mut u8 (PtrToPtr); StorageDead(_4); StorageDead(_3); - StorageDead(_1); diff --git a/tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.PreCodegen.after.panic-abort.mir b/tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.PreCodegen.after.panic-abort.mir index d979c5ec1d5a..8f41fb70925f 100644 --- a/tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.PreCodegen.after.panic-abort.mir +++ b/tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.PreCodegen.after.panic-abort.mir @@ -4,35 +4,34 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () { debug slice => _1; debug f => _2; let mut _0: (); - let mut _12: std::slice::Iter<'_, T>; + let mut _11: std::slice::Iter<'_, T>; + let mut _12: std::iter::Enumerate>; let mut _13: std::iter::Enumerate>; - let mut _14: std::iter::Enumerate>; - let mut _15: &mut std::iter::Enumerate>; - let mut _16: std::option::Option<(usize, &T)>; - let mut _17: isize; - let mut _20: &impl Fn(usize, &T); - let mut _21: (usize, &T); - let _22: (); + let mut _14: &mut std::iter::Enumerate>; + let mut _15: std::option::Option<(usize, &T)>; + let mut _16: isize; + let mut _19: &impl Fn(usize, &T); + let mut _20: (usize, &T); + let _21: (); scope 1 { - debug iter => _14; - let _18: usize; - let _19: &T; + debug iter => _13; + let _17: usize; + let _18: &T; scope 2 { - debug i => _18; - debug x => _19; + debug i => _17; + debug x => _18; } } scope 3 (inlined core::slice::::iter) { scope 4 (inlined std::slice::Iter::<'_, T>::new) { let _3: usize; - let mut _7: bool; + let mut _7: *mut T; let mut _8: *mut T; - let mut _9: *mut T; - let mut _11: *const T; + let mut _10: *const T; scope 5 { let _6: std::ptr::NonNull; scope 6 { - let _10: *const T; + let _9: *const T; scope 7 { } scope 11 (inlined without_provenance::) { @@ -61,7 +60,7 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () { } bb0: { - StorageLive(_12); + StorageLive(_11); StorageLive(_3); StorageLive(_6); StorageLive(_4); @@ -70,62 +69,59 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () { _4 = &raw const (*_1); _5 = _4 as *const T (PtrToPtr); _6 = NonNull:: { pointer: _5 }; - StorageLive(_10); - StorageLive(_7); - _7 = const ::IS_ZST; - switchInt(move _7) -> [0: bb1, otherwise: bb2]; + StorageLive(_9); + switchInt(const ::IS_ZST) -> [0: bb1, otherwise: bb2]; } bb1: { - StorageLive(_9); StorageLive(_8); - _8 = _4 as *mut T (PtrToPtr); - _9 = Offset(_8, _3); + StorageLive(_7); + _7 = _4 as *mut T (PtrToPtr); + _8 = Offset(_7, _3); + StorageDead(_7); + _9 = move _8 as *const T (PointerCoercion(MutToConstPointer)); StorageDead(_8); - _10 = move _9 as *const T (PointerCoercion(MutToConstPointer)); - StorageDead(_9); goto -> bb3; } bb2: { - _10 = _3 as *const T (Transmute); + _9 = _3 as *const T (Transmute); goto -> bb3; } bb3: { - StorageDead(_7); - StorageLive(_11); - _11 = _10; - _12 = std::slice::Iter::<'_, T> { ptr: _6, end_or_len: move _11, _marker: const ZeroSized: PhantomData<&T> }; - StorageDead(_11); + StorageLive(_10); + _10 = _9; + _11 = std::slice::Iter::<'_, T> { ptr: _6, end_or_len: move _10, _marker: const ZeroSized: PhantomData<&T> }; StorageDead(_10); + StorageDead(_9); StorageDead(_5); StorageDead(_4); StorageDead(_6); StorageDead(_3); - _13 = Enumerate::> { iter: _12, count: const 0_usize }; - StorageDead(_12); - StorageLive(_14); - _14 = _13; + _12 = Enumerate::> { iter: _11, count: const 0_usize }; + StorageDead(_11); + StorageLive(_13); + _13 = _12; goto -> bb4; } bb4: { - StorageLive(_16); StorageLive(_15); - _15 = &mut _14; - _16 = > as Iterator>::next(move _15) -> [return: bb5, unwind unreachable]; + StorageLive(_14); + _14 = &mut _13; + _15 = > as Iterator>::next(move _14) -> [return: bb5, unwind unreachable]; } bb5: { - StorageDead(_15); - _17 = discriminant(_16); - switchInt(move _17) -> [0: bb6, 1: bb8, otherwise: bb10]; + StorageDead(_14); + _16 = discriminant(_15); + switchInt(move _16) -> [0: bb6, 1: bb8, otherwise: bb10]; } bb6: { - StorageDead(_16); - StorageDead(_14); + StorageDead(_15); + StorageDead(_13); drop(_2) -> [return: bb7, unwind unreachable]; } @@ -134,19 +130,19 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () { } bb8: { - _18 = (((_16 as Some).0: (usize, &T)).0: usize); - _19 = (((_16 as Some).0: (usize, &T)).1: &T); + _17 = (((_15 as Some).0: (usize, &T)).0: usize); + _18 = (((_15 as Some).0: (usize, &T)).1: &T); + StorageLive(_19); + _19 = &_2; StorageLive(_20); - _20 = &_2; - StorageLive(_21); - _21 = (_18, _19); - _22 = >::call(move _20, move _21) -> [return: bb9, unwind unreachable]; + _20 = (_17, _18); + _21 = >::call(move _19, move _20) -> [return: bb9, unwind unreachable]; } bb9: { - StorageDead(_21); StorageDead(_20); - StorageDead(_16); + StorageDead(_19); + StorageDead(_15); goto -> bb4; } diff --git a/tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.PreCodegen.after.panic-unwind.mir index 8491c49f7673..17cf305468e8 100644 --- a/tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.PreCodegen.after.panic-unwind.mir +++ b/tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.PreCodegen.after.panic-unwind.mir @@ -4,35 +4,34 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () { debug slice => _1; debug f => _2; let mut _0: (); - let mut _12: std::slice::Iter<'_, T>; + let mut _11: std::slice::Iter<'_, T>; + let mut _12: std::iter::Enumerate>; let mut _13: std::iter::Enumerate>; - let mut _14: std::iter::Enumerate>; - let mut _15: &mut std::iter::Enumerate>; - let mut _16: std::option::Option<(usize, &T)>; - let mut _17: isize; - let mut _20: &impl Fn(usize, &T); - let mut _21: (usize, &T); - let _22: (); + let mut _14: &mut std::iter::Enumerate>; + let mut _15: std::option::Option<(usize, &T)>; + let mut _16: isize; + let mut _19: &impl Fn(usize, &T); + let mut _20: (usize, &T); + let _21: (); scope 1 { - debug iter => _14; - let _18: usize; - let _19: &T; + debug iter => _13; + let _17: usize; + let _18: &T; scope 2 { - debug i => _18; - debug x => _19; + debug i => _17; + debug x => _18; } } scope 3 (inlined core::slice::::iter) { scope 4 (inlined std::slice::Iter::<'_, T>::new) { let _3: usize; - let mut _7: bool; + let mut _7: *mut T; let mut _8: *mut T; - let mut _9: *mut T; - let mut _11: *const T; + let mut _10: *const T; scope 5 { let _6: std::ptr::NonNull; scope 6 { - let _10: *const T; + let _9: *const T; scope 7 { } scope 11 (inlined without_provenance::) { @@ -61,7 +60,7 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () { } bb0: { - StorageLive(_12); + StorageLive(_11); StorageLive(_3); StorageLive(_6); StorageLive(_4); @@ -70,62 +69,59 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () { _4 = &raw const (*_1); _5 = _4 as *const T (PtrToPtr); _6 = NonNull:: { pointer: _5 }; - StorageLive(_10); - StorageLive(_7); - _7 = const ::IS_ZST; - switchInt(move _7) -> [0: bb1, otherwise: bb2]; + StorageLive(_9); + switchInt(const ::IS_ZST) -> [0: bb1, otherwise: bb2]; } bb1: { - StorageLive(_9); StorageLive(_8); - _8 = _4 as *mut T (PtrToPtr); - _9 = Offset(_8, _3); + StorageLive(_7); + _7 = _4 as *mut T (PtrToPtr); + _8 = Offset(_7, _3); + StorageDead(_7); + _9 = move _8 as *const T (PointerCoercion(MutToConstPointer)); StorageDead(_8); - _10 = move _9 as *const T (PointerCoercion(MutToConstPointer)); - StorageDead(_9); goto -> bb3; } bb2: { - _10 = _3 as *const T (Transmute); + _9 = _3 as *const T (Transmute); goto -> bb3; } bb3: { - StorageDead(_7); - StorageLive(_11); - _11 = _10; - _12 = std::slice::Iter::<'_, T> { ptr: _6, end_or_len: move _11, _marker: const ZeroSized: PhantomData<&T> }; - StorageDead(_11); + StorageLive(_10); + _10 = _9; + _11 = std::slice::Iter::<'_, T> { ptr: _6, end_or_len: move _10, _marker: const ZeroSized: PhantomData<&T> }; StorageDead(_10); + StorageDead(_9); StorageDead(_5); StorageDead(_4); StorageDead(_6); StorageDead(_3); - _13 = Enumerate::> { iter: _12, count: const 0_usize }; - StorageDead(_12); - StorageLive(_14); - _14 = _13; + _12 = Enumerate::> { iter: _11, count: const 0_usize }; + StorageDead(_11); + StorageLive(_13); + _13 = _12; goto -> bb4; } bb4: { - StorageLive(_16); StorageLive(_15); - _15 = &mut _14; - _16 = > as Iterator>::next(move _15) -> [return: bb5, unwind: bb11]; + StorageLive(_14); + _14 = &mut _13; + _15 = > as Iterator>::next(move _14) -> [return: bb5, unwind: bb11]; } bb5: { - StorageDead(_15); - _17 = discriminant(_16); - switchInt(move _17) -> [0: bb6, 1: bb8, otherwise: bb10]; + StorageDead(_14); + _16 = discriminant(_15); + switchInt(move _16) -> [0: bb6, 1: bb8, otherwise: bb10]; } bb6: { - StorageDead(_16); - StorageDead(_14); + StorageDead(_15); + StorageDead(_13); drop(_2) -> [return: bb7, unwind continue]; } @@ -134,19 +130,19 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () { } bb8: { - _18 = (((_16 as Some).0: (usize, &T)).0: usize); - _19 = (((_16 as Some).0: (usize, &T)).1: &T); + _17 = (((_15 as Some).0: (usize, &T)).0: usize); + _18 = (((_15 as Some).0: (usize, &T)).1: &T); + StorageLive(_19); + _19 = &_2; StorageLive(_20); - _20 = &_2; - StorageLive(_21); - _21 = (_18, _19); - _22 = >::call(move _20, move _21) -> [return: bb9, unwind: bb11]; + _20 = (_17, _18); + _21 = >::call(move _19, move _20) -> [return: bb9, unwind: bb11]; } bb9: { - StorageDead(_21); StorageDead(_20); - StorageDead(_16); + StorageDead(_19); + StorageDead(_15); goto -> bb4; } diff --git a/tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.panic-abort.mir b/tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.panic-abort.mir index 67dd0c85ea1d..3c1bbdc87424 100644 --- a/tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.panic-abort.mir +++ b/tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.panic-abort.mir @@ -4,32 +4,31 @@ fn forward_loop(_1: &[T], _2: impl Fn(&T)) -> () { debug slice => _1; debug f => _2; let mut _0: (); + let mut _11: std::slice::Iter<'_, T>; let mut _12: std::slice::Iter<'_, T>; - let mut _13: std::slice::Iter<'_, T>; - let mut _14: &mut std::slice::Iter<'_, T>; - let mut _15: std::option::Option<&T>; - let mut _16: isize; - let mut _18: &impl Fn(&T); - let mut _19: (&T,); - let _20: (); + let mut _13: &mut std::slice::Iter<'_, T>; + let mut _14: std::option::Option<&T>; + let mut _15: isize; + let mut _17: &impl Fn(&T); + let mut _18: (&T,); + let _19: (); scope 1 { - debug iter => _13; - let _17: &T; + debug iter => _12; + let _16: &T; scope 2 { - debug x => _17; + debug x => _16; } } scope 3 (inlined core::slice::::iter) { scope 4 (inlined std::slice::Iter::<'_, T>::new) { let _3: usize; - let mut _7: bool; + let mut _7: *mut T; let mut _8: *mut T; - let mut _9: *mut T; - let mut _11: *const T; + let mut _10: *const T; scope 5 { let _6: std::ptr::NonNull; scope 6 { - let _10: *const T; + let _9: *const T; scope 7 { } scope 11 (inlined without_provenance::) { @@ -62,60 +61,57 @@ fn forward_loop(_1: &[T], _2: impl Fn(&T)) -> () { _4 = &raw const (*_1); _5 = _4 as *const T (PtrToPtr); _6 = NonNull:: { pointer: _5 }; - StorageLive(_10); - StorageLive(_7); - _7 = const ::IS_ZST; - switchInt(move _7) -> [0: bb1, otherwise: bb2]; + StorageLive(_9); + switchInt(const ::IS_ZST) -> [0: bb1, otherwise: bb2]; } bb1: { - StorageLive(_9); StorageLive(_8); - _8 = _4 as *mut T (PtrToPtr); - _9 = Offset(_8, _3); + StorageLive(_7); + _7 = _4 as *mut T (PtrToPtr); + _8 = Offset(_7, _3); + StorageDead(_7); + _9 = move _8 as *const T (PointerCoercion(MutToConstPointer)); StorageDead(_8); - _10 = move _9 as *const T (PointerCoercion(MutToConstPointer)); - StorageDead(_9); goto -> bb3; } bb2: { - _10 = _3 as *const T (Transmute); + _9 = _3 as *const T (Transmute); goto -> bb3; } bb3: { - StorageDead(_7); - StorageLive(_11); - _11 = _10; - _12 = std::slice::Iter::<'_, T> { ptr: _6, end_or_len: move _11, _marker: const ZeroSized: PhantomData<&T> }; - StorageDead(_11); + StorageLive(_10); + _10 = _9; + _11 = std::slice::Iter::<'_, T> { ptr: _6, end_or_len: move _10, _marker: const ZeroSized: PhantomData<&T> }; StorageDead(_10); + StorageDead(_9); StorageDead(_5); StorageDead(_4); StorageDead(_6); StorageDead(_3); - StorageLive(_13); - _13 = _12; + StorageLive(_12); + _12 = _11; goto -> bb4; } bb4: { - StorageLive(_15); StorageLive(_14); - _14 = &mut _13; - _15 = as Iterator>::next(move _14) -> [return: bb5, unwind unreachable]; + StorageLive(_13); + _13 = &mut _12; + _14 = as Iterator>::next(move _13) -> [return: bb5, unwind unreachable]; } bb5: { - StorageDead(_14); - _16 = discriminant(_15); - switchInt(move _16) -> [0: bb6, 1: bb8, otherwise: bb10]; + StorageDead(_13); + _15 = discriminant(_14); + switchInt(move _15) -> [0: bb6, 1: bb8, otherwise: bb10]; } bb6: { - StorageDead(_15); - StorageDead(_13); + StorageDead(_14); + StorageDead(_12); drop(_2) -> [return: bb7, unwind unreachable]; } @@ -124,18 +120,18 @@ fn forward_loop(_1: &[T], _2: impl Fn(&T)) -> () { } bb8: { - _17 = ((_15 as Some).0: &T); + _16 = ((_14 as Some).0: &T); + StorageLive(_17); + _17 = &_2; StorageLive(_18); - _18 = &_2; - StorageLive(_19); - _19 = (_17,); - _20 = >::call(move _18, move _19) -> [return: bb9, unwind unreachable]; + _18 = (_16,); + _19 = >::call(move _17, move _18) -> [return: bb9, unwind unreachable]; } bb9: { - StorageDead(_19); StorageDead(_18); - StorageDead(_15); + StorageDead(_17); + StorageDead(_14); goto -> bb4; } diff --git a/tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.panic-unwind.mir index 7c41e9e1f1b7..b2ec1ea7b9f2 100644 --- a/tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.panic-unwind.mir +++ b/tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.panic-unwind.mir @@ -4,32 +4,31 @@ fn forward_loop(_1: &[T], _2: impl Fn(&T)) -> () { debug slice => _1; debug f => _2; let mut _0: (); + let mut _11: std::slice::Iter<'_, T>; let mut _12: std::slice::Iter<'_, T>; - let mut _13: std::slice::Iter<'_, T>; - let mut _14: &mut std::slice::Iter<'_, T>; - let mut _15: std::option::Option<&T>; - let mut _16: isize; - let mut _18: &impl Fn(&T); - let mut _19: (&T,); - let _20: (); + let mut _13: &mut std::slice::Iter<'_, T>; + let mut _14: std::option::Option<&T>; + let mut _15: isize; + let mut _17: &impl Fn(&T); + let mut _18: (&T,); + let _19: (); scope 1 { - debug iter => _13; - let _17: &T; + debug iter => _12; + let _16: &T; scope 2 { - debug x => _17; + debug x => _16; } } scope 3 (inlined core::slice::::iter) { scope 4 (inlined std::slice::Iter::<'_, T>::new) { let _3: usize; - let mut _7: bool; + let mut _7: *mut T; let mut _8: *mut T; - let mut _9: *mut T; - let mut _11: *const T; + let mut _10: *const T; scope 5 { let _6: std::ptr::NonNull; scope 6 { - let _10: *const T; + let _9: *const T; scope 7 { } scope 11 (inlined without_provenance::) { @@ -62,60 +61,57 @@ fn forward_loop(_1: &[T], _2: impl Fn(&T)) -> () { _4 = &raw const (*_1); _5 = _4 as *const T (PtrToPtr); _6 = NonNull:: { pointer: _5 }; - StorageLive(_10); - StorageLive(_7); - _7 = const ::IS_ZST; - switchInt(move _7) -> [0: bb1, otherwise: bb2]; + StorageLive(_9); + switchInt(const ::IS_ZST) -> [0: bb1, otherwise: bb2]; } bb1: { - StorageLive(_9); StorageLive(_8); - _8 = _4 as *mut T (PtrToPtr); - _9 = Offset(_8, _3); + StorageLive(_7); + _7 = _4 as *mut T (PtrToPtr); + _8 = Offset(_7, _3); + StorageDead(_7); + _9 = move _8 as *const T (PointerCoercion(MutToConstPointer)); StorageDead(_8); - _10 = move _9 as *const T (PointerCoercion(MutToConstPointer)); - StorageDead(_9); goto -> bb3; } bb2: { - _10 = _3 as *const T (Transmute); + _9 = _3 as *const T (Transmute); goto -> bb3; } bb3: { - StorageDead(_7); - StorageLive(_11); - _11 = _10; - _12 = std::slice::Iter::<'_, T> { ptr: _6, end_or_len: move _11, _marker: const ZeroSized: PhantomData<&T> }; - StorageDead(_11); + StorageLive(_10); + _10 = _9; + _11 = std::slice::Iter::<'_, T> { ptr: _6, end_or_len: move _10, _marker: const ZeroSized: PhantomData<&T> }; StorageDead(_10); + StorageDead(_9); StorageDead(_5); StorageDead(_4); StorageDead(_6); StorageDead(_3); - StorageLive(_13); - _13 = _12; + StorageLive(_12); + _12 = _11; goto -> bb4; } bb4: { - StorageLive(_15); StorageLive(_14); - _14 = &mut _13; - _15 = as Iterator>::next(move _14) -> [return: bb5, unwind: bb11]; + StorageLive(_13); + _13 = &mut _12; + _14 = as Iterator>::next(move _13) -> [return: bb5, unwind: bb11]; } bb5: { - StorageDead(_14); - _16 = discriminant(_15); - switchInt(move _16) -> [0: bb6, 1: bb8, otherwise: bb10]; + StorageDead(_13); + _15 = discriminant(_14); + switchInt(move _15) -> [0: bb6, 1: bb8, otherwise: bb10]; } bb6: { - StorageDead(_15); - StorageDead(_13); + StorageDead(_14); + StorageDead(_12); drop(_2) -> [return: bb7, unwind continue]; } @@ -124,18 +120,18 @@ fn forward_loop(_1: &[T], _2: impl Fn(&T)) -> () { } bb8: { - _17 = ((_15 as Some).0: &T); + _16 = ((_14 as Some).0: &T); + StorageLive(_17); + _17 = &_2; StorageLive(_18); - _18 = &_2; - StorageLive(_19); - _19 = (_17,); - _20 = >::call(move _18, move _19) -> [return: bb9, unwind: bb11]; + _18 = (_16,); + _19 = >::call(move _17, move _18) -> [return: bb9, unwind: bb11]; } bb9: { - StorageDead(_19); StorageDead(_18); - StorageDead(_15); + StorageDead(_17); + StorageDead(_14); goto -> bb4; } diff --git a/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-abort.mir b/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-abort.mir index ffeef1e04a15..bf982f076de7 100644 --- a/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-abort.mir +++ b/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-abort.mir @@ -4,35 +4,34 @@ fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () { debug slice => _1; debug f => _2; let mut _0: (); - let mut _12: std::slice::Iter<'_, T>; + let mut _11: std::slice::Iter<'_, T>; + let mut _12: std::iter::Rev>; let mut _13: std::iter::Rev>; - let mut _14: std::iter::Rev>; - let mut _16: std::option::Option<&T>; - let mut _17: isize; - let mut _19: &impl Fn(&T); - let mut _20: (&T,); - let _21: (); + let mut _15: std::option::Option<&T>; + let mut _16: isize; + let mut _18: &impl Fn(&T); + let mut _19: (&T,); + let _20: (); scope 1 { - debug iter => _14; - let _18: &T; + debug iter => _13; + let _17: &T; scope 2 { - debug x => _18; + debug x => _17; } scope 17 (inlined > as Iterator>::next) { - let mut _15: &mut std::slice::Iter<'_, T>; + let mut _14: &mut std::slice::Iter<'_, T>; } } scope 3 (inlined core::slice::::iter) { scope 4 (inlined std::slice::Iter::<'_, T>::new) { let _3: usize; - let mut _7: bool; + let mut _7: *mut T; let mut _8: *mut T; - let mut _9: *mut T; - let mut _11: *const T; + let mut _10: *const T; scope 5 { let _6: std::ptr::NonNull; scope 6 { - let _10: *const T; + let _9: *const T; scope 7 { } scope 11 (inlined without_provenance::) { @@ -61,7 +60,7 @@ fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () { } bb0: { - StorageLive(_12); + StorageLive(_11); StorageLive(_3); StorageLive(_6); StorageLive(_4); @@ -70,62 +69,59 @@ fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () { _4 = &raw const (*_1); _5 = _4 as *const T (PtrToPtr); _6 = NonNull:: { pointer: _5 }; - StorageLive(_10); - StorageLive(_7); - _7 = const ::IS_ZST; - switchInt(move _7) -> [0: bb1, otherwise: bb2]; + StorageLive(_9); + switchInt(const ::IS_ZST) -> [0: bb1, otherwise: bb2]; } bb1: { - StorageLive(_9); StorageLive(_8); - _8 = _4 as *mut T (PtrToPtr); - _9 = Offset(_8, _3); + StorageLive(_7); + _7 = _4 as *mut T (PtrToPtr); + _8 = Offset(_7, _3); + StorageDead(_7); + _9 = move _8 as *const T (PointerCoercion(MutToConstPointer)); StorageDead(_8); - _10 = move _9 as *const T (PointerCoercion(MutToConstPointer)); - StorageDead(_9); goto -> bb3; } bb2: { - _10 = _3 as *const T (Transmute); + _9 = _3 as *const T (Transmute); goto -> bb3; } bb3: { - StorageDead(_7); - StorageLive(_11); - _11 = _10; - _12 = std::slice::Iter::<'_, T> { ptr: _6, end_or_len: move _11, _marker: const ZeroSized: PhantomData<&T> }; - StorageDead(_11); + StorageLive(_10); + _10 = _9; + _11 = std::slice::Iter::<'_, T> { ptr: _6, end_or_len: move _10, _marker: const ZeroSized: PhantomData<&T> }; StorageDead(_10); + StorageDead(_9); StorageDead(_5); StorageDead(_4); StorageDead(_6); StorageDead(_3); - _13 = Rev::> { iter: _12 }; - StorageDead(_12); - StorageLive(_14); - _14 = _13; + _12 = Rev::> { iter: _11 }; + StorageDead(_11); + StorageLive(_13); + _13 = _12; goto -> bb4; } bb4: { - StorageLive(_16); StorageLive(_15); - _15 = &mut (_14.0: std::slice::Iter<'_, T>); - _16 = as DoubleEndedIterator>::next_back(move _15) -> [return: bb5, unwind unreachable]; + StorageLive(_14); + _14 = &mut (_13.0: std::slice::Iter<'_, T>); + _15 = as DoubleEndedIterator>::next_back(move _14) -> [return: bb5, unwind unreachable]; } bb5: { - StorageDead(_15); - _17 = discriminant(_16); - switchInt(move _17) -> [0: bb6, 1: bb8, otherwise: bb10]; + StorageDead(_14); + _16 = discriminant(_15); + switchInt(move _16) -> [0: bb6, 1: bb8, otherwise: bb10]; } bb6: { - StorageDead(_16); - StorageDead(_14); + StorageDead(_15); + StorageDead(_13); drop(_2) -> [return: bb7, unwind unreachable]; } @@ -134,18 +130,18 @@ fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () { } bb8: { - _18 = ((_16 as Some).0: &T); + _17 = ((_15 as Some).0: &T); + StorageLive(_18); + _18 = &_2; StorageLive(_19); - _19 = &_2; - StorageLive(_20); - _20 = (_18,); - _21 = >::call(move _19, move _20) -> [return: bb9, unwind unreachable]; + _19 = (_17,); + _20 = >::call(move _18, move _19) -> [return: bb9, unwind unreachable]; } bb9: { - StorageDead(_20); StorageDead(_19); - StorageDead(_16); + StorageDead(_18); + StorageDead(_15); goto -> bb4; } diff --git a/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-unwind.mir index c7cd37afd866..532b81625212 100644 --- a/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-unwind.mir +++ b/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-unwind.mir @@ -4,35 +4,34 @@ fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () { debug slice => _1; debug f => _2; let mut _0: (); - let mut _12: std::slice::Iter<'_, T>; + let mut _11: std::slice::Iter<'_, T>; + let mut _12: std::iter::Rev>; let mut _13: std::iter::Rev>; - let mut _14: std::iter::Rev>; - let mut _16: std::option::Option<&T>; - let mut _17: isize; - let mut _19: &impl Fn(&T); - let mut _20: (&T,); - let _21: (); + let mut _15: std::option::Option<&T>; + let mut _16: isize; + let mut _18: &impl Fn(&T); + let mut _19: (&T,); + let _20: (); scope 1 { - debug iter => _14; - let _18: &T; + debug iter => _13; + let _17: &T; scope 2 { - debug x => _18; + debug x => _17; } scope 17 (inlined > as Iterator>::next) { - let mut _15: &mut std::slice::Iter<'_, T>; + let mut _14: &mut std::slice::Iter<'_, T>; } } scope 3 (inlined core::slice::::iter) { scope 4 (inlined std::slice::Iter::<'_, T>::new) { let _3: usize; - let mut _7: bool; + let mut _7: *mut T; let mut _8: *mut T; - let mut _9: *mut T; - let mut _11: *const T; + let mut _10: *const T; scope 5 { let _6: std::ptr::NonNull; scope 6 { - let _10: *const T; + let _9: *const T; scope 7 { } scope 11 (inlined without_provenance::) { @@ -61,7 +60,7 @@ fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () { } bb0: { - StorageLive(_12); + StorageLive(_11); StorageLive(_3); StorageLive(_6); StorageLive(_4); @@ -70,62 +69,59 @@ fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () { _4 = &raw const (*_1); _5 = _4 as *const T (PtrToPtr); _6 = NonNull:: { pointer: _5 }; - StorageLive(_10); - StorageLive(_7); - _7 = const ::IS_ZST; - switchInt(move _7) -> [0: bb1, otherwise: bb2]; + StorageLive(_9); + switchInt(const ::IS_ZST) -> [0: bb1, otherwise: bb2]; } bb1: { - StorageLive(_9); StorageLive(_8); - _8 = _4 as *mut T (PtrToPtr); - _9 = Offset(_8, _3); + StorageLive(_7); + _7 = _4 as *mut T (PtrToPtr); + _8 = Offset(_7, _3); + StorageDead(_7); + _9 = move _8 as *const T (PointerCoercion(MutToConstPointer)); StorageDead(_8); - _10 = move _9 as *const T (PointerCoercion(MutToConstPointer)); - StorageDead(_9); goto -> bb3; } bb2: { - _10 = _3 as *const T (Transmute); + _9 = _3 as *const T (Transmute); goto -> bb3; } bb3: { - StorageDead(_7); - StorageLive(_11); - _11 = _10; - _12 = std::slice::Iter::<'_, T> { ptr: _6, end_or_len: move _11, _marker: const ZeroSized: PhantomData<&T> }; - StorageDead(_11); + StorageLive(_10); + _10 = _9; + _11 = std::slice::Iter::<'_, T> { ptr: _6, end_or_len: move _10, _marker: const ZeroSized: PhantomData<&T> }; StorageDead(_10); + StorageDead(_9); StorageDead(_5); StorageDead(_4); StorageDead(_6); StorageDead(_3); - _13 = Rev::> { iter: _12 }; - StorageDead(_12); - StorageLive(_14); - _14 = _13; + _12 = Rev::> { iter: _11 }; + StorageDead(_11); + StorageLive(_13); + _13 = _12; goto -> bb4; } bb4: { - StorageLive(_16); StorageLive(_15); - _15 = &mut (_14.0: std::slice::Iter<'_, T>); - _16 = as DoubleEndedIterator>::next_back(move _15) -> [return: bb5, unwind: bb11]; + StorageLive(_14); + _14 = &mut (_13.0: std::slice::Iter<'_, T>); + _15 = as DoubleEndedIterator>::next_back(move _14) -> [return: bb5, unwind: bb11]; } bb5: { - StorageDead(_15); - _17 = discriminant(_16); - switchInt(move _17) -> [0: bb6, 1: bb8, otherwise: bb10]; + StorageDead(_14); + _16 = discriminant(_15); + switchInt(move _16) -> [0: bb6, 1: bb8, otherwise: bb10]; } bb6: { - StorageDead(_16); - StorageDead(_14); + StorageDead(_15); + StorageDead(_13); drop(_2) -> [return: bb7, unwind continue]; } @@ -134,18 +130,18 @@ fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () { } bb8: { - _18 = ((_16 as Some).0: &T); + _17 = ((_15 as Some).0: &T); + StorageLive(_18); + _18 = &_2; StorageLive(_19); - _19 = &_2; - StorageLive(_20); - _20 = (_18,); - _21 = >::call(move _19, move _20) -> [return: bb9, unwind: bb11]; + _19 = (_17,); + _20 = >::call(move _18, move _19) -> [return: bb9, unwind: bb11]; } bb9: { - StorageDead(_20); StorageDead(_19); - StorageDead(_16); + StorageDead(_18); + StorageDead(_15); goto -> bb4; } diff --git a/tests/mir-opt/single_use_consts.assign_const_to_return.SingleUseConsts.panic-abort.diff b/tests/mir-opt/single_use_consts.assign_const_to_return.SingleUseConsts.panic-abort.diff new file mode 100644 index 000000000000..8818c891e94b --- /dev/null +++ b/tests/mir-opt/single_use_consts.assign_const_to_return.SingleUseConsts.panic-abort.diff @@ -0,0 +1,12 @@ +- // MIR for `assign_const_to_return` before SingleUseConsts ++ // MIR for `assign_const_to_return` after SingleUseConsts + + fn assign_const_to_return() -> bool { + let mut _0: bool; + + bb0: { + _0 = const ::ASSOC_BOOL; + return; + } + } + diff --git a/tests/mir-opt/single_use_consts.assign_const_to_return.SingleUseConsts.panic-unwind.diff b/tests/mir-opt/single_use_consts.assign_const_to_return.SingleUseConsts.panic-unwind.diff new file mode 100644 index 000000000000..8818c891e94b --- /dev/null +++ b/tests/mir-opt/single_use_consts.assign_const_to_return.SingleUseConsts.panic-unwind.diff @@ -0,0 +1,12 @@ +- // MIR for `assign_const_to_return` before SingleUseConsts ++ // MIR for `assign_const_to_return` after SingleUseConsts + + fn assign_const_to_return() -> bool { + let mut _0: bool; + + bb0: { + _0 = const ::ASSOC_BOOL; + return; + } + } + diff --git a/tests/mir-opt/single_use_consts.if_const.SingleUseConsts.panic-abort.diff b/tests/mir-opt/single_use_consts.if_const.SingleUseConsts.panic-abort.diff new file mode 100644 index 000000000000..468076e5ee3c --- /dev/null +++ b/tests/mir-opt/single_use_consts.if_const.SingleUseConsts.panic-abort.diff @@ -0,0 +1,31 @@ +- // MIR for `if_const` before SingleUseConsts ++ // MIR for `if_const` after SingleUseConsts + + fn if_const() -> i32 { + let mut _0: i32; + let mut _1: bool; + + bb0: { + StorageLive(_1); +- _1 = const ::ASSOC_BOOL; +- switchInt(move _1) -> [0: bb2, otherwise: bb1]; ++ nop; ++ switchInt(const ::ASSOC_BOOL) -> [0: bb2, otherwise: bb1]; + } + + bb1: { + _0 = const 7_i32; + goto -> bb3; + } + + bb2: { + _0 = const 42_i32; + goto -> bb3; + } + + bb3: { + StorageDead(_1); + return; + } + } + diff --git a/tests/mir-opt/single_use_consts.if_const.SingleUseConsts.panic-unwind.diff b/tests/mir-opt/single_use_consts.if_const.SingleUseConsts.panic-unwind.diff new file mode 100644 index 000000000000..468076e5ee3c --- /dev/null +++ b/tests/mir-opt/single_use_consts.if_const.SingleUseConsts.panic-unwind.diff @@ -0,0 +1,31 @@ +- // MIR for `if_const` before SingleUseConsts ++ // MIR for `if_const` after SingleUseConsts + + fn if_const() -> i32 { + let mut _0: i32; + let mut _1: bool; + + bb0: { + StorageLive(_1); +- _1 = const ::ASSOC_BOOL; +- switchInt(move _1) -> [0: bb2, otherwise: bb1]; ++ nop; ++ switchInt(const ::ASSOC_BOOL) -> [0: bb2, otherwise: bb1]; + } + + bb1: { + _0 = const 7_i32; + goto -> bb3; + } + + bb2: { + _0 = const 42_i32; + goto -> bb3; + } + + bb3: { + StorageDead(_1); + return; + } + } + diff --git a/tests/mir-opt/single_use_consts.if_const_debug.SingleUseConsts.panic-abort.diff b/tests/mir-opt/single_use_consts.if_const_debug.SingleUseConsts.panic-abort.diff new file mode 100644 index 000000000000..ad1a2b300f2a --- /dev/null +++ b/tests/mir-opt/single_use_consts.if_const_debug.SingleUseConsts.panic-abort.diff @@ -0,0 +1,46 @@ +- // MIR for `if_const_debug` before SingleUseConsts ++ // MIR for `if_const_debug` after SingleUseConsts + + fn if_const_debug() -> i32 { + let mut _0: i32; + let _1: bool; + let _2: (); + let mut _3: bool; + scope 1 { +- debug my_bool => _1; ++ debug my_bool => const ::ASSOC_BOOL; + } + + bb0: { + StorageLive(_1); +- _1 = const ::ASSOC_BOOL; ++ nop; + StorageLive(_2); + _2 = do_whatever() -> [return: bb1, unwind unreachable]; + } + + bb1: { + StorageDead(_2); + StorageLive(_3); +- _3 = _1; ++ _3 = const ::ASSOC_BOOL; + switchInt(move _3) -> [0: bb3, otherwise: bb2]; + } + + bb2: { + _0 = const 7_i32; + goto -> bb4; + } + + bb3: { + _0 = const 42_i32; + goto -> bb4; + } + + bb4: { + StorageDead(_3); + StorageDead(_1); + return; + } + } + diff --git a/tests/mir-opt/single_use_consts.if_const_debug.SingleUseConsts.panic-unwind.diff b/tests/mir-opt/single_use_consts.if_const_debug.SingleUseConsts.panic-unwind.diff new file mode 100644 index 000000000000..827a292e5d02 --- /dev/null +++ b/tests/mir-opt/single_use_consts.if_const_debug.SingleUseConsts.panic-unwind.diff @@ -0,0 +1,46 @@ +- // MIR for `if_const_debug` before SingleUseConsts ++ // MIR for `if_const_debug` after SingleUseConsts + + fn if_const_debug() -> i32 { + let mut _0: i32; + let _1: bool; + let _2: (); + let mut _3: bool; + scope 1 { +- debug my_bool => _1; ++ debug my_bool => const ::ASSOC_BOOL; + } + + bb0: { + StorageLive(_1); +- _1 = const ::ASSOC_BOOL; ++ nop; + StorageLive(_2); + _2 = do_whatever() -> [return: bb1, unwind continue]; + } + + bb1: { + StorageDead(_2); + StorageLive(_3); +- _3 = _1; ++ _3 = const ::ASSOC_BOOL; + switchInt(move _3) -> [0: bb3, otherwise: bb2]; + } + + bb2: { + _0 = const 7_i32; + goto -> bb4; + } + + bb3: { + _0 = const 42_i32; + goto -> bb4; + } + + bb4: { + StorageDead(_3); + StorageDead(_1); + return; + } + } + diff --git a/tests/mir-opt/single_use_consts.keep_parameter.SingleUseConsts.panic-abort.diff b/tests/mir-opt/single_use_consts.keep_parameter.SingleUseConsts.panic-abort.diff new file mode 100644 index 000000000000..f7d823af9e3d --- /dev/null +++ b/tests/mir-opt/single_use_consts.keep_parameter.SingleUseConsts.panic-abort.diff @@ -0,0 +1,14 @@ +- // MIR for `keep_parameter` before SingleUseConsts ++ // MIR for `keep_parameter` after SingleUseConsts + + fn keep_parameter(_1: i32) -> () { + debug other => _1; + let mut _0: (); + + bb0: { + _1 = const ::ASSOC_INT; + _0 = const (); + return; + } + } + diff --git a/tests/mir-opt/single_use_consts.keep_parameter.SingleUseConsts.panic-unwind.diff b/tests/mir-opt/single_use_consts.keep_parameter.SingleUseConsts.panic-unwind.diff new file mode 100644 index 000000000000..f7d823af9e3d --- /dev/null +++ b/tests/mir-opt/single_use_consts.keep_parameter.SingleUseConsts.panic-unwind.diff @@ -0,0 +1,14 @@ +- // MIR for `keep_parameter` before SingleUseConsts ++ // MIR for `keep_parameter` after SingleUseConsts + + fn keep_parameter(_1: i32) -> () { + debug other => _1; + let mut _0: (); + + bb0: { + _1 = const ::ASSOC_INT; + _0 = const (); + return; + } + } + diff --git a/tests/mir-opt/single_use_consts.match_const.SingleUseConsts.panic-abort.diff b/tests/mir-opt/single_use_consts.match_const.SingleUseConsts.panic-abort.diff new file mode 100644 index 000000000000..8d87438a47ae --- /dev/null +++ b/tests/mir-opt/single_use_consts.match_const.SingleUseConsts.panic-abort.diff @@ -0,0 +1,36 @@ +- // MIR for `match_const` before SingleUseConsts ++ // MIR for `match_const` after SingleUseConsts + + fn match_const() -> &str { + let mut _0: &str; + let mut _1: i32; + + bb0: { + StorageLive(_1); +- _1 = const ::ASSOC_INT; +- switchInt(_1) -> [7: bb2, 42: bb3, otherwise: bb1]; ++ nop; ++ switchInt(const ::ASSOC_INT) -> [7: bb2, 42: bb3, otherwise: bb1]; + } + + bb1: { + _0 = const "world"; + goto -> bb4; + } + + bb2: { + _0 = const "hello"; + goto -> bb4; + } + + bb3: { + _0 = const "towel"; + goto -> bb4; + } + + bb4: { + StorageDead(_1); + return; + } + } + diff --git a/tests/mir-opt/single_use_consts.match_const.SingleUseConsts.panic-unwind.diff b/tests/mir-opt/single_use_consts.match_const.SingleUseConsts.panic-unwind.diff new file mode 100644 index 000000000000..8d87438a47ae --- /dev/null +++ b/tests/mir-opt/single_use_consts.match_const.SingleUseConsts.panic-unwind.diff @@ -0,0 +1,36 @@ +- // MIR for `match_const` before SingleUseConsts ++ // MIR for `match_const` after SingleUseConsts + + fn match_const() -> &str { + let mut _0: &str; + let mut _1: i32; + + bb0: { + StorageLive(_1); +- _1 = const ::ASSOC_INT; +- switchInt(_1) -> [7: bb2, 42: bb3, otherwise: bb1]; ++ nop; ++ switchInt(const ::ASSOC_INT) -> [7: bb2, 42: bb3, otherwise: bb1]; + } + + bb1: { + _0 = const "world"; + goto -> bb4; + } + + bb2: { + _0 = const "hello"; + goto -> bb4; + } + + bb3: { + _0 = const "towel"; + goto -> bb4; + } + + bb4: { + StorageDead(_1); + return; + } + } + diff --git a/tests/mir-opt/single_use_consts.match_const_debug.SingleUseConsts.panic-abort.diff b/tests/mir-opt/single_use_consts.match_const_debug.SingleUseConsts.panic-abort.diff new file mode 100644 index 000000000000..f192f3feb96e --- /dev/null +++ b/tests/mir-opt/single_use_consts.match_const_debug.SingleUseConsts.panic-abort.diff @@ -0,0 +1,47 @@ +- // MIR for `match_const_debug` before SingleUseConsts ++ // MIR for `match_const_debug` after SingleUseConsts + + fn match_const_debug() -> &str { + let mut _0: &str; + let _1: i32; + let _2: (); + scope 1 { +- debug my_int => _1; ++ debug my_int => const ::ASSOC_INT; + } + + bb0: { + StorageLive(_1); +- _1 = const ::ASSOC_INT; ++ nop; + StorageLive(_2); + _2 = do_whatever() -> [return: bb1, unwind unreachable]; + } + + bb1: { + StorageDead(_2); +- switchInt(_1) -> [7: bb3, 42: bb4, otherwise: bb2]; ++ switchInt(const ::ASSOC_INT) -> [7: bb3, 42: bb4, otherwise: bb2]; + } + + bb2: { + _0 = const "world"; + goto -> bb5; + } + + bb3: { + _0 = const "hello"; + goto -> bb5; + } + + bb4: { + _0 = const "towel"; + goto -> bb5; + } + + bb5: { + StorageDead(_1); + return; + } + } + diff --git a/tests/mir-opt/single_use_consts.match_const_debug.SingleUseConsts.panic-unwind.diff b/tests/mir-opt/single_use_consts.match_const_debug.SingleUseConsts.panic-unwind.diff new file mode 100644 index 000000000000..261faf415f3b --- /dev/null +++ b/tests/mir-opt/single_use_consts.match_const_debug.SingleUseConsts.panic-unwind.diff @@ -0,0 +1,47 @@ +- // MIR for `match_const_debug` before SingleUseConsts ++ // MIR for `match_const_debug` after SingleUseConsts + + fn match_const_debug() -> &str { + let mut _0: &str; + let _1: i32; + let _2: (); + scope 1 { +- debug my_int => _1; ++ debug my_int => const ::ASSOC_INT; + } + + bb0: { + StorageLive(_1); +- _1 = const ::ASSOC_INT; ++ nop; + StorageLive(_2); + _2 = do_whatever() -> [return: bb1, unwind continue]; + } + + bb1: { + StorageDead(_2); +- switchInt(_1) -> [7: bb3, 42: bb4, otherwise: bb2]; ++ switchInt(const ::ASSOC_INT) -> [7: bb3, 42: bb4, otherwise: bb2]; + } + + bb2: { + _0 = const "world"; + goto -> bb5; + } + + bb3: { + _0 = const "hello"; + goto -> bb5; + } + + bb4: { + _0 = const "towel"; + goto -> bb5; + } + + bb5: { + StorageDead(_1); + return; + } + } + diff --git a/tests/mir-opt/single_use_consts.never_used_debug.SingleUseConsts.panic-abort.diff b/tests/mir-opt/single_use_consts.never_used_debug.SingleUseConsts.panic-abort.diff new file mode 100644 index 000000000000..8ef94a790a34 --- /dev/null +++ b/tests/mir-opt/single_use_consts.never_used_debug.SingleUseConsts.panic-abort.diff @@ -0,0 +1,21 @@ +- // MIR for `never_used_debug` before SingleUseConsts ++ // MIR for `never_used_debug` after SingleUseConsts + + fn never_used_debug() -> () { + let mut _0: (); + let _1: i32; + scope 1 { +- debug my_int => _1; ++ debug my_int => const ::ASSOC_INT; + } + + bb0: { + StorageLive(_1); +- _1 = const ::ASSOC_INT; ++ nop; + _0 = const (); + StorageDead(_1); + return; + } + } + diff --git a/tests/mir-opt/single_use_consts.never_used_debug.SingleUseConsts.panic-unwind.diff b/tests/mir-opt/single_use_consts.never_used_debug.SingleUseConsts.panic-unwind.diff new file mode 100644 index 000000000000..8ef94a790a34 --- /dev/null +++ b/tests/mir-opt/single_use_consts.never_used_debug.SingleUseConsts.panic-unwind.diff @@ -0,0 +1,21 @@ +- // MIR for `never_used_debug` before SingleUseConsts ++ // MIR for `never_used_debug` after SingleUseConsts + + fn never_used_debug() -> () { + let mut _0: (); + let _1: i32; + scope 1 { +- debug my_int => _1; ++ debug my_int => const ::ASSOC_INT; + } + + bb0: { + StorageLive(_1); +- _1 = const ::ASSOC_INT; ++ nop; + _0 = const (); + StorageDead(_1); + return; + } + } + diff --git a/tests/mir-opt/single_use_consts.rs b/tests/mir-opt/single_use_consts.rs new file mode 100644 index 000000000000..ecb602c647a5 --- /dev/null +++ b/tests/mir-opt/single_use_consts.rs @@ -0,0 +1,80 @@ +//@ test-mir-pass: SingleUseConsts +//@ compile-flags: -C debuginfo=full +// EMIT_MIR_FOR_EACH_PANIC_STRATEGY + +trait MyTrait { + const ASSOC_BOOL: bool; + const ASSOC_INT: i32; +} + +// EMIT_MIR single_use_consts.if_const.SingleUseConsts.diff +fn if_const() -> i32 { + // CHECK-LABEL: fn if_const( + // CHECK: switchInt(const ::ASSOC_BOOL) + if T::ASSOC_BOOL { 7 } else { 42 } +} + +// EMIT_MIR single_use_consts.match_const.SingleUseConsts.diff +fn match_const() -> &'static str { + // CHECK-LABEL: fn match_const( + // CHECK: switchInt(const ::ASSOC_INT) + match T::ASSOC_INT { + 7 => "hello", + 42 => "towel", + _ => "world", + } +} + +// EMIT_MIR single_use_consts.if_const_debug.SingleUseConsts.diff +fn if_const_debug() -> i32 { + // CHECK-LABEL: fn if_const_debug( + // CHECK: my_bool => const ::ASSOC_BOOL; + // FIXME: `if` forces a temporary (unlike `match`), so the const isn't direct + // CHECK: _3 = const ::ASSOC_BOOL; + // CHECK: switchInt(move _3) + let my_bool = T::ASSOC_BOOL; + do_whatever(); + if my_bool { 7 } else { 42 } +} + +// EMIT_MIR single_use_consts.match_const_debug.SingleUseConsts.diff +fn match_const_debug() -> &'static str { + // CHECK-LABEL: fn match_const_debug( + // CHECK: my_int => const ::ASSOC_INT; + // CHECK: switchInt(const ::ASSOC_INT) + let my_int = T::ASSOC_INT; + do_whatever(); + match my_int { + 7 => "hello", + 42 => "towel", + _ => "world", + } +} + +// EMIT_MIR single_use_consts.never_used_debug.SingleUseConsts.diff +#[allow(unused_variables)] +fn never_used_debug() { + // CHECK-LABEL: fn never_used_debug( + // CHECK: my_int => const ::ASSOC_INT; + // CHECK-NOT: ASSOC_INT + // CHECK: nop + // CHECK-NOT: ASSOC_INT + let my_int = T::ASSOC_INT; +} + +// EMIT_MIR single_use_consts.assign_const_to_return.SingleUseConsts.diff +fn assign_const_to_return() -> bool { + // CHECK-LABEL: fn assign_const_to_return( + // CHECK: _0 = const ::ASSOC_BOOL; + T::ASSOC_BOOL +} + +// EMIT_MIR single_use_consts.keep_parameter.SingleUseConsts.diff +fn keep_parameter(mut other: i32) { + // CHECK-LABEL: fn keep_parameter( + // CHECK: _1 = const ::ASSOC_INT; + // CHECK: _0 = const (); + other = T::ASSOC_INT; +} + +fn do_whatever() {} From 476f46a8e6a1778319b198dccba0579aa5a58009 Mon Sep 17 00:00:00 2001 From: Scott McMurray Date: Sun, 2 Jun 2024 20:54:15 -0700 Subject: [PATCH 42/50] Try keeping a bitset for which locals need debuginfo updates --- .../src/single_use_consts.rs | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/compiler/rustc_mir_transform/src/single_use_consts.rs b/compiler/rustc_mir_transform/src/single_use_consts.rs index 864d109e3869..93736e55996e 100644 --- a/compiler/rustc_mir_transform/src/single_use_consts.rs +++ b/compiler/rustc_mir_transform/src/single_use_consts.rs @@ -28,7 +28,8 @@ impl<'tcx> MirPass<'tcx> for SingleUseConsts { fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { let mut finder = SingleUseConstsFinder { ineligible_locals: BitSet::new_empty(body.local_decls.len()), - locations: IndexVec::new(), + locations: IndexVec::from_elem(LocationPair::new(), &body.local_decls), + locals_in_debug_info: BitSet::new_empty(body.local_decls.len()), }; finder.ineligible_locals.insert_range(..=Local::from_usize(body.arg_count)); @@ -57,8 +58,10 @@ impl<'tcx> MirPass<'tcx> for SingleUseConsts { let mut replacer = LocalReplacer { tcx, local, operand: Some(operand) }; - for var_debug_info in &mut body.var_debug_info { - replacer.visit_var_debug_info(var_debug_info); + if finder.locals_in_debug_info.contains(local) { + for var_debug_info in &mut body.var_debug_info { + replacer.visit_var_debug_info(var_debug_info); + } } let Some(use_loc) = locations.use_loc else { continue }; @@ -94,6 +97,7 @@ impl LocationPair { struct SingleUseConstsFinder { ineligible_locals: BitSet, locations: IndexVec, + locals_in_debug_info: BitSet, } impl<'tcx> Visitor<'tcx> for SingleUseConstsFinder { @@ -102,7 +106,7 @@ impl<'tcx> Visitor<'tcx> for SingleUseConstsFinder { && let Rvalue::Use(operand) = rvalue && let Operand::Constant(_) = operand { - let locations = self.locations.ensure_contains_elem(local, LocationPair::new); + let locations = &mut self.locations[local]; if locations.init_loc.is_some() { self.ineligible_locals.insert(local); } else { @@ -117,7 +121,7 @@ impl<'tcx> Visitor<'tcx> for SingleUseConstsFinder { if let Some(place) = operand.place() && let Some(local) = place.as_local() { - let locations = self.locations.ensure_contains_elem(local, LocationPair::new); + let locations = &mut self.locations[local]; if locations.use_loc.is_some() { self.ineligible_locals.insert(local); } else { @@ -138,9 +142,9 @@ impl<'tcx> Visitor<'tcx> for SingleUseConstsFinder { fn visit_var_debug_info(&mut self, var_debug_info: &VarDebugInfo<'tcx>) { if let VarDebugInfoContents::Place(place) = &var_debug_info.value - && let Some(_local) = place.as_local() + && let Some(local) = place.as_local() { - // It's a simple one that we can easily update + self.locals_in_debug_info.insert(local); } else { self.super_var_debug_info(var_debug_info); } From 8fbab183d7202880f87f6cc722d63cc4bbd1d140 Mon Sep 17 00:00:00 2001 From: Scott McMurray Date: Sun, 9 Jun 2024 23:47:41 -0700 Subject: [PATCH 43/50] Delete `ConstDebugInfo` pass --- .../src/const_debuginfo.rs | 103 ------------------ compiler/rustc_mir_transform/src/lib.rs | 2 - ...const_debuginfo.main.SingleUseConsts.diff} | 46 +++++--- tests/mir-opt/const_debuginfo.rs | 6 +- ...issue_106141.outer.Inline.panic-abort.diff | 2 +- ...ssue_106141.outer.Inline.panic-unwind.diff | 2 +- 6 files changed, 36 insertions(+), 125 deletions(-) delete mode 100644 compiler/rustc_mir_transform/src/const_debuginfo.rs rename tests/mir-opt/{const_debuginfo.main.ConstDebugInfo.diff => const_debuginfo.main.SingleUseConsts.diff} (79%) diff --git a/compiler/rustc_mir_transform/src/const_debuginfo.rs b/compiler/rustc_mir_transform/src/const_debuginfo.rs deleted file mode 100644 index c758325fb989..000000000000 --- a/compiler/rustc_mir_transform/src/const_debuginfo.rs +++ /dev/null @@ -1,103 +0,0 @@ -//! Finds locals which are assigned once to a const and unused except for debuginfo and converts -//! their debuginfo to use the const directly, allowing the local to be removed. - -use rustc_middle::{ - mir::{ - visit::{PlaceContext, Visitor}, - Body, ConstOperand, Local, Location, Operand, Rvalue, StatementKind, VarDebugInfoContents, - }, - ty::TyCtxt, -}; - -use crate::MirPass; -use rustc_index::{bit_set::BitSet, IndexVec}; - -pub struct ConstDebugInfo; - -impl<'tcx> MirPass<'tcx> for ConstDebugInfo { - fn is_enabled(&self, sess: &rustc_session::Session) -> bool { - // Disabled in favour of `SingleUseConsts` - sess.mir_opt_level() > 2 - } - - fn run_pass(&self, _tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { - trace!("running ConstDebugInfo on {:?}", body.source); - - for (local, constant) in find_optimization_opportunities(body) { - for debuginfo in &mut body.var_debug_info { - if let VarDebugInfoContents::Place(p) = debuginfo.value { - if p.local == local && p.projection.is_empty() { - trace!( - "changing debug info for {:?} from place {:?} to constant {:?}", - debuginfo.name, - p, - constant - ); - debuginfo.value = VarDebugInfoContents::Const(constant); - } - } - } - } - } -} - -struct LocalUseVisitor { - local_mutating_uses: IndexVec, - local_assignment_locations: IndexVec>, -} - -fn find_optimization_opportunities<'tcx>(body: &Body<'tcx>) -> Vec<(Local, ConstOperand<'tcx>)> { - let mut visitor = LocalUseVisitor { - local_mutating_uses: IndexVec::from_elem(0, &body.local_decls), - local_assignment_locations: IndexVec::from_elem(None, &body.local_decls), - }; - - visitor.visit_body(body); - - let mut locals_to_debuginfo = BitSet::new_empty(body.local_decls.len()); - for debuginfo in &body.var_debug_info { - if let VarDebugInfoContents::Place(p) = debuginfo.value - && let Some(l) = p.as_local() - { - locals_to_debuginfo.insert(l); - } - } - - let mut eligible_locals = Vec::new(); - for (local, mutating_uses) in visitor.local_mutating_uses.drain_enumerated(..) { - if mutating_uses != 1 || !locals_to_debuginfo.contains(local) { - continue; - } - - if let Some(location) = visitor.local_assignment_locations[local] { - let bb = &body[location.block]; - - // The value is assigned as the result of a call, not a constant - if bb.statements.len() == location.statement_index { - continue; - } - - if let StatementKind::Assign(box (p, Rvalue::Use(Operand::Constant(box c)))) = - &bb.statements[location.statement_index].kind - { - if let Some(local) = p.as_local() { - eligible_locals.push((local, *c)); - } - } - } - } - - eligible_locals -} - -impl Visitor<'_> for LocalUseVisitor { - fn visit_local(&mut self, local: Local, context: PlaceContext, location: Location) { - if context.is_mutating_use() { - self.local_mutating_uses[local] = self.local_mutating_uses[local].saturating_add(1); - - if context.is_place_assignment() { - self.local_assignment_locations[local] = Some(location); - } - } - } -} diff --git a/compiler/rustc_mir_transform/src/lib.rs b/compiler/rustc_mir_transform/src/lib.rs index 23e2c1287712..551760f4703d 100644 --- a/compiler/rustc_mir_transform/src/lib.rs +++ b/compiler/rustc_mir_transform/src/lib.rs @@ -55,7 +55,6 @@ mod remove_place_mention; // This pass is public to allow external drivers to perform MIR cleanup mod add_subtyping_projections; pub mod cleanup_post_borrowck; -mod const_debuginfo; mod copy_prop; mod coroutine; mod cost_checker; @@ -595,7 +594,6 @@ fn run_optimization_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { &simplify::SimplifyLocals::AfterGVN, &dataflow_const_prop::DataflowConstProp, &single_use_consts::SingleUseConsts, - &const_debuginfo::ConstDebugInfo, &o1(simplify_branches::SimplifyConstCondition::AfterConstProp), &jump_threading::JumpThreading, &early_otherwise_branch::EarlyOtherwiseBranch, diff --git a/tests/mir-opt/const_debuginfo.main.ConstDebugInfo.diff b/tests/mir-opt/const_debuginfo.main.SingleUseConsts.diff similarity index 79% rename from tests/mir-opt/const_debuginfo.main.ConstDebugInfo.diff rename to tests/mir-opt/const_debuginfo.main.SingleUseConsts.diff index c1529dbee13c..ac33f51984cd 100644 --- a/tests/mir-opt/const_debuginfo.main.ConstDebugInfo.diff +++ b/tests/mir-opt/const_debuginfo.main.SingleUseConsts.diff @@ -1,5 +1,5 @@ -- // MIR for `main` before ConstDebugInfo -+ // MIR for `main` after ConstDebugInfo +- // MIR for `main` before SingleUseConsts ++ // MIR for `main` after SingleUseConsts fn main() -> () { let mut _0: (); @@ -56,39 +56,53 @@ bb0: { nop; - _1 = const 1_u8; +- _1 = const 1_u8; nop; - _2 = const 2_u8; +- _2 = const 2_u8; nop; - _3 = const 3_u8; +- _3 = const 3_u8; ++ nop; ++ nop; ++ nop; StorageLive(_4); StorageLive(_5); StorageLive(_6); - _6 = const 1_u8; +- _6 = const 1_u8; ++ nop; StorageLive(_7); - _7 = const 2_u8; - _5 = const 3_u8; +- _7 = const 2_u8; +- _5 = const 3_u8; ++ nop; ++ nop; StorageDead(_7); StorageDead(_6); StorageLive(_8); - _8 = const 3_u8; - _4 = const 6_u8; +- _8 = const 3_u8; +- _4 = const 6_u8; ++ nop; ++ nop; StorageDead(_8); StorageDead(_5); StorageLive(_9); - _9 = const "hello, world!"; +- _9 = const "hello, world!"; ++ nop; StorageLive(_10); _10 = (const true, const false, const 123_u32); StorageLive(_11); - _11 = const Option::::Some(99_u16); +- _11 = const Option::::Some(99_u16); ++ nop; StorageLive(_12); - _12 = const Point {{ x: 32_u32, y: 32_u32 }}; +- _12 = const Point {{ x: 32_u32, y: 32_u32 }}; ++ nop; StorageLive(_13); nop; - _14 = const 32_u32; +- _14 = const 32_u32; ++ nop; StorageLive(_15); - _15 = const 32_u32; - _13 = const 64_u32; +- _15 = const 32_u32; +- _13 = const 64_u32; ++ nop; ++ nop; StorageDead(_15); nop; _0 = const (); diff --git a/tests/mir-opt/const_debuginfo.rs b/tests/mir-opt/const_debuginfo.rs index b880d7e07a6e..907d7fef0674 100644 --- a/tests/mir-opt/const_debuginfo.rs +++ b/tests/mir-opt/const_debuginfo.rs @@ -1,12 +1,14 @@ -//@ test-mir-pass: ConstDebugInfo +//@ test-mir-pass: SingleUseConsts //@ compile-flags: -C overflow-checks=no -Zmir-enable-passes=+GVN +#![allow(unused)] + struct Point { x: u32, y: u32, } -// EMIT_MIR const_debuginfo.main.ConstDebugInfo.diff +// EMIT_MIR const_debuginfo.main.SingleUseConsts.diff fn main() { // CHECK-LABEL: fn main( // CHECK: debug x => const 1_u8; diff --git a/tests/mir-opt/inline/issue_106141.outer.Inline.panic-abort.diff b/tests/mir-opt/inline/issue_106141.outer.Inline.panic-abort.diff index 24e5587f9632..2ab79cc2a509 100644 --- a/tests/mir-opt/inline/issue_106141.outer.Inline.panic-abort.diff +++ b/tests/mir-opt/inline/issue_106141.outer.Inline.panic-abort.diff @@ -8,7 +8,7 @@ + let mut _2: bool; + let mut _3: bool; + scope 2 { -+ debug buffer => const inner::promoted[0]; ++ debug buffer => _1; + scope 3 { + debug index => _0; + } diff --git a/tests/mir-opt/inline/issue_106141.outer.Inline.panic-unwind.diff b/tests/mir-opt/inline/issue_106141.outer.Inline.panic-unwind.diff index 4eb8a5c98473..4d96a8628859 100644 --- a/tests/mir-opt/inline/issue_106141.outer.Inline.panic-unwind.diff +++ b/tests/mir-opt/inline/issue_106141.outer.Inline.panic-unwind.diff @@ -8,7 +8,7 @@ + let mut _2: bool; + let mut _3: bool; + scope 2 { -+ debug buffer => const inner::promoted[0]; ++ debug buffer => _1; + scope 3 { + debug index => _0; + } From 91f5530b2db1ea992d4e5c3ef214609d6e9145c1 Mon Sep 17 00:00:00 2001 From: binarycat Date: Sun, 9 Jun 2024 22:37:05 -0400 Subject: [PATCH 44/50] migrate tests/run-make/llvm-outputs to use rmake.rs part of #121876 --- src/tools/run-make-support/src/rustc.rs | 7 +++++++ .../tidy/src/allowed_run_make_makefiles.txt | 1 - tests/run-make/llvm-outputs/Makefile | 5 ----- tests/run-make/llvm-outputs/rmake.rs | 20 +++++++++++++++++++ 4 files changed, 27 insertions(+), 6 deletions(-) delete mode 100644 tests/run-make/llvm-outputs/Makefile create mode 100644 tests/run-make/llvm-outputs/rmake.rs diff --git a/src/tools/run-make-support/src/rustc.rs b/src/tools/run-make-support/src/rustc.rs index d4c00d23b8b1..5ea231442bc2 100644 --- a/src/tools/run-make-support/src/rustc.rs +++ b/src/tools/run-make-support/src/rustc.rs @@ -107,6 +107,13 @@ impl Rustc { self } + /// Specify path to the output directory. Equivalent to `--out-dir`` in rustc. + pub fn out_dir>(&mut self, path: P) -> &mut Self { + self.cmd.arg("--out-dir"); + self.cmd.arg(path.as_ref()); + self + } + /// This flag defers LTO optimizations to the linker. pub fn linker_plugin_lto(&mut self, option: &str) -> &mut Self { self.cmd.arg(format!("-Clinker-plugin-lto={option}")); diff --git a/src/tools/tidy/src/allowed_run_make_makefiles.txt b/src/tools/tidy/src/allowed_run_make_makefiles.txt index a015f96ae51d..babf1abbe64a 100644 --- a/src/tools/tidy/src/allowed_run_make_makefiles.txt +++ b/src/tools/tidy/src/allowed_run_make_makefiles.txt @@ -122,7 +122,6 @@ run-make/link-framework/Makefile run-make/link-path-order/Makefile run-make/linkage-attr-on-static/Makefile run-make/llvm-ident/Makefile -run-make/llvm-outputs/Makefile run-make/long-linker-command-lines-cmd-exe/Makefile run-make/long-linker-command-lines/Makefile run-make/longjmp-across-rust/Makefile diff --git a/tests/run-make/llvm-outputs/Makefile b/tests/run-make/llvm-outputs/Makefile deleted file mode 100644 index cccf1dd66fb9..000000000000 --- a/tests/run-make/llvm-outputs/Makefile +++ /dev/null @@ -1,5 +0,0 @@ -include ../tools.mk - -all: - echo 'fn main() {}' | $(BARE_RUSTC) - --out-dir=$(TMPDIR)/random_directory_that_does_not_exist_ir/ --emit=llvm-ir - echo 'fn main() {}' | $(BARE_RUSTC) - --out-dir=$(TMPDIR)/random_directory_that_does_not_exist_bc/ --emit=llvm-bc diff --git a/tests/run-make/llvm-outputs/rmake.rs b/tests/run-make/llvm-outputs/rmake.rs new file mode 100644 index 000000000000..2dc3030ca91b --- /dev/null +++ b/tests/run-make/llvm-outputs/rmake.rs @@ -0,0 +1,20 @@ +// test that directories get created when emitting llvm bitcode and IR + +use run_make_support::{cwd, run_in_tmpdir, rustc}; +use std::path::PathBuf; + +fn main() { + let mut path_bc = PathBuf::new(); + let mut path_ir = PathBuf::new(); + run_in_tmpdir(|| { + let p = cwd(); + path_bc = p.join("nonexistant_dir_bc"); + path_ir = p.join("nonexistant_dir_ir"); + rustc().input("-").stdin("fn main() {}").out_dir(&path_bc).emit("llvm-bc").run(); + rustc().input("-").stdin("fn main() {}").out_dir(&path_ir).emit("llvm-ir").run(); + assert!(path_bc.exists()); + assert!(path_ir.exists()); + }); + assert!(!path_bc.exists()); + assert!(!path_ir.exists()); +} From 29629d0075c13b9c22b624ca29cc19c512ecb16a Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Wed, 5 Jun 2024 13:37:19 +1000 Subject: [PATCH 45/50] Remove some unused crate dependencies. I found these by setting the `unused_crate_dependencies` lint temporarily to `Warn`. --- Cargo.lock | 19 ------------------- compiler/rustc_ast_ir/Cargo.toml | 1 - compiler/rustc_baked_icu_data/Cargo.toml | 1 - compiler/rustc_data_structures/Cargo.toml | 3 +-- compiler/rustc_driver_impl/Cargo.toml | 1 - compiler/rustc_index_macros/Cargo.toml | 3 +-- compiler/rustc_middle/Cargo.toml | 3 +-- compiler/rustc_mir_build/Cargo.toml | 2 -- compiler/rustc_next_trait_solver/Cargo.toml | 15 +-------------- compiler/rustc_query_impl/Cargo.toml | 3 +-- compiler/stable_mir/Cargo.toml | 1 - library/test/Cargo.toml | 2 -- 12 files changed, 5 insertions(+), 49 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 58d95f927bf9..ba8b2c270059 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3627,7 +3627,6 @@ dependencies = [ "rustc_macros", "rustc_serialize", "rustc_span", - "smallvec", ] [[package]] @@ -3708,7 +3707,6 @@ dependencies = [ "icu_locid", "icu_locid_transform", "icu_provider", - "icu_provider_adapters", "zerovec", ] @@ -3889,7 +3887,6 @@ dependencies = [ "portable-atomic", "rustc-hash", "rustc-rayon", - "rustc-rayon-core", "rustc_arena", "rustc_graphviz", "rustc_index", @@ -3930,7 +3927,6 @@ dependencies = [ "rustc_expand", "rustc_feature", "rustc_fluent_macro", - "rustc_hir", "rustc_hir_analysis", "rustc_hir_pretty", "rustc_hir_typeck", @@ -4193,7 +4189,6 @@ dependencies = [ "proc-macro2", "quote", "syn 2.0.66", - "synstructure", ] [[package]] @@ -4385,7 +4380,6 @@ dependencies = [ "field-offset", "gsgdt", "polonius-engine", - "rustc-rayon", "rustc-rayon-core", "rustc_apfloat", "rustc_arena", @@ -4417,7 +4411,6 @@ dependencies = [ name = "rustc_mir_build" version = "0.0.0" dependencies = [ - "either", "itertools 0.12.1", "rustc_apfloat", "rustc_arena", @@ -4436,7 +4429,6 @@ dependencies = [ "rustc_span", "rustc_target", "rustc_trait_selection", - "smallvec", "tracing", ] @@ -4511,14 +4503,7 @@ dependencies = [ name = "rustc_next_trait_solver" version = "0.0.0" dependencies = [ - "derivative", - "rustc_ast_ir", - "rustc_data_structures", - "rustc_macros", - "rustc_serialize", "rustc_type_ir", - "rustc_type_ir_macros", - "tracing", ] [[package]] @@ -4623,7 +4608,6 @@ version = "0.0.0" dependencies = [ "field-offset", "measureme", - "rustc-rayon-core", "rustc_data_structures", "rustc_errors", "rustc_hir", @@ -5329,7 +5313,6 @@ name = "stable_mir" version = "0.1.0-preview" dependencies = [ "scoped-tls", - "tracing", ] [[package]] @@ -5625,8 +5608,6 @@ dependencies = [ "core", "getopts", "libc", - "panic_abort", - "panic_unwind", "std", ] diff --git a/compiler/rustc_ast_ir/Cargo.toml b/compiler/rustc_ast_ir/Cargo.toml index e761b7adad3f..a78c91e0615b 100644 --- a/compiler/rustc_ast_ir/Cargo.toml +++ b/compiler/rustc_ast_ir/Cargo.toml @@ -9,7 +9,6 @@ rustc_data_structures = { path = "../rustc_data_structures", optional = true } rustc_macros = { path = "../rustc_macros", optional = true } rustc_serialize = { path = "../rustc_serialize", optional = true } rustc_span = { path = "../rustc_span", optional = true } -smallvec = { version = "1.8.1" } # tidy-alphabetical-end [features] diff --git a/compiler/rustc_baked_icu_data/Cargo.toml b/compiler/rustc_baked_icu_data/Cargo.toml index 48af4e6f600b..e6cfb4887c91 100644 --- a/compiler/rustc_baked_icu_data/Cargo.toml +++ b/compiler/rustc_baked_icu_data/Cargo.toml @@ -9,7 +9,6 @@ icu_list = "1.2" icu_locid = "1.2" icu_locid_transform = "1.3.2" icu_provider = "1.2" -icu_provider_adapters = "1.2" zerovec = "0.10.0" # tidy-alphabetical-end diff --git a/compiler/rustc_data_structures/Cargo.toml b/compiler/rustc_data_structures/Cargo.toml index 2b61e17efa28..6876046a5838 100644 --- a/compiler/rustc_data_structures/Cargo.toml +++ b/compiler/rustc_data_structures/Cargo.toml @@ -16,7 +16,6 @@ libc = "0.2" measureme = "11" rustc-hash = "1.1.0" rustc-rayon = { version = "0.5.0", optional = true } -rustc-rayon-core = { version = "0.5.0", optional = true } rustc_arena = { path = "../rustc_arena" } rustc_graphviz = { path = "../rustc_graphviz" } rustc_index = { path = "../rustc_index", package = "rustc_index" } @@ -52,5 +51,5 @@ portable-atomic = "1.5.1" [features] # tidy-alphabetical-start -rustc_use_parallel_compiler = ["indexmap/rustc-rayon", "rustc-rayon", "rustc-rayon-core"] +rustc_use_parallel_compiler = ["indexmap/rustc-rayon", "rustc-rayon"] # tidy-alphabetical-end diff --git a/compiler/rustc_driver_impl/Cargo.toml b/compiler/rustc_driver_impl/Cargo.toml index 5f7504add8d6..91cbffcd7072 100644 --- a/compiler/rustc_driver_impl/Cargo.toml +++ b/compiler/rustc_driver_impl/Cargo.toml @@ -19,7 +19,6 @@ rustc_errors = { path = "../rustc_errors" } rustc_expand = { path = "../rustc_expand" } rustc_feature = { path = "../rustc_feature" } rustc_fluent_macro = { path = "../rustc_fluent_macro" } -rustc_hir = { path = "../rustc_hir" } rustc_hir_analysis = { path = "../rustc_hir_analysis" } rustc_hir_pretty = { path = "../rustc_hir_pretty" } rustc_hir_typeck = { path = "../rustc_hir_typeck" } diff --git a/compiler/rustc_index_macros/Cargo.toml b/compiler/rustc_index_macros/Cargo.toml index c4ca29db3c2d..07ee81788ce4 100644 --- a/compiler/rustc_index_macros/Cargo.toml +++ b/compiler/rustc_index_macros/Cargo.toml @@ -7,11 +7,10 @@ edition = "2021" proc-macro = true [dependencies] -synstructure = "0.13.0" syn = { version = "2.0.9", features = ["full"] } proc-macro2 = "1" quote = "1" [features] default = ["nightly"] -nightly = [] \ No newline at end of file +nightly = [] diff --git a/compiler/rustc_middle/Cargo.toml b/compiler/rustc_middle/Cargo.toml index d1cdabc293dd..3dc592980fdb 100644 --- a/compiler/rustc_middle/Cargo.toml +++ b/compiler/rustc_middle/Cargo.toml @@ -11,7 +11,6 @@ either = "1.5.0" field-offset = "0.3.5" gsgdt = "0.1.2" polonius-engine = "0.13.0" -rustc-rayon = { version = "0.5.0", optional = true } rustc-rayon-core = { version = "0.5.0", optional = true } rustc_apfloat = "0.2.0" rustc_arena = { path = "../rustc_arena" } @@ -41,5 +40,5 @@ tracing = "0.1" [features] # tidy-alphabetical-start -rustc_use_parallel_compiler = ["rustc-rayon", "rustc-rayon-core"] +rustc_use_parallel_compiler = ["rustc-rayon-core"] # tidy-alphabetical-end diff --git a/compiler/rustc_mir_build/Cargo.toml b/compiler/rustc_mir_build/Cargo.toml index 77f27236437d..5d828d0093f3 100644 --- a/compiler/rustc_mir_build/Cargo.toml +++ b/compiler/rustc_mir_build/Cargo.toml @@ -5,7 +5,6 @@ edition = "2021" [dependencies] # tidy-alphabetical-start -either = "1" itertools = "0.12" rustc_apfloat = "0.2.0" rustc_arena = { path = "../rustc_arena" } @@ -24,6 +23,5 @@ rustc_session = { path = "../rustc_session" } rustc_span = { path = "../rustc_span" } rustc_target = { path = "../rustc_target" } rustc_trait_selection = { path = "../rustc_trait_selection" } -smallvec = { version = "1.8.1", features = ["union", "may_dangle"] } tracing = "0.1" # tidy-alphabetical-end diff --git a/compiler/rustc_next_trait_solver/Cargo.toml b/compiler/rustc_next_trait_solver/Cargo.toml index c30d21fd7843..50dbc991f8fd 100644 --- a/compiler/rustc_next_trait_solver/Cargo.toml +++ b/compiler/rustc_next_trait_solver/Cargo.toml @@ -5,22 +5,9 @@ edition = "2021" [dependencies] # tidy-alphabetical-start -derivative = "2.2.0" -rustc_ast_ir = { path = "../rustc_ast_ir", default-features = false } -rustc_data_structures = { path = "../rustc_data_structures", optional = true } -rustc_macros = { path = "../rustc_macros", optional = true } -rustc_serialize = { path = "../rustc_serialize", optional = true } rustc_type_ir = { path = "../rustc_type_ir", default-features = false } -rustc_type_ir_macros = { path = "../rustc_type_ir_macros" } -tracing = "0.1" # tidy-alphabetical-end [features] default = ["nightly"] -nightly = [ - "rustc_type_ir/nightly", - "rustc_macros", - "rustc_serialize", - "rustc_data_structures", - "rustc_ast_ir/nightly", -] +nightly = ["rustc_type_ir/nightly"] diff --git a/compiler/rustc_query_impl/Cargo.toml b/compiler/rustc_query_impl/Cargo.toml index c57f22a0da2b..2bb1be22b985 100644 --- a/compiler/rustc_query_impl/Cargo.toml +++ b/compiler/rustc_query_impl/Cargo.toml @@ -7,7 +7,6 @@ edition = "2021" # tidy-alphabetical-start field-offset = "0.3.5" measureme = "11" -rustc-rayon-core = { version = "0.5.0", optional = true } rustc_data_structures = { path = "../rustc_data_structures" } rustc_errors = { path = "../rustc_errors" } rustc_hir = { path = "../rustc_hir" } @@ -23,5 +22,5 @@ tracing = "0.1" [features] # tidy-alphabetical-start -rustc_use_parallel_compiler = ["rustc-rayon-core", "rustc_query_system/rustc_use_parallel_compiler"] +rustc_use_parallel_compiler = ["rustc_query_system/rustc_use_parallel_compiler"] # tidy-alphabetical-end diff --git a/compiler/stable_mir/Cargo.toml b/compiler/stable_mir/Cargo.toml index c61e217bf9f0..4ed611527365 100644 --- a/compiler/stable_mir/Cargo.toml +++ b/compiler/stable_mir/Cargo.toml @@ -4,5 +4,4 @@ version = "0.1.0-preview" edition = "2021" [dependencies] -tracing = "0.1" scoped-tls = "1.0" diff --git a/library/test/Cargo.toml b/library/test/Cargo.toml index 0e2409f63ab1..75cc7c00e389 100644 --- a/library/test/Cargo.toml +++ b/library/test/Cargo.toml @@ -7,8 +7,6 @@ edition = "2021" getopts = { version = "0.2.21", features = ['rustc-dep-of-std'] } std = { path = "../std" } core = { path = "../core" } -panic_unwind = { path = "../panic_unwind" } -panic_abort = { path = "../panic_abort" } [target.'cfg(not(all(windows, target_env = "msvc")))'.dependencies] libc = { version = "0.2.150", default-features = false } From faac70b66e5135717a651dd3f13e6504e7b0c8c9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Mon, 10 Jun 2024 12:41:52 +0200 Subject: [PATCH 46/50] Update `rustc-perf` submodule before running tidy --- src/bootstrap/src/core/build_steps/test.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/bootstrap/src/core/build_steps/test.rs b/src/bootstrap/src/core/build_steps/test.rs index fb7b40b73212..29cd90222b25 100644 --- a/src/bootstrap/src/core/build_steps/test.rs +++ b/src/bootstrap/src/core/build_steps/test.rs @@ -1101,6 +1101,8 @@ impl Step for Tidy { /// Once tidy passes, this step also runs `fmt --check` if tests are being run /// for the `dev` or `nightly` channels. fn run(self, builder: &Builder<'_>) { + builder.build.update_submodule(Path::new("src/tools/rustc-perf")); + let mut cmd = builder.tool_cmd(Tool::Tidy); cmd.arg(&builder.src); cmd.arg(&builder.initial_cargo); From 256387b63e33edf3517157fa737ee4369d9d3e3f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=AE=B8=E6=9D=B0=E5=8F=8B=20Jieyou=20Xu=20=28Joe=29?= Date: Mon, 10 Jun 2024 10:09:48 +0000 Subject: [PATCH 47/50] run-make: add run_in_tmpdir self-test --- .../run-make/run-in-tmpdir-self-test/rmake.rs | 38 +++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 tests/run-make/run-in-tmpdir-self-test/rmake.rs diff --git a/tests/run-make/run-in-tmpdir-self-test/rmake.rs b/tests/run-make/run-in-tmpdir-self-test/rmake.rs new file mode 100644 index 000000000000..83b99bfe8632 --- /dev/null +++ b/tests/run-make/run-in-tmpdir-self-test/rmake.rs @@ -0,0 +1,38 @@ +//! This is a self-test for the `run_in_tmpdir` helper in the support library. This test tries to +//! check that files and directories created within the temporary directory gets properly cleared +//! when returning from the closure. + +use std::fs; +use std::path::{Path, PathBuf}; + +use run_make_support::{cwd, run_in_tmpdir}; + +fn main() { + let mut file_path = PathBuf::new(); + let mut dir_path = PathBuf::new(); + let mut readonly_file_path = PathBuf::new(); + let test_cwd = cwd(); + run_in_tmpdir(|| { + assert_ne!(test_cwd, cwd(), "test cwd should not be the same as tmpdir cwd"); + + file_path = cwd().join("foo.txt"); + fs::write(&file_path, "hi").unwrap(); + + dir_path = cwd().join("bar"); + fs::create_dir_all(&dir_path).unwrap(); + + readonly_file_path = cwd().join("readonly-file.txt"); + fs::write(&readonly_file_path, "owo").unwrap(); + let mut perms = fs::metadata(&readonly_file_path).unwrap().permissions(); + perms.set_readonly(true); + fs::set_permissions(&mut readonly_file_path, perms).unwrap(); + + assert!(file_path.exists()); + assert!(dir_path.exists()); + assert!(readonly_file_path.exists()); + }); + assert!(!file_path.exists()); + assert!(!dir_path.exists()); + assert!(!readonly_file_path.exists()); + assert_eq!(test_cwd, cwd(), "test cwd is not correctly restored"); +} From 3c57ea0df79c8ee2ad1ff99881f80ab87b186935 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sat, 8 Jun 2024 16:13:45 +0200 Subject: [PATCH 48/50] ScalarInt: size mismatches are a bug, do not delay the panic --- .../rustc_codegen_cranelift/src/constant.rs | 6 +- .../src/intrinsics/llvm_x86.rs | 10 +- .../src/intrinsics/simd.rs | 11 +- .../src/value_and_place.rs | 4 +- compiler/rustc_codegen_gcc/src/common.rs | 2 +- compiler/rustc_codegen_llvm/src/common.rs | 2 +- compiler/rustc_codegen_llvm/src/intrinsic.rs | 2 +- compiler/rustc_codegen_ssa/src/common.rs | 2 +- .../src/const_eval/valtrees.rs | 8 +- .../src/interpret/discriminant.rs | 15 +- .../src/interpret/intrinsics.rs | 2 +- .../rustc_const_eval/src/interpret/memory.rs | 2 +- .../rustc_const_eval/src/interpret/operand.rs | 17 +- .../src/interpret/operator.rs | 8 +- .../src/interpret/validity.rs | 4 +- compiler/rustc_hir_typeck/src/pat.rs | 5 +- compiler/rustc_middle/src/mir/consts.rs | 14 +- .../rustc_middle/src/mir/interpret/value.rs | 33 +-- compiler/rustc_middle/src/thir.rs | 4 +- compiler/rustc_middle/src/ty/consts.rs | 6 +- compiler/rustc_middle/src/ty/consts/int.rs | 258 ++++++++---------- .../rustc_middle/src/ty/consts/valtree.rs | 9 +- compiler/rustc_middle/src/ty/print/pretty.rs | 4 +- compiler/rustc_mir_build/src/build/mod.rs | 15 +- compiler/rustc_mir_build/src/thir/constant.rs | 8 +- .../src/thir/pattern/const_to_pat.rs | 7 +- .../src/dataflow_const_prop.rs | 6 +- compiler/rustc_mir_transform/src/gvn.rs | 6 +- .../src/known_panics_lint.rs | 18 +- .../rustc_mir_transform/src/match_branches.rs | 2 +- .../rustc_mir_transform/src/promote_consts.rs | 6 +- .../src/simplify_comparison_integral.rs | 2 +- compiler/rustc_mir_transform/src/validate.rs | 6 +- compiler/rustc_pattern_analysis/src/rustc.rs | 9 +- compiler/rustc_transmute/src/layout/tree.rs | 2 +- compiler/rustc_ty_utils/src/consts.rs | 2 +- src/librustdoc/clean/utils.rs | 3 +- .../clippy_lints/src/large_const_arrays.rs | 2 +- .../clippy_lints/src/large_stack_arrays.rs | 2 +- .../clippy/clippy_lints/src/non_copy_const.rs | 2 +- .../src/zero_repeat_side_effects.rs | 3 +- src/tools/clippy/clippy_utils/src/consts.rs | 4 +- src/tools/clippy/clippy_utils/src/ty.rs | 20 +- src/tools/miri/src/intrinsics/simd.rs | 3 +- src/tools/miri/src/shims/unix/socket.rs | 4 +- 45 files changed, 247 insertions(+), 313 deletions(-) diff --git a/compiler/rustc_codegen_cranelift/src/constant.rs b/compiler/rustc_codegen_cranelift/src/constant.rs index ba98f2e772cb..a53598018f4a 100644 --- a/compiler/rustc_codegen_cranelift/src/constant.rs +++ b/compiler/rustc_codegen_cranelift/src/constant.rs @@ -110,7 +110,7 @@ pub(crate) fn codegen_const_value<'tcx>( if fx.clif_type(layout.ty).is_some() { return CValue::const_val(fx, layout, int); } else { - let raw_val = int.size().truncate(int.assert_bits(int.size())); + let raw_val = int.size().truncate(int.to_bits(int.size())); let val = match int.size().bytes() { 1 => fx.bcx.ins().iconst(types::I8, raw_val as i64), 2 => fx.bcx.ins().iconst(types::I16, raw_val as i64), @@ -501,12 +501,12 @@ pub(crate) fn mir_operand_get_const_val<'tcx>( Ordering::Equal => scalar_int, Ordering::Less => match ty.kind() { ty::Uint(_) => ScalarInt::try_from_uint( - scalar_int.assert_uint(scalar_int.size()), + scalar_int.to_uint(scalar_int.size()), fx.layout_of(*ty).size, ) .unwrap(), ty::Int(_) => ScalarInt::try_from_int( - scalar_int.assert_int(scalar_int.size()), + scalar_int.to_int(scalar_int.size()), fx.layout_of(*ty).size, ) .unwrap(), diff --git a/compiler/rustc_codegen_cranelift/src/intrinsics/llvm_x86.rs b/compiler/rustc_codegen_cranelift/src/intrinsics/llvm_x86.rs index 27b55ecc72ee..d454f3c1de7e 100644 --- a/compiler/rustc_codegen_cranelift/src/intrinsics/llvm_x86.rs +++ b/compiler/rustc_codegen_cranelift/src/intrinsics/llvm_x86.rs @@ -902,7 +902,7 @@ pub(crate) fn codegen_x86_llvm_intrinsic_call<'tcx>( .span_fatal(span, "Index argument for `_mm_cmpestri` is not a constant"); }; - let imm8 = imm8.try_to_u8().unwrap_or_else(|_| panic!("kind not scalar: {:?}", imm8)); + let imm8 = imm8.to_u8(); codegen_inline_asm_inner( fx, @@ -955,7 +955,7 @@ pub(crate) fn codegen_x86_llvm_intrinsic_call<'tcx>( .span_fatal(span, "Index argument for `_mm_cmpestrm` is not a constant"); }; - let imm8 = imm8.try_to_u8().unwrap_or_else(|_| panic!("kind not scalar: {:?}", imm8)); + let imm8 = imm8.to_u8(); codegen_inline_asm_inner( fx, @@ -1003,7 +1003,7 @@ pub(crate) fn codegen_x86_llvm_intrinsic_call<'tcx>( ); }; - let imm8 = imm8.try_to_u8().unwrap_or_else(|_| panic!("kind not scalar: {:?}", imm8)); + let imm8 = imm8.to_u8(); codegen_inline_asm_inner( fx, @@ -1040,7 +1040,7 @@ pub(crate) fn codegen_x86_llvm_intrinsic_call<'tcx>( ); }; - let imm8 = imm8.try_to_u8().unwrap_or_else(|_| panic!("kind not scalar: {:?}", imm8)); + let imm8 = imm8.to_u8(); codegen_inline_asm_inner( fx, @@ -1195,7 +1195,7 @@ pub(crate) fn codegen_x86_llvm_intrinsic_call<'tcx>( .span_fatal(span, "Func argument for `_mm_sha1rnds4_epu32` is not a constant"); }; - let func = func.try_to_u8().unwrap_or_else(|_| panic!("kind not scalar: {:?}", func)); + let func = func.to_u8(); codegen_inline_asm_inner( fx, diff --git a/compiler/rustc_codegen_cranelift/src/intrinsics/simd.rs b/compiler/rustc_codegen_cranelift/src/intrinsics/simd.rs index 65eeaf156d84..ca910dccb0d0 100644 --- a/compiler/rustc_codegen_cranelift/src/intrinsics/simd.rs +++ b/compiler/rustc_codegen_cranelift/src/intrinsics/simd.rs @@ -147,8 +147,7 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>( let total_len = lane_count * 2; - let indexes = - idx.iter().map(|idx| idx.unwrap_leaf().try_to_u32().unwrap()).collect::>(); + let indexes = idx.iter().map(|idx| idx.unwrap_leaf().to_u32()).collect::>(); for &idx in &indexes { assert!(u64::from(idx) < total_len, "idx {} out of range 0..{}", idx, total_len); @@ -282,9 +281,7 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>( fx.tcx.dcx().span_fatal(span, "Index argument for `simd_insert` is not a constant"); }; - let idx: u32 = idx_const - .try_to_u32() - .unwrap_or_else(|_| panic!("kind not scalar: {:?}", idx_const)); + let idx: u32 = idx_const.to_u32(); let (lane_count, _lane_ty) = base.layout().ty.simd_size_and_type(fx.tcx); if u64::from(idx) >= lane_count { fx.tcx.dcx().span_fatal( @@ -330,9 +327,7 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>( return; }; - let idx = idx_const - .try_to_u32() - .unwrap_or_else(|_| panic!("kind not scalar: {:?}", idx_const)); + let idx = idx_const.to_u32(); let (lane_count, _lane_ty) = v.layout().ty.simd_size_and_type(fx.tcx); if u64::from(idx) >= lane_count { fx.tcx.dcx().span_fatal( diff --git a/compiler/rustc_codegen_cranelift/src/value_and_place.rs b/compiler/rustc_codegen_cranelift/src/value_and_place.rs index 512a96450a4b..1aa28daeafc7 100644 --- a/compiler/rustc_codegen_cranelift/src/value_and_place.rs +++ b/compiler/rustc_codegen_cranelift/src/value_and_place.rs @@ -327,7 +327,7 @@ impl<'tcx> CValue<'tcx> { let val = match layout.ty.kind() { ty::Uint(UintTy::U128) | ty::Int(IntTy::I128) => { - let const_val = const_val.assert_bits(layout.size); + let const_val = const_val.to_bits(layout.size); let lsb = fx.bcx.ins().iconst(types::I64, const_val as u64 as i64); let msb = fx.bcx.ins().iconst(types::I64, (const_val >> 64) as u64 as i64); fx.bcx.ins().iconcat(lsb, msb) @@ -339,7 +339,7 @@ impl<'tcx> CValue<'tcx> { | ty::Ref(..) | ty::RawPtr(..) | ty::FnPtr(..) => { - let raw_val = const_val.size().truncate(const_val.assert_bits(layout.size)); + let raw_val = const_val.size().truncate(const_val.to_bits(layout.size)); fx.bcx.ins().iconst(clif_ty, raw_val as i64) } ty::Float(FloatTy::F32) => { diff --git a/compiler/rustc_codegen_gcc/src/common.rs b/compiler/rustc_codegen_gcc/src/common.rs index 78d943192db0..548c23cc7948 100644 --- a/compiler/rustc_codegen_gcc/src/common.rs +++ b/compiler/rustc_codegen_gcc/src/common.rs @@ -166,7 +166,7 @@ impl<'gcc, 'tcx> ConstMethods<'tcx> for CodegenCx<'gcc, 'tcx> { let bitsize = if layout.is_bool() { 1 } else { layout.size(self).bits() }; match cv { Scalar::Int(int) => { - let data = int.assert_bits(layout.size(self)); + let data = int.to_bits(layout.size(self)); // FIXME(antoyo): there's some issues with using the u128 code that follows, so hard-code // the paths for floating-point values. diff --git a/compiler/rustc_codegen_llvm/src/common.rs b/compiler/rustc_codegen_llvm/src/common.rs index ab8036a1410f..4ffc92eb6335 100644 --- a/compiler/rustc_codegen_llvm/src/common.rs +++ b/compiler/rustc_codegen_llvm/src/common.rs @@ -244,7 +244,7 @@ impl<'ll, 'tcx> ConstMethods<'tcx> for CodegenCx<'ll, 'tcx> { let bitsize = if layout.is_bool() { 1 } else { layout.size(self).bits() }; match cv { Scalar::Int(int) => { - let data = int.assert_bits(layout.size(self)); + let data = int.to_bits(layout.size(self)); let llval = self.const_uint_big(self.type_ix(bitsize), data); if matches!(layout.primitive(), Pointer(_)) { unsafe { llvm::LLVMConstIntToPtr(llval, llty) } diff --git a/compiler/rustc_codegen_llvm/src/intrinsic.rs b/compiler/rustc_codegen_llvm/src/intrinsic.rs index 7b1038d56176..5622c5e24200 100644 --- a/compiler/rustc_codegen_llvm/src/intrinsic.rs +++ b/compiler/rustc_codegen_llvm/src/intrinsic.rs @@ -1221,7 +1221,7 @@ fn generic_simd_intrinsic<'ll, 'tcx>( .iter() .enumerate() .map(|(arg_idx, val)| { - let idx = val.unwrap_leaf().try_to_i32().unwrap(); + let idx = val.unwrap_leaf().to_i32(); if idx >= i32::try_from(total_len).unwrap() { bx.sess().dcx().emit_err(InvalidMonomorphization::SimdIndexOutOfBounds { span, diff --git a/compiler/rustc_codegen_ssa/src/common.rs b/compiler/rustc_codegen_ssa/src/common.rs index e4a36b3f5918..27b0f127e926 100644 --- a/compiler/rustc_codegen_ssa/src/common.rs +++ b/compiler/rustc_codegen_ssa/src/common.rs @@ -163,7 +163,7 @@ pub fn asm_const_to_str<'tcx>( let mir::ConstValue::Scalar(scalar) = const_value else { span_bug!(sp, "expected Scalar for promoted asm const, but got {:#?}", const_value) }; - let value = scalar.assert_bits(ty_and_layout.size); + let value = scalar.assert_scalar_int().to_bits(ty_and_layout.size); match ty_and_layout.ty.kind() { ty::Uint(_) => value.to_string(), ty::Int(int_ty) => match int_ty.normalize(tcx.sess.target.pointer_width) { diff --git a/compiler/rustc_const_eval/src/const_eval/valtrees.rs b/compiler/rustc_const_eval/src/const_eval/valtrees.rs index 5312f1f946f5..66993476bef4 100644 --- a/compiler/rustc_const_eval/src/const_eval/valtrees.rs +++ b/compiler/rustc_const_eval/src/const_eval/valtrees.rs @@ -95,10 +95,10 @@ fn const_to_valtree_inner<'tcx>( } ty::Bool | ty::Int(_) | ty::Uint(_) | ty::Float(_) | ty::Char => { let val = ecx.read_immediate(place)?; - let val = val.to_scalar(); + let val = val.to_scalar_int().unwrap(); *num_nodes += 1; - Ok(ty::ValTree::Leaf(val.assert_int())) + Ok(ty::ValTree::Leaf(val)) } ty::Pat(base, ..) => { @@ -125,7 +125,7 @@ fn const_to_valtree_inner<'tcx>( let val = val.to_scalar(); // We are in the CTFE machine, so ptr-to-int casts will fail. // This can only be `Ok` if `val` already is an integer. - let Ok(val) = val.try_to_int() else { + let Ok(val) = val.try_to_scalar_int() else { return Err(ValTreeCreationError::NonSupportedType); }; // It's just a ScalarInt! @@ -411,7 +411,7 @@ fn valtree_into_mplace<'tcx>( ty::Adt(def, _) if def.is_enum() => { // First element of valtree corresponds to variant let scalar_int = branches[0].unwrap_leaf(); - let variant_idx = VariantIdx::from_u32(scalar_int.try_to_u32().unwrap()); + let variant_idx = VariantIdx::from_u32(scalar_int.to_u32()); let variant = def.variant(variant_idx); debug!(?variant); diff --git a/compiler/rustc_const_eval/src/interpret/discriminant.rs b/compiler/rustc_const_eval/src/interpret/discriminant.rs index 67fbf9642bf0..0dbee8c1d948 100644 --- a/compiler/rustc_const_eval/src/interpret/discriminant.rs +++ b/compiler/rustc_const_eval/src/interpret/discriminant.rs @@ -123,14 +123,14 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { // (`tag_bits` itself is only used for error messages below.) let tag_bits = tag_val .to_scalar() - .try_to_int() + .try_to_scalar_int() .map_err(|dbg_val| err_ub!(InvalidTag(dbg_val)))? - .assert_bits(tag_layout.size); + .to_bits(tag_layout.size); // Cast bits from tag layout to discriminant layout. // After the checks we did above, this cannot fail, as // discriminants are int-like. let discr_val = self.int_to_int_or_float(&tag_val, discr_layout).unwrap(); - let discr_bits = discr_val.to_scalar().assert_bits(discr_layout.size); + let discr_bits = discr_val.to_scalar().to_bits(discr_layout.size)?; // Convert discriminant to variant index, and catch invalid discriminants. let index = match *ty.kind() { ty::Adt(adt, _) => { @@ -152,7 +152,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { // discriminant (encoded in niche/tag) and variant index are the same. let variants_start = niche_variants.start().as_u32(); let variants_end = niche_variants.end().as_u32(); - let variant = match tag_val.try_to_int() { + let variant = match tag_val.try_to_scalar_int() { Err(dbg_val) => { // So this is a pointer then, and casting to an int failed. // Can only happen during CTFE. @@ -167,7 +167,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { untagged_variant } Ok(tag_bits) => { - let tag_bits = tag_bits.assert_bits(tag_layout.size); + let tag_bits = tag_bits.to_bits(tag_layout.size); // We need to use machine arithmetic to get the relative variant idx: // variant_index_relative = tag_val - niche_start_val let tag_val = ImmTy::from_uint(tag_bits, tag_layout); @@ -175,7 +175,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { let variant_index_relative_val = self.binary_op(mir::BinOp::Sub, &tag_val, &niche_start_val)?; let variant_index_relative = - variant_index_relative_val.to_scalar().assert_bits(tag_val.layout.size); + variant_index_relative_val.to_scalar().to_bits(tag_val.layout.size)?; // Check if this is in the range that indicates an actual discriminant. if variant_index_relative <= u128::from(variants_end - variants_start) { let variant_index_relative = u32::try_from(variant_index_relative) @@ -294,8 +294,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { ImmTy::from_uint(variant_index_relative, tag_layout); let tag = self .binary_op(mir::BinOp::Add, &variant_index_relative_val, &niche_start_val)? - .to_scalar() - .assert_int(); + .to_scalar_int()?; Ok(Some((tag, tag_field))) } } diff --git a/compiler/rustc_const_eval/src/interpret/intrinsics.rs b/compiler/rustc_const_eval/src/interpret/intrinsics.rs index 18b76443cd95..dac5c10addc2 100644 --- a/compiler/rustc_const_eval/src/interpret/intrinsics.rs +++ b/compiler/rustc_const_eval/src/interpret/intrinsics.rs @@ -519,7 +519,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { // `x % y != 0` or `y == 0` or `x == T::MIN && y == -1`. // First, check x % y != 0 (or if that computation overflows). let rem = self.binary_op(BinOp::Rem, a, b)?; - if rem.to_scalar().assert_bits(a.layout.size) != 0 { + if rem.to_scalar().to_bits(a.layout.size)? != 0 { throw_ub_custom!( fluent::const_eval_exact_div_has_remainder, a = format!("{a}"), diff --git a/compiler/rustc_const_eval/src/interpret/memory.rs b/compiler/rustc_const_eval/src/interpret/memory.rs index 521f28b7123e..7eb73e9b52f6 100644 --- a/compiler/rustc_const_eval/src/interpret/memory.rs +++ b/compiler/rustc_const_eval/src/interpret/memory.rs @@ -1344,7 +1344,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { /// Test if this value might be null. /// If the machine does not support ptr-to-int casts, this is conservative. pub fn scalar_may_be_null(&self, scalar: Scalar) -> InterpResult<'tcx, bool> { - Ok(match scalar.try_to_int() { + Ok(match scalar.try_to_scalar_int() { Ok(int) => int.is_null(), Err(_) => { // Can only happen during CTFE. diff --git a/compiler/rustc_const_eval/src/interpret/operand.rs b/compiler/rustc_const_eval/src/interpret/operand.rs index bbb2c2f39385..0a7e9853763f 100644 --- a/compiler/rustc_const_eval/src/interpret/operand.rs +++ b/compiler/rustc_const_eval/src/interpret/operand.rs @@ -87,6 +87,12 @@ impl Immediate { } } + #[inline] + #[cfg_attr(debug_assertions, track_caller)] // only in debug builds due to perf (see #98980) + pub fn to_scalar_int(self) -> ScalarInt { + self.to_scalar().try_to_scalar_int().unwrap() + } + #[inline] #[cfg_attr(debug_assertions, track_caller)] // only in debug builds due to perf (see #98980) pub fn to_scalar_pair(self) -> (Scalar, Scalar) { @@ -219,19 +225,11 @@ impl<'tcx, Prov: Provenance> ImmTy<'tcx, Prov> { Self::from_scalar(Scalar::from(s), layout) } - #[inline] - pub fn try_from_uint(i: impl Into, layout: TyAndLayout<'tcx>) -> Option { - Some(Self::from_scalar(Scalar::try_from_uint(i, layout.size)?, layout)) - } #[inline] pub fn from_uint(i: impl Into, layout: TyAndLayout<'tcx>) -> Self { Self::from_scalar(Scalar::from_uint(i, layout.size), layout) } - #[inline] - pub fn try_from_int(i: impl Into, layout: TyAndLayout<'tcx>) -> Option { - Some(Self::from_scalar(Scalar::try_from_int(i, layout.size)?, layout)) - } #[inline] pub fn from_int(i: impl Into, layout: TyAndLayout<'tcx>) -> Self { Self::from_scalar(Scalar::from_int(i, layout.size), layout) @@ -276,7 +274,8 @@ impl<'tcx, Prov: Provenance> ImmTy<'tcx, Prov> { #[inline] pub fn to_const_int(self) -> ConstInt { assert!(self.layout.ty.is_integral()); - let int = self.to_scalar().assert_int(); + let int = self.imm.to_scalar_int(); + assert_eq!(int.size(), self.layout.size); ConstInt::new(int, self.layout.ty.is_signed(), self.layout.ty.is_ptr_sized_integral()) } diff --git a/compiler/rustc_const_eval/src/interpret/operator.rs b/compiler/rustc_const_eval/src/interpret/operator.rs index 6d005dfcd864..c821c98073d7 100644 --- a/compiler/rustc_const_eval/src/interpret/operator.rs +++ b/compiler/rustc_const_eval/src/interpret/operator.rs @@ -95,10 +95,10 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { let l = left.to_scalar_int()?; let r = right.to_scalar_int()?; // Prepare to convert the values to signed or unsigned form. - let l_signed = || l.assert_int(left.layout.size); - let l_unsigned = || l.assert_uint(left.layout.size); - let r_signed = || r.assert_int(right.layout.size); - let r_unsigned = || r.assert_uint(right.layout.size); + let l_signed = || l.to_int(left.layout.size); + let l_unsigned = || l.to_uint(left.layout.size); + let r_signed = || r.to_int(right.layout.size); + let r_unsigned = || r.to_uint(right.layout.size); let throw_ub_on_overflow = match bin_op { AddUnchecked => Some(sym::unchecked_add), diff --git a/compiler/rustc_const_eval/src/interpret/validity.rs b/compiler/rustc_const_eval/src/interpret/validity.rs index 3407c7b8c792..f532f6bbe371 100644 --- a/compiler/rustc_const_eval/src/interpret/validity.rs +++ b/compiler/rustc_const_eval/src/interpret/validity.rs @@ -653,8 +653,8 @@ impl<'rt, 'tcx, M: Machine<'tcx>> ValidityVisitor<'rt, 'tcx, M> { let WrappingRange { start, end } = valid_range; let max_value = size.unsigned_int_max(); assert!(end <= max_value); - let bits = match scalar.try_to_int() { - Ok(int) => int.assert_bits(size), + let bits = match scalar.try_to_scalar_int() { + Ok(int) => int.to_bits(size), Err(_) => { // So this is a pointer then, and casting to an int failed. // Can only happen during CTFE. diff --git a/compiler/rustc_hir_typeck/src/pat.rs b/compiler/rustc_hir_typeck/src/pat.rs index be91e7d45b61..9476dc704831 100644 --- a/compiler/rustc_hir_typeck/src/pat.rs +++ b/compiler/rustc_hir_typeck/src/pat.rs @@ -2385,11 +2385,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { min_len: u64, ) -> (Option>, Ty<'tcx>) { let len = match len.eval(self.tcx, self.param_env, span) { - // FIXME(BoxyUwU): Assert the `Ty` is a `usize`? Ok((_, val)) => val .try_to_scalar() - .and_then(|scalar| scalar.try_to_int().ok()) - .and_then(|int| int.try_to_target_usize(self.tcx).ok()), + .and_then(|scalar| scalar.try_to_scalar_int().ok()) + .map(|int| int.to_target_usize(self.tcx)), Err(ErrorHandled::Reported(..)) => { let guar = self.error_scrutinee_unfixed_length(span); return (Some(Ty::new_error(self.tcx, guar)), arr_ty); diff --git a/compiler/rustc_middle/src/mir/consts.rs b/compiler/rustc_middle/src/mir/consts.rs index cc8979dd990e..89f5acacf9d1 100644 --- a/compiler/rustc_middle/src/mir/consts.rs +++ b/compiler/rustc_middle/src/mir/consts.rs @@ -84,11 +84,11 @@ impl<'tcx> ConstValue<'tcx> { } pub fn try_to_scalar_int(&self) -> Option { - self.try_to_scalar()?.try_to_int().ok() + self.try_to_scalar()?.try_to_scalar_int().ok() } pub fn try_to_bits(&self, size: Size) -> Option { - self.try_to_scalar_int()?.try_to_bits(size).ok() + Some(self.try_to_scalar_int()?.to_bits(size)) } pub fn try_to_bool(&self) -> Option { @@ -96,7 +96,7 @@ impl<'tcx> ConstValue<'tcx> { } pub fn try_to_target_usize(&self, tcx: TyCtxt<'tcx>) -> Option { - self.try_to_scalar_int()?.try_to_target_usize(tcx).ok() + Some(self.try_to_scalar_int()?.to_target_usize(tcx)) } pub fn try_to_bits_for_ty( @@ -300,7 +300,7 @@ impl<'tcx> Const<'tcx> { #[inline] pub fn try_to_bits(self, size: Size) -> Option { - self.try_to_scalar_int()?.try_to_bits(size).ok() + Some(self.try_to_scalar_int()?.to_bits(size)) } #[inline] @@ -367,7 +367,7 @@ impl<'tcx> Const<'tcx> { tcx: TyCtxt<'tcx>, param_env: ty::ParamEnv<'tcx>, ) -> Option { - self.try_eval_scalar(tcx, param_env)?.try_to_int().ok() + self.try_eval_scalar(tcx, param_env)?.try_to_scalar_int().ok() } #[inline] @@ -375,7 +375,7 @@ impl<'tcx> Const<'tcx> { let int = self.try_eval_scalar_int(tcx, param_env)?; let size = tcx.layout_of(param_env.with_reveal_all_normalized(tcx).and(self.ty())).ok()?.size; - int.try_to_bits(size).ok() + Some(int.to_bits(size)) } /// Panics if the value cannot be evaluated or doesn't contain a valid integer of the given type. @@ -391,7 +391,7 @@ impl<'tcx> Const<'tcx> { tcx: TyCtxt<'tcx>, param_env: ty::ParamEnv<'tcx>, ) -> Option { - self.try_eval_scalar_int(tcx, param_env)?.try_to_target_usize(tcx).ok() + Some(self.try_eval_scalar_int(tcx, param_env)?.to_target_usize(tcx)) } #[inline] diff --git a/compiler/rustc_middle/src/mir/interpret/value.rs b/compiler/rustc_middle/src/mir/interpret/value.rs index 853572656879..70e5ad0635ba 100644 --- a/compiler/rustc_middle/src/mir/interpret/value.rs +++ b/compiler/rustc_middle/src/mir/interpret/value.rs @@ -122,16 +122,12 @@ impl Scalar { Scalar::Int(c.into()) } - #[inline] - pub fn try_from_uint(i: impl Into, size: Size) -> Option { - ScalarInt::try_from_uint(i, size).map(Scalar::Int) - } - #[inline] pub fn from_uint(i: impl Into, size: Size) -> Self { let i = i.into(); - Self::try_from_uint(i, size) + ScalarInt::try_from_uint(i, size) .unwrap_or_else(|| bug!("Unsigned value {:#x} does not fit in {} bits", i, size.bits())) + .into() } #[inline] @@ -164,16 +160,12 @@ impl Scalar { Self::from_uint(i, cx.data_layout().pointer_size) } - #[inline] - pub fn try_from_int(i: impl Into, size: Size) -> Option { - ScalarInt::try_from_int(i, size).map(Scalar::Int) - } - #[inline] pub fn from_int(i: impl Into, size: Size) -> Self { let i = i.into(); - Self::try_from_int(i, size) + ScalarInt::try_from_int(i, size) .unwrap_or_else(|| bug!("Signed value {:#x} does not fit in {} bits", i, size.bits())) + .into() } #[inline] @@ -227,7 +219,7 @@ impl Scalar { } /// This is almost certainly not the method you want! You should dispatch on the type - /// and use `to_{u8,u16,...}`/`scalar_to_ptr` to perform ptr-to-int / int-to-ptr casts as needed. + /// and use `to_{u8,u16,...}`/`to_pointer` to perform ptr-to-int / int-to-ptr casts as needed. /// /// This method only exists for the benefit of low-level operations that truly need to treat the /// scalar in whatever form it is. @@ -289,7 +281,7 @@ impl<'tcx, Prov: Provenance> Scalar { /// The error type is `AllocId`, not `CtfeProvenance`, since `AllocId` is the "minimal" /// component all provenance types must have. #[inline] - pub fn try_to_int(self) -> Result> { + pub fn try_to_scalar_int(self) -> Result> { match self { Scalar::Int(int) => Ok(int), Scalar::Ptr(ptr, sz) => { @@ -307,13 +299,13 @@ impl<'tcx, Prov: Provenance> Scalar { #[inline(always)] pub fn to_scalar_int(self) -> InterpResult<'tcx, ScalarInt> { - self.try_to_int().map_err(|_| err_unsup!(ReadPointerAsInt(None)).into()) + self.try_to_scalar_int().map_err(|_| err_unsup!(ReadPointerAsInt(None)).into()) } #[inline(always)] #[cfg_attr(debug_assertions, track_caller)] // only in debug builds due to perf (see #98980) - pub fn assert_int(self) -> ScalarInt { - self.try_to_int().unwrap() + pub fn assert_scalar_int(self) -> ScalarInt { + self.try_to_scalar_int().expect("got a pointer where a ScalarInt was expected") } /// This throws UB (instead of ICEing) on a size mismatch since size mismatches can arise in @@ -330,13 +322,6 @@ impl<'tcx, Prov: Provenance> Scalar { }) } - #[inline(always)] - #[cfg_attr(debug_assertions, track_caller)] // only in debug builds due to perf (see #98980) - pub fn assert_bits(self, target_size: Size) -> u128 { - self.to_bits(target_size) - .unwrap_or_else(|_| panic!("assertion failed: {self:?} fits {target_size:?}")) - } - pub fn to_bool(self) -> InterpResult<'tcx, bool> { let val = self.to_u8()?; match val { diff --git a/compiler/rustc_middle/src/thir.rs b/compiler/rustc_middle/src/thir.rs index 454897aa6720..7c8b0ec671a4 100644 --- a/compiler/rustc_middle/src/thir.rs +++ b/compiler/rustc_middle/src/thir.rs @@ -1033,8 +1033,8 @@ impl<'tcx> PatRangeBoundary<'tcx> { if let (Some(a), Some(b)) = (a.try_to_scalar_int(), b.try_to_scalar_int()) { let sz = ty.primitive_size(tcx); let cmp = match ty.kind() { - ty::Uint(_) | ty::Char => a.assert_uint(sz).cmp(&b.assert_uint(sz)), - ty::Int(_) => a.assert_int(sz).cmp(&b.assert_int(sz)), + ty::Uint(_) | ty::Char => a.to_uint(sz).cmp(&b.to_uint(sz)), + ty::Int(_) => a.to_int(sz).cmp(&b.to_int(sz)), _ => unreachable!(), }; return Some(cmp); diff --git a/compiler/rustc_middle/src/ty/consts.rs b/compiler/rustc_middle/src/ty/consts.rs index cc1daeb64191..12f0c38b054a 100644 --- a/compiler/rustc_middle/src/ty/consts.rs +++ b/compiler/rustc_middle/src/ty/consts.rs @@ -376,7 +376,7 @@ impl<'tcx> Const<'tcx> { param_env: ParamEnv<'tcx>, ) -> Option<(Ty<'tcx>, ScalarInt)> { let (ty, scalar) = self.try_eval_scalar(tcx, param_env)?; - let val = scalar.try_to_int().ok()?; + let val = scalar.try_to_scalar_int().ok()?; Some((ty, val)) } @@ -388,7 +388,7 @@ impl<'tcx> Const<'tcx> { let (ty, scalar) = self.try_eval_scalar_int(tcx, param_env)?; let size = tcx.layout_of(param_env.with_reveal_all_normalized(tcx).and(ty)).ok()?.size; // if `ty` does not depend on generic parameters, use an empty param_env - scalar.try_to_bits(size).ok() + Some(scalar.to_bits(size)) } #[inline] @@ -405,7 +405,7 @@ impl<'tcx> Const<'tcx> { param_env: ParamEnv<'tcx>, ) -> Option { let (_, scalar) = self.try_eval_scalar_int(tcx, param_env)?; - scalar.try_to_target_usize(tcx).ok() + Some(scalar.to_target_usize(tcx)) } #[inline] diff --git a/compiler/rustc_middle/src/ty/consts/int.rs b/compiler/rustc_middle/src/ty/consts/int.rs index 40ac87873a0a..52320dd141ba 100644 --- a/compiler/rustc_middle/src/ty/consts/int.rs +++ b/compiler/rustc_middle/src/ty/consts/int.rs @@ -246,6 +246,10 @@ impl ScalarInt { Self::try_from_uint(i, tcx.data_layout.pointer_size) } + /// Try to convert this ScalarInt to the raw underlying bits. + /// Fails if the size is wrong. Generally a wrong size should lead to a panic, + /// but Miri sometimes wants to be resilient to size mismatches, + /// so the interpreter will generally use this `try` method. #[inline] pub fn try_to_bits(self, target_size: Size) -> Result { assert_ne!(target_size.bytes(), 0, "you should never look at the bits of a ZST"); @@ -258,165 +262,149 @@ impl ScalarInt { } #[inline] - pub fn assert_bits(self, target_size: Size) -> u128 { + pub fn to_bits(self, target_size: Size) -> u128 { self.try_to_bits(target_size).unwrap_or_else(|size| { bug!("expected int of size {}, but got size {}", target_size.bytes(), size.bytes()) }) } - /// Tries to convert the `ScalarInt` to an unsigned integer of the given size. - /// Fails if the size of the `ScalarInt` is not equal to `size` and returns the - /// `ScalarInt`s size in that case. + /// Extracts the bits from the scalar without checking the size. #[inline] - pub fn try_to_uint(self, size: Size) -> Result { - self.try_to_bits(size) + pub fn to_bits_unchecked(self) -> u128 { + self.check_data(); + self.data + } + + /// Converts the `ScalarInt` to an unsigned integer of the given size. + /// Panics if the size of the `ScalarInt` is not equal to `size`. + #[inline] + pub fn to_uint(self, size: Size) -> u128 { + self.to_bits(size) + } + + /// Converts the `ScalarInt` to `u8`. + /// Panics if the `size` of the `ScalarInt`in not equal to 1 byte. + #[inline] + pub fn to_u8(self) -> u8 { + self.to_uint(Size::from_bits(8)).try_into().unwrap() + } + + /// Converts the `ScalarInt` to `u16`. + /// Panics if the size of the `ScalarInt` in not equal to 2 bytes. + #[inline] + pub fn to_u16(self) -> u16 { + self.to_uint(Size::from_bits(16)).try_into().unwrap() + } + + /// Converts the `ScalarInt` to `u32`. + /// Panics if the `size` of the `ScalarInt` in not equal to 4 bytes. + #[inline] + pub fn to_u32(self) -> u32 { + self.to_uint(Size::from_bits(32)).try_into().unwrap() + } + + /// Converts the `ScalarInt` to `u64`. + /// Panics if the `size` of the `ScalarInt` in not equal to 8 bytes. + #[inline] + pub fn to_u64(self) -> u64 { + self.to_uint(Size::from_bits(64)).try_into().unwrap() + } + + /// Converts the `ScalarInt` to `u128`. + /// Panics if the `size` of the `ScalarInt` in not equal to 16 bytes. + #[inline] + pub fn to_u128(self) -> u128 { + self.to_uint(Size::from_bits(128)) } #[inline] - pub fn assert_uint(self, size: Size) -> u128 { - self.assert_bits(size) + pub fn to_target_usize(&self, tcx: TyCtxt<'_>) -> u64 { + self.to_uint(tcx.data_layout.pointer_size).try_into().unwrap() } - // Tries to convert the `ScalarInt` to `u8`. Fails if the `size` of the `ScalarInt` - // in not equal to 1 byte and returns the `size` value of the `ScalarInt` in - // that case. + /// Converts the `ScalarInt` to `bool`. + /// Panics if the `size` of the `ScalarInt` is not equal to 1 byte. + /// Errors if it is not a valid `bool`. #[inline] - pub fn try_to_u8(self) -> Result { - self.try_to_uint(Size::from_bits(8)).map(|v| u8::try_from(v).unwrap()) - } - - /// Tries to convert the `ScalarInt` to `u16`. Fails if the size of the `ScalarInt` - /// in not equal to 2 bytes and returns the `size` value of the `ScalarInt` in - /// that case. - #[inline] - pub fn try_to_u16(self) -> Result { - self.try_to_uint(Size::from_bits(16)).map(|v| u16::try_from(v).unwrap()) - } - - /// Tries to convert the `ScalarInt` to `u32`. Fails if the `size` of the `ScalarInt` - /// in not equal to 4 bytes and returns the `size` value of the `ScalarInt` in - /// that case. - #[inline] - pub fn try_to_u32(self) -> Result { - self.try_to_uint(Size::from_bits(32)).map(|v| u32::try_from(v).unwrap()) - } - - /// Tries to convert the `ScalarInt` to `u64`. Fails if the `size` of the `ScalarInt` - /// in not equal to 8 bytes and returns the `size` value of the `ScalarInt` in - /// that case. - #[inline] - pub fn try_to_u64(self) -> Result { - self.try_to_uint(Size::from_bits(64)).map(|v| u64::try_from(v).unwrap()) - } - - /// Tries to convert the `ScalarInt` to `u128`. Fails if the `size` of the `ScalarInt` - /// in not equal to 16 bytes and returns the `size` value of the `ScalarInt` in - /// that case. - #[inline] - pub fn try_to_u128(self) -> Result { - self.try_to_uint(Size::from_bits(128)) - } - - #[inline] - pub fn try_to_target_usize(&self, tcx: TyCtxt<'_>) -> Result { - self.try_to_uint(tcx.data_layout.pointer_size).map(|v| u64::try_from(v).unwrap()) - } - - // Tries to convert the `ScalarInt` to `bool`. Fails if the `size` of the `ScalarInt` - // in not equal to 1 byte or if the value is not 0 or 1 and returns the `size` - // value of the `ScalarInt` in that case. - #[inline] - pub fn try_to_bool(self) -> Result { - match self.try_to_u8()? { + pub fn try_to_bool(self) -> Result { + match self.to_u8() { 0 => Ok(false), 1 => Ok(true), - _ => Err(self.size()), + _ => Err(()), } } - /// Tries to convert the `ScalarInt` to a signed integer of the given size. - /// Fails if the size of the `ScalarInt` is not equal to `size` and returns the - /// `ScalarInt`s size in that case. + /// Converts the `ScalarInt` to a signed integer of the given size. + /// Panics if the size of the `ScalarInt` is not equal to `size`. #[inline] - pub fn try_to_int(self, size: Size) -> Result { - let b = self.try_to_bits(size)?; - Ok(size.sign_extend(b) as i128) - } - - #[inline] - pub fn assert_int(self, size: Size) -> i128 { - let b = self.assert_bits(size); + pub fn to_int(self, size: Size) -> i128 { + let b = self.to_bits(size); size.sign_extend(b) as i128 } - /// Tries to convert the `ScalarInt` to i8. - /// Fails if the size of the `ScalarInt` is not equal to 1 byte - /// and returns the `ScalarInt`s size in that case. - pub fn try_to_i8(self) -> Result { - self.try_to_int(Size::from_bits(8)).map(|v| i8::try_from(v).unwrap()) + /// Converts the `ScalarInt` to i8. + /// Panics if the size of the `ScalarInt` is not equal to 1 byte. + pub fn to_i8(self) -> i8 { + self.to_int(Size::from_bits(8)).try_into().unwrap() } - /// Tries to convert the `ScalarInt` to i16. - /// Fails if the size of the `ScalarInt` is not equal to 2 bytes - /// and returns the `ScalarInt`s size in that case. - pub fn try_to_i16(self) -> Result { - self.try_to_int(Size::from_bits(16)).map(|v| i16::try_from(v).unwrap()) + /// Converts the `ScalarInt` to i16. + /// Panics if the size of the `ScalarInt` is not equal to 2 bytes. + pub fn to_i16(self) -> i16 { + self.to_int(Size::from_bits(16)).try_into().unwrap() } - /// Tries to convert the `ScalarInt` to i32. - /// Fails if the size of the `ScalarInt` is not equal to 4 bytes - /// and returns the `ScalarInt`s size in that case. - pub fn try_to_i32(self) -> Result { - self.try_to_int(Size::from_bits(32)).map(|v| i32::try_from(v).unwrap()) + /// Converts the `ScalarInt` to i32. + /// Panics if the size of the `ScalarInt` is not equal to 4 bytes. + pub fn to_i32(self) -> i32 { + self.to_int(Size::from_bits(32)).try_into().unwrap() } - /// Tries to convert the `ScalarInt` to i64. - /// Fails if the size of the `ScalarInt` is not equal to 8 bytes - /// and returns the `ScalarInt`s size in that case. - pub fn try_to_i64(self) -> Result { - self.try_to_int(Size::from_bits(64)).map(|v| i64::try_from(v).unwrap()) + /// Converts the `ScalarInt` to i64. + /// Panics if the size of the `ScalarInt` is not equal to 8 bytes. + pub fn to_i64(self) -> i64 { + self.to_int(Size::from_bits(64)).try_into().unwrap() } - /// Tries to convert the `ScalarInt` to i128. - /// Fails if the size of the `ScalarInt` is not equal to 16 bytes - /// and returns the `ScalarInt`s size in that case. - pub fn try_to_i128(self) -> Result { - self.try_to_int(Size::from_bits(128)) + /// Converts the `ScalarInt` to i128. + /// Panics if the size of the `ScalarInt` is not equal to 16 bytes. + pub fn to_i128(self) -> i128 { + self.to_int(Size::from_bits(128)) } #[inline] - pub fn try_to_target_isize(&self, tcx: TyCtxt<'_>) -> Result { - self.try_to_int(tcx.data_layout.pointer_size).map(|v| i64::try_from(v).unwrap()) + pub fn to_target_isize(&self, tcx: TyCtxt<'_>) -> i64 { + self.to_int(tcx.data_layout.pointer_size).try_into().unwrap() } #[inline] - pub fn try_to_float(self) -> Result { + pub fn to_float(self) -> F { // Going through `to_uint` to check size and truncation. - Ok(F::from_bits(self.try_to_bits(Size::from_bits(F::BITS))?)) + F::from_bits(self.to_bits(Size::from_bits(F::BITS))) } #[inline] - pub fn try_to_f16(self) -> Result { - self.try_to_float() + pub fn to_f16(self) -> Half { + self.to_float() } #[inline] - pub fn try_to_f32(self) -> Result { - self.try_to_float() + pub fn to_f32(self) -> Single { + self.to_float() } #[inline] - pub fn try_to_f64(self) -> Result { - self.try_to_float() + pub fn to_f64(self) -> Double { + self.to_float() } #[inline] - pub fn try_to_f128(self) -> Result { - self.try_to_float() + pub fn to_f128(self) -> Quad { + self.to_float() } } -macro_rules! from { +macro_rules! from_x_for_scalar_int { ($($ty:ty),*) => { $( impl From<$ty> for ScalarInt { @@ -432,30 +420,29 @@ macro_rules! from { } } -macro_rules! try_from { +macro_rules! from_scalar_int_for_x { ($($ty:ty),*) => { $( - impl TryFrom for $ty { - type Error = Size; + impl From for $ty { #[inline] - fn try_from(int: ScalarInt) -> Result { + fn from(int: ScalarInt) -> Self { // The `unwrap` cannot fail because to_bits (if it succeeds) // is guaranteed to return a value that fits into the size. - int.try_to_bits(Size::from_bytes(std::mem::size_of::<$ty>())) - .map(|u| u.try_into().unwrap()) + int.to_bits(Size::from_bytes(std::mem::size_of::<$ty>())) + .try_into().unwrap() } } )* } } -from!(u8, u16, u32, u64, u128, bool); -try_from!(u8, u16, u32, u64, u128); +from_x_for_scalar_int!(u8, u16, u32, u64, u128, bool); +from_scalar_int_for_x!(u8, u16, u32, u64, u128); impl TryFrom for bool { - type Error = Size; + type Error = (); #[inline] - fn try_from(int: ScalarInt) -> Result { + fn try_from(int: ScalarInt) -> Result { int.try_to_bool() } } @@ -463,7 +450,7 @@ impl TryFrom for bool { impl From for ScalarInt { #[inline] fn from(c: char) -> Self { - Self { data: c as u128, size: NonZero::new(std::mem::size_of::() as u8).unwrap() } + (c as u32).into() } } @@ -476,10 +463,7 @@ impl TryFrom for char { #[inline] fn try_from(int: ScalarInt) -> Result { - let Ok(bits) = int.try_to_bits(Size::from_bytes(std::mem::size_of::())) else { - return Err(CharTryFromScalarInt); - }; - match char::from_u32(bits.try_into().unwrap()) { + match char::from_u32(int.to_u32()) { Some(c) => Ok(c), None => Err(CharTryFromScalarInt), } @@ -494,11 +478,10 @@ impl From for ScalarInt { } } -impl TryFrom for Half { - type Error = Size; +impl From for Half { #[inline] - fn try_from(int: ScalarInt) -> Result { - int.try_to_bits(Size::from_bytes(2)).map(Self::from_bits) + fn from(int: ScalarInt) -> Self { + Self::from_bits(int.to_bits(Size::from_bytes(2))) } } @@ -510,11 +493,10 @@ impl From for ScalarInt { } } -impl TryFrom for Single { - type Error = Size; +impl From for Single { #[inline] - fn try_from(int: ScalarInt) -> Result { - int.try_to_bits(Size::from_bytes(4)).map(Self::from_bits) + fn from(int: ScalarInt) -> Self { + Self::from_bits(int.to_bits(Size::from_bytes(4))) } } @@ -526,11 +508,10 @@ impl From for ScalarInt { } } -impl TryFrom for Double { - type Error = Size; +impl From for Double { #[inline] - fn try_from(int: ScalarInt) -> Result { - int.try_to_bits(Size::from_bytes(8)).map(Self::from_bits) + fn from(int: ScalarInt) -> Self { + Self::from_bits(int.to_bits(Size::from_bytes(8))) } } @@ -542,11 +523,10 @@ impl From for ScalarInt { } } -impl TryFrom for Quad { - type Error = Size; +impl From for Quad { #[inline] - fn try_from(int: ScalarInt) -> Result { - int.try_to_bits(Size::from_bytes(16)).map(Self::from_bits) + fn from(int: ScalarInt) -> Self { + Self::from_bits(int.to_bits(Size::from_bytes(16))) } } diff --git a/compiler/rustc_middle/src/ty/consts/valtree.rs b/compiler/rustc_middle/src/ty/consts/valtree.rs index 96bc5515a569..efc91357af8c 100644 --- a/compiler/rustc_middle/src/ty/consts/valtree.rs +++ b/compiler/rustc_middle/src/ty/consts/valtree.rs @@ -79,7 +79,7 @@ impl<'tcx> ValTree<'tcx> { } pub fn try_to_target_usize(self, tcx: TyCtxt<'tcx>) -> Option { - self.try_to_scalar_int().and_then(|s| s.try_to_target_usize(tcx).ok()) + self.try_to_scalar_int().map(|s| s.to_target_usize(tcx)) } /// Get the values inside the ValTree as a slice of bytes. This only works for @@ -100,8 +100,9 @@ impl<'tcx> ValTree<'tcx> { _ => return None, } - Some(tcx.arena.alloc_from_iter( - self.unwrap_branch().into_iter().map(|v| v.unwrap_leaf().try_to_u8().unwrap()), - )) + Some( + tcx.arena + .alloc_from_iter(self.unwrap_branch().into_iter().map(|v| v.unwrap_leaf().to_u8())), + ) } } diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index 49d46eb3c4bf..662eafd0ccb6 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -1652,7 +1652,7 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write { if let ty::ConstKind::Value(_, ty::ValTree::Leaf(int)) = len.kind() { match self.tcx().try_get_global_alloc(prov.alloc_id()) { Some(GlobalAlloc::Memory(alloc)) => { - let len = int.assert_bits(self.tcx().data_layout.pointer_size); + let len = int.to_bits(self.tcx().data_layout.pointer_size); let range = AllocRange { start: offset, size: Size::from_bytes(len) }; if let Ok(byte_str) = @@ -1730,7 +1730,7 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write { } // Pointer types ty::Ref(..) | ty::RawPtr(_, _) | ty::FnPtr(_) => { - let data = int.assert_bits(self.tcx().data_layout.pointer_size); + let data = int.to_bits(self.tcx().data_layout.pointer_size); self.typed_value( |this| { write!(this, "0x{data:x}")?; diff --git a/compiler/rustc_mir_build/src/build/mod.rs b/compiler/rustc_mir_build/src/build/mod.rs index 193f0d124bb8..601e5d4d3dc7 100644 --- a/compiler/rustc_mir_build/src/build/mod.rs +++ b/compiler/rustc_mir_build/src/build/mod.rs @@ -15,11 +15,10 @@ use rustc_index::{Idx, IndexSlice, IndexVec}; use rustc_infer::infer::{InferCtxt, TyCtxtInferExt}; use rustc_middle::hir::place::PlaceBase as HirPlaceBase; use rustc_middle::middle::region; -use rustc_middle::mir::interpret::Scalar; use rustc_middle::mir::*; use rustc_middle::query::TyCtxtAt; use rustc_middle::thir::{self, ExprId, LintLevel, LocalVarId, Param, ParamId, PatKind, Thir}; -use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitableExt}; +use rustc_middle::ty::{self, ScalarInt, Ty, TyCtxt, TypeVisitableExt}; use rustc_middle::{bug, span_bug}; use rustc_span::symbol::sym; use rustc_span::Span; @@ -1014,14 +1013,14 @@ fn parse_float_into_constval<'tcx>( float_ty: ty::FloatTy, neg: bool, ) -> Option> { - parse_float_into_scalar(num, float_ty, neg).map(ConstValue::Scalar) + parse_float_into_scalar(num, float_ty, neg).map(|s| ConstValue::Scalar(s.into())) } pub(crate) fn parse_float_into_scalar( num: Symbol, float_ty: ty::FloatTy, neg: bool, -) -> Option { +) -> Option { let num = num.as_str(); match float_ty { // FIXME(f16_f128): When available, compare to the library parser as with `f32` and `f64` @@ -1030,7 +1029,7 @@ pub(crate) fn parse_float_into_scalar( if neg { f = -f; } - Some(Scalar::from_f16(f)) + Some(ScalarInt::from(f)) } ty::FloatTy::F32 => { let Ok(rust_f) = num.parse::() else { return None }; @@ -1053,7 +1052,7 @@ pub(crate) fn parse_float_into_scalar( f = -f; } - Some(Scalar::from_f32(f)) + Some(ScalarInt::from(f)) } ty::FloatTy::F64 => { let Ok(rust_f) = num.parse::() else { return None }; @@ -1076,7 +1075,7 @@ pub(crate) fn parse_float_into_scalar( f = -f; } - Some(Scalar::from_f64(f)) + Some(ScalarInt::from(f)) } // FIXME(f16_f128): When available, compare to the library parser as with `f32` and `f64` ty::FloatTy::F128 => { @@ -1084,7 +1083,7 @@ pub(crate) fn parse_float_into_scalar( if neg { f = -f; } - Some(Scalar::from_f128(f)) + Some(ScalarInt::from(f)) } } } diff --git a/compiler/rustc_mir_build/src/thir/constant.rs b/compiler/rustc_mir_build/src/thir/constant.rs index 31bc72184caa..a98e046d4dc0 100644 --- a/compiler/rustc_mir_build/src/thir/constant.rs +++ b/compiler/rustc_mir_build/src/thir/constant.rs @@ -58,11 +58,9 @@ pub(crate) fn lit_to_const<'tcx>( } (ast::LitKind::Bool(b), ty::Bool) => ty::ValTree::from_scalar_int((*b).into()), (ast::LitKind::Float(n, _), ty::Float(fty)) => { - let bits = parse_float_into_scalar(*n, *fty, neg) - .ok_or_else(|| { - tcx.dcx().bug(format!("couldn't parse float literal: {:?}", lit_input.lit)) - })? - .assert_int(); + let bits = parse_float_into_scalar(*n, *fty, neg).ok_or_else(|| { + tcx.dcx().bug(format!("couldn't parse float literal: {:?}", lit_input.lit)) + })?; ty::ValTree::from_scalar_int(bits) } (ast::LitKind::Char(c), ty::Char) => ty::ValTree::from_scalar_int((*c).into()), diff --git a/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs b/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs index 36495101d3f4..192d706bce2c 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs @@ -282,8 +282,7 @@ impl<'tcx> ConstToPat<'tcx> { } ty::Adt(adt_def, args) if adt_def.is_enum() => { let (&variant_index, fields) = cv.unwrap_branch().split_first().unwrap(); - let variant_index = - VariantIdx::from_u32(variant_index.unwrap_leaf().try_to_u32().ok().unwrap()); + let variant_index = VariantIdx::from_u32(variant_index.unwrap_leaf().to_u32()); PatKind::Variant { adt_def: *adt_def, args, @@ -371,8 +370,8 @@ impl<'tcx> ConstToPat<'tcx> { let v = cv.unwrap_leaf(); let is_nan = match flt { ty::FloatTy::F16 => unimplemented!("f16_f128"), - ty::FloatTy::F32 => v.try_to_f32().unwrap().is_nan(), - ty::FloatTy::F64 => v.try_to_f64().unwrap().is_nan(), + ty::FloatTy::F32 => v.to_f32().is_nan(), + ty::FloatTy::F64 => v.to_f64().is_nan(), ty::FloatTy::F128 => unimplemented!("f16_f128"), }; if is_nan { diff --git a/compiler/rustc_mir_transform/src/dataflow_const_prop.rs b/compiler/rustc_mir_transform/src/dataflow_const_prop.rs index eba5d13d33f6..0fd85eb345d0 100644 --- a/compiler/rustc_mir_transform/src/dataflow_const_prop.rs +++ b/compiler/rustc_mir_transform/src/dataflow_const_prop.rs @@ -326,7 +326,7 @@ impl<'tcx> ValueAnalysis<'tcx> for ConstAnalysis<'_, 'tcx> { // This allows the set of visited edges to grow monotonically with the lattice. FlatSet::Bottom => TerminatorEdges::None, FlatSet::Elem(scalar) => { - let choice = scalar.assert_bits(scalar.size()); + let choice = scalar.assert_scalar_int().to_bits_unchecked(); TerminatorEdges::Single(targets.target_for_value(choice)) } FlatSet::Top => TerminatorEdges::SwitchInt { discr, targets }, @@ -609,7 +609,7 @@ fn propagatable_scalar( map: &Map, ) -> Option { if let FlatSet::Elem(value) = state.get_idx(place, map) - && value.try_to_int().is_ok() + && value.try_to_scalar_int().is_ok() { // Do not attempt to propagate pointers, as we may fail to preserve their identity. Some(value) @@ -670,7 +670,7 @@ fn try_write_constant<'tcx>( let FlatSet::Elem(Scalar::Int(discr)) = state.get_idx(discr, map) else { throw_machine_stop_str!("discriminant with provenance") }; - let discr_bits = discr.assert_bits(discr.size()); + let discr_bits = discr.to_bits(discr.size()); let Some((variant, _)) = def.discriminants(*ecx.tcx).find(|(_, var)| discr_bits == var.val) else { throw_machine_stop_str!("illegal discriminant for enum") }; diff --git a/compiler/rustc_mir_transform/src/gvn.rs b/compiler/rustc_mir_transform/src/gvn.rs index ebfb372329ee..ab7b210b4d02 100644 --- a/compiler/rustc_mir_transform/src/gvn.rs +++ b/compiler/rustc_mir_transform/src/gvn.rs @@ -471,7 +471,7 @@ impl<'body, 'tcx> VnState<'body, 'tcx> { let slice = self.evaluated[slice].as_ref()?; let usize_layout = self.ecx.layout_of(self.tcx.types.usize).unwrap(); let len = slice.len(&self.ecx).ok()?; - let imm = ImmTy::try_from_uint(len, usize_layout)?; + let imm = ImmTy::from_uint(len, usize_layout); imm.into() } NullaryOp(null_op, ty) => { @@ -492,7 +492,7 @@ impl<'body, 'tcx> VnState<'body, 'tcx> { NullOp::UbChecks => return None, }; let usize_layout = self.ecx.layout_of(self.tcx.types.usize).unwrap(); - let imm = ImmTy::try_from_uint(val, usize_layout)?; + let imm = ImmTy::from_uint(val, usize_layout); imm.into() } UnaryOp(un_op, operand) => { @@ -1180,7 +1180,7 @@ fn op_to_prop_const<'tcx>( // If this constant has scalar ABI, return it as a `ConstValue::Scalar`. if let Abi::Scalar(abi::Scalar::Initialized { .. }) = op.layout.abi && let Ok(scalar) = ecx.read_scalar(op) - && scalar.try_to_int().is_ok() + && scalar.try_to_scalar_int().is_ok() { return Some(ConstValue::Scalar(scalar)); } diff --git a/compiler/rustc_mir_transform/src/known_panics_lint.rs b/compiler/rustc_mir_transform/src/known_panics_lint.rs index 47bbddbc31d4..6a20b46e7f9c 100644 --- a/compiler/rustc_mir_transform/src/known_panics_lint.rs +++ b/compiler/rustc_mir_transform/src/known_panics_lint.rs @@ -356,15 +356,12 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> { debug!("check_binary_op: reporting assert for {:?}", location); let panic = AssertKind::Overflow( op, - match l { - Some(l) => l.to_const_int(), - // Invent a dummy value, the diagnostic ignores it anyway - None => ConstInt::new( - ScalarInt::try_from_uint(1_u8, left_size).unwrap(), - left_ty.is_signed(), - left_ty.is_ptr_sized_integral(), - ), - }, + // Invent a dummy value, the diagnostic ignores it anyway + ConstInt::new( + ScalarInt::try_from_uint(1_u8, left_size).unwrap(), + left_ty.is_signed(), + left_ty.is_ptr_sized_integral(), + ), r.to_const_int(), ); self.report_assert_as_lint(location, AssertLintKind::ArithmeticOverflow, panic); @@ -787,8 +784,7 @@ impl<'tcx> Visitor<'tcx> for ConstPropagator<'_, 'tcx> { TerminatorKind::SwitchInt { ref discr, ref targets } => { if let Some(ref value) = self.eval_operand(discr) && let Some(value_const) = self.use_ecx(|this| this.ecx.read_scalar(value)) - && let Ok(constant) = value_const.try_to_int() - && let Ok(constant) = constant.try_to_bits(constant.size()) + && let Ok(constant) = value_const.to_bits(value_const.size()) { // We managed to evaluate the discriminant, so we know we only need to visit // one target. diff --git a/compiler/rustc_mir_transform/src/match_branches.rs b/compiler/rustc_mir_transform/src/match_branches.rs index 1411d9be2236..6ab4ec6fe7e6 100644 --- a/compiler/rustc_mir_transform/src/match_branches.rs +++ b/compiler/rustc_mir_transform/src/match_branches.rs @@ -372,7 +372,7 @@ impl<'tcx> SimplifyMatch<'tcx> for SimplifyToExp { } fn int_equal(l: ScalarInt, r: impl Into, size: Size) -> bool { - l.assert_int(l.size()) == ScalarInt::try_from_uint(r, size).unwrap().assert_int(size) + l.to_bits_unchecked() == ScalarInt::try_from_uint(r, size).unwrap().to_bits_unchecked() } // We first compare the two branches, and then the other branches need to fulfill the same conditions. diff --git a/compiler/rustc_mir_transform/src/promote_consts.rs b/compiler/rustc_mir_transform/src/promote_consts.rs index 7ec59cc983f5..ecd1179ca995 100644 --- a/compiler/rustc_mir_transform/src/promote_consts.rs +++ b/compiler/rustc_mir_transform/src/promote_consts.rs @@ -500,14 +500,14 @@ impl<'tcx> Validator<'_, 'tcx> { } _ => None, }; - match rhs_val.map(|x| x.assert_uint(sz)) { + match rhs_val.map(|x| x.to_uint(sz)) { // for the zero test, int vs uint does not matter Some(x) if x != 0 => {} // okay _ => return Err(Unpromotable), // value not known or 0 -- not okay } // Furthermore, for signed divison, we also have to exclude `int::MIN / -1`. if lhs_ty.is_signed() { - match rhs_val.map(|x| x.assert_int(sz)) { + match rhs_val.map(|x| x.to_int(sz)) { Some(-1) | None => { // The RHS is -1 or unknown, so we have to be careful. // But is the LHS int::MIN? @@ -518,7 +518,7 @@ impl<'tcx> Validator<'_, 'tcx> { _ => None, }; let lhs_min = sz.signed_int_min(); - match lhs_val.map(|x| x.assert_int(sz)) { + match lhs_val.map(|x| x.to_int(sz)) { Some(x) if x != lhs_min => {} // okay _ => return Err(Unpromotable), // value not known or int::MIN -- not okay } diff --git a/compiler/rustc_mir_transform/src/simplify_comparison_integral.rs b/compiler/rustc_mir_transform/src/simplify_comparison_integral.rs index 03907babf2b0..e174cccdad6b 100644 --- a/compiler/rustc_mir_transform/src/simplify_comparison_integral.rs +++ b/compiler/rustc_mir_transform/src/simplify_comparison_integral.rs @@ -49,7 +49,7 @@ impl<'tcx> MirPass<'tcx> for SimplifyComparisonIntegral { let layout = tcx .layout_of(param_env.and(opt.branch_value_ty)) .expect("if we have an evaluated constant we must know the layout"); - int.assert_bits(layout.size) + int.to_bits(layout.size) } Scalar::Ptr(..) => continue, }; diff --git a/compiler/rustc_mir_transform/src/validate.rs b/compiler/rustc_mir_transform/src/validate.rs index 3b4d4c938771..586c12549953 100644 --- a/compiler/rustc_mir_transform/src/validate.rs +++ b/compiler/rustc_mir_transform/src/validate.rs @@ -5,12 +5,12 @@ use rustc_index::bit_set::BitSet; use rustc_index::IndexVec; use rustc_infer::traits::Reveal; use rustc_middle::mir::coverage::CoverageKind; -use rustc_middle::mir::interpret::Scalar; use rustc_middle::mir::visit::{NonUseContext, PlaceContext, Visitor}; use rustc_middle::mir::*; use rustc_middle::ty::adjustment::PointerCoercion; use rustc_middle::ty::{ - self, CoroutineArgsExt, InstanceDef, ParamEnv, Ty, TyCtxt, TypeVisitableExt, Variance, + self, CoroutineArgsExt, InstanceDef, ParamEnv, ScalarInt, Ty, TyCtxt, TypeVisitableExt, + Variance, }; use rustc_middle::{bug, span_bug}; use rustc_target::abi::{Size, FIRST_VARIANT}; @@ -1478,7 +1478,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { }); for (value, _) in targets.iter() { - if Scalar::<()>::try_from_uint(value, size).is_none() { + if ScalarInt::try_from_uint(value, size).is_none() { self.fail( location, format!("the value {value:#x} is not a proper {switch_ty:?}"), diff --git a/compiler/rustc_pattern_analysis/src/rustc.rs b/compiler/rustc_pattern_analysis/src/rustc.rs index 81c5f3552319..8391c694c64b 100644 --- a/compiler/rustc_pattern_analysis/src/rustc.rs +++ b/compiler/rustc_pattern_analysis/src/rustc.rs @@ -6,11 +6,12 @@ use rustc_hir::def_id::DefId; use rustc_hir::HirId; use rustc_index::{Idx, IndexVec}; use rustc_middle::middle::stability::EvalResult; -use rustc_middle::mir::interpret::Scalar; use rustc_middle::mir::{self, Const}; use rustc_middle::thir::{self, FieldPat, Pat, PatKind, PatRange, PatRangeBoundary}; use rustc_middle::ty::layout::IntegerExt; -use rustc_middle::ty::{self, FieldDef, OpaqueTypeKey, Ty, TyCtxt, TypeVisitableExt, VariantDef}; +use rustc_middle::ty::{ + self, FieldDef, OpaqueTypeKey, ScalarInt, Ty, TyCtxt, TypeVisitableExt, VariantDef, +}; use rustc_middle::{bug, span_bug}; use rustc_session::lint; use rustc_span::{ErrorGuaranteed, Span, DUMMY_SP}; @@ -701,9 +702,9 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> { ty::Int(_) => miint.as_finite_int(size.bits()).unwrap(), _ => miint.as_finite_uint().unwrap(), }; - match Scalar::try_from_uint(bits, size) { + match ScalarInt::try_from_uint(bits, size) { Some(scalar) => { - let value = mir::Const::from_scalar(tcx, scalar, ty.inner()); + let value = mir::Const::from_scalar(tcx, scalar.into(), ty.inner()); PatRangeBoundary::Finite(value) } // The value doesn't fit. Since `x >= 0` and 0 always encodes the minimum value diff --git a/compiler/rustc_transmute/src/layout/tree.rs b/compiler/rustc_transmute/src/layout/tree.rs index 604b68d2cd4a..eae1a9dfaa2c 100644 --- a/compiler/rustc_transmute/src/layout/tree.rs +++ b/compiler/rustc_transmute/src/layout/tree.rs @@ -420,7 +420,7 @@ pub(crate) mod rustc { fn from_tag(tag: ScalarInt, tcx: TyCtxt<'tcx>) -> Self { use rustc_target::abi::Endian; let size = tag.size(); - let bits = tag.assert_bits(size); + let bits = tag.to_bits(size); let bytes: [u8; 16]; let bytes = match tcx.data_layout.endian { Endian::Little => { diff --git a/compiler/rustc_ty_utils/src/consts.rs b/compiler/rustc_ty_utils/src/consts.rs index 1aec40e95f69..58f812fc7cfa 100644 --- a/compiler/rustc_ty_utils/src/consts.rs +++ b/compiler/rustc_ty_utils/src/consts.rs @@ -47,7 +47,7 @@ fn destructure_const<'tcx>( ty::Adt(def, args) => { let (variant_idx, branches) = if def.is_enum() { let (head, rest) = branches.split_first().unwrap(); - (VariantIdx::from_u32(head.unwrap_leaf().try_to_u32().unwrap()), rest) + (VariantIdx::from_u32(head.unwrap_leaf().to_u32()), rest) } else { (FIRST_VARIANT, branches) }; diff --git a/src/librustdoc/clean/utils.rs b/src/librustdoc/clean/utils.rs index 7fc3d4508d7d..7c83d4387193 100644 --- a/src/librustdoc/clean/utils.rs +++ b/src/librustdoc/clean/utils.rs @@ -431,8 +431,7 @@ fn print_const_with_custom_print_scalar<'tcx>( (mir::Const::Val(mir::ConstValue::Scalar(int), _), ty::Int(i)) => { let ty = ct.ty(); let size = tcx.layout_of(ty::ParamEnv::empty().and(ty)).unwrap().size; - let data = int.assert_bits(size); - let sign_extended_data = size.sign_extend(data) as i128; + let sign_extended_data = int.assert_scalar_int().to_int(size); let mut output = if with_underscores { format_integer_with_underscore_sep(&sign_extended_data.to_string()) } else { diff --git a/src/tools/clippy/clippy_lints/src/large_const_arrays.rs b/src/tools/clippy/clippy_lints/src/large_const_arrays.rs index 77d05020c828..7f8197c0cc01 100644 --- a/src/tools/clippy/clippy_lints/src/large_const_arrays.rs +++ b/src/tools/clippy/clippy_lints/src/large_const_arrays.rs @@ -55,7 +55,7 @@ impl<'tcx> LateLintPass<'tcx> for LargeConstArrays { && let ty = cx.tcx.type_of(item.owner_id).instantiate_identity() && let ty::Array(element_type, cst) = ty.kind() && let ConstKind::Value(_, ty::ValTree::Leaf(element_count)) = cst.kind() - && let Ok(element_count) = element_count.try_to_target_usize(cx.tcx) + && let element_count = element_count.to_target_usize(cx.tcx) && let Ok(element_size) = cx.layout_of(*element_type).map(|l| l.size.bytes()) && self.maximum_allowed_size < u128::from(element_count) * u128::from(element_size) { diff --git a/src/tools/clippy/clippy_lints/src/large_stack_arrays.rs b/src/tools/clippy/clippy_lints/src/large_stack_arrays.rs index f0f3f53647b9..c9bfc9c85d95 100644 --- a/src/tools/clippy/clippy_lints/src/large_stack_arrays.rs +++ b/src/tools/clippy/clippy_lints/src/large_stack_arrays.rs @@ -65,7 +65,7 @@ impl<'tcx> LateLintPass<'tcx> for LargeStackArrays { && !self.is_from_vec_macro(cx, expr.span) && let ty::Array(element_type, cst) = cx.typeck_results().expr_ty(expr).kind() && let ConstKind::Value(_, ty::ValTree::Leaf(element_count)) = cst.kind() - && let Ok(element_count) = element_count.try_to_target_usize(cx.tcx) + && let element_count = element_count.to_target_usize(cx.tcx) && let Ok(element_size) = cx.layout_of(*element_type).map(|l| l.size.bytes()) && !cx.tcx.hir().parent_iter(expr.hir_id).any(|(_, node)| { matches!( diff --git a/src/tools/clippy/clippy_lints/src/non_copy_const.rs b/src/tools/clippy/clippy_lints/src/non_copy_const.rs index 76d9cee18aa7..20a97645af95 100644 --- a/src/tools/clippy/clippy_lints/src/non_copy_const.rs +++ b/src/tools/clippy/clippy_lints/src/non_copy_const.rs @@ -199,7 +199,7 @@ impl<'tcx> NonCopyConst<'tcx> { .any(|field| Self::is_value_unfrozen_raw_inner(cx, *field, ty)), ty::Adt(def, args) if def.is_enum() => { let (&variant_index, fields) = val.unwrap_branch().split_first().unwrap(); - let variant_index = VariantIdx::from_u32(variant_index.unwrap_leaf().try_to_u32().ok().unwrap()); + let variant_index = VariantIdx::from_u32(variant_index.unwrap_leaf().to_u32()); fields .iter() .copied() diff --git a/src/tools/clippy/clippy_lints/src/zero_repeat_side_effects.rs b/src/tools/clippy/clippy_lints/src/zero_repeat_side_effects.rs index 848b49130dc2..8796b8f61d16 100644 --- a/src/tools/clippy/clippy_lints/src/zero_repeat_side_effects.rs +++ b/src/tools/clippy/clippy_lints/src/zero_repeat_side_effects.rs @@ -56,8 +56,7 @@ impl LateLintPass<'_> for ZeroRepeatSideEffects { } else if let ExprKind::Repeat(inner_expr, _) = expr.kind && let ty::Array(_, cst) = cx.typeck_results().expr_ty(expr).kind() && let ConstKind::Value(_, ty::ValTree::Leaf(element_count)) = cst.kind() - && let Ok(element_count) = element_count.try_to_target_usize(cx.tcx) - && element_count == 0 + && element_count.to_target_usize(cx.tcx) == 0 { inner_check(cx, expr, inner_expr, false); } diff --git a/src/tools/clippy/clippy_utils/src/consts.rs b/src/tools/clippy/clippy_utils/src/consts.rs index 5c9cad2b45d4..e9e1aa7e4453 100644 --- a/src/tools/clippy/clippy_utils/src/consts.rs +++ b/src/tools/clippy/clippy_utils/src/consts.rs @@ -810,14 +810,14 @@ pub fn mir_to_const<'tcx>(lcx: &LateContext<'tcx>, result: mir::Const<'tcx>) -> (ConstValue::Scalar(Scalar::Int(int)), _) => match result.ty().kind() { ty::Adt(adt_def, _) if adt_def.is_struct() => Some(Constant::Adt(result)), ty::Bool => Some(Constant::Bool(int == ScalarInt::TRUE)), - ty::Uint(_) | ty::Int(_) => Some(Constant::Int(int.assert_bits(int.size()))), + ty::Uint(_) | ty::Int(_) => Some(Constant::Int(int.to_bits(int.size()))), ty::Float(FloatTy::F32) => Some(Constant::F32(f32::from_bits( int.try_into().expect("invalid f32 bit representation"), ))), ty::Float(FloatTy::F64) => Some(Constant::F64(f64::from_bits( int.try_into().expect("invalid f64 bit representation"), ))), - ty::RawPtr(_, _) => Some(Constant::RawPtr(int.assert_bits(int.size()))), + ty::RawPtr(_, _) => Some(Constant::RawPtr(int.to_bits(int.size()))), _ => None, }, (_, ty::Ref(_, inner_ty, _)) if matches!(inner_ty.kind(), ty::Str) => { diff --git a/src/tools/clippy/clippy_utils/src/ty.rs b/src/tools/clippy/clippy_utils/src/ty.rs index f0dac6f5d9c4..6e5626297c95 100644 --- a/src/tools/clippy/clippy_utils/src/ty.rs +++ b/src/tools/clippy/clippy_utils/src/ty.rs @@ -23,7 +23,7 @@ use rustc_middle::ty::{ }; use rustc_span::symbol::Ident; use rustc_span::{sym, Span, Symbol, DUMMY_SP}; -use rustc_target::abi::{Size, VariantIdx}; +use rustc_target::abi::VariantIdx; use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt as _; use rustc_trait_selection::traits::query::normalize::QueryNormalizeExt; use rustc_trait_selection::traits::{Obligation, ObligationCause}; @@ -865,22 +865,8 @@ impl core::ops::Add for EnumValue { pub fn read_explicit_enum_value(tcx: TyCtxt<'_>, id: DefId) -> Option { if let Ok(ConstValue::Scalar(Scalar::Int(value))) = tcx.const_eval_poly(id) { match tcx.type_of(id).instantiate_identity().kind() { - ty::Int(_) => Some(EnumValue::Signed(match value.size().bytes() { - 1 => i128::from(value.assert_bits(Size::from_bytes(1)) as u8 as i8), - 2 => i128::from(value.assert_bits(Size::from_bytes(2)) as u16 as i16), - 4 => i128::from(value.assert_bits(Size::from_bytes(4)) as u32 as i32), - 8 => i128::from(value.assert_bits(Size::from_bytes(8)) as u64 as i64), - 16 => value.assert_bits(Size::from_bytes(16)) as i128, - _ => return None, - })), - ty::Uint(_) => Some(EnumValue::Unsigned(match value.size().bytes() { - 1 => value.assert_bits(Size::from_bytes(1)), - 2 => value.assert_bits(Size::from_bytes(2)), - 4 => value.assert_bits(Size::from_bytes(4)), - 8 => value.assert_bits(Size::from_bytes(8)), - 16 => value.assert_bits(Size::from_bytes(16)), - _ => return None, - })), + ty::Int(_) => Some(EnumValue::Signed(value.to_int(value.size()))), + ty::Uint(_) => Some(EnumValue::Unsigned(value.to_uint(value.size()))), _ => None, } } else { diff --git a/src/tools/miri/src/intrinsics/simd.rs b/src/tools/miri/src/intrinsics/simd.rs index 8ba4964ff896..acdfc6ab67db 100644 --- a/src/tools/miri/src/intrinsics/simd.rs +++ b/src/tools/miri/src/intrinsics/simd.rs @@ -600,8 +600,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { for i in 0..dest_len { let src_index: u64 = index[usize::try_from(i).unwrap()] .unwrap_leaf() - .try_to_u32() - .unwrap() + .to_u32() .into(); let dest = this.project_index(&dest, i)?; diff --git a/src/tools/miri/src/shims/unix/socket.rs b/src/tools/miri/src/shims/unix/socket.rs index a0fa3bcee342..93ad7d242945 100644 --- a/src/tools/miri/src/shims/unix/socket.rs +++ b/src/tools/miri/src/shims/unix/socket.rs @@ -51,9 +51,9 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { let fds = &mut this.machine.fds; let sv0 = fds.insert_fd(FileDescriptor::new(SocketPair)); - let sv0 = Scalar::try_from_int(sv0, sv.layout.size).unwrap(); + let sv0 = Scalar::from_int(sv0, sv.layout.size); let sv1 = fds.insert_fd(FileDescriptor::new(SocketPair)); - let sv1 = Scalar::try_from_int(sv1, sv.layout.size).unwrap(); + let sv1 = Scalar::from_int(sv1, sv.layout.size); this.write_scalar(sv0, &sv)?; this.write_scalar(sv1, &sv.offset(sv.layout.size, sv.layout, this)?)?; From 251d2d0d4d8dd23349994611fe61e708b8f2bbe8 Mon Sep 17 00:00:00 2001 From: Gurinder Singh Date: Mon, 10 Jun 2024 17:14:49 +0530 Subject: [PATCH 49/50] Add explanatory note to async block type mismatch error --- .../src/infer/error_reporting/note_and_explain.rs | 9 +++++++++ tests/ui/async-await/coroutine-desc.stderr | 4 ++++ 2 files changed, 13 insertions(+) diff --git a/compiler/rustc_infer/src/infer/error_reporting/note_and_explain.rs b/compiler/rustc_infer/src/infer/error_reporting/note_and_explain.rs index b88677b3a4ec..effb4090692c 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/note_and_explain.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/note_and_explain.rs @@ -32,6 +32,15 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { diag.note("no two closures, even if identical, have the same type"); diag.help("consider boxing your closure and/or using it as a trait object"); } + (ty::Coroutine(def_id1, ..), ty::Coroutine(def_id2, ..)) + if self.tcx.coroutine_is_async(def_id1) + && self.tcx.coroutine_is_async(def_id2) => + { + diag.note("no two async blocks, even if identical, have the same type"); + diag.help( + "consider pinning your async block and casting it to a trait object", + ); + } (ty::Alias(ty::Opaque, ..), ty::Alias(ty::Opaque, ..)) => { // Issue #63167 diag.note("distinct uses of `impl Trait` result in different opaque types"); diff --git a/tests/ui/async-await/coroutine-desc.stderr b/tests/ui/async-await/coroutine-desc.stderr index 1f1e303ea4c6..4c165ff619a3 100644 --- a/tests/ui/async-await/coroutine-desc.stderr +++ b/tests/ui/async-await/coroutine-desc.stderr @@ -10,6 +10,8 @@ LL | fun(async {}, async {}); | = note: expected `async` block `{async block@$DIR/coroutine-desc.rs:10:9: 10:17}` found `async` block `{async block@$DIR/coroutine-desc.rs:10:19: 10:27}` + = note: no two async blocks, even if identical, have the same type + = help: consider pinning your async block and casting it to a trait object note: function defined here --> $DIR/coroutine-desc.rs:8:4 | @@ -51,6 +53,8 @@ LL | fun((async || {})(), (async || {})()); | = note: expected `async` closure body `{async closure body@$DIR/coroutine-desc.rs:14:19: 14:21}` found `async` closure body `{async closure body@$DIR/coroutine-desc.rs:14:36: 14:38}` + = note: no two async blocks, even if identical, have the same type + = help: consider pinning your async block and casting it to a trait object note: function defined here --> $DIR/coroutine-desc.rs:8:4 | From 144760e23609cff6bc550d3f2ba39430bbfd4fa1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Mon, 10 Jun 2024 14:31:21 +0200 Subject: [PATCH 50/50] CI: add Rust for Linux `auto` job --- src/ci/docker/host-x86_64/rfl/Dockerfile | 40 ++++++++++++++ src/ci/docker/scripts/rfl-build.sh | 68 ++++++++++++++++++++++++ src/ci/github-actions/jobs.yml | 5 ++ 3 files changed, 113 insertions(+) create mode 100644 src/ci/docker/host-x86_64/rfl/Dockerfile create mode 100755 src/ci/docker/scripts/rfl-build.sh diff --git a/src/ci/docker/host-x86_64/rfl/Dockerfile b/src/ci/docker/host-x86_64/rfl/Dockerfile new file mode 100644 index 000000000000..97298519cf20 --- /dev/null +++ b/src/ci/docker/host-x86_64/rfl/Dockerfile @@ -0,0 +1,40 @@ +FROM ubuntu:22.04 + +ARG DEBIAN_FRONTEND=noninteractive + +# libclang1 is required for libclang.so, required by bindgen +# clang, llvm and lld is required by RfL to compile host code +RUN apt-get update && apt-get install -y --no-install-recommends \ + g++ \ + make \ + ninja-build \ + file \ + curl \ + ca-certificates \ + python3 \ + git \ + cmake \ + flex \ + bison \ + bc \ + clang-15 \ + libclang1-15 \ + llvm-15 \ + lld-15 \ + libelf-dev \ + libedit-dev \ + libssl-dev \ + pkg-config \ + zlib1g-dev \ + && rm -rf /var/lib/apt/lists/* + +COPY scripts/sccache.sh /scripts/ +RUN sh /scripts/sccache.sh + +# RfL needs access to cland, lld and llvm tools +ENV PATH="${PATH}:/usr/lib/llvm-15/bin" + +ENV RUST_CONFIGURE_ARGS --build=x86_64-unknown-linux-gnu + +COPY /scripts/rfl-build.sh /tmp/rfl-build.sh +ENV SCRIPT bash /tmp/rfl-build.sh diff --git a/src/ci/docker/scripts/rfl-build.sh b/src/ci/docker/scripts/rfl-build.sh new file mode 100755 index 000000000000..da7b029ca732 --- /dev/null +++ b/src/ci/docker/scripts/rfl-build.sh @@ -0,0 +1,68 @@ +#!/bin/bash + +set -euo pipefail + +LINUX_VERSION=c13320499ba0efd93174ef6462ae8a7a2933f6e7 + +# Build rustc, rustdoc and cargo +../x.py build --stage 1 library rustdoc +../x.py build --stage 0 cargo + +# Install rustup so that we can use the built toolchain easily, and also +# install bindgen in an easy way. +curl --proto '=https' --tlsv1.2 -sSf -o rustup.sh https://sh.rustup.rs +sh rustup.sh -y --default-toolchain none + +source /cargo/env + +BUILD_DIR=$(realpath ./build) +rustup toolchain link local "${BUILD_DIR}"/x86_64-unknown-linux-gnu/stage1 +rustup default local + +mkdir -p rfl +cd rfl + +# Remove existing directory to make local builds easier +rm -rf linux || true + +# Download Linux at a specific commit +mkdir -p linux +git -C linux init +git -C linux remote add origin https://github.com/torvalds/linux.git +git -C linux fetch --depth 1 origin ${LINUX_VERSION} +git -C linux checkout FETCH_HEAD + +# Install bindgen +"${BUILD_DIR}"/x86_64-unknown-linux-gnu/stage0/bin/cargo install \ + --version $(linux/scripts/min-tool-version.sh bindgen) \ + bindgen-cli + +# Configure Rust for Linux +cat < linux/kernel/configs/rfl-for-rust-ci.config +# CONFIG_WERROR is not set + +CONFIG_RUST=y + +CONFIG_SAMPLES=y +CONFIG_SAMPLES_RUST=y + +CONFIG_SAMPLE_RUST_MINIMAL=m +CONFIG_SAMPLE_RUST_PRINT=y + +CONFIG_RUST_PHYLIB_ABSTRACTIONS=y +CONFIG_AX88796B_PHY=y +CONFIG_AX88796B_RUST_PHY=y + +CONFIG_KUNIT=y +CONFIG_RUST_KERNEL_DOCTESTS=y +EOF + +make -C linux LLVM=1 -j$(($(nproc) + 1)) \ + rustavailable \ + defconfig \ + rfl-for-rust-ci.config + +make -C linux LLVM=1 -j$(($(nproc) + 1)) \ + samples/rust/rust_minimal.o \ + samples/rust/rust_print.o \ + drivers/net/phy/ax88796b_rust.o diff --git a/src/ci/github-actions/jobs.yml b/src/ci/github-actions/jobs.yml index 48c39d2c33e5..62836acc2d9a 100644 --- a/src/ci/github-actions/jobs.yml +++ b/src/ci/github-actions/jobs.yml @@ -465,3 +465,8 @@ auto: RUST_CONFIGURE_ARGS: --build=x86_64-pc-windows-msvc --enable-extended --enable-profiler SCRIPT: python x.py dist bootstrap --include-default-paths <<: *job-windows-8c + + # Tests integration with Rust for Linux. + # Builds stage 1 compiler and tries to compile a few RfL examples with it. + - image: rfl + <<: *job-linux-8c