Skip to content

Commit f7eb383

Browse files
authored
Rollup merge of #94681 - RalfJung:miri-cast, r=oli-obk
CTFE engine: expose misc_cast to Miri We need that to implement `simd_cast`/`simd_as` in Miri. While at it, also change other code outside `cast.rs` to use `misc_cast` instead of lower-level methods. r? `@oli-obk`
2 parents 02539e1 + d29d230 commit f7eb383

File tree

2 files changed

+13
-8
lines changed

2 files changed

+13
-8
lines changed

compiler/rustc_const_eval/src/interpret/cast.rs

+5-5
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
9797
Ok(())
9898
}
9999

100-
fn misc_cast(
100+
pub fn misc_cast(
101101
&self,
102102
src: &ImmTy<'tcx, M::PointerTag>,
103103
cast_ty: Ty<'tcx>,
@@ -139,7 +139,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
139139
if let Some(discr) = src.layout.ty.discriminant_for_variant(*self.tcx, index) {
140140
assert!(src.layout.is_zst());
141141
let discr_layout = self.layout_of(discr.ty)?;
142-
return Ok(self.cast_from_scalar(discr.val, discr_layout, cast_ty).into());
142+
return Ok(self.cast_from_int_like(discr.val, discr_layout, cast_ty).into());
143143
}
144144
}
145145
Variants::Multiple { .. } => {}
@@ -169,17 +169,17 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
169169
}
170170
}
171171

172-
// # The remaining source values are scalar.
172+
// # The remaining source values are scalar and "int-like".
173173

174174
// For all remaining casts, we either
175175
// (a) cast a raw ptr to usize, or
176176
// (b) cast from an integer-like (including bool, char, enums).
177177
// In both cases we want the bits.
178178
let bits = src.to_scalar()?.to_bits(src.layout.size)?;
179-
Ok(self.cast_from_scalar(bits, src.layout, cast_ty).into())
179+
Ok(self.cast_from_int_like(bits, src.layout, cast_ty).into())
180180
}
181181

182-
pub(super) fn cast_from_scalar(
182+
fn cast_from_int_like(
183183
&self,
184184
v: u128, // raw bits (there is no ScalarTy so we separate data+layout)
185185
src_layout: TyAndLayout<'tcx>,

compiler/rustc_const_eval/src/interpret/operand.rs

+8-3
Original file line numberDiff line numberDiff line change
@@ -681,18 +681,22 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
681681
let tag_val = self.read_immediate(&self.operand_field(op, tag_field)?)?;
682682
assert_eq!(tag_layout.size, tag_val.layout.size);
683683
assert_eq!(tag_layout.abi.is_signed(), tag_val.layout.abi.is_signed());
684-
let tag_val = tag_val.to_scalar()?;
685-
trace!("tag value: {:?}", tag_val);
684+
trace!("tag value: {}", tag_val);
686685

687686
// Figure out which discriminant and variant this corresponds to.
688687
Ok(match *tag_encoding {
689688
TagEncoding::Direct => {
689+
// Generate a specific error if `tag_val` is not an integer.
690+
// (`tag_bits` itself is only used for error messages below.)
690691
let tag_bits = tag_val
692+
.to_scalar()?
691693
.try_to_int()
692694
.map_err(|dbg_val| err_ub!(InvalidTag(dbg_val)))?
693695
.assert_bits(tag_layout.size);
694696
// Cast bits from tag layout to discriminant layout.
695-
let discr_val = self.cast_from_scalar(tag_bits, tag_layout, discr_layout.ty);
697+
// After the checks we did above, this cannot fail.
698+
let discr_val =
699+
self.misc_cast(&tag_val, discr_layout.ty).unwrap().to_scalar().unwrap();
696700
let discr_bits = discr_val.assert_bits(discr_layout.size);
697701
// Convert discriminant to variant index, and catch invalid discriminants.
698702
let index = match *op.layout.ty.kind() {
@@ -712,6 +716,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
712716
(discr_val, index.0)
713717
}
714718
TagEncoding::Niche { dataful_variant, ref niche_variants, niche_start } => {
719+
let tag_val = tag_val.to_scalar()?;
715720
// Compute the variant this niche value/"tag" corresponds to. With niche layout,
716721
// discriminant (encoded in niche/tag) and variant index are the same.
717722
let variants_start = niche_variants.start().as_u32();

0 commit comments

Comments
 (0)