diff options
| author | bors <bors@rust-lang.org> | 2024-06-11 13:38:45 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2024-06-11 13:38:45 +0000 |
| commit | 0c960618b56f662d933e8b864cd9632a99174e87 (patch) | |
| tree | 296aea982f866aa33a8d21cc784f2ca081690c33 /compiler/rustc_const_eval/src | |
| parent | 20ba13c38e5b8451b7b09e4009efc9010bfa3f2c (diff) | |
| parent | cfd48bdd7e124565de8022f8b87ef5a3aa7f78cd (diff) | |
| download | rust-0c960618b56f662d933e8b864cd9632a99174e87.tar.gz rust-0c960618b56f662d933e8b864cd9632a99174e87.zip | |
Auto merge of #126274 - jieyouxu:rollup-uj93sfm, r=jieyouxu
Rollup of 5 pull requests Successful merges: - #126186 (Migrate `run-make/multiple-emits` to `rmake.rs`) - #126236 (Delegation: fix ICE on recursive delegation) - #126254 (Remove ignore-cross-compile directive from ui/macros/proc_macro) - #126258 (Do not define opaque types when selecting impls) - #126265 (interpret: ensure we check bool/char for validity when they are used in a cast) r? `@ghost` `@rustbot` modify labels: rollup
Diffstat (limited to 'compiler/rustc_const_eval/src')
| -rw-r--r-- | compiler/rustc_const_eval/src/interpret/cast.rs | 10 | ||||
| -rw-r--r-- | compiler/rustc_const_eval/src/interpret/intrinsics.rs | 16 | ||||
| -rw-r--r-- | compiler/rustc_const_eval/src/interpret/operator.rs | 29 |
3 files changed, 29 insertions, 26 deletions
diff --git a/compiler/rustc_const_eval/src/interpret/cast.rs b/compiler/rustc_const_eval/src/interpret/cast.rs index 19414c72c6a..0a45bbb3edb 100644 --- a/compiler/rustc_const_eval/src/interpret/cast.rs +++ b/compiler/rustc_const_eval/src/interpret/cast.rs @@ -274,9 +274,13 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { // Let's make sure v is sign-extended *if* it has a signed type. let signed = src_layout.abi.is_signed(); // Also asserts that abi is `Scalar`. - let v = scalar.to_bits(src_layout.size)?; - let v = if signed { self.sign_extend(v, src_layout) } else { v }; - trace!("cast_from_scalar: {}, {} -> {}", v, src_layout.ty, cast_ty); + let v = match src_layout.ty.kind() { + Uint(_) | RawPtr(..) | FnPtr(..) => scalar.to_uint(src_layout.size)?, + Int(_) => scalar.to_int(src_layout.size)? as u128, // we will cast back to `i128` below if the sign matters + Bool => scalar.to_bool()?.into(), + Char => scalar.to_char()?.into(), + _ => span_bug!(self.cur_span(), "invalid int-like cast from {}", src_layout.ty), + }; Ok(match *cast_ty.kind() { // int -> int diff --git a/compiler/rustc_const_eval/src/interpret/intrinsics.rs b/compiler/rustc_const_eval/src/interpret/intrinsics.rs index dac5c10addc..7f16d441606 100644 --- a/compiler/rustc_const_eval/src/interpret/intrinsics.rs +++ b/compiler/rustc_const_eval/src/interpret/intrinsics.rs @@ -197,7 +197,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { // rotate_right: (X << ((BW - S) % BW)) | (X >> (S % BW)) let layout_val = self.layout_of(instance_args.type_at(0))?; let val = self.read_scalar(&args[0])?; - let val_bits = val.to_bits(layout_val.size)?; + let val_bits = val.to_bits(layout_val.size)?; // sign is ignored here let layout_raw_shift = self.layout_of(self.tcx.types.u32)?; let raw_shift = self.read_scalar(&args[1])?; @@ -484,7 +484,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { ret_layout: TyAndLayout<'tcx>, ) -> InterpResult<'tcx, Scalar<M::Provenance>> { assert!(layout.ty.is_integral(), "invalid type for numeric intrinsic: {}", layout.ty); - let bits = val.to_bits(layout.size)?; + let bits = val.to_bits(layout.size)?; // these operations all ignore the sign let extra = 128 - u128::from(layout.size.bits()); let bits_out = match name { sym::ctpop => u128::from(bits.count_ones()), @@ -519,6 +519,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { // `x % y != 0` or `y == 0` or `x == T::MIN && y == -1`. // First, check x % y != 0 (or if that computation overflows). let rem = self.binary_op(BinOp::Rem, a, b)?; + // sign does not matter for 0 test, so `to_bits` is fine if rem.to_scalar().to_bits(a.layout.size)? != 0 { throw_ub_custom!( fluent::const_eval_exact_div_has_remainder, @@ -545,22 +546,19 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { self.binary_op(mir_op.wrapping_to_overflowing().unwrap(), l, r)?.to_scalar_pair(); Ok(if overflowed.to_bool()? { let size = l.layout.size; - let num_bits = size.bits(); if l.layout.abi.is_signed() { // For signed ints the saturated value depends on the sign of the first // term since the sign of the second term can be inferred from this and // the fact that the operation has overflowed (if either is 0 no // overflow can occur) - let first_term: u128 = l.to_scalar().to_bits(l.layout.size)?; - let first_term_positive = first_term & (1 << (num_bits - 1)) == 0; - if first_term_positive { + let first_term: i128 = l.to_scalar().to_int(l.layout.size)?; + if first_term >= 0 { // Negative overflow not possible since the positive first term // can only increase an (in range) negative term for addition - // or corresponding negated positive term for subtraction + // or corresponding negated positive term for subtraction. Scalar::from_int(size.signed_int_max(), size) } else { - // Positive overflow not possible for similar reason - // max negative + // Positive overflow not possible for similar reason. Scalar::from_int(size.signed_int_min(), size) } } else { diff --git a/compiler/rustc_const_eval/src/interpret/operator.rs b/compiler/rustc_const_eval/src/interpret/operator.rs index c821c98073d..a6eef9f5662 100644 --- a/compiler/rustc_const_eval/src/interpret/operator.rs +++ b/compiler/rustc_const_eval/src/interpret/operator.rs @@ -437,23 +437,24 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { }; Ok(ImmTy::from_scalar(res, layout)) } - _ if layout.ty.is_integral() => { - let val = val.to_scalar(); - let val = val.to_bits(layout.size)?; + ty::Int(..) => { + let val = val.to_scalar().to_int(layout.size)?; let res = match un_op { - Not => self.truncate(!val, layout), // bitwise negation, then truncate - Neg => { - // arithmetic negation - assert!(layout.abi.is_signed()); - let val = self.sign_extend(val, layout) as i128; - let res = val.wrapping_neg(); - let res = res as u128; - // Truncate to target type. - self.truncate(res, layout) - } + Not => !val, + Neg => val.wrapping_neg(), _ => span_bug!(self.cur_span(), "Invalid integer op {:?}", un_op), }; - Ok(ImmTy::from_uint(res, layout)) + let res = ScalarInt::truncate_from_int(res, layout.size).0; + Ok(ImmTy::from_scalar(res.into(), layout)) + } + ty::Uint(..) => { + let val = val.to_scalar().to_uint(layout.size)?; + let res = match un_op { + Not => !val, + _ => span_bug!(self.cur_span(), "Invalid unsigned integer op {:?}", un_op), + }; + let res = ScalarInt::truncate_from_uint(res, layout.size).0; + Ok(ImmTy::from_scalar(res.into(), layout)) } ty::RawPtr(..) => { assert_eq!(un_op, PtrMetadata); |
