Skip to content

Commit 2d7f7ff

Browse files
authored
Rollup merge of #126159 - RalfJung:scalarint-size-mismatch, r=oli-obk
ScalarInt: size mismatches are a bug, do not delay the panic Cc [Zulip](https://rust-lang.zulipchat.com/#narrow/stream/146212-t-compiler.2Fconst-eval/topic/Why.20are.20ScalarInt.20to.20iN.2FuN.20methods.20fallible.3F) r? ``@oli-obk``
2 parents bcc6fda + 3c57ea0 commit 2d7f7ff

File tree

45 files changed

+229
-295
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

45 files changed

+229
-295
lines changed

compiler/rustc_codegen_cranelift/src/constant.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ pub(crate) fn codegen_const_value<'tcx>(
110110
if fx.clif_type(layout.ty).is_some() {
111111
return CValue::const_val(fx, layout, int);
112112
} else {
113-
let raw_val = int.size().truncate(int.assert_bits(int.size()));
113+
let raw_val = int.size().truncate(int.to_bits(int.size()));
114114
let val = match int.size().bytes() {
115115
1 => fx.bcx.ins().iconst(types::I8, raw_val as i64),
116116
2 => fx.bcx.ins().iconst(types::I16, raw_val as i64),
@@ -501,12 +501,12 @@ pub(crate) fn mir_operand_get_const_val<'tcx>(
501501
Ordering::Equal => scalar_int,
502502
Ordering::Less => match ty.kind() {
503503
ty::Uint(_) => ScalarInt::try_from_uint(
504-
scalar_int.assert_uint(scalar_int.size()),
504+
scalar_int.to_uint(scalar_int.size()),
505505
fx.layout_of(*ty).size,
506506
)
507507
.unwrap(),
508508
ty::Int(_) => ScalarInt::try_from_int(
509-
scalar_int.assert_int(scalar_int.size()),
509+
scalar_int.to_int(scalar_int.size()),
510510
fx.layout_of(*ty).size,
511511
)
512512
.unwrap(),

compiler/rustc_codegen_cranelift/src/intrinsics/llvm_x86.rs

+5-5
Original file line numberDiff line numberDiff line change
@@ -902,7 +902,7 @@ pub(crate) fn codegen_x86_llvm_intrinsic_call<'tcx>(
902902
.span_fatal(span, "Index argument for `_mm_cmpestri` is not a constant");
903903
};
904904

905-
let imm8 = imm8.try_to_u8().unwrap_or_else(|_| panic!("kind not scalar: {:?}", imm8));
905+
let imm8 = imm8.to_u8();
906906

907907
codegen_inline_asm_inner(
908908
fx,
@@ -955,7 +955,7 @@ pub(crate) fn codegen_x86_llvm_intrinsic_call<'tcx>(
955955
.span_fatal(span, "Index argument for `_mm_cmpestrm` is not a constant");
956956
};
957957

958-
let imm8 = imm8.try_to_u8().unwrap_or_else(|_| panic!("kind not scalar: {:?}", imm8));
958+
let imm8 = imm8.to_u8();
959959

960960
codegen_inline_asm_inner(
961961
fx,
@@ -1003,7 +1003,7 @@ pub(crate) fn codegen_x86_llvm_intrinsic_call<'tcx>(
10031003
);
10041004
};
10051005

1006-
let imm8 = imm8.try_to_u8().unwrap_or_else(|_| panic!("kind not scalar: {:?}", imm8));
1006+
let imm8 = imm8.to_u8();
10071007

10081008
codegen_inline_asm_inner(
10091009
fx,
@@ -1040,7 +1040,7 @@ pub(crate) fn codegen_x86_llvm_intrinsic_call<'tcx>(
10401040
);
10411041
};
10421042

1043-
let imm8 = imm8.try_to_u8().unwrap_or_else(|_| panic!("kind not scalar: {:?}", imm8));
1043+
let imm8 = imm8.to_u8();
10441044

10451045
codegen_inline_asm_inner(
10461046
fx,
@@ -1195,7 +1195,7 @@ pub(crate) fn codegen_x86_llvm_intrinsic_call<'tcx>(
11951195
.span_fatal(span, "Func argument for `_mm_sha1rnds4_epu32` is not a constant");
11961196
};
11971197

1198-
let func = func.try_to_u8().unwrap_or_else(|_| panic!("kind not scalar: {:?}", func));
1198+
let func = func.to_u8();
11991199

12001200
codegen_inline_asm_inner(
12011201
fx,

compiler/rustc_codegen_cranelift/src/intrinsics/simd.rs

+3-8
Original file line numberDiff line numberDiff line change
@@ -147,8 +147,7 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>(
147147

148148
let total_len = lane_count * 2;
149149

150-
let indexes =
151-
idx.iter().map(|idx| idx.unwrap_leaf().try_to_u32().unwrap()).collect::<Vec<u32>>();
150+
let indexes = idx.iter().map(|idx| idx.unwrap_leaf().to_u32()).collect::<Vec<u32>>();
152151

153152
for &idx in &indexes {
154153
assert!(u64::from(idx) < total_len, "idx {} out of range 0..{}", idx, total_len);
@@ -282,9 +281,7 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>(
282281
fx.tcx.dcx().span_fatal(span, "Index argument for `simd_insert` is not a constant");
283282
};
284283

285-
let idx: u32 = idx_const
286-
.try_to_u32()
287-
.unwrap_or_else(|_| panic!("kind not scalar: {:?}", idx_const));
284+
let idx: u32 = idx_const.to_u32();
288285
let (lane_count, _lane_ty) = base.layout().ty.simd_size_and_type(fx.tcx);
289286
if u64::from(idx) >= lane_count {
290287
fx.tcx.dcx().span_fatal(
@@ -330,9 +327,7 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>(
330327
return;
331328
};
332329

333-
let idx = idx_const
334-
.try_to_u32()
335-
.unwrap_or_else(|_| panic!("kind not scalar: {:?}", idx_const));
330+
let idx = idx_const.to_u32();
336331
let (lane_count, _lane_ty) = v.layout().ty.simd_size_and_type(fx.tcx);
337332
if u64::from(idx) >= lane_count {
338333
fx.tcx.dcx().span_fatal(

compiler/rustc_codegen_cranelift/src/value_and_place.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -327,7 +327,7 @@ impl<'tcx> CValue<'tcx> {
327327

328328
let val = match layout.ty.kind() {
329329
ty::Uint(UintTy::U128) | ty::Int(IntTy::I128) => {
330-
let const_val = const_val.assert_bits(layout.size);
330+
let const_val = const_val.to_bits(layout.size);
331331
let lsb = fx.bcx.ins().iconst(types::I64, const_val as u64 as i64);
332332
let msb = fx.bcx.ins().iconst(types::I64, (const_val >> 64) as u64 as i64);
333333
fx.bcx.ins().iconcat(lsb, msb)
@@ -339,7 +339,7 @@ impl<'tcx> CValue<'tcx> {
339339
| ty::Ref(..)
340340
| ty::RawPtr(..)
341341
| ty::FnPtr(..) => {
342-
let raw_val = const_val.size().truncate(const_val.assert_bits(layout.size));
342+
let raw_val = const_val.size().truncate(const_val.to_bits(layout.size));
343343
fx.bcx.ins().iconst(clif_ty, raw_val as i64)
344344
}
345345
ty::Float(FloatTy::F32) => {

compiler/rustc_codegen_gcc/src/common.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,7 @@ impl<'gcc, 'tcx> ConstMethods<'tcx> for CodegenCx<'gcc, 'tcx> {
166166
let bitsize = if layout.is_bool() { 1 } else { layout.size(self).bits() };
167167
match cv {
168168
Scalar::Int(int) => {
169-
let data = int.assert_bits(layout.size(self));
169+
let data = int.to_bits(layout.size(self));
170170

171171
// FIXME(antoyo): there's some issues with using the u128 code that follows, so hard-code
172172
// the paths for floating-point values.

compiler/rustc_codegen_llvm/src/common.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -244,7 +244,7 @@ impl<'ll, 'tcx> ConstMethods<'tcx> for CodegenCx<'ll, 'tcx> {
244244
let bitsize = if layout.is_bool() { 1 } else { layout.size(self).bits() };
245245
match cv {
246246
Scalar::Int(int) => {
247-
let data = int.assert_bits(layout.size(self));
247+
let data = int.to_bits(layout.size(self));
248248
let llval = self.const_uint_big(self.type_ix(bitsize), data);
249249
if matches!(layout.primitive(), Pointer(_)) {
250250
unsafe { llvm::LLVMConstIntToPtr(llval, llty) }

compiler/rustc_codegen_llvm/src/intrinsic.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1223,7 +1223,7 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
12231223
.iter()
12241224
.enumerate()
12251225
.map(|(arg_idx, val)| {
1226-
let idx = val.unwrap_leaf().try_to_i32().unwrap();
1226+
let idx = val.unwrap_leaf().to_i32();
12271227
if idx >= i32::try_from(total_len).unwrap() {
12281228
bx.sess().dcx().emit_err(InvalidMonomorphization::SimdIndexOutOfBounds {
12291229
span,

compiler/rustc_codegen_ssa/src/common.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,7 @@ pub fn asm_const_to_str<'tcx>(
163163
let mir::ConstValue::Scalar(scalar) = const_value else {
164164
span_bug!(sp, "expected Scalar for promoted asm const, but got {:#?}", const_value)
165165
};
166-
let value = scalar.assert_bits(ty_and_layout.size);
166+
let value = scalar.assert_scalar_int().to_bits(ty_and_layout.size);
167167
match ty_and_layout.ty.kind() {
168168
ty::Uint(_) => value.to_string(),
169169
ty::Int(int_ty) => match int_ty.normalize(tcx.sess.target.pointer_width) {

compiler/rustc_const_eval/src/const_eval/valtrees.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -95,10 +95,10 @@ fn const_to_valtree_inner<'tcx>(
9595
}
9696
ty::Bool | ty::Int(_) | ty::Uint(_) | ty::Float(_) | ty::Char => {
9797
let val = ecx.read_immediate(place)?;
98-
let val = val.to_scalar();
98+
let val = val.to_scalar_int().unwrap();
9999
*num_nodes += 1;
100100

101-
Ok(ty::ValTree::Leaf(val.assert_int()))
101+
Ok(ty::ValTree::Leaf(val))
102102
}
103103

104104
ty::Pat(base, ..) => {
@@ -125,7 +125,7 @@ fn const_to_valtree_inner<'tcx>(
125125
let val = val.to_scalar();
126126
// We are in the CTFE machine, so ptr-to-int casts will fail.
127127
// This can only be `Ok` if `val` already is an integer.
128-
let Ok(val) = val.try_to_int() else {
128+
let Ok(val) = val.try_to_scalar_int() else {
129129
return Err(ValTreeCreationError::NonSupportedType);
130130
};
131131
// It's just a ScalarInt!
@@ -411,7 +411,7 @@ fn valtree_into_mplace<'tcx>(
411411
ty::Adt(def, _) if def.is_enum() => {
412412
// First element of valtree corresponds to variant
413413
let scalar_int = branches[0].unwrap_leaf();
414-
let variant_idx = VariantIdx::from_u32(scalar_int.try_to_u32().unwrap());
414+
let variant_idx = VariantIdx::from_u32(scalar_int.to_u32());
415415
let variant = def.variant(variant_idx);
416416
debug!(?variant);
417417

compiler/rustc_const_eval/src/interpret/discriminant.rs

+7-8
Original file line numberDiff line numberDiff line change
@@ -123,14 +123,14 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
123123
// (`tag_bits` itself is only used for error messages below.)
124124
let tag_bits = tag_val
125125
.to_scalar()
126-
.try_to_int()
126+
.try_to_scalar_int()
127127
.map_err(|dbg_val| err_ub!(InvalidTag(dbg_val)))?
128-
.assert_bits(tag_layout.size);
128+
.to_bits(tag_layout.size);
129129
// Cast bits from tag layout to discriminant layout.
130130
// After the checks we did above, this cannot fail, as
131131
// discriminants are int-like.
132132
let discr_val = self.int_to_int_or_float(&tag_val, discr_layout).unwrap();
133-
let discr_bits = discr_val.to_scalar().assert_bits(discr_layout.size);
133+
let discr_bits = discr_val.to_scalar().to_bits(discr_layout.size)?;
134134
// Convert discriminant to variant index, and catch invalid discriminants.
135135
let index = match *ty.kind() {
136136
ty::Adt(adt, _) => {
@@ -152,7 +152,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
152152
// discriminant (encoded in niche/tag) and variant index are the same.
153153
let variants_start = niche_variants.start().as_u32();
154154
let variants_end = niche_variants.end().as_u32();
155-
let variant = match tag_val.try_to_int() {
155+
let variant = match tag_val.try_to_scalar_int() {
156156
Err(dbg_val) => {
157157
// So this is a pointer then, and casting to an int failed.
158158
// Can only happen during CTFE.
@@ -167,15 +167,15 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
167167
untagged_variant
168168
}
169169
Ok(tag_bits) => {
170-
let tag_bits = tag_bits.assert_bits(tag_layout.size);
170+
let tag_bits = tag_bits.to_bits(tag_layout.size);
171171
// We need to use machine arithmetic to get the relative variant idx:
172172
// variant_index_relative = tag_val - niche_start_val
173173
let tag_val = ImmTy::from_uint(tag_bits, tag_layout);
174174
let niche_start_val = ImmTy::from_uint(niche_start, tag_layout);
175175
let variant_index_relative_val =
176176
self.binary_op(mir::BinOp::Sub, &tag_val, &niche_start_val)?;
177177
let variant_index_relative =
178-
variant_index_relative_val.to_scalar().assert_bits(tag_val.layout.size);
178+
variant_index_relative_val.to_scalar().to_bits(tag_val.layout.size)?;
179179
// Check if this is in the range that indicates an actual discriminant.
180180
if variant_index_relative <= u128::from(variants_end - variants_start) {
181181
let variant_index_relative = u32::try_from(variant_index_relative)
@@ -294,8 +294,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
294294
ImmTy::from_uint(variant_index_relative, tag_layout);
295295
let tag = self
296296
.binary_op(mir::BinOp::Add, &variant_index_relative_val, &niche_start_val)?
297-
.to_scalar()
298-
.assert_int();
297+
.to_scalar_int()?;
299298
Ok(Some((tag, tag_field)))
300299
}
301300
}

compiler/rustc_const_eval/src/interpret/intrinsics.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -519,7 +519,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
519519
// `x % y != 0` or `y == 0` or `x == T::MIN && y == -1`.
520520
// First, check x % y != 0 (or if that computation overflows).
521521
let rem = self.binary_op(BinOp::Rem, a, b)?;
522-
if rem.to_scalar().assert_bits(a.layout.size) != 0 {
522+
if rem.to_scalar().to_bits(a.layout.size)? != 0 {
523523
throw_ub_custom!(
524524
fluent::const_eval_exact_div_has_remainder,
525525
a = format!("{a}"),

compiler/rustc_const_eval/src/interpret/memory.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1344,7 +1344,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
13441344
/// Test if this value might be null.
13451345
/// If the machine does not support ptr-to-int casts, this is conservative.
13461346
pub fn scalar_may_be_null(&self, scalar: Scalar<M::Provenance>) -> InterpResult<'tcx, bool> {
1347-
Ok(match scalar.try_to_int() {
1347+
Ok(match scalar.try_to_scalar_int() {
13481348
Ok(int) => int.is_null(),
13491349
Err(_) => {
13501350
// Can only happen during CTFE.

compiler/rustc_const_eval/src/interpret/operand.rs

+8-9
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,12 @@ impl<Prov: Provenance> Immediate<Prov> {
8787
}
8888
}
8989

90+
#[inline]
91+
#[cfg_attr(debug_assertions, track_caller)] // only in debug builds due to perf (see #98980)
92+
pub fn to_scalar_int(self) -> ScalarInt {
93+
self.to_scalar().try_to_scalar_int().unwrap()
94+
}
95+
9096
#[inline]
9197
#[cfg_attr(debug_assertions, track_caller)] // only in debug builds due to perf (see #98980)
9298
pub fn to_scalar_pair(self) -> (Scalar<Prov>, Scalar<Prov>) {
@@ -219,19 +225,11 @@ impl<'tcx, Prov: Provenance> ImmTy<'tcx, Prov> {
219225
Self::from_scalar(Scalar::from(s), layout)
220226
}
221227

222-
#[inline]
223-
pub fn try_from_uint(i: impl Into<u128>, layout: TyAndLayout<'tcx>) -> Option<Self> {
224-
Some(Self::from_scalar(Scalar::try_from_uint(i, layout.size)?, layout))
225-
}
226228
#[inline]
227229
pub fn from_uint(i: impl Into<u128>, layout: TyAndLayout<'tcx>) -> Self {
228230
Self::from_scalar(Scalar::from_uint(i, layout.size), layout)
229231
}
230232

231-
#[inline]
232-
pub fn try_from_int(i: impl Into<i128>, layout: TyAndLayout<'tcx>) -> Option<Self> {
233-
Some(Self::from_scalar(Scalar::try_from_int(i, layout.size)?, layout))
234-
}
235233
#[inline]
236234
pub fn from_int(i: impl Into<i128>, layout: TyAndLayout<'tcx>) -> Self {
237235
Self::from_scalar(Scalar::from_int(i, layout.size), layout)
@@ -276,7 +274,8 @@ impl<'tcx, Prov: Provenance> ImmTy<'tcx, Prov> {
276274
#[inline]
277275
pub fn to_const_int(self) -> ConstInt {
278276
assert!(self.layout.ty.is_integral());
279-
let int = self.to_scalar().assert_int();
277+
let int = self.imm.to_scalar_int();
278+
assert_eq!(int.size(), self.layout.size);
280279
ConstInt::new(int, self.layout.ty.is_signed(), self.layout.ty.is_ptr_sized_integral())
281280
}
282281

compiler/rustc_const_eval/src/interpret/operator.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -95,10 +95,10 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
9595
let l = left.to_scalar_int()?;
9696
let r = right.to_scalar_int()?;
9797
// Prepare to convert the values to signed or unsigned form.
98-
let l_signed = || l.assert_int(left.layout.size);
99-
let l_unsigned = || l.assert_uint(left.layout.size);
100-
let r_signed = || r.assert_int(right.layout.size);
101-
let r_unsigned = || r.assert_uint(right.layout.size);
98+
let l_signed = || l.to_int(left.layout.size);
99+
let l_unsigned = || l.to_uint(left.layout.size);
100+
let r_signed = || r.to_int(right.layout.size);
101+
let r_unsigned = || r.to_uint(right.layout.size);
102102

103103
let throw_ub_on_overflow = match bin_op {
104104
AddUnchecked => Some(sym::unchecked_add),

compiler/rustc_const_eval/src/interpret/validity.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -653,8 +653,8 @@ impl<'rt, 'tcx, M: Machine<'tcx>> ValidityVisitor<'rt, 'tcx, M> {
653653
let WrappingRange { start, end } = valid_range;
654654
let max_value = size.unsigned_int_max();
655655
assert!(end <= max_value);
656-
let bits = match scalar.try_to_int() {
657-
Ok(int) => int.assert_bits(size),
656+
let bits = match scalar.try_to_scalar_int() {
657+
Ok(int) => int.to_bits(size),
658658
Err(_) => {
659659
// So this is a pointer then, and casting to an int failed.
660660
// Can only happen during CTFE.

compiler/rustc_hir_typeck/src/pat.rs

+2-3
Original file line numberDiff line numberDiff line change
@@ -2385,11 +2385,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
23852385
min_len: u64,
23862386
) -> (Option<Ty<'tcx>>, Ty<'tcx>) {
23872387
let len = match len.eval(self.tcx, self.param_env, span) {
2388-
// FIXME(BoxyUwU): Assert the `Ty` is a `usize`?
23892388
Ok((_, val)) => val
23902389
.try_to_scalar()
2391-
.and_then(|scalar| scalar.try_to_int().ok())
2392-
.and_then(|int| int.try_to_target_usize(self.tcx).ok()),
2390+
.and_then(|scalar| scalar.try_to_scalar_int().ok())
2391+
.map(|int| int.to_target_usize(self.tcx)),
23932392
Err(ErrorHandled::Reported(..)) => {
23942393
let guar = self.error_scrutinee_unfixed_length(span);
23952394
return (Some(Ty::new_error(self.tcx, guar)), arr_ty);

0 commit comments

Comments
 (0)