From 04a7fefb20629af52d00018ac7013257eb661273 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Sun, 31 Jul 2022 22:00:53 +0300 Subject: linker: Update some outdated comments --- compiler/rustc_codegen_ssa/src/back/link.rs | 24 ++++++++++++------------ compiler/rustc_codegen_ssa/src/back/metadata.rs | 12 ++++++------ 2 files changed, 18 insertions(+), 18 deletions(-) (limited to 'compiler/rustc_codegen_ssa/src') diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs index 13a7b6be947..8cd2ba54864 100644 --- a/compiler/rustc_codegen_ssa/src/back/link.rs +++ b/compiler/rustc_codegen_ssa/src/back/link.rs @@ -1947,7 +1947,6 @@ fn linker_with_args<'a>( // Upstream rust libraries are not supposed to depend on our local native // libraries as that would violate the structure of the DAG, in that // scenario they are required to link to them as well in a shared fashion. - // (The current implementation still doesn't prevent it though, see the FIXME below.) // // Note that upstream rust libraries may contain native dependencies as // well, but they also can't depend on what we just started to add to the @@ -1968,15 +1967,16 @@ fn linker_with_args<'a>( // and move this option back to the top. cmd.add_as_needed(); - // FIXME: Move this below to other native libraries - // (or alternatively link all native libraries after their respective crates). - // This change is somewhat breaking in practice due to local static libraries being linked - // as whole-archive (#85144), so removing whole-archive may be a pre-requisite. + // Local native libraries of all kinds. + // + // If `-Zlink-native-libraries=false` is set, then the assumption is that an + // external build system already has the native dependencies defined, and it + // will provide them to the linker itself. if sess.opts.unstable_opts.link_native_libraries { add_local_native_libraries(cmd, sess, codegen_results); } - // Upstream rust libraries and their non-bundled static libraries + // Upstream rust libraries and their (possibly bundled) static native libraries. add_upstream_rust_crates( cmd, sess, @@ -1986,11 +1986,11 @@ fn linker_with_args<'a>( tmpdir, ); - // Upstream dynamic native libraries linked with `#[link]` attributes at and `-l` - // command line options. - // If -Zlink-native-libraries=false is set, then the assumption is that an - // external build system already has the native dependencies defined, and it - // will provide them to the linker itself. + // Dynamic native libraries from upstream crates. + // + // FIXME: Merge this to `add_upstream_rust_crates` so that all native libraries are linked + // together with their respective upstream crates, and in their originally specified order. + // This may be slightly breaking due to our use of `--as-needed` and needs a crater run. if sess.opts.unstable_opts.link_native_libraries { add_upstream_native_libraries(cmd, sess, codegen_results); } @@ -2401,7 +2401,7 @@ fn add_upstream_rust_crates<'a>( // or is an rlib already included via some other dylib crate, the symbols from // native libs will have already been included in that dylib. // - // If -Zlink-native-libraries=false is set, then the assumption is that an + // If `-Zlink-native-libraries=false` is set, then the assumption is that an // external build system already has the native dependencies defined, and it // will provide them to the linker itself. if sess.opts.unstable_opts.link_native_libraries { diff --git a/compiler/rustc_codegen_ssa/src/back/metadata.rs b/compiler/rustc_codegen_ssa/src/back/metadata.rs index 0302c28815a..b92e146bee2 100644 --- a/compiler/rustc_codegen_ssa/src/back/metadata.rs +++ b/compiler/rustc_codegen_ssa/src/back/metadata.rs @@ -187,12 +187,12 @@ pub enum MetadataPosition { Last, } -// For rlibs we "pack" rustc metadata into a dummy object file. When rustc -// creates a dylib crate type it will pass `--whole-archive` (or the -// platform equivalent) to include all object files from an rlib into the -// final dylib itself. This causes linkers to iterate and try to include all -// files located in an archive, so if metadata is stored in an archive then -// it needs to be of a form that the linker will be able to process. +// For rlibs we "pack" rustc metadata into a dummy object file. +// +// Historically it was needed because rustc linked rlibs as whole-archive in some cases. +// In that case linkers try to include all files located in an archive, so if metadata is stored +// in an archive then it needs to be of a form that the linker is able to process. +// Now it's not clear whether metadata still needs to be wrapped into an object file or not. // // Note, though, that we don't actually want this metadata to show up in any // final output of the compiler. Instead this is purely for rustc's own -- cgit 1.4.1-3-g733a5 From 3c8563abcf91eda340aa77d238954dd00fa0cb34 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sat, 6 Aug 2022 17:18:59 -0400 Subject: make NOP dyn casts not require anything about the vtable --- compiler/rustc_codegen_cranelift/src/unsize.rs | 1 + compiler/rustc_codegen_ssa/src/base.rs | 1 + compiler/rustc_const_eval/src/interpret/cast.rs | 7 +++++- .../ui/consts/const-eval/ub-wide-ptr.32bit.stderr | 26 +++++++++++++++------- .../ui/consts/const-eval/ub-wide-ptr.64bit.stderr | 26 +++++++++++++++------- src/test/ui/consts/const-eval/ub-wide-ptr.rs | 6 ++--- 6 files changed, 46 insertions(+), 21 deletions(-) (limited to 'compiler/rustc_codegen_ssa/src') diff --git a/compiler/rustc_codegen_cranelift/src/unsize.rs b/compiler/rustc_codegen_cranelift/src/unsize.rs index 052ca0a082b..dd9d891ddbd 100644 --- a/compiler/rustc_codegen_cranelift/src/unsize.rs +++ b/compiler/rustc_codegen_cranelift/src/unsize.rs @@ -29,6 +29,7 @@ pub(crate) fn unsized_info<'tcx>( let old_info = old_info.expect("unsized_info: missing old info for trait upcasting coercion"); if data_a.principal_def_id() == data_b.principal_def_id() { + // A NOP cast that doesn't actually change anything, should be allowed even with invalid vtables. return old_info; } diff --git a/compiler/rustc_codegen_ssa/src/base.rs b/compiler/rustc_codegen_ssa/src/base.rs index a840b270974..4c6be3f9108 100644 --- a/compiler/rustc_codegen_ssa/src/base.rs +++ b/compiler/rustc_codegen_ssa/src/base.rs @@ -151,6 +151,7 @@ pub fn unsized_info<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( let old_info = old_info.expect("unsized_info: missing old info for trait upcasting coercion"); if data_a.principal_def_id() == data_b.principal_def_id() { + // A NOP cast that doesn't actually change anything, should be allowed even with invalid vtables. return old_info; } diff --git a/compiler/rustc_const_eval/src/interpret/cast.rs b/compiler/rustc_const_eval/src/interpret/cast.rs index c97c31eb9da..14eb2a1537b 100644 --- a/compiler/rustc_const_eval/src/interpret/cast.rs +++ b/compiler/rustc_const_eval/src/interpret/cast.rs @@ -298,7 +298,12 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { self.write_immediate(val, dest) } (&ty::Dynamic(ref data_a, ..), &ty::Dynamic(ref data_b, ..)) => { - let (old_data, old_vptr) = self.read_immediate(src)?.to_scalar_pair()?; + let val = self.read_immediate(src)?; + if data_a.principal() == data_b.principal() { + // A NOP cast that doesn't actually change anything, should be allowed even with mismatching vtables. + return self.write_immediate(*val, dest); + } + let (old_data, old_vptr) = val.to_scalar_pair()?; let old_vptr = old_vptr.to_pointer(self)?; let (ty, old_trait) = self.get_ptr_vtable(old_vptr)?; if old_trait != data_a.principal() { diff --git a/src/test/ui/consts/const-eval/ub-wide-ptr.32bit.stderr b/src/test/ui/consts/const-eval/ub-wide-ptr.32bit.stderr index 345ead48151..9431fb33c53 100644 --- a/src/test/ui/consts/const-eval/ub-wide-ptr.32bit.stderr +++ b/src/test/ui/consts/const-eval/ub-wide-ptr.32bit.stderr @@ -278,26 +278,36 @@ LL | const TRAIT_OBJ_CONTENT_INVALID: &dyn Trait = unsafe { mem::transmute::<_, ╾allocN─╼ ╾allocN─╼ │ ╾──╼╾──╼ } -error[E0080]: evaluation of constant value failed - --> $DIR/ub-wide-ptr.rs:147:62 +error[E0080]: it is undefined behavior to use this value + --> $DIR/ub-wide-ptr.rs:147:1 | LL | const RAW_TRAIT_OBJ_VTABLE_NULL: *const dyn Trait = unsafe { mem::transmute((&92u8, 0usize)) }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ out-of-bounds pointer use: null pointer is a dangling pointer (it has no provenance) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered null pointer, but expected a vtable pointer + | + = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + = note: the raw bytes of the constant (size: 8, align: 4) { + ╾allocN─╼ 00 00 00 00 │ ╾──╼.... + } -error[E0080]: evaluation of constant value failed - --> $DIR/ub-wide-ptr.rs:150:65 +error[E0080]: it is undefined behavior to use this value + --> $DIR/ub-wide-ptr.rs:149:1 | LL | const RAW_TRAIT_OBJ_VTABLE_INVALID: *const dyn Trait = unsafe { mem::transmute((&92u8, &3u64)) }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ using allocN as vtable pointer but it does not point to a vtable + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered allocN, but expected a vtable pointer + | + = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + = note: the raw bytes of the constant (size: 8, align: 4) { + ╾allocN─╼ ╾allocN─╼ │ ╾──╼╾──╼ + } error[E0080]: could not evaluate static initializer - --> $DIR/ub-wide-ptr.rs:157:5 + --> $DIR/ub-wide-ptr.rs:155:5 | LL | mem::transmute::<_, &dyn Trait>((&92u8, 0usize)) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ out-of-bounds pointer use: null pointer is a dangling pointer (it has no provenance) error[E0080]: could not evaluate static initializer - --> $DIR/ub-wide-ptr.rs:161:5 + --> $DIR/ub-wide-ptr.rs:159:5 | LL | mem::transmute::<_, &dyn Trait>((&92u8, &3u64)) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ using allocN as vtable pointer but it does not point to a vtable diff --git a/src/test/ui/consts/const-eval/ub-wide-ptr.64bit.stderr b/src/test/ui/consts/const-eval/ub-wide-ptr.64bit.stderr index 501932cb95c..15ef703024a 100644 --- a/src/test/ui/consts/const-eval/ub-wide-ptr.64bit.stderr +++ b/src/test/ui/consts/const-eval/ub-wide-ptr.64bit.stderr @@ -278,26 +278,36 @@ LL | const TRAIT_OBJ_CONTENT_INVALID: &dyn Trait = unsafe { mem::transmute::<_, ╾──────allocN───────╼ ╾──────allocN───────╼ │ ╾──────╼╾──────╼ } -error[E0080]: evaluation of constant value failed - --> $DIR/ub-wide-ptr.rs:147:62 +error[E0080]: it is undefined behavior to use this value + --> $DIR/ub-wide-ptr.rs:147:1 | LL | const RAW_TRAIT_OBJ_VTABLE_NULL: *const dyn Trait = unsafe { mem::transmute((&92u8, 0usize)) }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ out-of-bounds pointer use: null pointer is a dangling pointer (it has no provenance) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered null pointer, but expected a vtable pointer + | + = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + = note: the raw bytes of the constant (size: 16, align: 8) { + ╾──────allocN───────╼ 00 00 00 00 00 00 00 00 │ ╾──────╼........ + } -error[E0080]: evaluation of constant value failed - --> $DIR/ub-wide-ptr.rs:150:65 +error[E0080]: it is undefined behavior to use this value + --> $DIR/ub-wide-ptr.rs:149:1 | LL | const RAW_TRAIT_OBJ_VTABLE_INVALID: *const dyn Trait = unsafe { mem::transmute((&92u8, &3u64)) }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ using allocN as vtable pointer but it does not point to a vtable + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered allocN, but expected a vtable pointer + | + = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + = note: the raw bytes of the constant (size: 16, align: 8) { + ╾──────allocN───────╼ ╾──────allocN───────╼ │ ╾──────╼╾──────╼ + } error[E0080]: could not evaluate static initializer - --> $DIR/ub-wide-ptr.rs:157:5 + --> $DIR/ub-wide-ptr.rs:155:5 | LL | mem::transmute::<_, &dyn Trait>((&92u8, 0usize)) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ out-of-bounds pointer use: null pointer is a dangling pointer (it has no provenance) error[E0080]: could not evaluate static initializer - --> $DIR/ub-wide-ptr.rs:161:5 + --> $DIR/ub-wide-ptr.rs:159:5 | LL | mem::transmute::<_, &dyn Trait>((&92u8, &3u64)) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ using allocN as vtable pointer but it does not point to a vtable diff --git a/src/test/ui/consts/const-eval/ub-wide-ptr.rs b/src/test/ui/consts/const-eval/ub-wide-ptr.rs index a0377ab1efd..2da694a8bc4 100644 --- a/src/test/ui/consts/const-eval/ub-wide-ptr.rs +++ b/src/test/ui/consts/const-eval/ub-wide-ptr.rs @@ -145,11 +145,9 @@ const TRAIT_OBJ_CONTENT_INVALID: &dyn Trait = unsafe { mem::transmute::<_, &bool // # raw trait object const RAW_TRAIT_OBJ_VTABLE_NULL: *const dyn Trait = unsafe { mem::transmute((&92u8, 0usize)) }; -//~^ ERROR evaluation of constant value failed -//~| null pointer +//~^ ERROR it is undefined behavior to use this value const RAW_TRAIT_OBJ_VTABLE_INVALID: *const dyn Trait = unsafe { mem::transmute((&92u8, &3u64)) }; -//~^ ERROR evaluation of constant value failed -//~| does not point to a vtable +//~^ ERROR it is undefined behavior to use this value const RAW_TRAIT_OBJ_CONTENT_INVALID: *const dyn Trait = unsafe { mem::transmute::<_, &bool>(&3u8) } as *const dyn Trait; // ok because raw // Const eval fails for these, so they need to be statics to error. -- cgit 1.4.1-3-g733a5 From 147032a61896db76e97bfde9fa0e711fd5e62b08 Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Tue, 16 Aug 2022 15:46:17 -0700 Subject: Move the cast_float_to_int fallback code to GCC Now that we require at least LLVM 13, that codegen backend is always using its intrinsic `fptosi.sat` and `fptoui.sat` conversions, so it doesn't need the manual implementation. However, the GCC backend still needs it, so we can move all of that code down there. --- Cargo.lock | 1 - compiler/rustc_codegen_gcc/src/builder.rs | 174 ++++++++++++++++++++++- compiler/rustc_codegen_gcc/src/lib.rs | 1 + compiler/rustc_codegen_llvm/src/builder.rs | 13 +- compiler/rustc_codegen_ssa/Cargo.toml | 1 - compiler/rustc_codegen_ssa/src/traits/builder.rs | 157 +------------------- 6 files changed, 177 insertions(+), 170 deletions(-) (limited to 'compiler/rustc_codegen_ssa/src') diff --git a/Cargo.lock b/Cargo.lock index 395f5a127bd..aabb04995eb 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3721,7 +3721,6 @@ dependencies = [ "object 0.29.0", "pathdiff", "regex", - "rustc_apfloat", "rustc_arena", "rustc_ast", "rustc_attr", diff --git a/compiler/rustc_codegen_gcc/src/builder.rs b/compiler/rustc_codegen_gcc/src/builder.rs index 4d40dd0994d..6994eeb00c3 100644 --- a/compiler/rustc_codegen_gcc/src/builder.rs +++ b/compiler/rustc_codegen_gcc/src/builder.rs @@ -15,8 +15,11 @@ use gccjit::{ Type, UnaryOp, }; +use rustc_apfloat::{ieee, Float, Round, Status}; use rustc_codegen_ssa::MemFlags; -use rustc_codegen_ssa::common::{AtomicOrdering, AtomicRmwBinOp, IntPredicate, RealPredicate, SynchronizationScope}; +use rustc_codegen_ssa::common::{ + AtomicOrdering, AtomicRmwBinOp, IntPredicate, RealPredicate, SynchronizationScope, TypeKind, +}; use rustc_codegen_ssa::mir::operand::{OperandRef, OperandValue}; use rustc_codegen_ssa::mir::place::PlaceRef; use rustc_codegen_ssa::traits::{ @@ -31,6 +34,7 @@ use rustc_codegen_ssa::traits::{ StaticBuilderMethods, }; use rustc_data_structures::fx::FxHashSet; +use rustc_middle::bug; use rustc_middle::ty::{ParamEnv, Ty, TyCtxt}; use rustc_middle::ty::layout::{FnAbiError, FnAbiOfHelpers, FnAbiRequest, HasParamEnv, HasTyCtxt, LayoutError, LayoutOfHelpers, TyAndLayout}; use rustc_span::Span; @@ -1271,12 +1275,12 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> { val } - fn fptoui_sat(&mut self, _val: RValue<'gcc>, _dest_ty: Type<'gcc>) -> Option> { - None + fn fptoui_sat(&mut self, val: RValue<'gcc>, dest_ty: Type<'gcc>) -> RValue<'gcc> { + self.fptoint_sat(false, val, dest_ty) } - fn fptosi_sat(&mut self, _val: RValue<'gcc>, _dest_ty: Type<'gcc>) -> Option> { - None + fn fptosi_sat(&mut self, val: RValue<'gcc>, dest_ty: Type<'gcc>) -> RValue<'gcc> { + self.fptoint_sat(true, val, dest_ty) } fn instrprof_increment(&mut self, _fn_name: RValue<'gcc>, _hash: RValue<'gcc>, _num_counters: RValue<'gcc>, _index: RValue<'gcc>) { @@ -1285,6 +1289,166 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> { } impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> { + fn fptoint_sat(&mut self, signed: bool, val: RValue<'gcc>, dest_ty: Type<'gcc>) -> RValue<'gcc> { + let src_ty = self.cx.val_ty(val); + let (float_ty, int_ty) = if self.cx.type_kind(src_ty) == TypeKind::Vector { + assert_eq!(self.cx.vector_length(src_ty), self.cx.vector_length(dest_ty)); + (self.cx.element_type(src_ty), self.cx.element_type(dest_ty)) + } else { + (src_ty, dest_ty) + }; + + // FIXME(jistone): the following was originally the fallback SSA implementation, before LLVM 13 + // added native `fptosi.sat` and `fptoui.sat` conversions, but it was used by GCC as well. + // Now that LLVM always relies on its own, the code has been moved to GCC, but the comments are + // still LLVM-specific. This should be updated, and use better GCC specifics if possible. + + let int_width = self.cx.int_width(int_ty); + let float_width = self.cx.float_width(float_ty); + // LLVM's fpto[su]i returns undef when the input val is infinite, NaN, or does not fit into the + // destination integer type after rounding towards zero. This `undef` value can cause UB in + // safe code (see issue #10184), so we implement a saturating conversion on top of it: + // Semantically, the mathematical value of the input is rounded towards zero to the next + // mathematical integer, and then the result is clamped into the range of the destination + // integer type. Positive and negative infinity are mapped to the maximum and minimum value of + // the destination integer type. NaN is mapped to 0. + // + // Define f_min and f_max as the largest and smallest (finite) floats that are exactly equal to + // a value representable in int_ty. + // They are exactly equal to int_ty::{MIN,MAX} if float_ty has enough significand bits. + // Otherwise, int_ty::MAX must be rounded towards zero, as it is one less than a power of two. + // int_ty::MIN, however, is either zero or a negative power of two and is thus exactly + // representable. Note that this only works if float_ty's exponent range is sufficiently large. + // f16 or 256 bit integers would break this property. Right now the smallest float type is f32 + // with exponents ranging up to 127, which is barely enough for i128::MIN = -2^127. + // On the other hand, f_max works even if int_ty::MAX is greater than float_ty::MAX. Because + // we're rounding towards zero, we just get float_ty::MAX (which is always an integer). + // This already happens today with u128::MAX = 2^128 - 1 > f32::MAX. + let int_max = |signed: bool, int_width: u64| -> u128 { + let shift_amount = 128 - int_width; + if signed { i128::MAX as u128 >> shift_amount } else { u128::MAX >> shift_amount } + }; + let int_min = |signed: bool, int_width: u64| -> i128 { + if signed { i128::MIN >> (128 - int_width) } else { 0 } + }; + + let compute_clamp_bounds_single = |signed: bool, int_width: u64| -> (u128, u128) { + let rounded_min = + ieee::Single::from_i128_r(int_min(signed, int_width), Round::TowardZero); + assert_eq!(rounded_min.status, Status::OK); + let rounded_max = + ieee::Single::from_u128_r(int_max(signed, int_width), Round::TowardZero); + assert!(rounded_max.value.is_finite()); + (rounded_min.value.to_bits(), rounded_max.value.to_bits()) + }; + let compute_clamp_bounds_double = |signed: bool, int_width: u64| -> (u128, u128) { + let rounded_min = + ieee::Double::from_i128_r(int_min(signed, int_width), Round::TowardZero); + assert_eq!(rounded_min.status, Status::OK); + let rounded_max = + ieee::Double::from_u128_r(int_max(signed, int_width), Round::TowardZero); + assert!(rounded_max.value.is_finite()); + (rounded_min.value.to_bits(), rounded_max.value.to_bits()) + }; + // To implement saturation, we perform the following steps: + // + // 1. Cast val to an integer with fpto[su]i. This may result in undef. + // 2. Compare val to f_min and f_max, and use the comparison results to select: + // a) int_ty::MIN if val < f_min or val is NaN + // b) int_ty::MAX if val > f_max + // c) the result of fpto[su]i otherwise + // 3. If val is NaN, return 0.0, otherwise return the result of step 2. + // + // This avoids resulting undef because values in range [f_min, f_max] by definition fit into the + // destination type. It creates an undef temporary, but *producing* undef is not UB. Our use of + // undef does not introduce any non-determinism either. + // More importantly, the above procedure correctly implements saturating conversion. + // Proof (sketch): + // If val is NaN, 0 is returned by definition. + // Otherwise, val is finite or infinite and thus can be compared with f_min and f_max. + // This yields three cases to consider: + // (1) if val in [f_min, f_max], the result of fpto[su]i is returned, which agrees with + // saturating conversion for inputs in that range. + // (2) if val > f_max, then val is larger than int_ty::MAX. This holds even if f_max is rounded + // (i.e., if f_max < int_ty::MAX) because in those cases, nextUp(f_max) is already larger + // than int_ty::MAX. Because val is larger than int_ty::MAX, the return value of int_ty::MAX + // is correct. + // (3) if val < f_min, then val is smaller than int_ty::MIN. As shown earlier, f_min exactly equals + // int_ty::MIN and therefore the return value of int_ty::MIN is correct. + // QED. + + let float_bits_to_llval = |bx: &mut Self, bits| { + let bits_llval = match float_width { + 32 => bx.cx().const_u32(bits as u32), + 64 => bx.cx().const_u64(bits as u64), + n => bug!("unsupported float width {}", n), + }; + bx.bitcast(bits_llval, float_ty) + }; + let (f_min, f_max) = match float_width { + 32 => compute_clamp_bounds_single(signed, int_width), + 64 => compute_clamp_bounds_double(signed, int_width), + n => bug!("unsupported float width {}", n), + }; + let f_min = float_bits_to_llval(self, f_min); + let f_max = float_bits_to_llval(self, f_max); + let int_max = self.cx.const_uint_big(int_ty, int_max(signed, int_width)); + let int_min = self.cx.const_uint_big(int_ty, int_min(signed, int_width) as u128); + let zero = self.cx.const_uint(int_ty, 0); + + // If we're working with vectors, constants must be "splatted": the constant is duplicated + // into each lane of the vector. The algorithm stays the same, we are just using the + // same constant across all lanes. + let maybe_splat = |bx: &mut Self, val| { + if bx.cx().type_kind(dest_ty) == TypeKind::Vector { + bx.vector_splat(bx.vector_length(dest_ty), val) + } else { + val + } + }; + let f_min = maybe_splat(self, f_min); + let f_max = maybe_splat(self, f_max); + let int_max = maybe_splat(self, int_max); + let int_min = maybe_splat(self, int_min); + let zero = maybe_splat(self, zero); + + // Step 1 ... + let fptosui_result = if signed { self.fptosi(val, dest_ty) } else { self.fptoui(val, dest_ty) }; + let less_or_nan = self.fcmp(RealPredicate::RealULT, val, f_min); + let greater = self.fcmp(RealPredicate::RealOGT, val, f_max); + + // Step 2: We use two comparisons and two selects, with %s1 being the + // result: + // %less_or_nan = fcmp ult %val, %f_min + // %greater = fcmp olt %val, %f_max + // %s0 = select %less_or_nan, int_ty::MIN, %fptosi_result + // %s1 = select %greater, int_ty::MAX, %s0 + // Note that %less_or_nan uses an *unordered* comparison. This + // comparison is true if the operands are not comparable (i.e., if val is + // NaN). The unordered comparison ensures that s1 becomes int_ty::MIN if + // val is NaN. + // + // Performance note: Unordered comparison can be lowered to a "flipped" + // comparison and a negation, and the negation can be merged into the + // select. Therefore, it not necessarily any more expensive than an + // ordered ("normal") comparison. Whether these optimizations will be + // performed is ultimately up to the backend, but at least x86 does + // perform them. + let s0 = self.select(less_or_nan, int_min, fptosui_result); + let s1 = self.select(greater, int_max, s0); + + // Step 3: NaN replacement. + // For unsigned types, the above step already yielded int_ty::MIN == 0 if val is NaN. + // Therefore we only need to execute this step for signed integer types. + if signed { + // LLVM has no isNaN predicate, so we use (val == val) instead + let cmp = self.fcmp(RealPredicate::RealOEQ, val, val); + self.select(cmp, s1, zero) + } else { + s1 + } + } + #[cfg(feature="master")] pub fn shuffle_vector(&mut self, v1: RValue<'gcc>, v2: RValue<'gcc>, mask: RValue<'gcc>) -> RValue<'gcc> { let struct_type = mask.get_type().is_struct().expect("mask of struct type"); diff --git a/compiler/rustc_codegen_gcc/src/lib.rs b/compiler/rustc_codegen_gcc/src/lib.rs index 8a206c0368f..223466fb9b5 100644 --- a/compiler/rustc_codegen_gcc/src/lib.rs +++ b/compiler/rustc_codegen_gcc/src/lib.rs @@ -19,6 +19,7 @@ #![warn(rust_2018_idioms)] #![warn(unused_lifetimes)] +extern crate rustc_apfloat; extern crate rustc_ast; extern crate rustc_codegen_ssa; extern crate rustc_data_structures; diff --git a/compiler/rustc_codegen_llvm/src/builder.rs b/compiler/rustc_codegen_llvm/src/builder.rs index 073feecb164..e7e373bf45d 100644 --- a/compiler/rustc_codegen_llvm/src/builder.rs +++ b/compiler/rustc_codegen_llvm/src/builder.rs @@ -725,11 +725,11 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> { unsafe { llvm::LLVMBuildSExt(self.llbuilder, val, dest_ty, UNNAMED) } } - fn fptoui_sat(&mut self, val: &'ll Value, dest_ty: &'ll Type) -> Option<&'ll Value> { + fn fptoui_sat(&mut self, val: &'ll Value, dest_ty: &'ll Type) -> &'ll Value { self.fptoint_sat(false, val, dest_ty) } - fn fptosi_sat(&mut self, val: &'ll Value, dest_ty: &'ll Type) -> Option<&'ll Value> { + fn fptosi_sat(&mut self, val: &'ll Value, dest_ty: &'ll Type) -> &'ll Value { self.fptoint_sat(true, val, dest_ty) } @@ -1429,12 +1429,7 @@ impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> { } } - fn fptoint_sat( - &mut self, - signed: bool, - val: &'ll Value, - dest_ty: &'ll Type, - ) -> Option<&'ll Value> { + fn fptoint_sat(&mut self, signed: bool, val: &'ll Value, dest_ty: &'ll Type) -> &'ll Value { let src_ty = self.cx.val_ty(val); let (float_ty, int_ty, vector_length) = if self.cx.type_kind(src_ty) == TypeKind::Vector { assert_eq!(self.cx.vector_length(src_ty), self.cx.vector_length(dest_ty)); @@ -1459,7 +1454,7 @@ impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> { format!("llvm.{}.sat.i{}.f{}", instr, int_width, float_width) }; let f = self.declare_cfn(&name, llvm::UnnamedAddr::No, self.type_func(&[src_ty], dest_ty)); - Some(self.call(self.type_func(&[src_ty], dest_ty), f, &[val], None)) + self.call(self.type_func(&[src_ty], dest_ty), f, &[val], None) } pub(crate) fn landing_pad( diff --git a/compiler/rustc_codegen_ssa/Cargo.toml b/compiler/rustc_codegen_ssa/Cargo.toml index 46d6344dbb2..d868e3d56ba 100644 --- a/compiler/rustc_codegen_ssa/Cargo.toml +++ b/compiler/rustc_codegen_ssa/Cargo.toml @@ -26,7 +26,6 @@ rustc_arena = { path = "../rustc_arena" } rustc_ast = { path = "../rustc_ast" } rustc_span = { path = "../rustc_span" } rustc_middle = { path = "../rustc_middle" } -rustc_apfloat = { path = "../rustc_apfloat" } rustc_attr = { path = "../rustc_attr" } rustc_symbol_mangling = { path = "../rustc_symbol_mangling" } rustc_data_structures = { path = "../rustc_data_structures" } diff --git a/compiler/rustc_codegen_ssa/src/traits/builder.rs b/compiler/rustc_codegen_ssa/src/traits/builder.rs index 9f49749bb41..10cf8948b5a 100644 --- a/compiler/rustc_codegen_ssa/src/traits/builder.rs +++ b/compiler/rustc_codegen_ssa/src/traits/builder.rs @@ -1,6 +1,5 @@ use super::abi::AbiBuilderMethods; use super::asm::AsmBuilderMethods; -use super::consts::ConstMethods; use super::coverageinfo::CoverageInfoBuilderMethods; use super::debuginfo::DebugInfoBuilderMethods; use super::intrinsic::IntrinsicCallMethods; @@ -15,7 +14,6 @@ use crate::mir::operand::OperandRef; use crate::mir::place::PlaceRef; use crate::MemFlags; -use rustc_apfloat::{ieee, Float, Round, Status}; use rustc_middle::ty::layout::{HasParamEnv, TyAndLayout}; use rustc_middle::ty::Ty; use rustc_span::Span; @@ -188,8 +186,8 @@ pub trait BuilderMethods<'a, 'tcx>: fn trunc(&mut self, val: Self::Value, dest_ty: Self::Type) -> Self::Value; fn sext(&mut self, val: Self::Value, dest_ty: Self::Type) -> Self::Value; - fn fptoui_sat(&mut self, val: Self::Value, dest_ty: Self::Type) -> Option; - fn fptosi_sat(&mut self, val: Self::Value, dest_ty: Self::Type) -> Option; + fn fptoui_sat(&mut self, val: Self::Value, dest_ty: Self::Type) -> Self::Value; + fn fptosi_sat(&mut self, val: Self::Value, dest_ty: Self::Type) -> Self::Value; fn fptoui(&mut self, val: Self::Value, dest_ty: Self::Type) -> Self::Value; fn fptosi(&mut self, val: Self::Value, dest_ty: Self::Type) -> Self::Value; fn uitofp(&mut self, val: Self::Value, dest_ty: Self::Type) -> Self::Value; @@ -223,156 +221,7 @@ pub trait BuilderMethods<'a, 'tcx>: return if signed { self.fptosi(x, dest_ty) } else { self.fptoui(x, dest_ty) }; } - let try_sat_result = - if signed { self.fptosi_sat(x, dest_ty) } else { self.fptoui_sat(x, dest_ty) }; - if let Some(try_sat_result) = try_sat_result { - return try_sat_result; - } - - let int_width = self.cx().int_width(int_ty); - let float_width = self.cx().float_width(float_ty); - // LLVM's fpto[su]i returns undef when the input x is infinite, NaN, or does not fit into the - // destination integer type after rounding towards zero. This `undef` value can cause UB in - // safe code (see issue #10184), so we implement a saturating conversion on top of it: - // Semantically, the mathematical value of the input is rounded towards zero to the next - // mathematical integer, and then the result is clamped into the range of the destination - // integer type. Positive and negative infinity are mapped to the maximum and minimum value of - // the destination integer type. NaN is mapped to 0. - // - // Define f_min and f_max as the largest and smallest (finite) floats that are exactly equal to - // a value representable in int_ty. - // They are exactly equal to int_ty::{MIN,MAX} if float_ty has enough significand bits. - // Otherwise, int_ty::MAX must be rounded towards zero, as it is one less than a power of two. - // int_ty::MIN, however, is either zero or a negative power of two and is thus exactly - // representable. Note that this only works if float_ty's exponent range is sufficiently large. - // f16 or 256 bit integers would break this property. Right now the smallest float type is f32 - // with exponents ranging up to 127, which is barely enough for i128::MIN = -2^127. - // On the other hand, f_max works even if int_ty::MAX is greater than float_ty::MAX. Because - // we're rounding towards zero, we just get float_ty::MAX (which is always an integer). - // This already happens today with u128::MAX = 2^128 - 1 > f32::MAX. - let int_max = |signed: bool, int_width: u64| -> u128 { - let shift_amount = 128 - int_width; - if signed { i128::MAX as u128 >> shift_amount } else { u128::MAX >> shift_amount } - }; - let int_min = |signed: bool, int_width: u64| -> i128 { - if signed { i128::MIN >> (128 - int_width) } else { 0 } - }; - - let compute_clamp_bounds_single = |signed: bool, int_width: u64| -> (u128, u128) { - let rounded_min = - ieee::Single::from_i128_r(int_min(signed, int_width), Round::TowardZero); - assert_eq!(rounded_min.status, Status::OK); - let rounded_max = - ieee::Single::from_u128_r(int_max(signed, int_width), Round::TowardZero); - assert!(rounded_max.value.is_finite()); - (rounded_min.value.to_bits(), rounded_max.value.to_bits()) - }; - let compute_clamp_bounds_double = |signed: bool, int_width: u64| -> (u128, u128) { - let rounded_min = - ieee::Double::from_i128_r(int_min(signed, int_width), Round::TowardZero); - assert_eq!(rounded_min.status, Status::OK); - let rounded_max = - ieee::Double::from_u128_r(int_max(signed, int_width), Round::TowardZero); - assert!(rounded_max.value.is_finite()); - (rounded_min.value.to_bits(), rounded_max.value.to_bits()) - }; - // To implement saturation, we perform the following steps: - // - // 1. Cast x to an integer with fpto[su]i. This may result in undef. - // 2. Compare x to f_min and f_max, and use the comparison results to select: - // a) int_ty::MIN if x < f_min or x is NaN - // b) int_ty::MAX if x > f_max - // c) the result of fpto[su]i otherwise - // 3. If x is NaN, return 0.0, otherwise return the result of step 2. - // - // This avoids resulting undef because values in range [f_min, f_max] by definition fit into the - // destination type. It creates an undef temporary, but *producing* undef is not UB. Our use of - // undef does not introduce any non-determinism either. - // More importantly, the above procedure correctly implements saturating conversion. - // Proof (sketch): - // If x is NaN, 0 is returned by definition. - // Otherwise, x is finite or infinite and thus can be compared with f_min and f_max. - // This yields three cases to consider: - // (1) if x in [f_min, f_max], the result of fpto[su]i is returned, which agrees with - // saturating conversion for inputs in that range. - // (2) if x > f_max, then x is larger than int_ty::MAX. This holds even if f_max is rounded - // (i.e., if f_max < int_ty::MAX) because in those cases, nextUp(f_max) is already larger - // than int_ty::MAX. Because x is larger than int_ty::MAX, the return value of int_ty::MAX - // is correct. - // (3) if x < f_min, then x is smaller than int_ty::MIN. As shown earlier, f_min exactly equals - // int_ty::MIN and therefore the return value of int_ty::MIN is correct. - // QED. - - let float_bits_to_llval = |bx: &mut Self, bits| { - let bits_llval = match float_width { - 32 => bx.cx().const_u32(bits as u32), - 64 => bx.cx().const_u64(bits as u64), - n => bug!("unsupported float width {}", n), - }; - bx.bitcast(bits_llval, float_ty) - }; - let (f_min, f_max) = match float_width { - 32 => compute_clamp_bounds_single(signed, int_width), - 64 => compute_clamp_bounds_double(signed, int_width), - n => bug!("unsupported float width {}", n), - }; - let f_min = float_bits_to_llval(self, f_min); - let f_max = float_bits_to_llval(self, f_max); - let int_max = self.cx().const_uint_big(int_ty, int_max(signed, int_width)); - let int_min = self.cx().const_uint_big(int_ty, int_min(signed, int_width) as u128); - let zero = self.cx().const_uint(int_ty, 0); - - // If we're working with vectors, constants must be "splatted": the constant is duplicated - // into each lane of the vector. The algorithm stays the same, we are just using the - // same constant across all lanes. - let maybe_splat = |bx: &mut Self, val| { - if bx.cx().type_kind(dest_ty) == TypeKind::Vector { - bx.vector_splat(bx.vector_length(dest_ty), val) - } else { - val - } - }; - let f_min = maybe_splat(self, f_min); - let f_max = maybe_splat(self, f_max); - let int_max = maybe_splat(self, int_max); - let int_min = maybe_splat(self, int_min); - let zero = maybe_splat(self, zero); - - // Step 1 ... - let fptosui_result = if signed { self.fptosi(x, dest_ty) } else { self.fptoui(x, dest_ty) }; - let less_or_nan = self.fcmp(RealPredicate::RealULT, x, f_min); - let greater = self.fcmp(RealPredicate::RealOGT, x, f_max); - - // Step 2: We use two comparisons and two selects, with %s1 being the - // result: - // %less_or_nan = fcmp ult %x, %f_min - // %greater = fcmp olt %x, %f_max - // %s0 = select %less_or_nan, int_ty::MIN, %fptosi_result - // %s1 = select %greater, int_ty::MAX, %s0 - // Note that %less_or_nan uses an *unordered* comparison. This - // comparison is true if the operands are not comparable (i.e., if x is - // NaN). The unordered comparison ensures that s1 becomes int_ty::MIN if - // x is NaN. - // - // Performance note: Unordered comparison can be lowered to a "flipped" - // comparison and a negation, and the negation can be merged into the - // select. Therefore, it not necessarily any more expensive than an - // ordered ("normal") comparison. Whether these optimizations will be - // performed is ultimately up to the backend, but at least x86 does - // perform them. - let s0 = self.select(less_or_nan, int_min, fptosui_result); - let s1 = self.select(greater, int_max, s0); - - // Step 3: NaN replacement. - // For unsigned types, the above step already yielded int_ty::MIN == 0 if x is NaN. - // Therefore we only need to execute this step for signed integer types. - if signed { - // LLVM has no isNaN predicate, so we use (x == x) instead - let cmp = self.fcmp(RealPredicate::RealOEQ, x, x); - self.select(cmp, s1, zero) - } else { - s1 - } + if signed { self.fptosi_sat(x, dest_ty) } else { self.fptoui_sat(x, dest_ty) } } fn icmp(&mut self, op: IntPredicate, lhs: Self::Value, rhs: Self::Value) -> Self::Value; -- cgit 1.4.1-3-g733a5 From b562f9596373881caa704e6046b2e168dd4a4eed Mon Sep 17 00:00:00 2001 From: Eric Holk Date: Mon, 22 Aug 2022 11:25:56 -0700 Subject: Refactor part of codegen_call_terminator --- compiler/rustc_codegen_ssa/src/mir/block.rs | 91 ++++++++++++++--------------- 1 file changed, 44 insertions(+), 47 deletions(-) (limited to 'compiler/rustc_codegen_ssa/src') diff --git a/compiler/rustc_codegen_ssa/src/mir/block.rs b/compiler/rustc_codegen_ssa/src/mir/block.rs index 3eee58d9d1c..47a40be5d8c 100644 --- a/compiler/rustc_codegen_ssa/src/mir/block.rs +++ b/compiler/rustc_codegen_ssa/src/mir/block.rs @@ -798,58 +798,55 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { let mut op = self.codegen_operand(&mut bx, arg); if let (0, Some(ty::InstanceDef::Virtual(_, idx))) = (i, def) { - if let Pair(..) = op.val { - // In the case of Rc, we need to explicitly pass a - // *mut RcBox with a Scalar (not ScalarPair) ABI. This is a hack - // that is understood elsewhere in the compiler as a method on - // `dyn Trait`. - // To get a `*mut RcBox`, we just keep unwrapping newtypes until - // we get a value of a built-in pointer type - 'descend_newtypes: while !op.layout.ty.is_unsafe_ptr() - && !op.layout.ty.is_region_ptr() - { - for i in 0..op.layout.fields.count() { - let field = op.extract_field(&mut bx, i); - if !field.layout.is_zst() { - // we found the one non-zero-sized field that is allowed - // now find *its* non-zero-sized field, or stop if it's a - // pointer - op = field; - continue 'descend_newtypes; + match op.val { + Pair(data_ptr, meta) => { + // In the case of Rc, we need to explicitly pass a + // *mut RcBox with a Scalar (not ScalarPair) ABI. This is a hack + // that is understood elsewhere in the compiler as a method on + // `dyn Trait`. + // To get a `*mut RcBox`, we just keep unwrapping newtypes until + // we get a value of a built-in pointer type + 'descend_newtypes: while !op.layout.ty.is_unsafe_ptr() + && !op.layout.ty.is_region_ptr() + { + for i in 0..op.layout.fields.count() { + let field = op.extract_field(&mut bx, i); + if !field.layout.is_zst() { + // we found the one non-zero-sized field that is allowed + // now find *its* non-zero-sized field, or stop if it's a + // pointer + op = field; + continue 'descend_newtypes; + } } + + span_bug!(span, "receiver has no non-zero-sized fields {:?}", op); } - span_bug!(span, "receiver has no non-zero-sized fields {:?}", op); + // now that we have `*dyn Trait` or `&dyn Trait`, split it up into its + // data pointer and vtable. Look up the method in the vtable, and pass + // the data pointer as the first argument + llfn = Some(meth::VirtualIndex::from_index(idx).get_fn( + &mut bx, + meta, + op.layout.ty, + &fn_abi, + )); + llargs.push(data_ptr); + continue 'make_args; } - - // now that we have `*dyn Trait` or `&dyn Trait`, split it up into its - // data pointer and vtable. Look up the method in the vtable, and pass - // the data pointer as the first argument - match op.val { - Pair(data_ptr, meta) => { - llfn = Some(meth::VirtualIndex::from_index(idx).get_fn( - &mut bx, - meta, - op.layout.ty, - &fn_abi, - )); - llargs.push(data_ptr); - continue 'make_args; - } - other => bug!("expected a Pair, got {:?}", other), + Ref(data_ptr, Some(meta), _) => { + // by-value dynamic dispatch + llfn = Some(meth::VirtualIndex::from_index(idx).get_fn( + &mut bx, + meta, + op.layout.ty, + &fn_abi, + )); + llargs.push(data_ptr); + continue; } - } else if let Ref(data_ptr, Some(meta), _) = op.val { - // by-value dynamic dispatch - llfn = Some(meth::VirtualIndex::from_index(idx).get_fn( - &mut bx, - meta, - op.layout.ty, - &fn_abi, - )); - llargs.push(data_ptr); - continue; - } else { - span_bug!(span, "can't codegen a virtual call on {:?}", op); + _ => span_bug!(span, "can't codegen a virtual call on {:?}", op), } } -- cgit 1.4.1-3-g733a5 From 3f883b850d81be5ba6a2a4039de33fd7dd7c188d Mon Sep 17 00:00:00 2001 From: Adrian Tombu Date: Wed, 24 Aug 2022 19:15:44 +0200 Subject: Start adding enum errors for deserialize_rlink --- compiler/rustc_codegen_ssa/src/lib.rs | 26 ++++++++++---- .../rustc_codegen_ssa/src/session_diagnostic.rs | 42 ++++++++++++++++++++++ compiler/rustc_driver/src/lib.rs | 4 +-- compiler/rustc_driver/src/session_diagnostics.rs | 3 +- .../locales/en-US/codegen_ssa.ftl | 9 +++++ compiler/rustc_error_messages/src/lib.rs | 1 + compiler/rustc_macros/src/lib.rs | 1 + 7 files changed, 76 insertions(+), 10 deletions(-) create mode 100644 compiler/rustc_codegen_ssa/src/session_diagnostic.rs create mode 100644 compiler/rustc_error_messages/locales/en-US/codegen_ssa.ftl (limited to 'compiler/rustc_codegen_ssa/src') diff --git a/compiler/rustc_codegen_ssa/src/lib.rs b/compiler/rustc_codegen_ssa/src/lib.rs index 1802eedf193..deabdca75cb 100644 --- a/compiler/rustc_codegen_ssa/src/lib.rs +++ b/compiler/rustc_codegen_ssa/src/lib.rs @@ -21,6 +21,7 @@ extern crate tracing; #[macro_use] extern crate rustc_middle; +use crate::session_diagnostic::{DeserializeRlinkError, DeserializeRlinkErrorSub}; use rustc_ast as ast; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_data_structures::sync::Lrc; @@ -49,6 +50,7 @@ pub mod glue; pub mod meth; pub mod mir; pub mod mono_item; +pub mod session_diagnostic; pub mod target_features; pub mod traits; @@ -212,30 +214,40 @@ impl CodegenResults { encoder.finish() } - pub fn deserialize_rlink(data: Vec) -> Result { + pub fn deserialize_rlink(data: Vec) -> Result { // The Decodable machinery is not used here because it panics if the input data is invalid // and because its internal representation may change. if !data.starts_with(RLINK_MAGIC) { - return Err("The input does not look like a .rlink file".to_string()); + return Err(DeserializeRlinkError { sub: DeserializeRlinkErrorSub::WrongFileType }); } let data = &data[RLINK_MAGIC.len()..]; if data.len() < 4 { - return Err("The input does not contain version number".to_string()); + return Err(DeserializeRlinkError { + sub: DeserializeRlinkErrorSub::EmptyVersionNumber, + }); } let mut version_array: [u8; 4] = Default::default(); version_array.copy_from_slice(&data[..4]); if u32::from_be_bytes(version_array) != RLINK_VERSION { - return Err(".rlink file was produced with encoding version {version_array}, but the current version is {RLINK_VERSION}".to_string()); + return Err(DeserializeRlinkError { + sub: DeserializeRlinkErrorSub::EncodingVersionMismatch { + version_array: String::from_utf8_lossy(&version_array).to_string(), + rlink_version: RLINK_VERSION.to_string(), + }, + }); } let mut decoder = MemDecoder::new(&data[4..], 0); let rustc_version = decoder.read_str(); let current_version = RUSTC_VERSION.unwrap(); if rustc_version != current_version { - return Err(format!( - ".rlink file was produced by rustc version {rustc_version}, but the current version is {current_version}." - )); + return Err(DeserializeRlinkError { + sub: DeserializeRlinkErrorSub::RustcVersionMismatch { + rustc_version: rustc_version.to_string(), + current_version: current_version.to_string(), + }, + }); } let codegen_results = CodegenResults::decode(&mut decoder); diff --git a/compiler/rustc_codegen_ssa/src/session_diagnostic.rs b/compiler/rustc_codegen_ssa/src/session_diagnostic.rs new file mode 100644 index 00000000000..ac7065ae23c --- /dev/null +++ b/compiler/rustc_codegen_ssa/src/session_diagnostic.rs @@ -0,0 +1,42 @@ +use rustc_errors::{fluent, DiagnosticArgValue, IntoDiagnosticArg}; +use rustc_macros::{SessionDiagnostic, SessionSubdiagnostic}; +use std::borrow::Cow; + +#[derive(SessionDiagnostic)] +#[diag(codegen_ssa::error)] +pub struct DeserializeRlinkError { + #[subdiagnostic] + pub sub: DeserializeRlinkErrorSub, +} + +#[derive(SessionSubdiagnostic)] +pub enum DeserializeRlinkErrorSub { + #[note(codegen_ssa::wrong_file_type)] + WrongFileType, + + #[note(codegen_ssa::empty_version_number)] + EmptyVersionNumber, + + #[note(codegen_ssa::encoding_version_mismatch)] + EncodingVersionMismatch { version_array: String, rlink_version: String }, + + #[note(codegen_ssa::rustc_version_mismatch)] + RustcVersionMismatch { rustc_version: String, current_version: String }, +} + +impl IntoDiagnosticArg for DeserializeRlinkErrorSub { + fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> { + DiagnosticArgValue::Str(Cow::Borrowed(match self { + DeserializeRlinkErrorSub::WrongFileType => fluent::codegen_ssa::wrong_file_type, + DeserializeRlinkErrorSub::EmptyVersionNumber => { + fluent::codegen_ssa::empty_version_number + } + DeserializeRlinkErrorSub::EncodingVersionMismatch { version_array, rlink_version } => { + fluent::codegen_ssa::encoding_version_mismatch + } + DeserializeRlinkErrorSub::RustcVersionMismatch { rustc_version, current_version } => { + fluent::codegen_ssa::rustc_version_mismatch + } + })) + } +} diff --git a/compiler/rustc_driver/src/lib.rs b/compiler/rustc_driver/src/lib.rs index 90e4d629b61..99999909d57 100644 --- a/compiler/rustc_driver/src/lib.rs +++ b/compiler/rustc_driver/src/lib.rs @@ -590,8 +590,8 @@ pub fn try_process_rlink(sess: &Session, compiler: &interface::Compiler) -> Comp }); let codegen_results = match CodegenResults::deserialize_rlink(rlink_data) { Ok(codegen) => codegen, - Err(error_message) => { - sess.emit_fatal(RlinkUnableToDeserialize { error_message }); + Err(err) => { + sess.emit_fatal(RlinkUnableToDeserialize { err }); } }; let result = compiler.codegen_backend().link(sess, codegen_results, &outputs); diff --git a/compiler/rustc_driver/src/session_diagnostics.rs b/compiler/rustc_driver/src/session_diagnostics.rs index a5dbef45475..86ee51bc97d 100644 --- a/compiler/rustc_driver/src/session_diagnostics.rs +++ b/compiler/rustc_driver/src/session_diagnostics.rs @@ -1,3 +1,4 @@ +use rustc_codegen_ssa::session_diagnostic::DeserializeRlinkError; use rustc_macros::SessionDiagnostic; #[derive(SessionDiagnostic)] @@ -9,7 +10,7 @@ pub(crate) struct RlinkUnableToRead { #[derive(SessionDiagnostic)] #[diag(driver::rlink_unable_to_deserialize)] pub(crate) struct RlinkUnableToDeserialize { - pub error_message: String, + pub err: DeserializeRlinkError, } #[derive(SessionDiagnostic)] diff --git a/compiler/rustc_error_messages/locales/en-US/codegen_ssa.ftl b/compiler/rustc_error_messages/locales/en-US/codegen_ssa.ftl new file mode 100644 index 00000000000..f93ac354773 --- /dev/null +++ b/compiler/rustc_error_messages/locales/en-US/codegen_ssa.ftl @@ -0,0 +1,9 @@ +codegen_ssa_error = Error while deserializing rlink file + +codegen_ssa_wrong_file_type = The input does not look like a .rlink file + +codegen_ssa_empty_version_number = The input does not contain version number + +codegen_ssa_encoding_version_mismatch = .rlink file was produced with encoding version `{$version_array}`, but the current version is `{$rlink_version}` + +codegen_ssa_rustc_version_mismatch = .rlink file was produced by rustc version `{$rustc_version}`, but the current version is `{$current_version}` diff --git a/compiler/rustc_error_messages/src/lib.rs b/compiler/rustc_error_messages/src/lib.rs index 2ea07ca1a48..b4fd883d845 100644 --- a/compiler/rustc_error_messages/src/lib.rs +++ b/compiler/rustc_error_messages/src/lib.rs @@ -35,6 +35,7 @@ fluent_messages! { ast_passes => "../locales/en-US/ast_passes.ftl", borrowck => "../locales/en-US/borrowck.ftl", builtin_macros => "../locales/en-US/builtin_macros.ftl", + codegen_ssa => "../locales/en-US/codegen_ssa.ftl", const_eval => "../locales/en-US/const_eval.ftl", driver => "../locales/en-US/driver.ftl", expand => "../locales/en-US/expand.ftl", diff --git a/compiler/rustc_macros/src/lib.rs b/compiler/rustc_macros/src/lib.rs index 87d7ab6ed51..bcf406bcb95 100644 --- a/compiler/rustc_macros/src/lib.rs +++ b/compiler/rustc_macros/src/lib.rs @@ -163,6 +163,7 @@ decl_derive!( decl_derive!( [SessionSubdiagnostic, attributes( // struct/variant attributes + diag, label, help, note, -- cgit 1.4.1-3-g733a5 From bf7ce6a1a605d897832783a3d0c830d2466d90be Mon Sep 17 00:00:00 2001 From: Adrian Tombu Date: Thu, 25 Aug 2022 18:05:23 +0200 Subject: Replace spaghetti with a simple errors enum --- compiler/rustc_codegen_ssa/src/lib.rs | 33 +++++++++-------- .../rustc_codegen_ssa/src/session_diagnostic.rs | 42 ---------------------- compiler/rustc_driver/src/lib.rs | 26 ++++++++++++-- compiler/rustc_driver/src/session_diagnostics.rs | 23 +++++++++--- .../locales/en-US/codegen_ssa.ftl | 9 ----- .../rustc_error_messages/locales/en-US/driver.ftl | 8 ++++- compiler/rustc_error_messages/src/lib.rs | 1 - 7 files changed, 65 insertions(+), 77 deletions(-) delete mode 100644 compiler/rustc_codegen_ssa/src/session_diagnostic.rs delete mode 100644 compiler/rustc_error_messages/locales/en-US/codegen_ssa.ftl (limited to 'compiler/rustc_codegen_ssa/src') diff --git a/compiler/rustc_codegen_ssa/src/lib.rs b/compiler/rustc_codegen_ssa/src/lib.rs index deabdca75cb..d6fa1a15373 100644 --- a/compiler/rustc_codegen_ssa/src/lib.rs +++ b/compiler/rustc_codegen_ssa/src/lib.rs @@ -21,7 +21,6 @@ extern crate tracing; #[macro_use] extern crate rustc_middle; -use crate::session_diagnostic::{DeserializeRlinkError, DeserializeRlinkErrorSub}; use rustc_ast as ast; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_data_structures::sync::Lrc; @@ -50,7 +49,6 @@ pub mod glue; pub mod meth; pub mod mir; pub mod mono_item; -pub mod session_diagnostic; pub mod target_features; pub mod traits; @@ -170,6 +168,13 @@ pub struct CodegenResults { pub crate_info: CrateInfo, } +pub enum CodegenErrors { + WrongFileType, + EmptyVersionNumber, + EncodingVersionMismatch { version_array: String, rlink_version: String }, + RustcVersionMismatch { rustc_version: String, current_version: String }, +} + pub fn provide(providers: &mut Providers) { crate::back::symbol_export::provide(providers); crate::base::provide(providers); @@ -214,27 +219,23 @@ impl CodegenResults { encoder.finish() } - pub fn deserialize_rlink(data: Vec) -> Result { + pub fn deserialize_rlink(data: Vec) -> Result { // The Decodable machinery is not used here because it panics if the input data is invalid // and because its internal representation may change. if !data.starts_with(RLINK_MAGIC) { - return Err(DeserializeRlinkError { sub: DeserializeRlinkErrorSub::WrongFileType }); + return Err(CodegenErrors::WrongFileType); } let data = &data[RLINK_MAGIC.len()..]; if data.len() < 4 { - return Err(DeserializeRlinkError { - sub: DeserializeRlinkErrorSub::EmptyVersionNumber, - }); + return Err(CodegenErrors::EmptyVersionNumber); } let mut version_array: [u8; 4] = Default::default(); version_array.copy_from_slice(&data[..4]); if u32::from_be_bytes(version_array) != RLINK_VERSION { - return Err(DeserializeRlinkError { - sub: DeserializeRlinkErrorSub::EncodingVersionMismatch { - version_array: String::from_utf8_lossy(&version_array).to_string(), - rlink_version: RLINK_VERSION.to_string(), - }, + return Err(CodegenErrors::EncodingVersionMismatch { + version_array: String::from_utf8_lossy(&version_array).to_string(), + rlink_version: RLINK_VERSION.to_string(), }); } @@ -242,11 +243,9 @@ impl CodegenResults { let rustc_version = decoder.read_str(); let current_version = RUSTC_VERSION.unwrap(); if rustc_version != current_version { - return Err(DeserializeRlinkError { - sub: DeserializeRlinkErrorSub::RustcVersionMismatch { - rustc_version: rustc_version.to_string(), - current_version: current_version.to_string(), - }, + return Err(CodegenErrors::RustcVersionMismatch { + rustc_version: rustc_version.to_string(), + current_version: current_version.to_string(), }); } diff --git a/compiler/rustc_codegen_ssa/src/session_diagnostic.rs b/compiler/rustc_codegen_ssa/src/session_diagnostic.rs deleted file mode 100644 index ac7065ae23c..00000000000 --- a/compiler/rustc_codegen_ssa/src/session_diagnostic.rs +++ /dev/null @@ -1,42 +0,0 @@ -use rustc_errors::{fluent, DiagnosticArgValue, IntoDiagnosticArg}; -use rustc_macros::{SessionDiagnostic, SessionSubdiagnostic}; -use std::borrow::Cow; - -#[derive(SessionDiagnostic)] -#[diag(codegen_ssa::error)] -pub struct DeserializeRlinkError { - #[subdiagnostic] - pub sub: DeserializeRlinkErrorSub, -} - -#[derive(SessionSubdiagnostic)] -pub enum DeserializeRlinkErrorSub { - #[note(codegen_ssa::wrong_file_type)] - WrongFileType, - - #[note(codegen_ssa::empty_version_number)] - EmptyVersionNumber, - - #[note(codegen_ssa::encoding_version_mismatch)] - EncodingVersionMismatch { version_array: String, rlink_version: String }, - - #[note(codegen_ssa::rustc_version_mismatch)] - RustcVersionMismatch { rustc_version: String, current_version: String }, -} - -impl IntoDiagnosticArg for DeserializeRlinkErrorSub { - fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> { - DiagnosticArgValue::Str(Cow::Borrowed(match self { - DeserializeRlinkErrorSub::WrongFileType => fluent::codegen_ssa::wrong_file_type, - DeserializeRlinkErrorSub::EmptyVersionNumber => { - fluent::codegen_ssa::empty_version_number - } - DeserializeRlinkErrorSub::EncodingVersionMismatch { version_array, rlink_version } => { - fluent::codegen_ssa::encoding_version_mismatch - } - DeserializeRlinkErrorSub::RustcVersionMismatch { rustc_version, current_version } => { - fluent::codegen_ssa::rustc_version_mismatch - } - })) - } -} diff --git a/compiler/rustc_driver/src/lib.rs b/compiler/rustc_driver/src/lib.rs index 99999909d57..a193d5db691 100644 --- a/compiler/rustc_driver/src/lib.rs +++ b/compiler/rustc_driver/src/lib.rs @@ -18,7 +18,7 @@ extern crate tracing; pub extern crate rustc_plugin_impl as plugin; use rustc_ast as ast; -use rustc_codegen_ssa::{traits::CodegenBackend, CodegenResults}; +use rustc_codegen_ssa::{traits::CodegenBackend, CodegenErrors, CodegenResults}; use rustc_data_structures::profiling::{get_resident_set_size, print_time_passes_entry}; use rustc_data_structures::sync::SeqCst; use rustc_errors::registry::{InvalidErrorCode, Registry}; @@ -60,7 +60,10 @@ pub mod args; pub mod pretty; mod session_diagnostics; -use crate::session_diagnostics::{RlinkNotAFile, RlinkUnableToDeserialize, RlinkUnableToRead}; +use crate::session_diagnostics::{ + RLinkEmptyVersionNumber, RLinkEncodingVersionMismatch, RLinkRustcVersionMismatch, + RLinkWrongFileType, RlinkNotAFile, RlinkUnableToRead, +}; /// Exit status code used for successful compilation and help output. pub const EXIT_SUCCESS: i32 = 0; @@ -591,7 +594,24 @@ pub fn try_process_rlink(sess: &Session, compiler: &interface::Compiler) -> Comp let codegen_results = match CodegenResults::deserialize_rlink(rlink_data) { Ok(codegen) => codegen, Err(err) => { - sess.emit_fatal(RlinkUnableToDeserialize { err }); + match err { + CodegenErrors::WrongFileType => sess.emit_fatal(RLinkWrongFileType), + CodegenErrors::EmptyVersionNumber => { + sess.emit_fatal(RLinkEmptyVersionNumber) + } + CodegenErrors::EncodingVersionMismatch { version_array, rlink_version } => { + sess.emit_fatal(RLinkEncodingVersionMismatch { + version_array, + rlink_version, + }) + } + CodegenErrors::RustcVersionMismatch { rustc_version, current_version } => { + sess.emit_fatal(RLinkRustcVersionMismatch { + rustc_version, + current_version, + }) + } + }; } }; let result = compiler.codegen_backend().link(sess, codegen_results, &outputs); diff --git a/compiler/rustc_driver/src/session_diagnostics.rs b/compiler/rustc_driver/src/session_diagnostics.rs index 86ee51bc97d..90197ad935e 100644 --- a/compiler/rustc_driver/src/session_diagnostics.rs +++ b/compiler/rustc_driver/src/session_diagnostics.rs @@ -1,4 +1,3 @@ -use rustc_codegen_ssa::session_diagnostic::DeserializeRlinkError; use rustc_macros::SessionDiagnostic; #[derive(SessionDiagnostic)] @@ -8,9 +7,25 @@ pub(crate) struct RlinkUnableToRead { } #[derive(SessionDiagnostic)] -#[diag(driver::rlink_unable_to_deserialize)] -pub(crate) struct RlinkUnableToDeserialize { - pub err: DeserializeRlinkError, +#[diag(driver::rlink_wrong_file_type)] +pub(crate) struct RLinkWrongFileType; + +#[derive(SessionDiagnostic)] +#[diag(driver::rlink_empty_version_number)] +pub(crate) struct RLinkEmptyVersionNumber; + +#[derive(SessionDiagnostic)] +#[diag(driver::rlink_encoding_version_mismatch)] +pub(crate) struct RLinkEncodingVersionMismatch { + pub version_array: String, + pub rlink_version: String, +} + +#[derive(SessionDiagnostic)] +#[diag(driver::rlink_rustc_version_mismatch)] +pub(crate) struct RLinkRustcVersionMismatch { + pub rustc_version: String, + pub current_version: String, } #[derive(SessionDiagnostic)] diff --git a/compiler/rustc_error_messages/locales/en-US/codegen_ssa.ftl b/compiler/rustc_error_messages/locales/en-US/codegen_ssa.ftl deleted file mode 100644 index f93ac354773..00000000000 --- a/compiler/rustc_error_messages/locales/en-US/codegen_ssa.ftl +++ /dev/null @@ -1,9 +0,0 @@ -codegen_ssa_error = Error while deserializing rlink file - -codegen_ssa_wrong_file_type = The input does not look like a .rlink file - -codegen_ssa_empty_version_number = The input does not contain version number - -codegen_ssa_encoding_version_mismatch = .rlink file was produced with encoding version `{$version_array}`, but the current version is `{$rlink_version}` - -codegen_ssa_rustc_version_mismatch = .rlink file was produced by rustc version `{$rustc_version}`, but the current version is `{$current_version}` diff --git a/compiler/rustc_error_messages/locales/en-US/driver.ftl b/compiler/rustc_error_messages/locales/en-US/driver.ftl index 0a2f0e8f883..73f084cf329 100644 --- a/compiler/rustc_error_messages/locales/en-US/driver.ftl +++ b/compiler/rustc_error_messages/locales/en-US/driver.ftl @@ -1,5 +1,11 @@ driver_rlink_unable_to_read = failed to read rlink file: `{$err}` -driver_rlink_unable_to_deserialize = could not deserialize .rlink file: `{$error_message}` +driver_rlink_wrong_file_type = The input does not look like a .rlink file + +driver_rlink_empty_version_number = The input does not contain version number + +driver_rlink_encoding_version_mismatch = .rlink file was produced with encoding version `{$version_array}`, but the current version is `{$rlink_version}` + +driver_rlink_rustc_version_mismatch = .rlink file was produced by rustc version `{$rustc_version}`, but the current version is `{$current_version}` driver_rlink_no_a_file = rlink must be a file diff --git a/compiler/rustc_error_messages/src/lib.rs b/compiler/rustc_error_messages/src/lib.rs index b4fd883d845..2ea07ca1a48 100644 --- a/compiler/rustc_error_messages/src/lib.rs +++ b/compiler/rustc_error_messages/src/lib.rs @@ -35,7 +35,6 @@ fluent_messages! { ast_passes => "../locales/en-US/ast_passes.ftl", borrowck => "../locales/en-US/borrowck.ftl", builtin_macros => "../locales/en-US/builtin_macros.ftl", - codegen_ssa => "../locales/en-US/codegen_ssa.ftl", const_eval => "../locales/en-US/const_eval.ftl", driver => "../locales/en-US/driver.ftl", expand => "../locales/en-US/expand.ftl", -- cgit 1.4.1-3-g733a5 From d0401f7f475a2cad5c81114ff916b766b3cbd9c6 Mon Sep 17 00:00:00 2001 From: Adrian Tombu Date: Thu, 25 Aug 2022 19:04:00 +0200 Subject: Code cleaning --- compiler/rustc_codegen_ssa/src/lib.rs | 12 ++++++------ compiler/rustc_driver/src/session_diagnostics.rs | 6 +++--- compiler/rustc_macros/src/lib.rs | 1 - 3 files changed, 9 insertions(+), 10 deletions(-) (limited to 'compiler/rustc_codegen_ssa/src') diff --git a/compiler/rustc_codegen_ssa/src/lib.rs b/compiler/rustc_codegen_ssa/src/lib.rs index d6fa1a15373..0faf51b062b 100644 --- a/compiler/rustc_codegen_ssa/src/lib.rs +++ b/compiler/rustc_codegen_ssa/src/lib.rs @@ -168,11 +168,11 @@ pub struct CodegenResults { pub crate_info: CrateInfo, } -pub enum CodegenErrors { +pub enum CodegenErrors<'a> { WrongFileType, EmptyVersionNumber, - EncodingVersionMismatch { version_array: String, rlink_version: String }, - RustcVersionMismatch { rustc_version: String, current_version: String }, + EncodingVersionMismatch { version_array: String, rlink_version: u32 }, + RustcVersionMismatch { rustc_version: String, current_version: &'a str }, } pub fn provide(providers: &mut Providers) { @@ -219,7 +219,7 @@ impl CodegenResults { encoder.finish() } - pub fn deserialize_rlink(data: Vec) -> Result { + pub fn deserialize_rlink<'a>(data: Vec) -> Result> { // The Decodable machinery is not used here because it panics if the input data is invalid // and because its internal representation may change. if !data.starts_with(RLINK_MAGIC) { @@ -235,7 +235,7 @@ impl CodegenResults { if u32::from_be_bytes(version_array) != RLINK_VERSION { return Err(CodegenErrors::EncodingVersionMismatch { version_array: String::from_utf8_lossy(&version_array).to_string(), - rlink_version: RLINK_VERSION.to_string(), + rlink_version: RLINK_VERSION, }); } @@ -245,7 +245,7 @@ impl CodegenResults { if rustc_version != current_version { return Err(CodegenErrors::RustcVersionMismatch { rustc_version: rustc_version.to_string(), - current_version: current_version.to_string(), + current_version, }); } diff --git a/compiler/rustc_driver/src/session_diagnostics.rs b/compiler/rustc_driver/src/session_diagnostics.rs index 90197ad935e..fe64d0fca9b 100644 --- a/compiler/rustc_driver/src/session_diagnostics.rs +++ b/compiler/rustc_driver/src/session_diagnostics.rs @@ -18,14 +18,14 @@ pub(crate) struct RLinkEmptyVersionNumber; #[diag(driver::rlink_encoding_version_mismatch)] pub(crate) struct RLinkEncodingVersionMismatch { pub version_array: String, - pub rlink_version: String, + pub rlink_version: u32, } #[derive(SessionDiagnostic)] #[diag(driver::rlink_rustc_version_mismatch)] -pub(crate) struct RLinkRustcVersionMismatch { +pub(crate) struct RLinkRustcVersionMismatch<'a> { pub rustc_version: String, - pub current_version: String, + pub current_version: &'a str, } #[derive(SessionDiagnostic)] diff --git a/compiler/rustc_macros/src/lib.rs b/compiler/rustc_macros/src/lib.rs index bcf406bcb95..87d7ab6ed51 100644 --- a/compiler/rustc_macros/src/lib.rs +++ b/compiler/rustc_macros/src/lib.rs @@ -163,7 +163,6 @@ decl_derive!( decl_derive!( [SessionSubdiagnostic, attributes( // struct/variant attributes - diag, label, help, note, -- cgit 1.4.1-3-g733a5 From e4bf113027aca77fea447e15fc09a7c8ded701e9 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Thu, 25 Aug 2022 17:52:37 +1000 Subject: Box `CastTarget` within `PassMode`. Because `PassMode::Cast` is by far the largest variant, but is relatively rare. This requires making `PassMode` not impl `Copy`, and `Clone` is no longer necessary. This causes lots of sigil adjusting, but nothing very notable. --- .../rustc_codegen_cranelift/src/abi/comments.rs | 2 +- .../rustc_codegen_cranelift/src/abi/pass_mode.rs | 20 ++++++---- .../rustc_codegen_cranelift/src/abi/returning.rs | 6 +-- compiler/rustc_codegen_gcc/src/abi.rs | 4 +- compiler/rustc_codegen_gcc/src/intrinsic/mod.rs | 6 +-- compiler/rustc_codegen_llvm/src/abi.rs | 46 ++++++++++------------ compiler/rustc_codegen_llvm/src/intrinsic.rs | 4 +- compiler/rustc_codegen_ssa/src/mir/block.rs | 8 ++-- compiler/rustc_codegen_ssa/src/mir/intrinsic.rs | 4 +- .../rustc_const_eval/src/interpret/terminator.rs | 4 +- compiler/rustc_target/src/abi/call/mod.rs | 10 ++--- 11 files changed, 57 insertions(+), 57 deletions(-) (limited to 'compiler/rustc_codegen_ssa/src') diff --git a/compiler/rustc_codegen_cranelift/src/abi/comments.rs b/compiler/rustc_codegen_cranelift/src/abi/comments.rs index 37d2679c10d..7f4619b5c94 100644 --- a/compiler/rustc_codegen_cranelift/src/abi/comments.rs +++ b/compiler/rustc_codegen_cranelift/src/abi/comments.rs @@ -24,7 +24,7 @@ pub(super) fn add_arg_comment<'tcx>( local: Option, local_field: Option, params: &[Value], - arg_abi_mode: PassMode, + arg_abi_mode: &PassMode, arg_layout: TyAndLayout<'tcx>, ) { if !fx.clif_comments.enabled() { diff --git a/compiler/rustc_codegen_cranelift/src/abi/pass_mode.rs b/compiler/rustc_codegen_cranelift/src/abi/pass_mode.rs index 6c10baa53d4..058dee176e2 100644 --- a/compiler/rustc_codegen_cranelift/src/abi/pass_mode.rs +++ b/compiler/rustc_codegen_cranelift/src/abi/pass_mode.rs @@ -38,7 +38,7 @@ fn apply_arg_attrs_to_abi_param(mut param: AbiParam, arg_attrs: ArgAttributes) - param } -fn cast_target_to_abi_params(cast: CastTarget) -> SmallVec<[AbiParam; 2]> { +fn cast_target_to_abi_params(cast: &CastTarget) -> SmallVec<[AbiParam; 2]> { let (rest_count, rem_bytes) = if cast.rest.unit.size.bytes() == 0 { (0, 0) } else { @@ -100,7 +100,7 @@ impl<'tcx> ArgAbiExt<'tcx> for ArgAbi<'tcx, Ty<'tcx>> { } _ => unreachable!("{:?}", self.layout.abi), }, - PassMode::Cast(cast) => cast_target_to_abi_params(cast), + PassMode::Cast(ref cast) => cast_target_to_abi_params(cast), PassMode::Indirect { attrs, extra_attrs: None, on_stack } => { if on_stack { // Abi requires aligning struct size to pointer size @@ -145,7 +145,9 @@ impl<'tcx> ArgAbiExt<'tcx> for ArgAbi<'tcx, Ty<'tcx>> { } _ => unreachable!("{:?}", self.layout.abi), }, - PassMode::Cast(cast) => (None, cast_target_to_abi_params(cast).into_iter().collect()), + PassMode::Cast(ref cast) => { + (None, cast_target_to_abi_params(cast).into_iter().collect()) + } PassMode::Indirect { attrs: _, extra_attrs: None, on_stack } => { assert!(!on_stack); (Some(AbiParam::special(pointer_ty(tcx), ArgumentPurpose::StructReturn)), vec![]) @@ -160,7 +162,7 @@ impl<'tcx> ArgAbiExt<'tcx> for ArgAbi<'tcx, Ty<'tcx>> { pub(super) fn to_casted_value<'tcx>( fx: &mut FunctionCx<'_, '_, 'tcx>, arg: CValue<'tcx>, - cast: CastTarget, + cast: &CastTarget, ) -> SmallVec<[Value; 2]> { let (ptr, meta) = arg.force_stack(fx); assert!(meta.is_none()); @@ -179,7 +181,7 @@ pub(super) fn from_casted_value<'tcx>( fx: &mut FunctionCx<'_, '_, 'tcx>, block_params: &[Value], layout: TyAndLayout<'tcx>, - cast: CastTarget, + cast: &CastTarget, ) -> CValue<'tcx> { let abi_params = cast_target_to_abi_params(cast); let abi_param_size: u32 = abi_params.iter().map(|param| param.value_type.bytes()).sum(); @@ -224,7 +226,7 @@ pub(super) fn adjust_arg_for_abi<'tcx>( let (a, b) = arg.load_scalar_pair(fx); smallvec![a, b] } - PassMode::Cast(cast) => to_casted_value(fx, arg, cast), + PassMode::Cast(ref cast) => to_casted_value(fx, arg, cast), PassMode::Indirect { .. } => { if is_owned { match arg.force_stack(fx) { @@ -268,7 +270,7 @@ pub(super) fn cvalue_for_param<'tcx>( local, local_field, &block_params, - arg_abi.mode, + &arg_abi.mode, arg_abi.layout, ); @@ -282,7 +284,9 @@ pub(super) fn cvalue_for_param<'tcx>( assert_eq!(block_params.len(), 2, "{:?}", block_params); Some(CValue::by_val_pair(block_params[0], block_params[1], arg_abi.layout)) } - PassMode::Cast(cast) => Some(from_casted_value(fx, &block_params, arg_abi.layout, cast)), + PassMode::Cast(ref cast) => { + Some(from_casted_value(fx, &block_params, arg_abi.layout, cast)) + } PassMode::Indirect { attrs: _, extra_attrs: None, on_stack: _ } => { assert_eq!(block_params.len(), 1, "{:?}", block_params); Some(CValue::by_ref(Pointer::new(block_params[0]), arg_abi.layout)) diff --git a/compiler/rustc_codegen_cranelift/src/abi/returning.rs b/compiler/rustc_codegen_cranelift/src/abi/returning.rs index ff3bb2dfd00..29ef5e2dfda 100644 --- a/compiler/rustc_codegen_cranelift/src/abi/returning.rs +++ b/compiler/rustc_codegen_cranelift/src/abi/returning.rs @@ -44,7 +44,7 @@ pub(super) fn codegen_return_param<'tcx>( Some(RETURN_PLACE), None, &ret_param, - fx.fn_abi.as_ref().unwrap().ret.mode, + &fx.fn_abi.as_ref().unwrap().ret.mode, fx.fn_abi.as_ref().unwrap().ret.layout, ); @@ -92,7 +92,7 @@ pub(super) fn codegen_with_call_return_arg<'tcx>( ret_place .write_cvalue(fx, CValue::by_val_pair(ret_val_a, ret_val_b, ret_arg_abi.layout)); } - PassMode::Cast(cast) => { + PassMode::Cast(ref cast) => { let results = fx.bcx.inst_results(call_inst).iter().copied().collect::>(); let result = @@ -131,7 +131,7 @@ pub(crate) fn codegen_return(fx: &mut FunctionCx<'_, '_, '_>) { let (ret_val_a, ret_val_b) = place.to_cvalue(fx).load_scalar_pair(fx); fx.bcx.ins().return_(&[ret_val_a, ret_val_b]); } - PassMode::Cast(cast) => { + PassMode::Cast(ref cast) => { let place = fx.get_local_place(RETURN_PLACE); let ret_val = place.to_cvalue(fx); let ret_vals = super::pass_mode::to_casted_value(fx, ret_val, cast); diff --git a/compiler/rustc_codegen_gcc/src/abi.rs b/compiler/rustc_codegen_gcc/src/abi.rs index 0ed3e1fbe93..9b55db6a547 100644 --- a/compiler/rustc_codegen_gcc/src/abi.rs +++ b/compiler/rustc_codegen_gcc/src/abi.rs @@ -133,7 +133,7 @@ impl<'gcc, 'tcx> FnAbiGccExt<'gcc, 'tcx> for FnAbi<'tcx, Ty<'tcx>> { match self.ret.mode { PassMode::Ignore => cx.type_void(), PassMode::Direct(_) | PassMode::Pair(..) => self.ret.layout.immediate_gcc_type(cx), - PassMode::Cast(cast) => cast.gcc_type(cx), + PassMode::Cast(ref cast) => cast.gcc_type(cx), PassMode::Indirect { .. } => { argument_tys.push(cx.type_ptr_to(self.ret.memory_ty(cx))); cx.type_void() @@ -157,7 +157,7 @@ impl<'gcc, 'tcx> FnAbiGccExt<'gcc, 'tcx> for FnAbi<'tcx, Ty<'tcx>> { PassMode::Indirect { extra_attrs: Some(_), .. } => { unimplemented!(); } - PassMode::Cast(cast) => cast.gcc_type(cx), + PassMode::Cast(ref cast) => cast.gcc_type(cx), PassMode::Indirect { extra_attrs: None, on_stack: true, .. } => { on_stack_param_indices.insert(argument_tys.len()); arg.memory_ty(cx) diff --git a/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs b/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs index 5fbdedac0c4..f4493776ea2 100644 --- a/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs +++ b/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs @@ -130,7 +130,7 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallMethods<'tcx> for Builder<'a, 'gcc, 'tcx> { sym::volatile_load | sym::unaligned_volatile_load => { let tp_ty = substs.type_at(0); let mut ptr = args[0].immediate(); - if let PassMode::Cast(ty) = fn_abi.ret.mode { + if let PassMode::Cast(ty) = &fn_abi.ret.mode { ptr = self.pointercast(ptr, self.type_ptr_to(ty.gcc_type(self))); } let load = self.volatile_load(ptr.get_type(), ptr); @@ -320,7 +320,7 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallMethods<'tcx> for Builder<'a, 'gcc, 'tcx> { }; if !fn_abi.ret.is_ignore() { - if let PassMode::Cast(ty) = fn_abi.ret.mode { + if let PassMode::Cast(ty) = &fn_abi.ret.mode { let ptr_llty = self.type_ptr_to(ty.gcc_type(self)); let ptr = self.pointercast(result.llval, ptr_llty); self.store(llval, ptr, result.align); @@ -416,7 +416,7 @@ impl<'gcc, 'tcx> ArgAbiExt<'gcc, 'tcx> for ArgAbi<'tcx, Ty<'tcx>> { else if self.is_unsized_indirect() { bug!("unsized `ArgAbi` must be handled through `store_fn_arg`"); } - else if let PassMode::Cast(cast) = self.mode { + else if let PassMode::Cast(ref cast) = self.mode { // FIXME(eddyb): Figure out when the simpler Store is safe, clang // uses it for i16 -> {i8, i8}, but not for i24 -> {i8, i8, i8}. let can_store_through_cast_ptr = false; diff --git a/compiler/rustc_codegen_llvm/src/abi.rs b/compiler/rustc_codegen_llvm/src/abi.rs index 9eb3574e77b..09c53afa6c8 100644 --- a/compiler/rustc_codegen_llvm/src/abi.rs +++ b/compiler/rustc_codegen_llvm/src/abi.rs @@ -213,7 +213,7 @@ impl<'ll, 'tcx> ArgAbiExt<'ll, 'tcx> for ArgAbi<'tcx, Ty<'tcx>> { OperandValue::Ref(val, None, self.layout.align.abi).store(bx, dst) } else if self.is_unsized_indirect() { bug!("unsized `ArgAbi` must be handled through `store_fn_arg`"); - } else if let PassMode::Cast(cast) = self.mode { + } else if let PassMode::Cast(cast) = &self.mode { // FIXME(eddyb): Figure out when the simpler Store is safe, clang // uses it for i16 -> {i8, i8}, but not for i24 -> {i8, i8, i8}. let can_store_through_cast_ptr = false; @@ -335,7 +335,7 @@ impl<'ll, 'tcx> FnAbiLlvmExt<'ll, 'tcx> for FnAbi<'tcx, Ty<'tcx>> { if let PassMode::Indirect { .. } = self.ret.mode { 1 } else { 0 } + args_capacity, ); - let llreturn_ty = match self.ret.mode { + let llreturn_ty = match &self.ret.mode { PassMode::Ignore => cx.type_void(), PassMode::Direct(_) | PassMode::Pair(..) => self.ret.layout.immediate_llvm_type(cx), PassMode::Cast(cast) => cast.llvm_type(cx), @@ -351,7 +351,7 @@ impl<'ll, 'tcx> FnAbiLlvmExt<'ll, 'tcx> for FnAbi<'tcx, Ty<'tcx>> { llargument_tys.push(ty.llvm_type(cx)); } - let llarg_ty = match arg.mode { + let llarg_ty = match &arg.mode { PassMode::Ignore => continue, PassMode::Direct(_) => arg.layout.immediate_llvm_type(cx), PassMode::Pair(..) => { @@ -426,11 +426,11 @@ impl<'ll, 'tcx> FnAbiLlvmExt<'ll, 'tcx> for FnAbi<'tcx, Ty<'tcx>> { i += 1; i - 1 }; - match self.ret.mode { - PassMode::Direct(ref attrs) => { + match &self.ret.mode { + PassMode::Direct(attrs) => { attrs.apply_attrs_to_llfn(llvm::AttributePlace::ReturnValue, cx, llfn); } - PassMode::Indirect { ref attrs, extra_attrs: _, on_stack } => { + PassMode::Indirect { attrs, extra_attrs: _, on_stack } => { assert!(!on_stack); let i = apply(attrs); let sret = llvm::CreateStructRetAttr(cx.llcx, self.ret.layout.llvm_type(cx)); @@ -445,23 +445,23 @@ impl<'ll, 'tcx> FnAbiLlvmExt<'ll, 'tcx> for FnAbi<'tcx, Ty<'tcx>> { if arg.pad.is_some() { apply(&ArgAttributes::new()); } - match arg.mode { + match &arg.mode { PassMode::Ignore => {} - PassMode::Indirect { ref attrs, extra_attrs: None, on_stack: true } => { + PassMode::Indirect { attrs, extra_attrs: None, on_stack: true } => { let i = apply(attrs); let byval = llvm::CreateByValAttr(cx.llcx, arg.layout.llvm_type(cx)); attributes::apply_to_llfn(llfn, llvm::AttributePlace::Argument(i), &[byval]); } - PassMode::Direct(ref attrs) - | PassMode::Indirect { ref attrs, extra_attrs: None, on_stack: false } => { + PassMode::Direct(attrs) + | PassMode::Indirect { attrs, extra_attrs: None, on_stack: false } => { apply(attrs); } - PassMode::Indirect { ref attrs, extra_attrs: Some(ref extra_attrs), on_stack } => { + PassMode::Indirect { attrs, extra_attrs: Some(extra_attrs), on_stack } => { assert!(!on_stack); apply(attrs); apply(extra_attrs); } - PassMode::Pair(ref a, ref b) => { + PassMode::Pair(a, b) => { apply(a); apply(b); } @@ -488,11 +488,11 @@ impl<'ll, 'tcx> FnAbiLlvmExt<'ll, 'tcx> for FnAbi<'tcx, Ty<'tcx>> { i += 1; i - 1 }; - match self.ret.mode { - PassMode::Direct(ref attrs) => { + match &self.ret.mode { + PassMode::Direct(attrs) => { attrs.apply_attrs_to_callsite(llvm::AttributePlace::ReturnValue, bx.cx, callsite); } - PassMode::Indirect { ref attrs, extra_attrs: _, on_stack } => { + PassMode::Indirect { attrs, extra_attrs: _, on_stack } => { assert!(!on_stack); let i = apply(bx.cx, attrs); let sret = llvm::CreateStructRetAttr(bx.cx.llcx, self.ret.layout.llvm_type(bx)); @@ -521,9 +521,9 @@ impl<'ll, 'tcx> FnAbiLlvmExt<'ll, 'tcx> for FnAbi<'tcx, Ty<'tcx>> { if arg.pad.is_some() { apply(bx.cx, &ArgAttributes::new()); } - match arg.mode { + match &arg.mode { PassMode::Ignore => {} - PassMode::Indirect { ref attrs, extra_attrs: None, on_stack: true } => { + PassMode::Indirect { attrs, extra_attrs: None, on_stack: true } => { let i = apply(bx.cx, attrs); let byval = llvm::CreateByValAttr(bx.cx.llcx, arg.layout.llvm_type(bx)); attributes::apply_to_callsite( @@ -532,19 +532,15 @@ impl<'ll, 'tcx> FnAbiLlvmExt<'ll, 'tcx> for FnAbi<'tcx, Ty<'tcx>> { &[byval], ); } - PassMode::Direct(ref attrs) - | PassMode::Indirect { ref attrs, extra_attrs: None, on_stack: false } => { + PassMode::Direct(attrs) + | PassMode::Indirect { attrs, extra_attrs: None, on_stack: false } => { apply(bx.cx, attrs); } - PassMode::Indirect { - ref attrs, - extra_attrs: Some(ref extra_attrs), - on_stack: _, - } => { + PassMode::Indirect { attrs, extra_attrs: Some(extra_attrs), on_stack: _ } => { apply(bx.cx, attrs); apply(bx.cx, extra_attrs); } - PassMode::Pair(ref a, ref b) => { + PassMode::Pair(a, b) => { apply(bx.cx, a); apply(bx.cx, b); } diff --git a/compiler/rustc_codegen_llvm/src/intrinsic.rs b/compiler/rustc_codegen_llvm/src/intrinsic.rs index 9f364749287..d46a6dd32c8 100644 --- a/compiler/rustc_codegen_llvm/src/intrinsic.rs +++ b/compiler/rustc_codegen_llvm/src/intrinsic.rs @@ -161,7 +161,7 @@ impl<'ll, 'tcx> IntrinsicCallMethods<'tcx> for Builder<'_, 'll, 'tcx> { sym::volatile_load | sym::unaligned_volatile_load => { let tp_ty = substs.type_at(0); let ptr = args[0].immediate(); - let load = if let PassMode::Cast(ty) = fn_abi.ret.mode { + let load = if let PassMode::Cast(ty) = &fn_abi.ret.mode { let llty = ty.llvm_type(self); let ptr = self.pointercast(ptr, self.type_ptr_to(llty)); self.volatile_load(llty, ptr) @@ -374,7 +374,7 @@ impl<'ll, 'tcx> IntrinsicCallMethods<'tcx> for Builder<'_, 'll, 'tcx> { }; if !fn_abi.ret.is_ignore() { - if let PassMode::Cast(ty) = fn_abi.ret.mode { + if let PassMode::Cast(ty) = &fn_abi.ret.mode { let ptr_llty = self.type_ptr_to(ty.llvm_type(self)); let ptr = self.pointercast(result.llval, ptr_llty); self.store(llval, ptr, result.align); diff --git a/compiler/rustc_codegen_ssa/src/mir/block.rs b/compiler/rustc_codegen_ssa/src/mir/block.rs index 47a40be5d8c..187af47114f 100644 --- a/compiler/rustc_codegen_ssa/src/mir/block.rs +++ b/compiler/rustc_codegen_ssa/src/mir/block.rs @@ -324,7 +324,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { bx.unreachable(); return; } - let llval = match self.fn_abi.ret.mode { + let llval = match &self.fn_abi.ret.mode { PassMode::Ignore | PassMode::Indirect { .. } => { bx.ret_void(); return; @@ -360,7 +360,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { llval } }; - let ty = bx.cast_backend_type(&cast_ty); + let ty = bx.cast_backend_type(cast_ty); let addr = bx.pointercast(llslot, bx.type_ptr_to(ty)); bx.load(ty, addr, self.fn_abi.ret.layout.align.abi) } @@ -1222,8 +1222,8 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { if by_ref && !arg.is_indirect() { // Have to load the argument, maybe while casting it. - if let PassMode::Cast(ty) = arg.mode { - let llty = bx.cast_backend_type(&ty); + if let PassMode::Cast(ty) = &arg.mode { + let llty = bx.cast_backend_type(ty); let addr = bx.pointercast(llval, bx.type_ptr_to(llty)); llval = bx.load(llty, addr, align.min(arg.layout.align.abi)); } else { diff --git a/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs b/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs index 94ac71a4dd2..e11ebdce80f 100644 --- a/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs +++ b/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs @@ -597,8 +597,8 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { }; if !fn_abi.ret.is_ignore() { - if let PassMode::Cast(ty) = fn_abi.ret.mode { - let ptr_llty = bx.type_ptr_to(bx.cast_backend_type(&ty)); + if let PassMode::Cast(ty) = &fn_abi.ret.mode { + let ptr_llty = bx.type_ptr_to(bx.cast_backend_type(ty)); let ptr = bx.pointercast(result.llval, ptr_llty); bx.store(llval, ptr, result.align); } else { diff --git a/compiler/rustc_const_eval/src/interpret/terminator.rs b/compiler/rustc_const_eval/src/interpret/terminator.rs index c8557d172ed..27bb828feac 100644 --- a/compiler/rustc_const_eval/src/interpret/terminator.rs +++ b/compiler/rustc_const_eval/src/interpret/terminator.rs @@ -218,7 +218,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { // Padding must be fully equal. let pad_compat = || caller_abi.pad == callee_abi.pad; // When comparing the PassMode, we have to be smart about comparing the attributes. - let arg_attr_compat = |a1: ArgAttributes, a2: ArgAttributes| { + let arg_attr_compat = |a1: &ArgAttributes, a2: &ArgAttributes| { // There's only one regular attribute that matters for the call ABI: InReg. // Everything else is things like noalias, dereferencable, nonnull, ... // (This also applies to pointee_size, pointee_align.) @@ -233,7 +233,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { } return true; }; - let mode_compat = || match (caller_abi.mode, callee_abi.mode) { + let mode_compat = || match (&caller_abi.mode, &callee_abi.mode) { (PassMode::Ignore, PassMode::Ignore) => true, (PassMode::Direct(a1), PassMode::Direct(a2)) => arg_attr_compat(a1, a2), (PassMode::Pair(a1, b1), PassMode::Pair(a2, b2)) => { diff --git a/compiler/rustc_target/src/abi/call/mod.rs b/compiler/rustc_target/src/abi/call/mod.rs index ab53ea6101d..d4430b1609b 100644 --- a/compiler/rustc_target/src/abi/call/mod.rs +++ b/compiler/rustc_target/src/abi/call/mod.rs @@ -26,7 +26,7 @@ mod x86; mod x86_64; mod x86_win64; -#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, HashStable_Generic)] +#[derive(PartialEq, Eq, Hash, Debug, HashStable_Generic)] pub enum PassMode { /// Ignore the argument. /// @@ -42,7 +42,7 @@ pub enum PassMode { Pair(ArgAttributes, ArgAttributes), /// Pass the argument after casting it, to either /// a single uniform or a pair of registers. - Cast(CastTarget), + Cast(Box), /// Pass the argument indirectly via a hidden pointer. /// The `extra_attrs` value, if any, is for the extra data (vtable or length) /// which indicates that it refers to an unsized rvalue. @@ -548,7 +548,7 @@ impl<'a, Ty> ArgAbi<'a, Ty> { } pub fn cast_to>(&mut self, target: T) { - self.mode = PassMode::Cast(target.into()); + self.mode = PassMode::Cast(Box::new(target.into())); } pub fn pad_with(&mut self, reg: Reg) { @@ -737,6 +737,6 @@ mod size_asserts { use super::*; use rustc_data_structures::static_assert_size; // These are in alphabetical order, which is easy to maintain. - static_assert_size!(ArgAbi<'_, usize>, 208); - static_assert_size!(FnAbi<'_, usize>, 248); + static_assert_size!(ArgAbi<'_, usize>, 72); + static_assert_size!(FnAbi<'_, usize>, 112); } -- cgit 1.4.1-3-g733a5 From b853e8a6194637751bffbcfdd5bb51c7bfecdff5 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Thu, 25 Aug 2022 19:18:01 +1000 Subject: Turn `ArgAbi::pad` into a `bool`. Because it's only ever set to `None` or `Some(Reg::i32())`. --- compiler/rustc_codegen_gcc/src/abi.rs | 4 ++-- compiler/rustc_codegen_llvm/src/abi.rs | 8 ++++---- compiler/rustc_codegen_ssa/src/mir/block.rs | 6 +++--- compiler/rustc_codegen_ssa/src/mir/mod.rs | 4 ++-- compiler/rustc_const_eval/src/interpret/terminator.rs | 2 +- compiler/rustc_target/src/abi/call/mips.rs | 2 +- compiler/rustc_target/src/abi/call/mod.rs | 12 ++++++------ compiler/rustc_target/src/abi/call/sparc.rs | 2 +- 8 files changed, 20 insertions(+), 20 deletions(-) (limited to 'compiler/rustc_codegen_ssa/src') diff --git a/compiler/rustc_codegen_gcc/src/abi.rs b/compiler/rustc_codegen_gcc/src/abi.rs index 87b730d29cd..3186b363e35 100644 --- a/compiler/rustc_codegen_gcc/src/abi.rs +++ b/compiler/rustc_codegen_gcc/src/abi.rs @@ -126,8 +126,8 @@ impl<'gcc, 'tcx> FnAbiGccExt<'gcc, 'tcx> for FnAbi<'tcx, Ty<'tcx>> { for arg in self.args.iter() { // add padding - if let Some(ty) = arg.pad { - argument_tys.push(ty.gcc_type(cx)); + if arg.pad_i32 { + argument_tys.push(Reg::i32().gcc_type(cx)); } let arg_ty = match arg.mode { diff --git a/compiler/rustc_codegen_llvm/src/abi.rs b/compiler/rustc_codegen_llvm/src/abi.rs index a06b07c1149..168cf3d0b58 100644 --- a/compiler/rustc_codegen_llvm/src/abi.rs +++ b/compiler/rustc_codegen_llvm/src/abi.rs @@ -345,8 +345,8 @@ impl<'ll, 'tcx> FnAbiLlvmExt<'ll, 'tcx> for FnAbi<'tcx, Ty<'tcx>> { for arg in args { // add padding - if let Some(ty) = arg.pad { - llargument_tys.push(ty.llvm_type(cx)); + if arg.pad_i32 { + llargument_tys.push(Reg::i32().llvm_type(cx)); } let llarg_ty = match &arg.mode { @@ -440,7 +440,7 @@ impl<'ll, 'tcx> FnAbiLlvmExt<'ll, 'tcx> for FnAbi<'tcx, Ty<'tcx>> { _ => {} } for arg in self.args.iter() { - if arg.pad.is_some() { + if arg.pad_i32 { apply(&ArgAttributes::new()); } match &arg.mode { @@ -516,7 +516,7 @@ impl<'ll, 'tcx> FnAbiLlvmExt<'ll, 'tcx> for FnAbi<'tcx, Ty<'tcx>> { } } for arg in self.args.iter() { - if arg.pad.is_some() { + if arg.pad_i32 { apply(bx.cx, &ArgAttributes::new()); } match &arg.mode { diff --git a/compiler/rustc_codegen_ssa/src/mir/block.rs b/compiler/rustc_codegen_ssa/src/mir/block.rs index 187af47114f..5b3f41263e7 100644 --- a/compiler/rustc_codegen_ssa/src/mir/block.rs +++ b/compiler/rustc_codegen_ssa/src/mir/block.rs @@ -21,7 +21,7 @@ use rustc_middle::ty::{self, Instance, Ty, TypeVisitable}; use rustc_span::source_map::Span; use rustc_span::{sym, Symbol}; use rustc_symbol_mangling::typeid::typeid_for_fnabi; -use rustc_target::abi::call::{ArgAbi, FnAbi, PassMode}; +use rustc_target::abi::call::{ArgAbi, FnAbi, PassMode, Reg}; use rustc_target::abi::{self, HasDataLayout, WrappingRange}; use rustc_target::spec::abi::Abi; @@ -1159,8 +1159,8 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { arg: &ArgAbi<'tcx, Ty<'tcx>>, ) { // Fill padding with undef value, where applicable. - if let Some(ty) = arg.pad { - llargs.push(bx.const_undef(bx.reg_backend_type(&ty))) + if arg.pad_i32 { + llargs.push(bx.const_undef(bx.reg_backend_type(&Reg::i32()))) } if arg.is_ignore() { diff --git a/compiler/rustc_codegen_ssa/src/mir/mod.rs b/compiler/rustc_codegen_ssa/src/mir/mod.rs index 8ee375fa9e3..f13b658b2ff 100644 --- a/compiler/rustc_codegen_ssa/src/mir/mod.rs +++ b/compiler/rustc_codegen_ssa/src/mir/mod.rs @@ -283,7 +283,7 @@ fn arg_local_refs<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( for i in 0..tupled_arg_tys.len() { let arg = &fx.fn_abi.args[idx]; idx += 1; - if arg.pad.is_some() { + if arg.pad_i32 { llarg_idx += 1; } let pr_field = place.project_field(bx, i); @@ -309,7 +309,7 @@ fn arg_local_refs<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( let arg = &fx.fn_abi.args[idx]; idx += 1; - if arg.pad.is_some() { + if arg.pad_i32 { llarg_idx += 1; } diff --git a/compiler/rustc_const_eval/src/interpret/terminator.rs b/compiler/rustc_const_eval/src/interpret/terminator.rs index 27bb828feac..2fcdf6ded98 100644 --- a/compiler/rustc_const_eval/src/interpret/terminator.rs +++ b/compiler/rustc_const_eval/src/interpret/terminator.rs @@ -216,7 +216,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { } }; // Padding must be fully equal. - let pad_compat = || caller_abi.pad == callee_abi.pad; + let pad_compat = || caller_abi.pad_i32 == callee_abi.pad_i32; // When comparing the PassMode, we have to be smart about comparing the attributes. let arg_attr_compat = |a1: &ArgAttributes, a2: &ArgAttributes| { // There's only one regular attribute that matters for the call ABI: InReg. diff --git a/compiler/rustc_target/src/abi/call/mips.rs b/compiler/rustc_target/src/abi/call/mips.rs index 83d8657af11..ff8f3236214 100644 --- a/compiler/rustc_target/src/abi/call/mips.rs +++ b/compiler/rustc_target/src/abi/call/mips.rs @@ -24,7 +24,7 @@ where if arg.layout.is_aggregate() { arg.cast_to(Uniform { unit: Reg::i32(), total: size }); if !offset.is_aligned(align) { - arg.pad_with(Reg::i32()); + arg.pad_with_i32(); } } else { arg.extend_integer_width_to(32); diff --git a/compiler/rustc_target/src/abi/call/mod.rs b/compiler/rustc_target/src/abi/call/mod.rs index bf30c24258e..33f533e68f0 100644 --- a/compiler/rustc_target/src/abi/call/mod.rs +++ b/compiler/rustc_target/src/abi/call/mod.rs @@ -465,7 +465,7 @@ pub struct ArgAbi<'a, Ty> { pub layout: TyAndLayout<'a, Ty>, /// Dummy argument, which is emitted before the real argument. - pub pad: Option, + pub pad_i32: bool, pub mode: PassMode, } @@ -486,7 +486,7 @@ impl<'a, Ty> ArgAbi<'a, Ty> { Abi::Vector { .. } => PassMode::Direct(ArgAttributes::new()), Abi::Aggregate { .. } => PassMode::Direct(ArgAttributes::new()), }; - ArgAbi { layout, pad: None, mode } + ArgAbi { layout, pad_i32: false, mode } } fn indirect_pass_mode(layout: &TyAndLayout<'a, Ty>) -> PassMode { @@ -551,8 +551,8 @@ impl<'a, Ty> ArgAbi<'a, Ty> { self.mode = PassMode::Cast(Box::new(target.into())); } - pub fn pad_with(&mut self, reg: Reg) { - self.pad = Some(reg); + pub fn pad_with_i32(&mut self) { + self.pad_i32 = true; } pub fn is_indirect(&self) -> bool { @@ -737,6 +737,6 @@ mod size_asserts { use super::*; use rustc_data_structures::static_assert_size; // These are in alphabetical order, which is easy to maintain. - static_assert_size!(ArgAbi<'_, usize>, 72); - static_assert_size!(FnAbi<'_, usize>, 96); + static_assert_size!(ArgAbi<'_, usize>, 64); + static_assert_size!(FnAbi<'_, usize>, 88); } diff --git a/compiler/rustc_target/src/abi/call/sparc.rs b/compiler/rustc_target/src/abi/call/sparc.rs index 83d8657af11..ff8f3236214 100644 --- a/compiler/rustc_target/src/abi/call/sparc.rs +++ b/compiler/rustc_target/src/abi/call/sparc.rs @@ -24,7 +24,7 @@ where if arg.layout.is_aggregate() { arg.cast_to(Uniform { unit: Reg::i32(), total: size }); if !offset.is_aligned(align) { - arg.pad_with(Reg::i32()); + arg.pad_with_i32(); } } else { arg.extend_integer_width_to(32); -- cgit 1.4.1-3-g733a5 From f974617bdafa2e5205c1e852fe3ce61f29e2c026 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Thu, 25 Aug 2022 22:19:38 +1000 Subject: Move `ArgAbi::pad_i32` into `PassMode::Cast`. Because it's only needed for that variant. This shrinks the types and clarifies the logic. --- .../rustc_codegen_cranelift/src/abi/pass_mode.rs | 11 +++--- .../rustc_codegen_cranelift/src/abi/returning.rs | 8 ++--- compiler/rustc_codegen_gcc/src/abi.rs | 15 +++++---- compiler/rustc_codegen_gcc/src/intrinsic/mod.rs | 8 ++--- compiler/rustc_codegen_llvm/src/abi.rs | 39 +++++++++++----------- compiler/rustc_codegen_llvm/src/intrinsic.rs | 4 +-- compiler/rustc_codegen_ssa/src/mir/block.rs | 34 +++++++++---------- compiler/rustc_codegen_ssa/src/mir/intrinsic.rs | 2 +- compiler/rustc_codegen_ssa/src/mir/mod.rs | 4 +-- .../rustc_const_eval/src/interpret/terminator.rs | 6 ++-- compiler/rustc_target/src/abi/call/mips.rs | 6 ++-- compiler/rustc_target/src/abi/call/mod.rs | 23 ++++++------- compiler/rustc_target/src/abi/call/sparc.rs | 6 ++-- compiler/rustc_target/src/abi/call/x86.rs | 2 +- 14 files changed, 80 insertions(+), 88 deletions(-) (limited to 'compiler/rustc_codegen_ssa/src') diff --git a/compiler/rustc_codegen_cranelift/src/abi/pass_mode.rs b/compiler/rustc_codegen_cranelift/src/abi/pass_mode.rs index 058dee176e2..165f15bb3f1 100644 --- a/compiler/rustc_codegen_cranelift/src/abi/pass_mode.rs +++ b/compiler/rustc_codegen_cranelift/src/abi/pass_mode.rs @@ -100,7 +100,10 @@ impl<'tcx> ArgAbiExt<'tcx> for ArgAbi<'tcx, Ty<'tcx>> { } _ => unreachable!("{:?}", self.layout.abi), }, - PassMode::Cast(ref cast) => cast_target_to_abi_params(cast), + PassMode::Cast(ref cast, pad_i32) => { + assert!(!pad_i32, "padding support not yet implemented"); + cast_target_to_abi_params(cast) + } PassMode::Indirect { attrs, extra_attrs: None, on_stack } => { if on_stack { // Abi requires aligning struct size to pointer size @@ -145,7 +148,7 @@ impl<'tcx> ArgAbiExt<'tcx> for ArgAbi<'tcx, Ty<'tcx>> { } _ => unreachable!("{:?}", self.layout.abi), }, - PassMode::Cast(ref cast) => { + PassMode::Cast(ref cast, _) => { (None, cast_target_to_abi_params(cast).into_iter().collect()) } PassMode::Indirect { attrs: _, extra_attrs: None, on_stack } => { @@ -226,7 +229,7 @@ pub(super) fn adjust_arg_for_abi<'tcx>( let (a, b) = arg.load_scalar_pair(fx); smallvec![a, b] } - PassMode::Cast(ref cast) => to_casted_value(fx, arg, cast), + PassMode::Cast(ref cast, _) => to_casted_value(fx, arg, cast), PassMode::Indirect { .. } => { if is_owned { match arg.force_stack(fx) { @@ -284,7 +287,7 @@ pub(super) fn cvalue_for_param<'tcx>( assert_eq!(block_params.len(), 2, "{:?}", block_params); Some(CValue::by_val_pair(block_params[0], block_params[1], arg_abi.layout)) } - PassMode::Cast(ref cast) => { + PassMode::Cast(ref cast, _) => { Some(from_casted_value(fx, &block_params, arg_abi.layout, cast)) } PassMode::Indirect { attrs: _, extra_attrs: None, on_stack: _ } => { diff --git a/compiler/rustc_codegen_cranelift/src/abi/returning.rs b/compiler/rustc_codegen_cranelift/src/abi/returning.rs index 29ef5e2dfda..aaa1418767a 100644 --- a/compiler/rustc_codegen_cranelift/src/abi/returning.rs +++ b/compiler/rustc_codegen_cranelift/src/abi/returning.rs @@ -13,7 +13,7 @@ pub(super) fn codegen_return_param<'tcx>( block_params_iter: &mut impl Iterator, ) -> CPlace<'tcx> { let (ret_place, ret_param): (_, SmallVec<[_; 2]>) = match fx.fn_abi.as_ref().unwrap().ret.mode { - PassMode::Ignore | PassMode::Direct(_) | PassMode::Pair(_, _) | PassMode::Cast(_) => { + PassMode::Ignore | PassMode::Direct(_) | PassMode::Pair(_, _) | PassMode::Cast(..) => { let is_ssa = ssa_analyzed[RETURN_PLACE] == crate::analyze::SsaKind::Ssa; ( super::make_local_place( @@ -75,7 +75,7 @@ pub(super) fn codegen_with_call_return_arg<'tcx>( PassMode::Indirect { attrs: _, extra_attrs: Some(_), on_stack: _ } => { unreachable!("unsized return value") } - PassMode::Direct(_) | PassMode::Pair(_, _) | PassMode::Cast(_) => (None, None), + PassMode::Direct(_) | PassMode::Pair(_, _) | PassMode::Cast(..) => (None, None), }; let call_inst = f(fx, return_ptr); @@ -92,7 +92,7 @@ pub(super) fn codegen_with_call_return_arg<'tcx>( ret_place .write_cvalue(fx, CValue::by_val_pair(ret_val_a, ret_val_b, ret_arg_abi.layout)); } - PassMode::Cast(ref cast) => { + PassMode::Cast(ref cast, _) => { let results = fx.bcx.inst_results(call_inst).iter().copied().collect::>(); let result = @@ -131,7 +131,7 @@ pub(crate) fn codegen_return(fx: &mut FunctionCx<'_, '_, '_>) { let (ret_val_a, ret_val_b) = place.to_cvalue(fx).load_scalar_pair(fx); fx.bcx.ins().return_(&[ret_val_a, ret_val_b]); } - PassMode::Cast(ref cast) => { + PassMode::Cast(ref cast, _) => { let place = fx.get_local_place(RETURN_PLACE); let ret_val = place.to_cvalue(fx); let ret_vals = super::pass_mode::to_casted_value(fx, ret_val, cast); diff --git a/compiler/rustc_codegen_gcc/src/abi.rs b/compiler/rustc_codegen_gcc/src/abi.rs index 3186b363e35..848c34211ff 100644 --- a/compiler/rustc_codegen_gcc/src/abi.rs +++ b/compiler/rustc_codegen_gcc/src/abi.rs @@ -117,7 +117,7 @@ impl<'gcc, 'tcx> FnAbiGccExt<'gcc, 'tcx> for FnAbi<'tcx, Ty<'tcx>> { match self.ret.mode { PassMode::Ignore => cx.type_void(), PassMode::Direct(_) | PassMode::Pair(..) => self.ret.layout.immediate_gcc_type(cx), - PassMode::Cast(ref cast) => cast.gcc_type(cx), + PassMode::Cast(ref cast, _) => cast.gcc_type(cx), PassMode::Indirect { .. } => { argument_tys.push(cx.type_ptr_to(self.ret.memory_ty(cx))); cx.type_void() @@ -125,11 +125,6 @@ impl<'gcc, 'tcx> FnAbiGccExt<'gcc, 'tcx> for FnAbi<'tcx, Ty<'tcx>> { }; for arg in self.args.iter() { - // add padding - if arg.pad_i32 { - argument_tys.push(Reg::i32().gcc_type(cx)); - } - let arg_ty = match arg.mode { PassMode::Ignore => continue, PassMode::Direct(_) => arg.layout.immediate_gcc_type(cx), @@ -141,7 +136,13 @@ impl<'gcc, 'tcx> FnAbiGccExt<'gcc, 'tcx> for FnAbi<'tcx, Ty<'tcx>> { PassMode::Indirect { extra_attrs: Some(_), .. } => { unimplemented!(); } - PassMode::Cast(ref cast) => cast.gcc_type(cx), + PassMode::Cast(ref cast, pad_i32) => { + // add padding + if pad_i32 { + argument_tys.push(Reg::i32().gcc_type(cx)); + } + cast.gcc_type(cx) + } PassMode::Indirect { extra_attrs: None, on_stack: true, .. } => { on_stack_param_indices.insert(argument_tys.len()); arg.memory_ty(cx) diff --git a/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs b/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs index f4493776ea2..352fe7568ef 100644 --- a/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs +++ b/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs @@ -130,7 +130,7 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallMethods<'tcx> for Builder<'a, 'gcc, 'tcx> { sym::volatile_load | sym::unaligned_volatile_load => { let tp_ty = substs.type_at(0); let mut ptr = args[0].immediate(); - if let PassMode::Cast(ty) = &fn_abi.ret.mode { + if let PassMode::Cast(ty, _) = &fn_abi.ret.mode { ptr = self.pointercast(ptr, self.type_ptr_to(ty.gcc_type(self))); } let load = self.volatile_load(ptr.get_type(), ptr); @@ -320,7 +320,7 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallMethods<'tcx> for Builder<'a, 'gcc, 'tcx> { }; if !fn_abi.ret.is_ignore() { - if let PassMode::Cast(ty) = &fn_abi.ret.mode { + if let PassMode::Cast(ty, _) = &fn_abi.ret.mode { let ptr_llty = self.type_ptr_to(ty.gcc_type(self)); let ptr = self.pointercast(result.llval, ptr_llty); self.store(llval, ptr, result.align); @@ -416,7 +416,7 @@ impl<'gcc, 'tcx> ArgAbiExt<'gcc, 'tcx> for ArgAbi<'tcx, Ty<'tcx>> { else if self.is_unsized_indirect() { bug!("unsized `ArgAbi` must be handled through `store_fn_arg`"); } - else if let PassMode::Cast(ref cast) = self.mode { + else if let PassMode::Cast(ref cast, _) = self.mode { // FIXME(eddyb): Figure out when the simpler Store is safe, clang // uses it for i16 -> {i8, i8}, but not for i24 -> {i8, i8, i8}. let can_store_through_cast_ptr = false; @@ -481,7 +481,7 @@ impl<'gcc, 'tcx> ArgAbiExt<'gcc, 'tcx> for ArgAbi<'tcx, Ty<'tcx>> { PassMode::Indirect { extra_attrs: Some(_), .. } => { OperandValue::Ref(next(), Some(next()), self.layout.align.abi).store(bx, dst); }, - PassMode::Direct(_) | PassMode::Indirect { extra_attrs: None, .. } | PassMode::Cast(_) => { + PassMode::Direct(_) | PassMode::Indirect { extra_attrs: None, .. } | PassMode::Cast(..) => { let next_arg = next(); self.store(bx, next_arg, dst); }, diff --git a/compiler/rustc_codegen_llvm/src/abi.rs b/compiler/rustc_codegen_llvm/src/abi.rs index 168cf3d0b58..0ce161d7e75 100644 --- a/compiler/rustc_codegen_llvm/src/abi.rs +++ b/compiler/rustc_codegen_llvm/src/abi.rs @@ -213,7 +213,7 @@ impl<'ll, 'tcx> ArgAbiExt<'ll, 'tcx> for ArgAbi<'tcx, Ty<'tcx>> { OperandValue::Ref(val, None, self.layout.align.abi).store(bx, dst) } else if self.is_unsized_indirect() { bug!("unsized `ArgAbi` must be handled through `store_fn_arg`"); - } else if let PassMode::Cast(cast) = &self.mode { + } else if let PassMode::Cast(cast, _) = &self.mode { // FIXME(eddyb): Figure out when the simpler Store is safe, clang // uses it for i16 -> {i8, i8}, but not for i24 -> {i8, i8, i8}. let can_store_through_cast_ptr = false; @@ -283,7 +283,7 @@ impl<'ll, 'tcx> ArgAbiExt<'ll, 'tcx> for ArgAbi<'tcx, Ty<'tcx>> { } PassMode::Direct(_) | PassMode::Indirect { attrs: _, extra_attrs: None, on_stack: _ } - | PassMode::Cast(_) => { + | PassMode::Cast(..) => { let next_arg = next(); self.store(bx, next_arg, dst); } @@ -336,7 +336,7 @@ impl<'ll, 'tcx> FnAbiLlvmExt<'ll, 'tcx> for FnAbi<'tcx, Ty<'tcx>> { let llreturn_ty = match &self.ret.mode { PassMode::Ignore => cx.type_void(), PassMode::Direct(_) | PassMode::Pair(..) => self.ret.layout.immediate_llvm_type(cx), - PassMode::Cast(cast) => cast.llvm_type(cx), + PassMode::Cast(cast, _) => cast.llvm_type(cx), PassMode::Indirect { .. } => { llargument_tys.push(cx.type_ptr_to(self.ret.memory_ty(cx))); cx.type_void() @@ -344,11 +344,6 @@ impl<'ll, 'tcx> FnAbiLlvmExt<'ll, 'tcx> for FnAbi<'tcx, Ty<'tcx>> { }; for arg in args { - // add padding - if arg.pad_i32 { - llargument_tys.push(Reg::i32().llvm_type(cx)); - } - let llarg_ty = match &arg.mode { PassMode::Ignore => continue, PassMode::Direct(_) => arg.layout.immediate_llvm_type(cx), @@ -364,7 +359,13 @@ impl<'ll, 'tcx> FnAbiLlvmExt<'ll, 'tcx> for FnAbi<'tcx, Ty<'tcx>> { llargument_tys.push(ptr_layout.scalar_pair_element_llvm_type(cx, 1, true)); continue; } - PassMode::Cast(cast) => cast.llvm_type(cx), + PassMode::Cast(cast, pad_i32) => { + // add padding + if *pad_i32 { + llargument_tys.push(Reg::i32().llvm_type(cx)); + } + cast.llvm_type(cx) + } PassMode::Indirect { attrs: _, extra_attrs: None, on_stack: _ } => { cx.type_ptr_to(arg.memory_ty(cx)) } @@ -434,15 +435,12 @@ impl<'ll, 'tcx> FnAbiLlvmExt<'ll, 'tcx> for FnAbi<'tcx, Ty<'tcx>> { let sret = llvm::CreateStructRetAttr(cx.llcx, self.ret.layout.llvm_type(cx)); attributes::apply_to_llfn(llfn, llvm::AttributePlace::Argument(i), &[sret]); } - PassMode::Cast(cast) => { + PassMode::Cast(cast, _) => { cast.attrs.apply_attrs_to_llfn(llvm::AttributePlace::ReturnValue, cx, llfn); } _ => {} } for arg in self.args.iter() { - if arg.pad_i32 { - apply(&ArgAttributes::new()); - } match &arg.mode { PassMode::Ignore => {} PassMode::Indirect { attrs, extra_attrs: None, on_stack: true } => { @@ -463,7 +461,10 @@ impl<'ll, 'tcx> FnAbiLlvmExt<'ll, 'tcx> for FnAbi<'tcx, Ty<'tcx>> { apply(a); apply(b); } - PassMode::Cast(cast) => { + PassMode::Cast(cast, pad_i32) => { + if *pad_i32 { + apply(&ArgAttributes::new()); + } apply(&cast.attrs); } } @@ -496,7 +497,7 @@ impl<'ll, 'tcx> FnAbiLlvmExt<'ll, 'tcx> for FnAbi<'tcx, Ty<'tcx>> { let sret = llvm::CreateStructRetAttr(bx.cx.llcx, self.ret.layout.llvm_type(bx)); attributes::apply_to_callsite(callsite, llvm::AttributePlace::Argument(i), &[sret]); } - PassMode::Cast(cast) => { + PassMode::Cast(cast, _) => { cast.attrs.apply_attrs_to_callsite( llvm::AttributePlace::ReturnValue, &bx.cx, @@ -516,9 +517,6 @@ impl<'ll, 'tcx> FnAbiLlvmExt<'ll, 'tcx> for FnAbi<'tcx, Ty<'tcx>> { } } for arg in self.args.iter() { - if arg.pad_i32 { - apply(bx.cx, &ArgAttributes::new()); - } match &arg.mode { PassMode::Ignore => {} PassMode::Indirect { attrs, extra_attrs: None, on_stack: true } => { @@ -542,7 +540,10 @@ impl<'ll, 'tcx> FnAbiLlvmExt<'ll, 'tcx> for FnAbi<'tcx, Ty<'tcx>> { apply(bx.cx, a); apply(bx.cx, b); } - PassMode::Cast(cast) => { + PassMode::Cast(cast, pad_i32) => { + if *pad_i32 { + apply(bx.cx, &ArgAttributes::new()); + } apply(bx.cx, &cast.attrs); } } diff --git a/compiler/rustc_codegen_llvm/src/intrinsic.rs b/compiler/rustc_codegen_llvm/src/intrinsic.rs index d46a6dd32c8..f4227fbd8fa 100644 --- a/compiler/rustc_codegen_llvm/src/intrinsic.rs +++ b/compiler/rustc_codegen_llvm/src/intrinsic.rs @@ -161,7 +161,7 @@ impl<'ll, 'tcx> IntrinsicCallMethods<'tcx> for Builder<'_, 'll, 'tcx> { sym::volatile_load | sym::unaligned_volatile_load => { let tp_ty = substs.type_at(0); let ptr = args[0].immediate(); - let load = if let PassMode::Cast(ty) = &fn_abi.ret.mode { + let load = if let PassMode::Cast(ty, _) = &fn_abi.ret.mode { let llty = ty.llvm_type(self); let ptr = self.pointercast(ptr, self.type_ptr_to(llty)); self.volatile_load(llty, ptr) @@ -374,7 +374,7 @@ impl<'ll, 'tcx> IntrinsicCallMethods<'tcx> for Builder<'_, 'll, 'tcx> { }; if !fn_abi.ret.is_ignore() { - if let PassMode::Cast(ty) = &fn_abi.ret.mode { + if let PassMode::Cast(ty, _) = &fn_abi.ret.mode { let ptr_llty = self.type_ptr_to(ty.llvm_type(self)); let ptr = self.pointercast(result.llval, ptr_llty); self.store(llval, ptr, result.align); diff --git a/compiler/rustc_codegen_ssa/src/mir/block.rs b/compiler/rustc_codegen_ssa/src/mir/block.rs index 5b3f41263e7..5c67d3b6431 100644 --- a/compiler/rustc_codegen_ssa/src/mir/block.rs +++ b/compiler/rustc_codegen_ssa/src/mir/block.rs @@ -339,7 +339,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { } } - PassMode::Cast(cast_ty) => { + PassMode::Cast(cast_ty, _) => { let op = match self.locals[mir::RETURN_PLACE] { LocalRef::Operand(Some(op)) => op, LocalRef::Operand(None) => bug!("use of return before def"), @@ -1158,39 +1158,35 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { llargs: &mut Vec, arg: &ArgAbi<'tcx, Ty<'tcx>>, ) { - // Fill padding with undef value, where applicable. - if arg.pad_i32 { - llargs.push(bx.const_undef(bx.reg_backend_type(&Reg::i32()))) - } - - if arg.is_ignore() { - return; - } - - if let PassMode::Pair(..) = arg.mode { - match op.val { + match arg.mode { + PassMode::Ignore => return, + PassMode::Cast(_, true) => { + // Fill padding with undef value, where applicable. + llargs.push(bx.const_undef(bx.reg_backend_type(&Reg::i32()))); + } + PassMode::Pair(..) => match op.val { Pair(a, b) => { llargs.push(a); llargs.push(b); return; } _ => bug!("codegen_argument: {:?} invalid for pair argument", op), - } - } else if arg.is_unsized_indirect() { - match op.val { + }, + PassMode::Indirect { attrs: _, extra_attrs: Some(_), on_stack: _ } => match op.val { Ref(a, Some(b), _) => { llargs.push(a); llargs.push(b); return; } _ => bug!("codegen_argument: {:?} invalid for unsized indirect argument", op), - } + }, + _ => {} } // Force by-ref if we have to load through a cast pointer. let (mut llval, align, by_ref) = match op.val { Immediate(_) | Pair(..) => match arg.mode { - PassMode::Indirect { .. } | PassMode::Cast(_) => { + PassMode::Indirect { .. } | PassMode::Cast(..) => { let scratch = PlaceRef::alloca(bx, arg.layout); op.val.store(bx, scratch); (scratch.llval, scratch.align, true) @@ -1222,7 +1218,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { if by_ref && !arg.is_indirect() { // Have to load the argument, maybe while casting it. - if let PassMode::Cast(ty) = &arg.mode { + if let PassMode::Cast(ty, _) = &arg.mode { let llty = bx.cast_backend_type(ty); let addr = bx.pointercast(llval, bx.type_ptr_to(llty)); llval = bx.load(llty, addr, align.min(arg.layout.align.abi)); @@ -1622,7 +1618,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { } DirectOperand(index) => { // If there is a cast, we have to store and reload. - let op = if let PassMode::Cast(_) = ret_abi.mode { + let op = if let PassMode::Cast(..) = ret_abi.mode { let tmp = PlaceRef::alloca(bx, ret_abi.layout); tmp.storage_live(bx); bx.store_arg(&ret_abi, llval, tmp); diff --git a/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs b/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs index e11ebdce80f..16aad07194d 100644 --- a/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs +++ b/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs @@ -597,7 +597,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { }; if !fn_abi.ret.is_ignore() { - if let PassMode::Cast(ty) = &fn_abi.ret.mode { + if let PassMode::Cast(ty, _) = &fn_abi.ret.mode { let ptr_llty = bx.type_ptr_to(bx.cast_backend_type(ty)); let ptr = bx.pointercast(result.llval, ptr_llty); bx.store(llval, ptr, result.align); diff --git a/compiler/rustc_codegen_ssa/src/mir/mod.rs b/compiler/rustc_codegen_ssa/src/mir/mod.rs index f13b658b2ff..c70c2bd9f74 100644 --- a/compiler/rustc_codegen_ssa/src/mir/mod.rs +++ b/compiler/rustc_codegen_ssa/src/mir/mod.rs @@ -283,7 +283,7 @@ fn arg_local_refs<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( for i in 0..tupled_arg_tys.len() { let arg = &fx.fn_abi.args[idx]; idx += 1; - if arg.pad_i32 { + if let PassMode::Cast(_, true) = arg.mode { llarg_idx += 1; } let pr_field = place.project_field(bx, i); @@ -309,7 +309,7 @@ fn arg_local_refs<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( let arg = &fx.fn_abi.args[idx]; idx += 1; - if arg.pad_i32 { + if let PassMode::Cast(_, true) = arg.mode { llarg_idx += 1; } diff --git a/compiler/rustc_const_eval/src/interpret/terminator.rs b/compiler/rustc_const_eval/src/interpret/terminator.rs index 2fcdf6ded98..35b1fefd286 100644 --- a/compiler/rustc_const_eval/src/interpret/terminator.rs +++ b/compiler/rustc_const_eval/src/interpret/terminator.rs @@ -215,8 +215,6 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { _ => false, } }; - // Padding must be fully equal. - let pad_compat = || caller_abi.pad_i32 == callee_abi.pad_i32; // When comparing the PassMode, we have to be smart about comparing the attributes. let arg_attr_compat = |a1: &ArgAttributes, a2: &ArgAttributes| { // There's only one regular attribute that matters for the call ABI: InReg. @@ -239,7 +237,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { (PassMode::Pair(a1, b1), PassMode::Pair(a2, b2)) => { arg_attr_compat(a1, a2) && arg_attr_compat(b1, b2) } - (PassMode::Cast(c1), PassMode::Cast(c2)) => c1 == c2, + (PassMode::Cast(c1, pad1), PassMode::Cast(c2, pad2)) => c1 == c2 && pad1 == pad2, ( PassMode::Indirect { attrs: a1, extra_attrs: None, on_stack: s1 }, PassMode::Indirect { attrs: a2, extra_attrs: None, on_stack: s2 }, @@ -251,7 +249,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { _ => false, }; - if layout_compat() && pad_compat() && mode_compat() { + if layout_compat() && mode_compat() { return true; } trace!( diff --git a/compiler/rustc_target/src/abi/call/mips.rs b/compiler/rustc_target/src/abi/call/mips.rs index ff8f3236214..edcd1bab8b4 100644 --- a/compiler/rustc_target/src/abi/call/mips.rs +++ b/compiler/rustc_target/src/abi/call/mips.rs @@ -22,10 +22,8 @@ where let align = arg.layout.align.max(dl.i32_align).min(dl.i64_align).abi; if arg.layout.is_aggregate() { - arg.cast_to(Uniform { unit: Reg::i32(), total: size }); - if !offset.is_aligned(align) { - arg.pad_with_i32(); - } + let pad_i32 = !offset.is_aligned(align); + arg.cast_to_and_pad_i32(Uniform { unit: Reg::i32(), total: size }, pad_i32); } else { arg.extend_integer_width_to(32); } diff --git a/compiler/rustc_target/src/abi/call/mod.rs b/compiler/rustc_target/src/abi/call/mod.rs index 33f533e68f0..d2eb804d004 100644 --- a/compiler/rustc_target/src/abi/call/mod.rs +++ b/compiler/rustc_target/src/abi/call/mod.rs @@ -40,9 +40,10 @@ pub enum PassMode { /// /// The argument has a layout abi of `ScalarPair`. Pair(ArgAttributes, ArgAttributes), - /// Pass the argument after casting it, to either - /// a single uniform or a pair of registers. - Cast(Box), + /// Pass the argument after casting it, to either a single uniform or a + /// pair of registers. The bool indicates if a `Reg::i32()` dummy argument + /// is emitted before the real argument. + Cast(Box, bool), /// Pass the argument indirectly via a hidden pointer. /// The `extra_attrs` value, if any, is for the extra data (vtable or length) /// which indicates that it refers to an unsized rvalue. @@ -463,10 +464,6 @@ impl<'a, Ty> TyAndLayout<'a, Ty> { #[derive(PartialEq, Eq, Hash, Debug, HashStable_Generic)] pub struct ArgAbi<'a, Ty> { pub layout: TyAndLayout<'a, Ty>, - - /// Dummy argument, which is emitted before the real argument. - pub pad_i32: bool, - pub mode: PassMode, } @@ -486,7 +483,7 @@ impl<'a, Ty> ArgAbi<'a, Ty> { Abi::Vector { .. } => PassMode::Direct(ArgAttributes::new()), Abi::Aggregate { .. } => PassMode::Direct(ArgAttributes::new()), }; - ArgAbi { layout, pad_i32: false, mode } + ArgAbi { layout, mode } } fn indirect_pass_mode(layout: &TyAndLayout<'a, Ty>) -> PassMode { @@ -548,11 +545,11 @@ impl<'a, Ty> ArgAbi<'a, Ty> { } pub fn cast_to>(&mut self, target: T) { - self.mode = PassMode::Cast(Box::new(target.into())); + self.mode = PassMode::Cast(Box::new(target.into()), false); } - pub fn pad_with_i32(&mut self) { - self.pad_i32 = true; + pub fn cast_to_and_pad_i32>(&mut self, target: T, pad_i32: bool) { + self.mode = PassMode::Cast(Box::new(target.into()), pad_i32); } pub fn is_indirect(&self) -> bool { @@ -737,6 +734,6 @@ mod size_asserts { use super::*; use rustc_data_structures::static_assert_size; // These are in alphabetical order, which is easy to maintain. - static_assert_size!(ArgAbi<'_, usize>, 64); - static_assert_size!(FnAbi<'_, usize>, 88); + static_assert_size!(ArgAbi<'_, usize>, 56); + static_assert_size!(FnAbi<'_, usize>, 80); } diff --git a/compiler/rustc_target/src/abi/call/sparc.rs b/compiler/rustc_target/src/abi/call/sparc.rs index ff8f3236214..edcd1bab8b4 100644 --- a/compiler/rustc_target/src/abi/call/sparc.rs +++ b/compiler/rustc_target/src/abi/call/sparc.rs @@ -22,10 +22,8 @@ where let align = arg.layout.align.max(dl.i32_align).min(dl.i64_align).abi; if arg.layout.is_aggregate() { - arg.cast_to(Uniform { unit: Reg::i32(), total: size }); - if !offset.is_aligned(align) { - arg.pad_with_i32(); - } + let pad_i32 = !offset.is_aligned(align); + arg.cast_to_and_pad_i32(Uniform { unit: Reg::i32(), total: size }, pad_i32); } else { arg.extend_integer_width_to(32); } diff --git a/compiler/rustc_target/src/abi/call/x86.rs b/compiler/rustc_target/src/abi/call/x86.rs index c2d70d1160c..7c26335dcf4 100644 --- a/compiler/rustc_target/src/abi/call/x86.rs +++ b/compiler/rustc_target/src/abi/call/x86.rs @@ -81,7 +81,7 @@ where PassMode::Direct(ref mut attrs) => attrs, PassMode::Pair(..) | PassMode::Indirect { attrs: _, extra_attrs: Some(_), on_stack: _ } - | PassMode::Cast(_) => { + | PassMode::Cast(..) => { unreachable!("x86 shouldn't be passing arguments by {:?}", arg.mode) } }; -- cgit 1.4.1-3-g733a5 From b48870b451dd9d3f3f827aa54d9becdfdd811ba3 Mon Sep 17 00:00:00 2001 From: Tomasz Miąsko Date: Tue, 5 Jul 2022 00:00:00 +0000 Subject: Replace `Body::basic_blocks()` with field access --- compiler/rustc_borrowck/src/constraint_generation.rs | 2 +- compiler/rustc_borrowck/src/dataflow.rs | 2 +- .../rustc_borrowck/src/diagnostics/explain_borrow.rs | 6 +++--- compiler/rustc_borrowck/src/diagnostics/move_errors.rs | 2 +- compiler/rustc_borrowck/src/location.rs | 2 +- compiler/rustc_borrowck/src/region_infer/values.rs | 4 ++-- compiler/rustc_borrowck/src/type_check/mod.rs | 2 +- compiler/rustc_codegen_cranelift/src/analyze.rs | 2 +- compiler/rustc_codegen_cranelift/src/base.rs | 4 ++-- compiler/rustc_codegen_cranelift/src/constant.rs | 2 +- compiler/rustc_codegen_ssa/src/mir/analyze.rs | 6 +++--- compiler/rustc_codegen_ssa/src/mir/mod.rs | 8 ++++---- compiler/rustc_const_eval/src/interpret/eval_context.rs | 2 +- .../src/interpret/intrinsics/caller_location.rs | 2 +- compiler/rustc_const_eval/src/interpret/step.rs | 2 +- .../rustc_const_eval/src/transform/check_consts/check.rs | 2 +- .../rustc_const_eval/src/transform/promote_consts.rs | 6 +++--- compiler/rustc_const_eval/src/transform/validate.rs | 8 ++++---- compiler/rustc_middle/src/mir/generic_graph.rs | 4 ++-- compiler/rustc_middle/src/mir/mod.rs | 7 +------ compiler/rustc_middle/src/mir/patch.rs | 10 +++++----- compiler/rustc_middle/src/mir/pretty.rs | 4 ++-- compiler/rustc_middle/src/mir/spanview.rs | 2 +- compiler/rustc_middle/src/mir/traversal.rs | 4 ++-- compiler/rustc_middle/src/mir/visit.rs | 2 +- compiler/rustc_mir_build/src/build/mod.rs | 2 +- compiler/rustc_mir_dataflow/src/framework/engine.rs | 9 ++++----- compiler/rustc_mir_dataflow/src/framework/graphviz.rs | 4 ++-- compiler/rustc_mir_dataflow/src/framework/tests.rs | 10 ++++------ compiler/rustc_mir_dataflow/src/move_paths/builder.rs | 2 +- compiler/rustc_mir_dataflow/src/move_paths/mod.rs | 2 +- compiler/rustc_mir_dataflow/src/rustc_peek.rs | 2 +- compiler/rustc_mir_dataflow/src/storage.rs | 2 +- .../rustc_mir_transform/src/abort_unwinding_calls.rs | 2 +- compiler/rustc_mir_transform/src/add_call_guards.rs | 2 +- .../src/add_moves_for_packed_drops.rs | 2 +- compiler/rustc_mir_transform/src/const_goto.rs | 4 ++-- compiler/rustc_mir_transform/src/const_prop.rs | 2 +- compiler/rustc_mir_transform/src/const_prop_lint.rs | 4 ++-- compiler/rustc_mir_transform/src/coverage/graph.rs | 4 ++-- compiler/rustc_mir_transform/src/coverage/mod.rs | 2 +- compiler/rustc_mir_transform/src/coverage/query.rs | 4 ++-- compiler/rustc_mir_transform/src/coverage/tests.rs | 6 +++--- compiler/rustc_mir_transform/src/deduplicate_blocks.rs | 5 ++--- compiler/rustc_mir_transform/src/dest_prop.rs | 6 +++--- .../rustc_mir_transform/src/early_otherwise_branch.rs | 6 +++--- compiler/rustc_mir_transform/src/elaborate_drops.rs | 12 ++++++------ compiler/rustc_mir_transform/src/ffi_unwind_calls.rs | 2 +- compiler/rustc_mir_transform/src/generator.rs | 14 +++++++------- compiler/rustc_mir_transform/src/inline.rs | 16 ++++++++-------- compiler/rustc_mir_transform/src/inline/cycle.rs | 2 +- .../src/multiple_return_terminators.rs | 2 +- compiler/rustc_mir_transform/src/normalize_array_len.rs | 4 ++-- compiler/rustc_mir_transform/src/nrvo.rs | 4 ++-- .../rustc_mir_transform/src/remove_noop_landing_pads.rs | 2 +- compiler/rustc_mir_transform/src/remove_uninit_drops.rs | 2 +- .../rustc_mir_transform/src/separate_const_switch.rs | 4 ++-- compiler/rustc_mir_transform/src/simplify.rs | 4 ++-- .../src/simplify_comparison_integral.rs | 2 +- compiler/rustc_mir_transform/src/simplify_try.rs | 4 ++-- .../src/uninhabited_enum_branching.rs | 6 +++--- compiler/rustc_monomorphize/src/partitioning/mod.rs | 2 +- compiler/rustc_ty_utils/src/ty.rs | 2 +- src/tools/clippy/clippy_lints/src/redundant_clone.rs | 6 +++--- .../clippy/clippy_utils/src/qualify_min_const_fn.rs | 2 +- 65 files changed, 131 insertions(+), 140 deletions(-) (limited to 'compiler/rustc_codegen_ssa/src') diff --git a/compiler/rustc_borrowck/src/constraint_generation.rs b/compiler/rustc_borrowck/src/constraint_generation.rs index 5e9cec5c350..144fd15fc24 100644 --- a/compiler/rustc_borrowck/src/constraint_generation.rs +++ b/compiler/rustc_borrowck/src/constraint_generation.rs @@ -31,7 +31,7 @@ pub(super) fn generate_constraints<'cx, 'tcx>( body, }; - for (bb, data) in body.basic_blocks().iter_enumerated() { + for (bb, data) in body.basic_blocks.iter_enumerated() { cg.visit_basic_block_data(bb, data); } } diff --git a/compiler/rustc_borrowck/src/dataflow.rs b/compiler/rustc_borrowck/src/dataflow.rs index 97d5a8d158e..816288eb50b 100644 --- a/compiler/rustc_borrowck/src/dataflow.rs +++ b/compiler/rustc_borrowck/src/dataflow.rs @@ -143,7 +143,7 @@ struct OutOfScopePrecomputer<'a, 'tcx> { impl<'a, 'tcx> OutOfScopePrecomputer<'a, 'tcx> { fn new(body: &'a Body<'tcx>, regioncx: &'a RegionInferenceContext<'tcx>) -> Self { OutOfScopePrecomputer { - visited: BitSet::new_empty(body.basic_blocks().len()), + visited: BitSet::new_empty(body.basic_blocks.len()), visit_stack: vec![], body, regioncx, diff --git a/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs b/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs index 68f9a7c5007..a6b8c6057e0 100644 --- a/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs +++ b/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs @@ -459,7 +459,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { return outmost_back_edge; } - let block = &self.body.basic_blocks()[location.block]; + let block = &self.body.basic_blocks[location.block]; if location.statement_index < block.statements.len() { let successor = location.successor_within_block(); @@ -518,7 +518,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { } if loop_head.dominates(from, &self.dominators) { - let block = &self.body.basic_blocks()[from.block]; + let block = &self.body.basic_blocks[from.block]; if from.statement_index < block.statements.len() { let successor = from.successor_within_block(); @@ -568,7 +568,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { UseSpans::PatUse(span) | UseSpans::OtherUse(span) | UseSpans::FnSelfUse { var_span: span, .. } => { - let block = &self.body.basic_blocks()[location.block]; + let block = &self.body.basic_blocks[location.block]; let kind = if let Some(&Statement { kind: StatementKind::FakeRead(box (FakeReadCause::ForLet(_), _)), diff --git a/compiler/rustc_borrowck/src/diagnostics/move_errors.rs b/compiler/rustc_borrowck/src/diagnostics/move_errors.rs index cb3cd479ae2..16c2f9ccc6a 100644 --- a/compiler/rustc_borrowck/src/diagnostics/move_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/move_errors.rs @@ -88,7 +88,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { if let Some(StatementKind::Assign(box ( place, Rvalue::Use(Operand::Move(move_from)), - ))) = self.body.basic_blocks()[location.block] + ))) = self.body.basic_blocks[location.block] .statements .get(location.statement_index) .map(|stmt| &stmt.kind) diff --git a/compiler/rustc_borrowck/src/location.rs b/compiler/rustc_borrowck/src/location.rs index 70a31169498..5ca3f2f4d03 100644 --- a/compiler/rustc_borrowck/src/location.rs +++ b/compiler/rustc_borrowck/src/location.rs @@ -33,7 +33,7 @@ impl LocationTable { pub(crate) fn new(body: &Body<'_>) -> Self { let mut num_points = 0; let statements_before_block = body - .basic_blocks() + .basic_blocks .iter() .map(|block_data| { let v = num_points; diff --git a/compiler/rustc_borrowck/src/region_infer/values.rs b/compiler/rustc_borrowck/src/region_infer/values.rs index c81ef10f7c7..de20a4bb465 100644 --- a/compiler/rustc_borrowck/src/region_infer/values.rs +++ b/compiler/rustc_borrowck/src/region_infer/values.rs @@ -25,7 +25,7 @@ impl RegionValueElements { pub(crate) fn new(body: &Body<'_>) -> Self { let mut num_points = 0; let statements_before_block: IndexVec = body - .basic_blocks() + .basic_blocks .iter() .map(|block_data| { let v = num_points; @@ -37,7 +37,7 @@ impl RegionValueElements { debug!("RegionValueElements: num_points={:#?}", num_points); let mut basic_blocks = IndexVec::with_capacity(num_points); - for (bb, bb_data) in body.basic_blocks().iter_enumerated() { + for (bb, bb_data) in body.basic_blocks.iter_enumerated() { basic_blocks.extend((0..=bb_data.statements.len()).map(|_| bb)); } diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs index 293d847ec9a..c1812aa4bba 100644 --- a/compiler/rustc_borrowck/src/type_check/mod.rs +++ b/compiler/rustc_borrowck/src/type_check/mod.rs @@ -2633,7 +2633,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { self.check_local(&body, local, local_decl); } - for (block, block_data) in body.basic_blocks().iter_enumerated() { + for (block, block_data) in body.basic_blocks.iter_enumerated() { let mut location = Location { block, statement_index: 0 }; for stmt in &block_data.statements { if !stmt.source_info.span.is_dummy() { diff --git a/compiler/rustc_codegen_cranelift/src/analyze.rs b/compiler/rustc_codegen_cranelift/src/analyze.rs index 35b89358b19..0cbb9f3ec2d 100644 --- a/compiler/rustc_codegen_cranelift/src/analyze.rs +++ b/compiler/rustc_codegen_cranelift/src/analyze.rs @@ -26,7 +26,7 @@ pub(crate) fn analyze(fx: &FunctionCx<'_, '_, '_>) -> IndexVec { }) .collect::>(); - for bb in fx.mir.basic_blocks().iter() { + for bb in fx.mir.basic_blocks.iter() { for stmt in bb.statements.iter() { match &stmt.kind { Assign(place_and_rval) => match &place_and_rval.1 { diff --git a/compiler/rustc_codegen_cranelift/src/base.rs b/compiler/rustc_codegen_cranelift/src/base.rs index 44c34d6c8cb..3011813c703 100644 --- a/compiler/rustc_codegen_cranelift/src/base.rs +++ b/compiler/rustc_codegen_cranelift/src/base.rs @@ -73,7 +73,7 @@ pub(crate) fn codegen_fn<'tcx>( // Predefine blocks let start_block = bcx.create_block(); let block_map: IndexVec = - (0..mir.basic_blocks().len()).map(|_| bcx.create_block()).collect(); + (0..mir.basic_blocks.len()).map(|_| bcx.create_block()).collect(); // Make FunctionCx let target_config = module.target_config(); @@ -271,7 +271,7 @@ fn codegen_fn_body(fx: &mut FunctionCx<'_, '_, '_>, start_block: Block) { } fx.tcx.sess.time("codegen prelude", || crate::abi::codegen_fn_prelude(fx, start_block)); - for (bb, bb_data) in fx.mir.basic_blocks().iter_enumerated() { + for (bb, bb_data) in fx.mir.basic_blocks.iter_enumerated() { let block = fx.get_block(bb); fx.bcx.switch_to_block(block); diff --git a/compiler/rustc_codegen_cranelift/src/constant.rs b/compiler/rustc_codegen_cranelift/src/constant.rs index 7f7fd0e9c57..e2b68f24a21 100644 --- a/compiler/rustc_codegen_cranelift/src/constant.rs +++ b/compiler/rustc_codegen_cranelift/src/constant.rs @@ -505,7 +505,7 @@ pub(crate) fn mir_operand_get_const_val<'tcx>( return None; } let mut computed_const_val = None; - for bb_data in fx.mir.basic_blocks() { + for bb_data in fx.mir.basic_blocks.iter() { for stmt in &bb_data.statements { match &stmt.kind { StatementKind::Assign(local_and_rvalue) if &local_and_rvalue.0 == place => { diff --git a/compiler/rustc_codegen_ssa/src/mir/analyze.rs b/compiler/rustc_codegen_ssa/src/mir/analyze.rs index 24da48ead63..c7617d2e464 100644 --- a/compiler/rustc_codegen_ssa/src/mir/analyze.rs +++ b/compiler/rustc_codegen_ssa/src/mir/analyze.rs @@ -266,7 +266,7 @@ pub fn cleanup_kinds(mir: &mir::Body<'_>) -> IndexVec, mir: &mir::Body<'tcx>, ) { - for (bb, data) in mir.basic_blocks().iter_enumerated() { + for (bb, data) in mir.basic_blocks.iter_enumerated() { match data.terminator().kind { TerminatorKind::Goto { .. } | TerminatorKind::Resume @@ -296,7 +296,7 @@ pub fn cleanup_kinds(mir: &mir::Body<'_>) -> IndexVec(result: &mut IndexVec, mir: &mir::Body<'tcx>) { - let mut funclet_succs = IndexVec::from_elem(None, mir.basic_blocks()); + let mut funclet_succs = IndexVec::from_elem(None, &mir.basic_blocks); let mut set_successor = |funclet: mir::BasicBlock, succ| match funclet_succs[funclet] { ref mut s @ None => { @@ -359,7 +359,7 @@ pub fn cleanup_kinds(mir: &mir::Body<'_>) -> IndexVec>( let start_llbb = Bx::append_block(cx, llfn, "start"); let mut bx = Bx::build(cx, start_llbb); - if mir.basic_blocks().iter().any(|bb| bb.is_cleanup) { + if mir.basic_blocks.iter().any(|bb| bb.is_cleanup) { bx.set_personality_fn(cx.eh_personality()); } let cleanup_kinds = analyze::cleanup_kinds(&mir); let cached_llbbs: IndexVec> = mir - .basic_blocks() + .basic_blocks .indices() .map(|bb| if bb == mir::START_BLOCK { Some(start_llbb) } else { None }) .collect(); @@ -172,8 +172,8 @@ pub fn codegen_mir<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( unreachable_block: None, double_unwind_guard: None, cleanup_kinds, - landing_pads: IndexVec::from_elem(None, mir.basic_blocks()), - funclets: IndexVec::from_fn_n(|_| None, mir.basic_blocks().len()), + landing_pads: IndexVec::from_elem(None, &mir.basic_blocks), + funclets: IndexVec::from_fn_n(|_| None, mir.basic_blocks.len()), locals: IndexVec::new(), debug_context, per_local_var_debug_info: None, diff --git a/compiler/rustc_const_eval/src/interpret/eval_context.rs b/compiler/rustc_const_eval/src/interpret/eval_context.rs index 150d6589b08..594bfd13f1d 100644 --- a/compiler/rustc_const_eval/src/interpret/eval_context.rs +++ b/compiler/rustc_const_eval/src/interpret/eval_context.rs @@ -782,7 +782,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { assert_eq!( unwinding, match self.frame().loc { - Ok(loc) => self.body().basic_blocks()[loc.block].is_cleanup, + Ok(loc) => self.body().basic_blocks[loc.block].is_cleanup, Err(_) => true, } ); diff --git a/compiler/rustc_const_eval/src/interpret/intrinsics/caller_location.rs b/compiler/rustc_const_eval/src/interpret/intrinsics/caller_location.rs index 5864b921552..91f4f042517 100644 --- a/compiler/rustc_const_eval/src/interpret/intrinsics/caller_location.rs +++ b/compiler/rustc_const_eval/src/interpret/intrinsics/caller_location.rs @@ -28,7 +28,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { let mut source_info = *frame.body.source_info(loc); // If this is a `Call` terminator, use the `fn_span` instead. - let block = &frame.body.basic_blocks()[loc.block]; + let block = &frame.body.basic_blocks[loc.block]; if loc.statement_index == block.statements.len() { debug!( "find_closest_untracked_caller_location: got terminator {:?} ({:?})", diff --git a/compiler/rustc_const_eval/src/interpret/step.rs b/compiler/rustc_const_eval/src/interpret/step.rs index fea158a9fe4..683e11ff7e0 100644 --- a/compiler/rustc_const_eval/src/interpret/step.rs +++ b/compiler/rustc_const_eval/src/interpret/step.rs @@ -53,7 +53,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { self.pop_stack_frame(/* unwinding */ true)?; return Ok(true); }; - let basic_block = &self.body().basic_blocks()[loc.block]; + let basic_block = &self.body().basic_blocks[loc.block]; if let Some(stmt) = basic_block.statements.get(loc.statement_index) { let old_frames = self.frame_idx(); diff --git a/compiler/rustc_const_eval/src/transform/check_consts/check.rs b/compiler/rustc_const_eval/src/transform/check_consts/check.rs index 0adb88a180f..cbfdb47dd1a 100644 --- a/compiler/rustc_const_eval/src/transform/check_consts/check.rs +++ b/compiler/rustc_const_eval/src/transform/check_consts/check.rs @@ -135,7 +135,7 @@ impl<'mir, 'tcx> Qualifs<'mir, 'tcx> { // qualifs for the return type. let return_block = ccx .body - .basic_blocks() + .basic_blocks .iter_enumerated() .find(|(_, block)| matches!(block.terminator().kind, TerminatorKind::Return)) .map(|(bb, _)| bb); diff --git a/compiler/rustc_const_eval/src/transform/promote_consts.rs b/compiler/rustc_const_eval/src/transform/promote_consts.rs index 161c89e3242..6301388d1e8 100644 --- a/compiler/rustc_const_eval/src/transform/promote_consts.rs +++ b/compiler/rustc_const_eval/src/transform/promote_consts.rs @@ -710,7 +710,7 @@ impl<'a, 'tcx> Promoter<'a, 'tcx> { } fn assign(&mut self, dest: Local, rvalue: Rvalue<'tcx>, span: Span) { - let last = self.promoted.basic_blocks().last().unwrap(); + let last = self.promoted.basic_blocks.last().unwrap(); let data = &mut self.promoted[last]; data.statements.push(Statement { source_info: SourceInfo::outermost(span), @@ -803,7 +803,7 @@ impl<'a, 'tcx> Promoter<'a, 'tcx> { self.visit_operand(arg, loc); } - let last = self.promoted.basic_blocks().last().unwrap(); + let last = self.promoted.basic_blocks.last().unwrap(); let new_target = self.new_block(); *self.promoted[last].terminator_mut() = Terminator { @@ -1041,7 +1041,7 @@ pub fn is_const_fn_in_array_repeat_expression<'tcx>( _ => {} } - for block in body.basic_blocks() { + for block in body.basic_blocks.iter() { if let Some(Terminator { kind: TerminatorKind::Call { func, destination, .. }, .. }) = &block.terminator { diff --git a/compiler/rustc_const_eval/src/transform/validate.rs b/compiler/rustc_const_eval/src/transform/validate.rs index 1a14cd79fa0..45a94972c11 100644 --- a/compiler/rustc_const_eval/src/transform/validate.rs +++ b/compiler/rustc_const_eval/src/transform/validate.rs @@ -140,8 +140,8 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { if bb == START_BLOCK { self.fail(location, "start block must not have predecessors") } - if let Some(bb) = self.body.basic_blocks().get(bb) { - let src = self.body.basic_blocks().get(location.block).unwrap(); + if let Some(bb) = self.body.basic_blocks.get(bb) { + let src = self.body.basic_blocks.get(location.block).unwrap(); match (src.is_cleanup, bb.is_cleanup, edge_kind) { // Non-cleanup blocks can jump to non-cleanup blocks along non-unwind edges (false, false, EdgeKind::Normal) @@ -881,13 +881,13 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { } TerminatorKind::Resume | TerminatorKind::Abort => { let bb = location.block; - if !self.body.basic_blocks()[bb].is_cleanup { + if !self.body.basic_blocks[bb].is_cleanup { self.fail(location, "Cannot `Resume` or `Abort` from non-cleanup basic block") } } TerminatorKind::Return => { let bb = location.block; - if self.body.basic_blocks()[bb].is_cleanup { + if self.body.basic_blocks[bb].is_cleanup { self.fail(location, "Cannot `Return` from cleanup basic block") } } diff --git a/compiler/rustc_middle/src/mir/generic_graph.rs b/compiler/rustc_middle/src/mir/generic_graph.rs index f3621cd99d3..d1f3561c02c 100644 --- a/compiler/rustc_middle/src/mir/generic_graph.rs +++ b/compiler/rustc_middle/src/mir/generic_graph.rs @@ -12,14 +12,14 @@ pub fn mir_fn_to_generic_graph<'tcx>(tcx: TyCtxt<'tcx>, body: &Body<'_>) -> Grap // Nodes let nodes: Vec = body - .basic_blocks() + .basic_blocks .iter_enumerated() .map(|(block, _)| bb_to_graph_node(block, body, dark_mode)) .collect(); // Edges let mut edges = Vec::new(); - for (source, _) in body.basic_blocks().iter_enumerated() { + for (source, _) in body.basic_blocks.iter_enumerated() { let def_id = body.source.def_id(); let terminator = body[source].terminator(); let labels = terminator.kind.fmt_successor_labels(); diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs index 9da9b4e91f6..f7a1e9b2864 100644 --- a/compiler/rustc_middle/src/mir/mod.rs +++ b/compiler/rustc_middle/src/mir/mod.rs @@ -331,11 +331,6 @@ impl<'tcx> Body<'tcx> { body } - #[inline] - pub fn basic_blocks(&self) -> &IndexVec> { - &self.basic_blocks - } - #[inline] pub fn basic_blocks_mut(&mut self) -> &mut IndexVec> { self.basic_blocks.as_mut() @@ -490,7 +485,7 @@ impl<'tcx> Index for Body<'tcx> { #[inline] fn index(&self, index: BasicBlock) -> &BasicBlockData<'tcx> { - &self.basic_blocks()[index] + &self.basic_blocks[index] } } diff --git a/compiler/rustc_middle/src/mir/patch.rs b/compiler/rustc_middle/src/mir/patch.rs index 8aa761aae8d..24fe3b47256 100644 --- a/compiler/rustc_middle/src/mir/patch.rs +++ b/compiler/rustc_middle/src/mir/patch.rs @@ -19,7 +19,7 @@ pub struct MirPatch<'tcx> { impl<'tcx> MirPatch<'tcx> { pub fn new(body: &Body<'tcx>) -> Self { let mut result = MirPatch { - patch_map: IndexVec::from_elem(None, body.basic_blocks()), + patch_map: IndexVec::from_elem(None, &body.basic_blocks), new_blocks: vec![], new_statements: vec![], new_locals: vec![], @@ -29,7 +29,7 @@ impl<'tcx> MirPatch<'tcx> { }; // Check if we already have a resume block - for (bb, block) in body.basic_blocks().iter_enumerated() { + for (bb, block) in body.basic_blocks.iter_enumerated() { if let TerminatorKind::Resume = block.terminator().kind && block.statements.is_empty() { result.resume_block = Some(bb); break; @@ -61,7 +61,7 @@ impl<'tcx> MirPatch<'tcx> { } pub fn terminator_loc(&self, body: &Body<'tcx>, bb: BasicBlock) -> Location { - let offset = match bb.index().checked_sub(body.basic_blocks().len()) { + let offset = match bb.index().checked_sub(body.basic_blocks.len()) { Some(index) => self.new_blocks[index].statements.len(), None => body[bb].statements.len(), }; @@ -129,7 +129,7 @@ impl<'tcx> MirPatch<'tcx> { debug!( "MirPatch: {} new blocks, starting from index {}", self.new_blocks.len(), - body.basic_blocks().len() + body.basic_blocks.len() ); let bbs = if self.patch_map.is_empty() && self.new_blocks.is_empty() { body.basic_blocks.as_mut_preserves_cfg() @@ -173,7 +173,7 @@ impl<'tcx> MirPatch<'tcx> { } pub fn source_info_for_location(&self, body: &Body<'tcx>, loc: Location) -> SourceInfo { - let data = match loc.block.index().checked_sub(body.basic_blocks().len()) { + let data = match loc.block.index().checked_sub(body.basic_blocks.len()) { Some(new) => &self.new_blocks[new], None => &body[loc.block], }; diff --git a/compiler/rustc_middle/src/mir/pretty.rs b/compiler/rustc_middle/src/mir/pretty.rs index 0ce41337b91..da6af89b09b 100644 --- a/compiler/rustc_middle/src/mir/pretty.rs +++ b/compiler/rustc_middle/src/mir/pretty.rs @@ -318,10 +318,10 @@ where F: FnMut(PassWhere, &mut dyn Write) -> io::Result<()>, { write_mir_intro(tcx, body, w)?; - for block in body.basic_blocks().indices() { + for block in body.basic_blocks.indices() { extra_data(PassWhere::BeforeBlock(block), w)?; write_basic_block(tcx, block, body, extra_data, w)?; - if block.index() + 1 != body.basic_blocks().len() { + if block.index() + 1 != body.basic_blocks.len() { writeln!(w)?; } } diff --git a/compiler/rustc_middle/src/mir/spanview.rs b/compiler/rustc_middle/src/mir/spanview.rs index 4418b848e51..6e64a3b80c1 100644 --- a/compiler/rustc_middle/src/mir/spanview.rs +++ b/compiler/rustc_middle/src/mir/spanview.rs @@ -105,7 +105,7 @@ where } let body_span = hir_body.unwrap().value.span; let mut span_viewables = Vec::new(); - for (bb, data) in body.basic_blocks().iter_enumerated() { + for (bb, data) in body.basic_blocks.iter_enumerated() { match spanview { MirSpanview::Statement => { for (i, statement) in data.statements.iter().enumerate() { diff --git a/compiler/rustc_middle/src/mir/traversal.rs b/compiler/rustc_middle/src/mir/traversal.rs index 627dc32f37e..55b2c592795 100644 --- a/compiler/rustc_middle/src/mir/traversal.rs +++ b/compiler/rustc_middle/src/mir/traversal.rs @@ -37,7 +37,7 @@ impl<'a, 'tcx> Preorder<'a, 'tcx> { Preorder { body, - visited: BitSet::new_empty(body.basic_blocks().len()), + visited: BitSet::new_empty(body.basic_blocks.len()), worklist, root_is_start_block: root == START_BLOCK, } @@ -71,7 +71,7 @@ impl<'a, 'tcx> Iterator for Preorder<'a, 'tcx> { fn size_hint(&self) -> (usize, Option) { // All the blocks, minus the number of blocks we've visited. - let upper = self.body.basic_blocks().len() - self.visited.count(); + let upper = self.body.basic_blocks.len() - self.visited.count(); let lower = if self.root_is_start_block { // We will visit all remaining blocks exactly once. diff --git a/compiler/rustc_middle/src/mir/visit.rs b/compiler/rustc_middle/src/mir/visit.rs index 4a85defb1ed..7bd65f42e3f 100644 --- a/compiler/rustc_middle/src/mir/visit.rs +++ b/compiler/rustc_middle/src/mir/visit.rs @@ -951,7 +951,7 @@ macro_rules! basic_blocks { $body.basic_blocks.as_mut_preserves_cfg() }; ($body:ident,) => { - $body.basic_blocks() + $body.basic_blocks }; } diff --git a/compiler/rustc_mir_build/src/build/mod.rs b/compiler/rustc_mir_build/src/build/mod.rs index 461c837f6df..684b228e87f 100644 --- a/compiler/rustc_mir_build/src/build/mod.rs +++ b/compiler/rustc_mir_build/src/build/mod.rs @@ -272,7 +272,7 @@ fn mir_build(tcx: TyCtxt<'_>, def: ty::WithOptConstParam) -> Body<'_ // by borrow checking. debug_assert!( !(body.local_decls.has_free_regions() - || body.basic_blocks().has_free_regions() + || body.basic_blocks.has_free_regions() || body.var_debug_info.has_free_regions() || body.yield_ty().has_free_regions()), "Unexpected free regions in MIR: {:?}", diff --git a/compiler/rustc_mir_dataflow/src/framework/engine.rs b/compiler/rustc_mir_dataflow/src/framework/engine.rs index f374658ceb6..ecfa90371f5 100644 --- a/compiler/rustc_mir_dataflow/src/framework/engine.rs +++ b/compiler/rustc_mir_dataflow/src/framework/engine.rs @@ -108,9 +108,9 @@ where // Otherwise, compute and store the cumulative transfer function for each block. let identity = GenKillSet::identity(analysis.bottom_value(body).domain_size()); - let mut trans_for_block = IndexVec::from_elem(identity, body.basic_blocks()); + let mut trans_for_block = IndexVec::from_elem(identity, &body.basic_blocks); - for (block, block_data) in body.basic_blocks().iter_enumerated() { + for (block, block_data) in body.basic_blocks.iter_enumerated() { let trans = &mut trans_for_block[block]; A::Direction::gen_kill_effects_in_block(&analysis, trans, block, block_data); } @@ -144,7 +144,7 @@ where apply_trans_for_block: Option>, ) -> Self { let bottom_value = analysis.bottom_value(body); - let mut entry_sets = IndexVec::from_elem(bottom_value.clone(), body.basic_blocks()); + let mut entry_sets = IndexVec::from_elem(bottom_value.clone(), &body.basic_blocks); analysis.initialize_start_block(body, &mut entry_sets[mir::START_BLOCK]); if A::Direction::IS_BACKWARD && entry_sets[mir::START_BLOCK] != bottom_value { @@ -197,8 +197,7 @@ where .. } = self; - let mut dirty_queue: WorkQueue = - WorkQueue::with_none(body.basic_blocks().len()); + let mut dirty_queue: WorkQueue = WorkQueue::with_none(body.basic_blocks.len()); if A::Direction::IS_FORWARD { for (bb, _) in traversal::reverse_postorder(body) { diff --git a/compiler/rustc_mir_dataflow/src/framework/graphviz.rs b/compiler/rustc_mir_dataflow/src/framework/graphviz.rs index c94198c56a8..579fe68a149 100644 --- a/compiler/rustc_mir_dataflow/src/framework/graphviz.rs +++ b/compiler/rustc_mir_dataflow/src/framework/graphviz.rs @@ -108,12 +108,12 @@ where type Edge = CfgEdge; fn nodes(&self) -> dot::Nodes<'_, Self::Node> { - self.body.basic_blocks().indices().collect::>().into() + self.body.basic_blocks.indices().collect::>().into() } fn edges(&self) -> dot::Edges<'_, Self::Edge> { self.body - .basic_blocks() + .basic_blocks .indices() .flat_map(|bb| dataflow_successors(self.body, bb)) .collect::>() diff --git a/compiler/rustc_mir_dataflow/src/framework/tests.rs b/compiler/rustc_mir_dataflow/src/framework/tests.rs index d9461fd3abd..17102454a88 100644 --- a/compiler/rustc_mir_dataflow/src/framework/tests.rs +++ b/compiler/rustc_mir_dataflow/src/framework/tests.rs @@ -100,9 +100,9 @@ impl MockAnalysis<'_, D> { fn mock_entry_sets(&self) -> IndexVec> { let empty = self.bottom_value(self.body); - let mut ret = IndexVec::from_elem(empty, &self.body.basic_blocks()); + let mut ret = IndexVec::from_elem(empty, &self.body.basic_blocks); - for (bb, _) in self.body.basic_blocks().iter_enumerated() { + for (bb, _) in self.body.basic_blocks.iter_enumerated() { ret[bb] = self.mock_entry_set(bb); } @@ -169,7 +169,7 @@ impl<'tcx, D: Direction> AnalysisDomain<'tcx> for MockAnalysis<'tcx, D> { const NAME: &'static str = "mock"; fn bottom_value(&self, body: &mir::Body<'tcx>) -> Self::Domain { - BitSet::new_empty(Self::BASIC_BLOCK_OFFSET + body.basic_blocks().len()) + BitSet::new_empty(Self::BASIC_BLOCK_OFFSET + body.basic_blocks.len()) } fn initialize_start_block(&self, _: &mir::Body<'tcx>, _: &mut Self::Domain) { @@ -271,9 +271,7 @@ fn test_cursor(analysis: MockAnalysis<'_, D>) { cursor.allow_unreachable(); let every_target = || { - body.basic_blocks() - .iter_enumerated() - .flat_map(|(bb, _)| SeekTarget::iter_in_block(body, bb)) + body.basic_blocks.iter_enumerated().flat_map(|(bb, _)| SeekTarget::iter_in_block(body, bb)) }; let mut seek_to_target = |targ| { diff --git a/compiler/rustc_mir_dataflow/src/move_paths/builder.rs b/compiler/rustc_mir_dataflow/src/move_paths/builder.rs index 116e5c1f3ce..c3258386223 100644 --- a/compiler/rustc_mir_dataflow/src/move_paths/builder.rs +++ b/compiler/rustc_mir_dataflow/src/move_paths/builder.rs @@ -243,7 +243,7 @@ pub(super) fn gather_moves<'tcx>( builder.gather_args(); - for (bb, block) in body.basic_blocks().iter_enumerated() { + for (bb, block) in body.basic_blocks.iter_enumerated() { for (i, stmt) in block.statements.iter().enumerate() { let source = Location { block: bb, statement_index: i }; builder.gather_statement(source, stmt); diff --git a/compiler/rustc_mir_dataflow/src/move_paths/mod.rs b/compiler/rustc_mir_dataflow/src/move_paths/mod.rs index a951c5b0b1c..b36e268cf8b 100644 --- a/compiler/rustc_mir_dataflow/src/move_paths/mod.rs +++ b/compiler/rustc_mir_dataflow/src/move_paths/mod.rs @@ -217,7 +217,7 @@ where fn new(body: &Body<'_>) -> Self { LocationMap { map: body - .basic_blocks() + .basic_blocks .iter() .map(|block| vec![T::default(); block.statements.len() + 1]) .collect(), diff --git a/compiler/rustc_mir_dataflow/src/rustc_peek.rs b/compiler/rustc_mir_dataflow/src/rustc_peek.rs index f2471f37a52..382d371840f 100644 --- a/compiler/rustc_mir_dataflow/src/rustc_peek.rs +++ b/compiler/rustc_mir_dataflow/src/rustc_peek.rs @@ -97,7 +97,7 @@ pub fn sanity_check_via_rustc_peek<'tcx, A>( let mut cursor = ResultsCursor::new(body, results); - let peek_calls = body.basic_blocks().iter_enumerated().filter_map(|(bb, block_data)| { + let peek_calls = body.basic_blocks.iter_enumerated().filter_map(|(bb, block_data)| { PeekCall::from_terminator(tcx, block_data.terminator()).map(|call| (bb, block_data, call)) }); diff --git a/compiler/rustc_mir_dataflow/src/storage.rs b/compiler/rustc_mir_dataflow/src/storage.rs index c909648ea01..e5a0e1d312e 100644 --- a/compiler/rustc_mir_dataflow/src/storage.rs +++ b/compiler/rustc_mir_dataflow/src/storage.rs @@ -7,7 +7,7 @@ use rustc_middle::mir::{self, Local}; pub fn always_storage_live_locals(body: &mir::Body<'_>) -> BitSet { let mut always_live_locals = BitSet::new_filled(body.local_decls.len()); - for block in body.basic_blocks() { + for block in &*body.basic_blocks { for statement in &block.statements { use mir::StatementKind::{StorageDead, StorageLive}; if let StorageLive(l) | StorageDead(l) = statement.kind { diff --git a/compiler/rustc_mir_transform/src/abort_unwinding_calls.rs b/compiler/rustc_mir_transform/src/abort_unwinding_calls.rs index 2502e8b603c..d8f85d2e379 100644 --- a/compiler/rustc_mir_transform/src/abort_unwinding_calls.rs +++ b/compiler/rustc_mir_transform/src/abort_unwinding_calls.rs @@ -56,7 +56,7 @@ impl<'tcx> MirPass<'tcx> for AbortUnwindingCalls { // example. let mut calls_to_terminate = Vec::new(); let mut cleanups_to_remove = Vec::new(); - for (id, block) in body.basic_blocks().iter_enumerated() { + for (id, block) in body.basic_blocks.iter_enumerated() { if block.is_cleanup { continue; } diff --git a/compiler/rustc_mir_transform/src/add_call_guards.rs b/compiler/rustc_mir_transform/src/add_call_guards.rs index f12c8560c0e..30966d22e2f 100644 --- a/compiler/rustc_mir_transform/src/add_call_guards.rs +++ b/compiler/rustc_mir_transform/src/add_call_guards.rs @@ -45,7 +45,7 @@ impl AddCallGuards { // We need a place to store the new blocks generated let mut new_blocks = Vec::new(); - let cur_len = body.basic_blocks().len(); + let cur_len = body.basic_blocks.len(); for block in body.basic_blocks_mut() { match block.terminator { diff --git a/compiler/rustc_mir_transform/src/add_moves_for_packed_drops.rs b/compiler/rustc_mir_transform/src/add_moves_for_packed_drops.rs index 8de0aad041c..ffb5d8c6d95 100644 --- a/compiler/rustc_mir_transform/src/add_moves_for_packed_drops.rs +++ b/compiler/rustc_mir_transform/src/add_moves_for_packed_drops.rs @@ -55,7 +55,7 @@ fn add_moves_for_packed_drops_patch<'tcx>(tcx: TyCtxt<'tcx>, body: &Body<'tcx>) let mut patch = MirPatch::new(body); let param_env = tcx.param_env(def_id); - for (bb, data) in body.basic_blocks().iter_enumerated() { + for (bb, data) in body.basic_blocks.iter_enumerated() { let loc = Location { block: bb, statement_index: data.statements.len() }; let terminator = data.terminator(); diff --git a/compiler/rustc_mir_transform/src/const_goto.rs b/compiler/rustc_mir_transform/src/const_goto.rs index 5acf939f06b..0a305a40209 100644 --- a/compiler/rustc_mir_transform/src/const_goto.rs +++ b/compiler/rustc_mir_transform/src/const_goto.rs @@ -61,14 +61,14 @@ impl<'tcx> Visitor<'tcx> for ConstGotoOptimizationFinder<'_, 'tcx> { let _: Option<_> = try { let target = terminator.kind.as_goto()?; // We only apply this optimization if the last statement is a const assignment - let last_statement = self.body.basic_blocks()[location.block].statements.last()?; + let last_statement = self.body.basic_blocks[location.block].statements.last()?; if let (place, Rvalue::Use(Operand::Constant(_const))) = last_statement.kind.as_assign()? { // We found a constant being assigned to `place`. // Now check that the target of this Goto switches on this place. - let target_bb = &self.body.basic_blocks()[target]; + let target_bb = &self.body.basic_blocks[target]; // The `StorageDead(..)` statement does not affect the functionality of mir. // We can move this part of the statement up to the predecessor. diff --git a/compiler/rustc_mir_transform/src/const_prop.rs b/compiler/rustc_mir_transform/src/const_prop.rs index 1c087b93b49..fdcc065f112 100644 --- a/compiler/rustc_mir_transform/src/const_prop.rs +++ b/compiler/rustc_mir_transform/src/const_prop.rs @@ -131,7 +131,7 @@ impl<'tcx> MirPass<'tcx> for ConstProp { let dummy_body = &Body::new( body.source, - body.basic_blocks().clone(), + (*body.basic_blocks).clone(), body.source_scopes.clone(), body.local_decls.clone(), Default::default(), diff --git a/compiler/rustc_mir_transform/src/const_prop_lint.rs b/compiler/rustc_mir_transform/src/const_prop_lint.rs index c2ea55af48a..1254aee3994 100644 --- a/compiler/rustc_mir_transform/src/const_prop_lint.rs +++ b/compiler/rustc_mir_transform/src/const_prop_lint.rs @@ -106,7 +106,7 @@ impl<'tcx> MirLint<'tcx> for ConstProp { let dummy_body = &Body::new( body.source, - body.basic_blocks().clone(), + (*body.basic_blocks).clone(), body.source_scopes.clone(), body.local_decls.clone(), Default::default(), @@ -524,7 +524,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> { impl<'tcx> Visitor<'tcx> for ConstPropagator<'_, 'tcx> { fn visit_body(&mut self, body: &Body<'tcx>) { - for (bb, data) in body.basic_blocks().iter_enumerated() { + for (bb, data) in body.basic_blocks.iter_enumerated() { self.visit_basic_block_data(bb, data); } } diff --git a/compiler/rustc_mir_transform/src/coverage/graph.rs b/compiler/rustc_mir_transform/src/coverage/graph.rs index 759ea7cd328..782129be088 100644 --- a/compiler/rustc_mir_transform/src/coverage/graph.rs +++ b/compiler/rustc_mir_transform/src/coverage/graph.rs @@ -713,7 +713,7 @@ impl< ShortCircuitPreorder { body, - visited: BitSet::new_empty(body.basic_blocks().len()), + visited: BitSet::new_empty(body.basic_blocks.len()), worklist, filtered_successors, } @@ -747,7 +747,7 @@ impl< } fn size_hint(&self) -> (usize, Option) { - let size = self.body.basic_blocks().len() - self.visited.count(); + let size = self.body.basic_blocks.len() - self.visited.count(); (size, Some(size)) } } diff --git a/compiler/rustc_mir_transform/src/coverage/mod.rs b/compiler/rustc_mir_transform/src/coverage/mod.rs index 2619626a567..299a8067b28 100644 --- a/compiler/rustc_mir_transform/src/coverage/mod.rs +++ b/compiler/rustc_mir_transform/src/coverage/mod.rs @@ -80,7 +80,7 @@ impl<'tcx> MirPass<'tcx> for InstrumentCoverage { return; } - match mir_body.basic_blocks()[mir::START_BLOCK].terminator().kind { + match mir_body.basic_blocks[mir::START_BLOCK].terminator().kind { TerminatorKind::Unreachable => { trace!("InstrumentCoverage skipped for unreachable `START_BLOCK`"); return; diff --git a/compiler/rustc_mir_transform/src/coverage/query.rs b/compiler/rustc_mir_transform/src/coverage/query.rs index 9d02f58ae65..dc1e68b253e 100644 --- a/compiler/rustc_mir_transform/src/coverage/query.rs +++ b/compiler/rustc_mir_transform/src/coverage/query.rs @@ -84,7 +84,7 @@ impl CoverageVisitor { } fn visit_body(&mut self, body: &Body<'_>) { - for bb_data in body.basic_blocks().iter() { + for bb_data in body.basic_blocks.iter() { for statement in bb_data.statements.iter() { if let StatementKind::Coverage(box ref coverage) = statement.kind { if is_inlined(body, statement) { @@ -138,7 +138,7 @@ fn coverageinfo<'tcx>(tcx: TyCtxt<'tcx>, instance_def: ty::InstanceDef<'tcx>) -> fn covered_code_regions<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> Vec<&'tcx CodeRegion> { let body = mir_body(tcx, def_id); - body.basic_blocks() + body.basic_blocks .iter() .flat_map(|data| { data.statements.iter().filter_map(|statement| match statement.kind { diff --git a/compiler/rustc_mir_transform/src/coverage/tests.rs b/compiler/rustc_mir_transform/src/coverage/tests.rs index 6380f03528a..9c9ed5fa510 100644 --- a/compiler/rustc_mir_transform/src/coverage/tests.rs +++ b/compiler/rustc_mir_transform/src/coverage/tests.rs @@ -176,7 +176,7 @@ fn debug_basic_blocks<'tcx>(mir_body: &Body<'tcx>) -> String { format!( "{:?}", mir_body - .basic_blocks() + .basic_blocks .iter_enumerated() .map(|(bb, data)| { let term = &data.terminator(); @@ -213,7 +213,7 @@ fn print_mir_graphviz(name: &str, mir_body: &Body<'_>) { "digraph {} {{\n{}\n}}", name, mir_body - .basic_blocks() + .basic_blocks .iter_enumerated() .map(|(bb, data)| { format!( @@ -653,7 +653,7 @@ fn test_traverse_coverage_with_loops() { fn synthesize_body_span_from_terminators(mir_body: &Body<'_>) -> Span { let mut some_span: Option = None; - for (_, data) in mir_body.basic_blocks().iter_enumerated() { + for (_, data) in mir_body.basic_blocks.iter_enumerated() { let term_span = data.terminator().source_info.span; if let Some(span) = some_span.as_mut() { *span = span.to(term_span); diff --git a/compiler/rustc_mir_transform/src/deduplicate_blocks.rs b/compiler/rustc_mir_transform/src/deduplicate_blocks.rs index d1977ed49fe..909116a77f5 100644 --- a/compiler/rustc_mir_transform/src/deduplicate_blocks.rs +++ b/compiler/rustc_mir_transform/src/deduplicate_blocks.rs @@ -58,7 +58,7 @@ fn find_duplicates(body: &Body<'_>) -> FxHashMap { let mut duplicates = FxHashMap::default(); let bbs_to_go_through = - body.basic_blocks().iter_enumerated().filter(|(_, bbd)| !bbd.is_cleanup).count(); + body.basic_blocks.iter_enumerated().filter(|(_, bbd)| !bbd.is_cleanup).count(); let mut same_hashes = FxHashMap::with_capacity_and_hasher(bbs_to_go_through, Default::default()); @@ -71,8 +71,7 @@ fn find_duplicates(body: &Body<'_>) -> FxHashMap { // When we see bb1, we see that it is a duplicate of bb3, and therefore insert it in the duplicates list // with replacement bb3. // When the duplicates are removed, we will end up with only bb3. - for (bb, bbd) in body.basic_blocks().iter_enumerated().rev().filter(|(_, bbd)| !bbd.is_cleanup) - { + for (bb, bbd) in body.basic_blocks.iter_enumerated().rev().filter(|(_, bbd)| !bbd.is_cleanup) { // Basic blocks can get really big, so to avoid checking for duplicates in basic blocks // that are unlikely to have duplicates, we stop early. The early bail number has been // found experimentally by eprintln while compiling the crates in the rustc-perf suite. diff --git a/compiler/rustc_mir_transform/src/dest_prop.rs b/compiler/rustc_mir_transform/src/dest_prop.rs index 33572068f5c..da55510920e 100644 --- a/compiler/rustc_mir_transform/src/dest_prop.rs +++ b/compiler/rustc_mir_transform/src/dest_prop.rs @@ -150,7 +150,7 @@ impl<'tcx> MirPass<'tcx> for DestinationPropagation { def_id, body.local_decls.len(), relevant, - body.basic_blocks().len() + body.basic_blocks.len() ); if relevant > MAX_LOCALS { warn!( @@ -159,11 +159,11 @@ impl<'tcx> MirPass<'tcx> for DestinationPropagation { ); return; } - if body.basic_blocks().len() > MAX_BLOCKS { + if body.basic_blocks.len() > MAX_BLOCKS { warn!( "too many blocks in {:?} ({}, max is {}), not optimizing", def_id, - body.basic_blocks().len(), + body.basic_blocks.len(), MAX_BLOCKS ); return; diff --git a/compiler/rustc_mir_transform/src/early_otherwise_branch.rs b/compiler/rustc_mir_transform/src/early_otherwise_branch.rs index dba42f7aff0..32e738bbcea 100644 --- a/compiler/rustc_mir_transform/src/early_otherwise_branch.rs +++ b/compiler/rustc_mir_transform/src/early_otherwise_branch.rs @@ -104,8 +104,8 @@ impl<'tcx> MirPass<'tcx> for EarlyOtherwiseBranch { let mut should_cleanup = false; // Also consider newly generated bbs in the same pass - for i in 0..body.basic_blocks().len() { - let bbs = body.basic_blocks(); + for i in 0..body.basic_blocks.len() { + let bbs = &*body.basic_blocks; let parent = BasicBlock::from_usize(i); let Some(opt_data) = evaluate_candidate(tcx, body, parent) else { continue @@ -316,7 +316,7 @@ fn evaluate_candidate<'tcx>( body: &Body<'tcx>, parent: BasicBlock, ) -> Option> { - let bbs = body.basic_blocks(); + let bbs = &body.basic_blocks; let TerminatorKind::SwitchInt { targets, switch_ty: parent_ty, diff --git a/compiler/rustc_mir_transform/src/elaborate_drops.rs b/compiler/rustc_mir_transform/src/elaborate_drops.rs index 9c1fcbaa69d..61118ecc8ed 100644 --- a/compiler/rustc_mir_transform/src/elaborate_drops.rs +++ b/compiler/rustc_mir_transform/src/elaborate_drops.rs @@ -89,13 +89,13 @@ fn find_dead_unwinds<'tcx>( debug!("find_dead_unwinds({:?})", body.span); // We only need to do this pass once, because unwind edges can only // reach cleanup blocks, which can't have unwind edges themselves. - let mut dead_unwinds = BitSet::new_empty(body.basic_blocks().len()); + let mut dead_unwinds = BitSet::new_empty(body.basic_blocks.len()); let mut flow_inits = MaybeInitializedPlaces::new(tcx, body, &env) .into_engine(tcx, body) .pass_name("find_dead_unwinds") .iterate_to_fixpoint() .into_results_cursor(body); - for (bb, bb_data) in body.basic_blocks().iter_enumerated() { + for (bb, bb_data) in body.basic_blocks.iter_enumerated() { let place = match bb_data.terminator().kind { TerminatorKind::Drop { ref place, unwind: Some(_), .. } | TerminatorKind::DropAndReplace { ref place, unwind: Some(_), .. } => { @@ -303,7 +303,7 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> { } fn collect_drop_flags(&mut self) { - for (bb, data) in self.body.basic_blocks().iter_enumerated() { + for (bb, data) in self.body.basic_blocks.iter_enumerated() { let terminator = data.terminator(); let place = match terminator.kind { TerminatorKind::Drop { ref place, .. } @@ -358,7 +358,7 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> { } fn elaborate_drops(&mut self) { - for (bb, data) in self.body.basic_blocks().iter_enumerated() { + for (bb, data) in self.body.basic_blocks.iter_enumerated() { let loc = Location { block: bb, statement_index: data.statements.len() }; let terminator = data.terminator(); @@ -515,7 +515,7 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> { } fn drop_flags_for_fn_rets(&mut self) { - for (bb, data) in self.body.basic_blocks().iter_enumerated() { + for (bb, data) in self.body.basic_blocks.iter_enumerated() { if let TerminatorKind::Call { destination, target: Some(tgt), cleanup: Some(_), .. } = data.terminator().kind @@ -550,7 +550,7 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> { // drop flags by themselves, to avoid the drop flags being // clobbered before they are read. - for (bb, data) in self.body.basic_blocks().iter_enumerated() { + for (bb, data) in self.body.basic_blocks.iter_enumerated() { debug!("drop_flags_for_locs({:?})", data); for i in 0..(data.statements.len() + 1) { debug!("drop_flag_for_locs: stmt {}", i); diff --git a/compiler/rustc_mir_transform/src/ffi_unwind_calls.rs b/compiler/rustc_mir_transform/src/ffi_unwind_calls.rs index 7728fdaffb0..7522a50a8c6 100644 --- a/compiler/rustc_mir_transform/src/ffi_unwind_calls.rs +++ b/compiler/rustc_mir_transform/src/ffi_unwind_calls.rs @@ -65,7 +65,7 @@ fn has_ffi_unwind_calls(tcx: TyCtxt<'_>, local_def_id: LocalDefId) -> bool { let mut tainted = false; - for block in body.basic_blocks() { + for block in body.basic_blocks.iter() { if block.is_cleanup { continue; } diff --git a/compiler/rustc_mir_transform/src/generator.rs b/compiler/rustc_mir_transform/src/generator.rs index 5b0d9900c0f..c260611b407 100644 --- a/compiler/rustc_mir_transform/src/generator.rs +++ b/compiler/rustc_mir_transform/src/generator.rs @@ -490,12 +490,12 @@ fn locals_live_across_suspend_points<'tcx>( .iterate_to_fixpoint() .into_results_cursor(body_ref); - let mut storage_liveness_map = IndexVec::from_elem(None, body.basic_blocks()); + let mut storage_liveness_map = IndexVec::from_elem(None, &body.basic_blocks); let mut live_locals_at_suspension_points = Vec::new(); let mut source_info_at_suspension_points = Vec::new(); let mut live_locals_at_any_suspension_point = BitSet::new_empty(body.local_decls.len()); - for (block, data) in body.basic_blocks().iter_enumerated() { + for (block, data) in body.basic_blocks.iter_enumerated() { if let TerminatorKind::Yield { .. } = data.terminator().kind { let loc = Location { block, statement_index: data.statements.len() }; @@ -704,7 +704,7 @@ impl<'mir, 'tcx> rustc_mir_dataflow::ResultsVisitor<'mir, 'tcx> impl StorageConflictVisitor<'_, '_, '_> { fn apply_state(&mut self, flow_state: &BitSet, loc: Location) { // Ignore unreachable blocks. - if self.body.basic_blocks()[loc.block].terminator().kind == TerminatorKind::Unreachable { + if self.body.basic_blocks[loc.block].terminator().kind == TerminatorKind::Unreachable { return; } @@ -886,7 +886,7 @@ fn elaborate_generator_drops<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { let mut elaborator = DropShimElaborator { body, patch: MirPatch::new(body), tcx, param_env }; - for (block, block_data) in body.basic_blocks().iter_enumerated() { + for (block, block_data) in body.basic_blocks.iter_enumerated() { let (target, unwind, source_info) = match block_data.terminator() { Terminator { source_info, kind: TerminatorKind::Drop { place, target, unwind } } => { if let Some(local) = place.as_local() { @@ -991,7 +991,7 @@ fn insert_panic_block<'tcx>( body: &mut Body<'tcx>, message: AssertMessage<'tcx>, ) -> BasicBlock { - let assert_block = BasicBlock::new(body.basic_blocks().len()); + let assert_block = BasicBlock::new(body.basic_blocks.len()); let term = TerminatorKind::Assert { cond: Operand::Constant(Box::new(Constant { span: body.span, @@ -1021,7 +1021,7 @@ fn can_return<'tcx>(tcx: TyCtxt<'tcx>, body: &Body<'tcx>, param_env: ty::ParamEn } // If there's a return terminator the function may return. - for block in body.basic_blocks() { + for block in body.basic_blocks.iter() { if let TerminatorKind::Return = block.terminator().kind { return true; } @@ -1038,7 +1038,7 @@ fn can_unwind<'tcx>(tcx: TyCtxt<'tcx>, body: &Body<'tcx>) -> bool { } // Unwinds can only start at certain terminators. - for block in body.basic_blocks() { + for block in body.basic_blocks.iter() { match block.terminator().kind { // These never unwind. TerminatorKind::Goto { .. } diff --git a/compiler/rustc_mir_transform/src/inline.rs b/compiler/rustc_mir_transform/src/inline.rs index d7d29840188..ba00f16308e 100644 --- a/compiler/rustc_mir_transform/src/inline.rs +++ b/compiler/rustc_mir_transform/src/inline.rs @@ -95,7 +95,7 @@ fn inline<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) -> bool { history: Vec::new(), changed: false, }; - let blocks = BasicBlock::new(0)..body.basic_blocks().next_index(); + let blocks = BasicBlock::new(0)..body.basic_blocks.next_index(); this.process_blocks(body, blocks); this.changed } @@ -217,9 +217,9 @@ impl<'tcx> Inliner<'tcx> { } } - let old_blocks = caller_body.basic_blocks().next_index(); + let old_blocks = caller_body.basic_blocks.next_index(); self.inline_call(caller_body, &callsite, callee_body); - let new_blocks = old_blocks..caller_body.basic_blocks().next_index(); + let new_blocks = old_blocks..caller_body.basic_blocks.next_index(); Ok(new_blocks) } @@ -409,14 +409,14 @@ impl<'tcx> Inliner<'tcx> { // Give a bonus functions with a small number of blocks, // We normally have two or three blocks for even // very small functions. - if callee_body.basic_blocks().len() <= 3 { + if callee_body.basic_blocks.len() <= 3 { threshold += threshold / 4; } debug!(" final inline threshold = {}", threshold); // FIXME: Give a bonus to functions with only a single caller let diverges = matches!( - callee_body.basic_blocks()[START_BLOCK].terminator().kind, + callee_body.basic_blocks[START_BLOCK].terminator().kind, TerminatorKind::Unreachable | TerminatorKind::Call { target: None, .. } ); if diverges && !matches!(callee_attrs.inline, InlineAttr::Always) { @@ -434,13 +434,13 @@ impl<'tcx> Inliner<'tcx> { // Traverse the MIR manually so we can account for the effects of inlining on the CFG. let mut work_list = vec![START_BLOCK]; - let mut visited = BitSet::new_empty(callee_body.basic_blocks().len()); + let mut visited = BitSet::new_empty(callee_body.basic_blocks.len()); while let Some(bb) = work_list.pop() { if !visited.insert(bb.index()) { continue; } - let blk = &callee_body.basic_blocks()[bb]; + let blk = &callee_body.basic_blocks[bb]; checker.visit_basic_block_data(bb, blk); let term = blk.terminator(); @@ -541,7 +541,7 @@ impl<'tcx> Inliner<'tcx> { args: &args, new_locals: Local::new(caller_body.local_decls.len()).., new_scopes: SourceScope::new(caller_body.source_scopes.len()).., - new_blocks: BasicBlock::new(caller_body.basic_blocks().len()).., + new_blocks: BasicBlock::new(caller_body.basic_blocks.len()).., destination: dest, callsite_scope: caller_body.source_scopes[callsite.source_info.scope].clone(), callsite, diff --git a/compiler/rustc_mir_transform/src/inline/cycle.rs b/compiler/rustc_mir_transform/src/inline/cycle.rs index 7810218fd67..b027f94925d 100644 --- a/compiler/rustc_mir_transform/src/inline/cycle.rs +++ b/compiler/rustc_mir_transform/src/inline/cycle.rs @@ -153,7 +153,7 @@ pub(crate) fn mir_inliner_callees<'tcx>( _ => tcx.instance_mir(instance), }; let mut calls = FxIndexSet::default(); - for bb_data in body.basic_blocks() { + for bb_data in body.basic_blocks.iter() { let terminator = bb_data.terminator(); if let TerminatorKind::Call { func, .. } = &terminator.kind { let ty = func.ty(&body.local_decls, tcx); diff --git a/compiler/rustc_mir_transform/src/multiple_return_terminators.rs b/compiler/rustc_mir_transform/src/multiple_return_terminators.rs index 22b6dead99c..3957cd92c4e 100644 --- a/compiler/rustc_mir_transform/src/multiple_return_terminators.rs +++ b/compiler/rustc_mir_transform/src/multiple_return_terminators.rs @@ -15,7 +15,7 @@ impl<'tcx> MirPass<'tcx> for MultipleReturnTerminators { fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { // find basic blocks with no statement and a return terminator - let mut bbs_simple_returns = BitSet::new_empty(body.basic_blocks().len()); + let mut bbs_simple_returns = BitSet::new_empty(body.basic_blocks.len()); let def_id = body.source.def_id(); let bbs = body.basic_blocks_mut(); for idx in bbs.indices() { diff --git a/compiler/rustc_mir_transform/src/normalize_array_len.rs b/compiler/rustc_mir_transform/src/normalize_array_len.rs index c0217a10541..a159e617178 100644 --- a/compiler/rustc_mir_transform/src/normalize_array_len.rs +++ b/compiler/rustc_mir_transform/src/normalize_array_len.rs @@ -21,10 +21,10 @@ impl<'tcx> MirPass<'tcx> for NormalizeArrayLen { fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { // early returns for edge cases of highly unrolled functions - if body.basic_blocks().len() > MAX_NUM_BLOCKS { + if body.basic_blocks.len() > MAX_NUM_BLOCKS { return; } - if body.local_decls().len() > MAX_NUM_LOCALS { + if body.local_decls.len() > MAX_NUM_LOCALS { return; } normalize_array_len_calls(tcx, body) diff --git a/compiler/rustc_mir_transform/src/nrvo.rs b/compiler/rustc_mir_transform/src/nrvo.rs index 42d732730ec..4291e81c78c 100644 --- a/compiler/rustc_mir_transform/src/nrvo.rs +++ b/compiler/rustc_mir_transform/src/nrvo.rs @@ -89,7 +89,7 @@ fn local_eligible_for_nrvo(body: &mut mir::Body<'_>) -> Option { } let mut copied_to_return_place = None; - for block in body.basic_blocks().indices() { + for block in body.basic_blocks.indices() { // Look for blocks with a `Return` terminator. if !matches!(body[block].terminator().kind, mir::TerminatorKind::Return) { continue; @@ -122,7 +122,7 @@ fn find_local_assigned_to_return_place( body: &mut mir::Body<'_>, ) -> Option { let mut block = start; - let mut seen = HybridBitSet::new_empty(body.basic_blocks().len()); + let mut seen = HybridBitSet::new_empty(body.basic_blocks.len()); // Iterate as long as `block` has exactly one predecessor that we have not yet visited. while seen.insert(block) { diff --git a/compiler/rustc_mir_transform/src/remove_noop_landing_pads.rs b/compiler/rustc_mir_transform/src/remove_noop_landing_pads.rs index 5c441c5b194..41a0bfac41a 100644 --- a/compiler/rustc_mir_transform/src/remove_noop_landing_pads.rs +++ b/compiler/rustc_mir_transform/src/remove_noop_landing_pads.rs @@ -94,7 +94,7 @@ impl RemoveNoopLandingPads { let mut jumps_folded = 0; let mut landing_pads_removed = 0; - let mut nop_landing_pads = BitSet::new_empty(body.basic_blocks().len()); + let mut nop_landing_pads = BitSet::new_empty(body.basic_blocks.len()); // This is a post-order traversal, so that if A post-dominates B // then A will be visited before B. diff --git a/compiler/rustc_mir_transform/src/remove_uninit_drops.rs b/compiler/rustc_mir_transform/src/remove_uninit_drops.rs index 96b715402e7..78b6f714a9b 100644 --- a/compiler/rustc_mir_transform/src/remove_uninit_drops.rs +++ b/compiler/rustc_mir_transform/src/remove_uninit_drops.rs @@ -35,7 +35,7 @@ impl<'tcx> MirPass<'tcx> for RemoveUninitDrops { .into_results_cursor(body); let mut to_remove = vec![]; - for (bb, block) in body.basic_blocks().iter_enumerated() { + for (bb, block) in body.basic_blocks.iter_enumerated() { let terminator = block.terminator(); let (TerminatorKind::Drop { place, .. } | TerminatorKind::DropAndReplace { place, .. }) = &terminator.kind diff --git a/compiler/rustc_mir_transform/src/separate_const_switch.rs b/compiler/rustc_mir_transform/src/separate_const_switch.rs index 925eb10a1f7..190f9c1ac15 100644 --- a/compiler/rustc_mir_transform/src/separate_const_switch.rs +++ b/compiler/rustc_mir_transform/src/separate_const_switch.rs @@ -62,7 +62,7 @@ impl<'tcx> MirPass<'tcx> for SeparateConstSwitch { pub fn separate_const_switch(body: &mut Body<'_>) -> usize { let mut new_blocks: SmallVec<[(BasicBlock, BasicBlock); 6]> = SmallVec::new(); let predecessors = body.basic_blocks.predecessors(); - 'block_iter: for (block_id, block) in body.basic_blocks().iter_enumerated() { + 'block_iter: for (block_id, block) in body.basic_blocks.iter_enumerated() { if let TerminatorKind::SwitchInt { discr: Operand::Copy(switch_place) | Operand::Move(switch_place), .. @@ -90,7 +90,7 @@ pub fn separate_const_switch(body: &mut Body<'_>) -> usize { let mut predecessors_left = predecessors[block_id].len(); 'predec_iter: for predecessor_id in predecessors[block_id].iter().copied() { - let predecessor = &body.basic_blocks()[predecessor_id]; + let predecessor = &body.basic_blocks[predecessor_id]; // First we make sure the predecessor jumps // in a reasonable way diff --git a/compiler/rustc_mir_transform/src/simplify.rs b/compiler/rustc_mir_transform/src/simplify.rs index 7a6ca917d0f..bed48db959a 100644 --- a/compiler/rustc_mir_transform/src/simplify.rs +++ b/compiler/rustc_mir_transform/src/simplify.rs @@ -74,7 +74,7 @@ pub struct CfgSimplifier<'a, 'tcx> { impl<'a, 'tcx> CfgSimplifier<'a, 'tcx> { pub fn new(body: &'a mut Body<'tcx>) -> Self { - let mut pred_count = IndexVec::from_elem(0u32, body.basic_blocks()); + let mut pred_count = IndexVec::from_elem(0u32, &body.basic_blocks); // we can't use mir.predecessors() here because that counts // dead blocks, which we don't want to. @@ -263,7 +263,7 @@ impl<'a, 'tcx> CfgSimplifier<'a, 'tcx> { pub fn remove_dead_blocks<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { let reachable = traversal::reachable_as_bitset(body); - let num_blocks = body.basic_blocks().len(); + let num_blocks = body.basic_blocks.len(); if num_blocks == reachable.count() { return; } diff --git a/compiler/rustc_mir_transform/src/simplify_comparison_integral.rs b/compiler/rustc_mir_transform/src/simplify_comparison_integral.rs index bbfaace7041..321d8c63b6e 100644 --- a/compiler/rustc_mir_transform/src/simplify_comparison_integral.rs +++ b/compiler/rustc_mir_transform/src/simplify_comparison_integral.rs @@ -151,7 +151,7 @@ struct OptimizationFinder<'a, 'tcx> { impl<'tcx> OptimizationFinder<'_, 'tcx> { fn find_optimizations(&self) -> Vec> { self.body - .basic_blocks() + .basic_blocks .iter_enumerated() .filter_map(|(bb_idx, bb)| { // find switch diff --git a/compiler/rustc_mir_transform/src/simplify_try.rs b/compiler/rustc_mir_transform/src/simplify_try.rs index d52f1261b23..baeb620ef24 100644 --- a/compiler/rustc_mir_transform/src/simplify_try.rs +++ b/compiler/rustc_mir_transform/src/simplify_try.rs @@ -596,7 +596,7 @@ struct SimplifyBranchSameOptimizationFinder<'a, 'tcx> { impl<'tcx> SimplifyBranchSameOptimizationFinder<'_, 'tcx> { fn find(&self) -> Vec { self.body - .basic_blocks() + .basic_blocks .iter_enumerated() .filter_map(|(bb_idx, bb)| { let (discr_switched_on, targets_and_values) = match &bb.terminator().kind { @@ -632,7 +632,7 @@ impl<'tcx> SimplifyBranchSameOptimizationFinder<'_, 'tcx> { let mut iter_bbs_reachable = targets_and_values .iter() - .map(|target_and_value| (target_and_value, &self.body.basic_blocks()[target_and_value.target])) + .map(|target_and_value| (target_and_value, &self.body.basic_blocks[target_and_value.target])) .filter(|(_, bb)| { // Reaching `unreachable` is UB so assume it doesn't happen. bb.terminator().kind != TerminatorKind::Unreachable diff --git a/compiler/rustc_mir_transform/src/uninhabited_enum_branching.rs b/compiler/rustc_mir_transform/src/uninhabited_enum_branching.rs index 30be64f5b2f..96ea15f1b80 100644 --- a/compiler/rustc_mir_transform/src/uninhabited_enum_branching.rs +++ b/compiler/rustc_mir_transform/src/uninhabited_enum_branching.rs @@ -79,7 +79,7 @@ fn ensure_otherwise_unreachable<'tcx>( targets: &SwitchTargets, ) -> Option> { let otherwise = targets.otherwise(); - let bb = &body.basic_blocks()[otherwise]; + let bb = &body.basic_blocks[otherwise]; if bb.terminator().kind == TerminatorKind::Unreachable && bb.statements.iter().all(|s| matches!(&s.kind, StatementKind::StorageDead(_))) { @@ -102,10 +102,10 @@ impl<'tcx> MirPass<'tcx> for UninhabitedEnumBranching { fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { trace!("UninhabitedEnumBranching starting for {:?}", body.source); - for bb in body.basic_blocks().indices() { + for bb in body.basic_blocks.indices() { trace!("processing block {:?}", bb); - let Some(discriminant_ty) = get_switched_on_type(&body.basic_blocks()[bb], tcx, body) else { + let Some(discriminant_ty) = get_switched_on_type(&body.basic_blocks[bb], tcx, body) else { continue; }; diff --git a/compiler/rustc_monomorphize/src/partitioning/mod.rs b/compiler/rustc_monomorphize/src/partitioning/mod.rs index ff2d3869328..43319dc5862 100644 --- a/compiler/rustc_monomorphize/src/partitioning/mod.rs +++ b/compiler/rustc_monomorphize/src/partitioning/mod.rs @@ -481,7 +481,7 @@ fn codegened_and_inlined_items<'tcx>(tcx: TyCtxt<'tcx>, (): ()) -> &'tcx DefIdSe continue; } let body = tcx.instance_mir(instance.def); - for block in body.basic_blocks() { + for block in body.basic_blocks.iter() { for statement in &block.statements { let mir::StatementKind::Coverage(_) = statement.kind else { continue }; let scope = statement.source_info.scope; diff --git a/compiler/rustc_ty_utils/src/ty.rs b/compiler/rustc_ty_utils/src/ty.rs index db0d45b86fc..acfeefb4d12 100644 --- a/compiler/rustc_ty_utils/src/ty.rs +++ b/compiler/rustc_ty_utils/src/ty.rs @@ -348,7 +348,7 @@ fn instance_def_size_estimate<'tcx>( match instance_def { InstanceDef::Item(..) | InstanceDef::DropGlue(..) => { let mir = tcx.instance_mir(instance_def); - mir.basic_blocks().iter().map(|bb| bb.statements.len() + 1).sum() + mir.basic_blocks.iter().map(|bb| bb.statements.len() + 1).sum() } // Estimate the size of other compiler-generated shims to be 1. _ => 1, diff --git a/src/tools/clippy/clippy_lints/src/redundant_clone.rs b/src/tools/clippy/clippy_lints/src/redundant_clone.rs index eddca604575..9fd86331ec7 100644 --- a/src/tools/clippy/clippy_lints/src/redundant_clone.rs +++ b/src/tools/clippy/clippy_lints/src/redundant_clone.rs @@ -105,7 +105,7 @@ impl<'tcx> LateLintPass<'tcx> for RedundantClone { vis.into_map(cx, maybe_storage_live_result) }; - for (bb, bbdata) in mir.basic_blocks().iter_enumerated() { + for (bb, bbdata) in mir.basic_blocks.iter_enumerated() { let terminator = bbdata.terminator(); if terminator.source_info.span.from_expansion() { @@ -186,7 +186,7 @@ impl<'tcx> LateLintPass<'tcx> for RedundantClone { unwrap_or_continue!(find_stmt_assigns_to(cx, mir, pred_arg, true, ps[0])); let loc = mir::Location { block: bb, - statement_index: mir.basic_blocks()[bb].statements.len(), + statement_index: mir.basic_blocks[bb].statements.len(), }; // This can be turned into `res = move local` if `arg` and `cloned` are not borrowed @@ -310,7 +310,7 @@ fn find_stmt_assigns_to<'tcx>( by_ref: bool, bb: mir::BasicBlock, ) -> Option<(mir::Local, CannotMoveOut)> { - let rvalue = mir.basic_blocks()[bb].statements.iter().rev().find_map(|stmt| { + let rvalue = mir.basic_blocks[bb].statements.iter().rev().find_map(|stmt| { if let mir::StatementKind::Assign(box (mir::Place { local, .. }, v)) = &stmt.kind { return if *local == to_local { Some(v) } else { None }; } diff --git a/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs b/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs index 3bf75bcbee8..74c222bbcbe 100644 --- a/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs +++ b/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs @@ -55,7 +55,7 @@ pub fn is_min_const_fn<'a, 'tcx>(tcx: TyCtxt<'tcx>, body: &'a Body<'tcx>, msrv: body.local_decls.iter().next().unwrap().source_info.span, )?; - for bb in body.basic_blocks() { + for bb in body.basic_blocks.iter() { check_terminator(tcx, body, bb.terminator(), msrv)?; for stmt in &bb.statements { check_statement(tcx, body, def_id, stmt)?; -- cgit 1.4.1-3-g733a5 From 2c77f3e9c5804edc0bb520c7b4774424cea6beb0 Mon Sep 17 00:00:00 2001 From: Luis Cardoso <61982523+LuisCardosoOliveira@users.noreply.github.com> Date: Wed, 24 Aug 2022 17:15:08 +0200 Subject: translations(rustc_session): migrate check_expected_reuse This commit migrates the errors in the function check_expected_reuse to use the new SessionDiagnostic. It also does some small refactor for the IncorrectCguReuseType to include the 'at least' word in the fluent translation file --- compiler/rustc_codegen_ssa/src/back/write.rs | 2 +- compiler/rustc_error_messages/locales/en-US/session.ftl | 5 ++++- compiler/rustc_session/src/cgu_reuse_tracker.rs | 17 +++++------------ compiler/rustc_session/src/errors.rs | 15 +++++++-------- 4 files changed, 17 insertions(+), 22 deletions(-) (limited to 'compiler/rustc_codegen_ssa/src') diff --git a/compiler/rustc_codegen_ssa/src/back/write.rs b/compiler/rustc_codegen_ssa/src/back/write.rs index 2930d09d71f..68f3b19b715 100644 --- a/compiler/rustc_codegen_ssa/src/back/write.rs +++ b/compiler/rustc_codegen_ssa/src/back/write.rs @@ -1892,7 +1892,7 @@ impl OngoingCodegen { } }); - sess.cgu_reuse_tracker.check_expected_reuse(sess.diagnostic()); + sess.cgu_reuse_tracker.check_expected_reuse(sess); sess.abort_if_errors(); diff --git a/compiler/rustc_error_messages/locales/en-US/session.ftl b/compiler/rustc_error_messages/locales/en-US/session.ftl index e94a7b2c1c8..983e5cee823 100644 --- a/compiler/rustc_error_messages/locales/en-US/session.ftl +++ b/compiler/rustc_error_messages/locales/en-US/session.ftl @@ -1,5 +1,8 @@ session_incorrect_cgu_reuse_type = - CGU-reuse for `{$cgu_user_name}` is `{$actual_reuse}` but should be `{$at_least}``${expected_reuse}` + CGU-reuse for `{$cgu_user_name}` is `{$actual_reuse}` but should be {$at_least -> + [one] {"at least "} + *[other] {""} + }`{$expected_reuse}` session_cgu_not_recorded = CGU-reuse for `{$cgu_user_name}` is (mangled: `{$cgu_name}`) was not recorded` diff --git a/compiler/rustc_session/src/cgu_reuse_tracker.rs b/compiler/rustc_session/src/cgu_reuse_tracker.rs index 0b75a89c4d8..2a4a772f610 100644 --- a/compiler/rustc_session/src/cgu_reuse_tracker.rs +++ b/compiler/rustc_session/src/cgu_reuse_tracker.rs @@ -2,7 +2,8 @@ //! compilation. This is used for incremental compilation tests and debug //! output. -use crate::errors::IncorrectCguReuseType; +use crate::errors::{CguNotRecorded, IncorrectCguReuseType}; +use crate::Session; use rustc_data_structures::fx::FxHashMap; use rustc_errors::{DiagnosticArgValue, IntoDiagnosticArg}; use rustc_span::{Span, Symbol}; @@ -104,7 +105,7 @@ impl CguReuseTracker { } } - pub fn check_expected_reuse(&self, diag: &rustc_errors::Handler) { + pub fn check_expected_reuse(&self, sess: &Session) { if let Some(ref data) = self.data { let data = data.lock().unwrap(); @@ -118,7 +119,7 @@ impl CguReuseTracker { }; if error { - let at_least = if at_least { "at least " } else { "" }; + let at_least = if at_least { 1 } else { 0 }; IncorrectCguReuseType { span: error_span.0, cgu_user_name: &cgu_user_name, @@ -128,15 +129,7 @@ impl CguReuseTracker { }; } } else { - //FIXME: Remove this once PR #100694 that implements `[fatal(..)]` is merged - let msg = format!( - "CGU-reuse for `{cgu_user_name}` (mangled: `{cgu_name}`) was \ - not recorded" - ); - diag.span_fatal(error_span.0, &msg) - - //FIXME: Uncomment this once PR #100694 that implements `[fatal(..)]` is merged - // CguNotRecorded { cgu_user_name, cgu_name }; + sess.emit_fatal(CguNotRecorded { cgu_user_name, cgu_name }); } } } diff --git a/compiler/rustc_session/src/errors.rs b/compiler/rustc_session/src/errors.rs index 54e5fe82f5c..7252f1799da 100644 --- a/compiler/rustc_session/src/errors.rs +++ b/compiler/rustc_session/src/errors.rs @@ -14,16 +14,15 @@ pub struct IncorrectCguReuseType<'a> { pub cgu_user_name: &'a str, pub actual_reuse: CguReuse, pub expected_reuse: CguReuse, - pub at_least: &'a str, + pub at_least: u8, } -//FIXME: Uncomment this once PR #100694 that implements `[fatal(..)]` is merged -// #[derive(SessionDiagnostic)] -// #[fatal(session::cgu_not_recorded)] -// pub struct CguNotRecorded<'a> { -// pub cgu_user_name: &'a str, -// pub cgu_name: &'a str, -// } +#[derive(SessionDiagnostic)] +#[diag(session::cgu_not_recorded)] +pub struct CguNotRecorded<'a> { + pub cgu_user_name: &'a str, + pub cgu_name: &'a str, +} #[derive(SessionDiagnostic)] #[diag(session::feature_gate_error, code = "E0658")] -- cgit 1.4.1-3-g733a5 From a7e4794c2effd128a223ce3df0816637ac0a8d7c Mon Sep 17 00:00:00 2001 From: Amanieu d'Antras Date: Sun, 28 Aug 2022 06:38:01 +0800 Subject: Fix handling of rust_eh_personality in reachable_non_generics --- compiler/rustc_codegen_ssa/src/back/symbol_export.rs | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) (limited to 'compiler/rustc_codegen_ssa/src') diff --git a/compiler/rustc_codegen_ssa/src/back/symbol_export.rs b/compiler/rustc_codegen_ssa/src/back/symbol_export.rs index e6b6055759d..32b340832ce 100644 --- a/compiler/rustc_codegen_ssa/src/back/symbol_export.rs +++ b/compiler/rustc_codegen_ssa/src/back/symbol_export.rs @@ -103,18 +103,14 @@ fn reachable_non_generics_provider(tcx: TyCtxt<'_>, cnum: CrateNum) -> DefIdMap< } }) .map(|def_id| { - let (export_level, used) = if special_runtime_crate { - let name = tcx.symbol_name(Instance::mono(tcx, def_id.to_def_id())).name; - // We won't link right if these symbols are stripped during LTO. - let used = match name { - "rust_eh_personality" - | "rust_eh_register_frames" - | "rust_eh_unregister_frames" => true, - _ => false, - }; - (SymbolExportLevel::Rust, used) + // We won't link right if this symbol is stripped during LTO. + let name = tcx.symbol_name(Instance::mono(tcx, def_id.to_def_id())).name; + let used = name == "rust_eh_personality"; + + let export_level = if special_runtime_crate { + SymbolExportLevel::Rust } else { - (symbol_export_level(tcx, def_id.to_def_id()), false) + symbol_export_level(tcx, def_id.to_def_id()) }; let codegen_attrs = tcx.codegen_fn_attrs(def_id.to_def_id()); debug!( -- cgit 1.4.1-3-g733a5 From 72fe79244d39c356e6fa1da4dfa58354983f98f7 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Mon, 29 Aug 2022 04:19:14 +0000 Subject: Simplify get_trait_ref a bit --- compiler/rustc_codegen_ssa/src/meth.rs | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) (limited to 'compiler/rustc_codegen_ssa/src') diff --git a/compiler/rustc_codegen_ssa/src/meth.rs b/compiler/rustc_codegen_ssa/src/meth.rs index 27d791d90a5..f8e982b7751 100644 --- a/compiler/rustc_codegen_ssa/src/meth.rs +++ b/compiler/rustc_codegen_ssa/src/meth.rs @@ -1,6 +1,6 @@ use crate::traits::*; -use rustc_middle::ty::{self, subst::GenericArgKind, ExistentialPredicate, Ty, TyCtxt}; +use rustc_middle::ty::{self, subst::GenericArgKind, Ty}; use rustc_session::config::Lto; use rustc_symbol_mangling::typeid_for_trait_ref; use rustc_target::abi::call::FnAbi; @@ -29,7 +29,7 @@ impl<'a, 'tcx> VirtualIndex { && bx.cx().sess().lto() == Lto::Fat { let typeid = - bx.typeid_metadata(typeid_for_trait_ref(bx.tcx(), get_trait_ref(bx.tcx(), ty))); + bx.typeid_metadata(typeid_for_trait_ref(bx.tcx(), expect_dyn_trait_in_self(ty))); let vtable_byte_offset = self.0 * bx.data_layout().pointer_size.bytes(); let type_checked_load = bx.type_checked_load(llvtable, vtable_byte_offset, typeid); let func = bx.extract_value(type_checked_load, 0); @@ -64,17 +64,13 @@ impl<'a, 'tcx> VirtualIndex { } } -fn get_trait_ref<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> ty::PolyExistentialTraitRef<'tcx> { +/// This takes a valid `self` receiver type and extracts the principal trait +/// ref of the type. +fn expect_dyn_trait_in_self<'tcx>(ty: Ty<'tcx>) -> ty::PolyExistentialTraitRef<'tcx> { for arg in ty.peel_refs().walk() { if let GenericArgKind::Type(ty) = arg.unpack() { - if let ty::Dynamic(trait_refs, _) = ty.kind() { - return trait_refs[0].map_bound(|trait_ref| match trait_ref { - ExistentialPredicate::Trait(tr) => tr, - ExistentialPredicate::Projection(proj) => proj.trait_ref(tcx), - ExistentialPredicate::AutoTrait(_) => { - bug!("auto traits don't have functions") - } - }); + if let ty::Dynamic(data, _) = ty.kind() { + return data.principal().expect("expected principal trait object"); } } } -- cgit 1.4.1-3-g733a5