Skip to content

Commit fbc6f2c

Browse files
committed
make some cast helpers infallible
1 parent 75b0a68 commit fbc6f2c

File tree

1 file changed

+17
-29
lines changed

1 file changed

+17
-29
lines changed

src/librustc_mir/interpret/cast.rs

Lines changed: 17 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -106,14 +106,10 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
106106
match src.layout.ty.kind {
107107
// Floating point
108108
Float(FloatTy::F32) => {
109-
return Ok(self
110-
.cast_from_float(src.to_scalar()?.to_f32()?, dest_layout.ty)?
111-
.into());
109+
return Ok(self.cast_from_float(src.to_scalar()?.to_f32()?, dest_layout.ty).into());
112110
}
113111
Float(FloatTy::F64) => {
114-
return Ok(self
115-
.cast_from_float(src.to_scalar()?.to_f64()?, dest_layout.ty)?
116-
.into());
112+
return Ok(self.cast_from_float(src.to_scalar()?.to_f64()?, dest_layout.ty).into());
117113
}
118114
// The rest is integer/pointer-"like", including fn ptr casts and casts from enums that
119115
// are represented as integers.
@@ -135,7 +131,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
135131
assert!(src.layout.is_zst());
136132
let discr_layout = self.layout_of(discr.ty)?;
137133
return Ok(self
138-
.cast_from_int_like(discr.val, discr_layout, dest_layout)?
134+
.cast_from_int_like(discr.val, discr_layout, dest_layout)
139135
.into());
140136
}
141137
}
@@ -173,15 +169,15 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
173169
// (b) cast from an integer-like (including bool, char, enums).
174170
// In both cases we want the bits.
175171
let bits = self.force_bits(src.to_scalar()?, src.layout.size)?;
176-
Ok(self.cast_from_int_like(bits, src.layout, dest_layout)?.into())
172+
Ok(self.cast_from_int_like(bits, src.layout, dest_layout).into())
177173
}
178174

179-
fn cast_from_int_like(
175+
pub(super) fn cast_from_int_like(
180176
&self,
181177
v: u128, // raw bits
182178
src_layout: TyAndLayout<'tcx>,
183179
dest_layout: TyAndLayout<'tcx>,
184-
) -> InterpResult<'tcx, Scalar<M::PointerTag>> {
180+
) -> Scalar<M::PointerTag> {
185181
// Let's make sure v is sign-extended *if* it has a signed type.
186182
let signed = src_layout.abi.is_signed();
187183
let v = if signed { self.sign_extend(v, src_layout) } else { v };
@@ -190,33 +186,25 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
190186
match dest_layout.ty.kind {
191187
Int(_) | Uint(_) | RawPtr(_) => {
192188
let v = self.truncate(v, dest_layout);
193-
Ok(Scalar::from_uint(v, dest_layout.size))
189+
Scalar::from_uint(v, dest_layout.size)
194190
}
195191

196-
Float(FloatTy::F32) if signed => {
197-
Ok(Scalar::from_f32(Single::from_i128(v as i128).value))
198-
}
199-
Float(FloatTy::F64) if signed => {
200-
Ok(Scalar::from_f64(Double::from_i128(v as i128).value))
201-
}
202-
Float(FloatTy::F32) => Ok(Scalar::from_f32(Single::from_u128(v).value)),
203-
Float(FloatTy::F64) => Ok(Scalar::from_f64(Double::from_u128(v).value)),
192+
Float(FloatTy::F32) if signed => Scalar::from_f32(Single::from_i128(v as i128).value),
193+
Float(FloatTy::F64) if signed => Scalar::from_f64(Double::from_i128(v as i128).value),
194+
Float(FloatTy::F32) => Scalar::from_f32(Single::from_u128(v).value),
195+
Float(FloatTy::F64) => Scalar::from_f64(Double::from_u128(v).value),
204196

205197
Char => {
206198
// `u8` to `char` cast
207-
Ok(Scalar::from_u32(u8::try_from(v).unwrap().into()))
199+
Scalar::from_u32(u8::try_from(v).unwrap().into())
208200
}
209201

210202
// Casts to bool are not permitted by rustc, no need to handle them here.
211203
_ => bug!("invalid int to {:?} cast", dest_layout.ty),
212204
}
213205
}
214206

215-
fn cast_from_float<F>(
216-
&self,
217-
f: F,
218-
dest_ty: Ty<'tcx>,
219-
) -> InterpResult<'tcx, Scalar<M::PointerTag>>
207+
fn cast_from_float<F>(&self, f: F, dest_ty: Ty<'tcx>) -> Scalar<M::PointerTag>
220208
where
221209
F: Float + Into<Scalar<M::PointerTag>> + FloatConvert<Single> + FloatConvert<Double>,
222210
{
@@ -229,20 +217,20 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
229217
// (https://doc.rust-lang.org/nightly/nightly-rustc/rustc_apfloat/trait.Float.html#method.to_i128_r).
230218
let v = f.to_u128(usize::try_from(width).unwrap()).value;
231219
// This should already fit the bit width
232-
Ok(Scalar::from_uint(v, Size::from_bits(width)))
220+
Scalar::from_uint(v, Size::from_bits(width))
233221
}
234222
// float -> int
235223
Int(t) => {
236224
let width = t.bit_width().unwrap_or_else(|| self.pointer_size().bits());
237225
// `to_i128` is a saturating cast, which is what we need
238226
// (https://doc.rust-lang.org/nightly/nightly-rustc/rustc_apfloat/trait.Float.html#method.to_i128_r).
239227
let v = f.to_i128(usize::try_from(width).unwrap()).value;
240-
Ok(Scalar::from_int(v, Size::from_bits(width)))
228+
Scalar::from_int(v, Size::from_bits(width))
241229
}
242230
// float -> f32
243-
Float(FloatTy::F32) => Ok(Scalar::from_f32(f.convert(&mut false).value)),
231+
Float(FloatTy::F32) => Scalar::from_f32(f.convert(&mut false).value),
244232
// float -> f64
245-
Float(FloatTy::F64) => Ok(Scalar::from_f64(f.convert(&mut false).value)),
233+
Float(FloatTy::F64) => Scalar::from_f64(f.convert(&mut false).value),
246234
// That's it.
247235
_ => bug!("invalid float to {:?} cast", dest_ty),
248236
}

0 commit comments

Comments
 (0)