X-Git-Url: https://git.lizzy.rs/?a=blobdiff_plain;f=src%2Flibrustc%2Fmir%2Finterpret%2Fvalue.rs;h=1909f3cb998be90584d99480dd7c2e837ed6fd06;hb=3836573ae4610f75d41d467e35d855efd6b000b5;hp=b8d6c1224463128f861704503c083f0756c4de99;hpb=0f96dd51c584bf7b93155a41ae31dee7777f1508;p=rust.git diff --git a/src/librustc/mir/interpret/value.rs b/src/librustc/mir/interpret/value.rs index b8d6c122446..1909f3cb998 100644 --- a/src/librustc/mir/interpret/value.rs +++ b/src/librustc/mir/interpret/value.rs @@ -1,11 +1,12 @@ use std::fmt; use rustc_macros::HashStable; +use rustc_apfloat::{Float, ieee::{Double, Single}}; use crate::ty::{Ty, InferConst, ParamConst, layout::{HasDataLayout, Size}, subst::SubstsRef}; use crate::ty::PlaceholderConst; use crate::hir::def_id::DefId; -use super::{EvalResult, Pointer, PointerArithmetic, Allocation, AllocId, sign_extend, truncate}; +use super::{InterpResult, Pointer, PointerArithmetic, Allocation, AllocId, sign_extend, truncate}; /// Represents the result of a raw const operation, pre-validation. #[derive(Copy, Clone, Debug, Eq, PartialEq, RustcEncodable, RustcDecodable, Hash, HashStable)] @@ -176,7 +177,7 @@ pub fn zst() -> Self { } #[inline] - pub fn ptr_offset(self, i: Size, cx: &impl HasDataLayout) -> EvalResult<'tcx, Self> { + pub fn ptr_offset(self, i: Size, cx: &impl HasDataLayout) -> InterpResult<'tcx, Self> { let dl = cx.data_layout(); match self { Scalar::Raw { data, size } => { @@ -206,7 +207,7 @@ pub fn ptr_wrapping_offset(self, i: Size, cx: &impl HasDataLayout) -> Self { } #[inline] - pub fn ptr_signed_offset(self, i: i64, cx: &impl HasDataLayout) -> EvalResult<'tcx, Self> { + pub fn ptr_signed_offset(self, i: i64, cx: &impl HasDataLayout) -> InterpResult<'tcx, Self> { let dl = cx.data_layout(); match self { Scalar::Raw { data, size } => { @@ -292,12 +293,12 @@ pub fn from_int(i: impl Into, size: Size) -> Self { } #[inline] - pub fn from_f32(f: f32) -> Self { + pub fn from_f32(f: Single) -> Self { Scalar::Raw { data: f.to_bits() as u128, size: 4 } } #[inline] - pub fn from_f64(f: f64) -> Self { + pub fn from_f64(f: Double) -> Self { Scalar::Raw { data: f.to_bits() as u128, size: 8 } } @@ -322,7 +323,7 @@ pub fn to_bits_or_ptr( } #[inline] - pub fn to_bits(self, target_size: Size) -> EvalResult<'tcx, u128> { + pub fn to_bits(self, target_size: Size) -> InterpResult<'tcx, u128> { match self { Scalar::Raw { data, size } => { assert_eq!(target_size.bytes(), size as u64); @@ -335,7 +336,7 @@ pub fn to_bits(self, target_size: Size) -> EvalResult<'tcx, u128> { } #[inline] - pub fn to_ptr(self) -> EvalResult<'tcx, Pointer> { + pub fn to_ptr(self) -> InterpResult<'tcx, Pointer> { match self { Scalar::Raw { data: 0, .. } => err!(InvalidNullPointerUsage), Scalar::Raw { .. } => err!(ReadBytesAsPointer), @@ -359,7 +360,7 @@ pub fn is_ptr(self) -> bool { } } - pub fn to_bool(self) -> EvalResult<'tcx, bool> { + pub fn to_bool(self) -> InterpResult<'tcx, bool> { match self { Scalar::Raw { data: 0, size: 1 } => Ok(false), Scalar::Raw { data: 1, size: 1 } => Ok(true), @@ -367,7 +368,7 @@ pub fn to_bool(self) -> EvalResult<'tcx, bool> { } } - pub fn to_char(self) -> EvalResult<'tcx, char> { + pub fn to_char(self) -> InterpResult<'tcx, char> { let val = self.to_u32()?; match ::std::char::from_u32(val) { Some(c) => Ok(c), @@ -375,51 +376,51 @@ pub fn to_char(self) -> EvalResult<'tcx, char> { } } - pub fn to_u8(self) -> EvalResult<'static, u8> { + pub fn to_u8(self) -> InterpResult<'static, u8> { let sz = Size::from_bits(8); let b = self.to_bits(sz)?; Ok(b as u8) } - pub fn to_u32(self) -> EvalResult<'static, u32> { + pub fn to_u32(self) -> InterpResult<'static, u32> { let sz = Size::from_bits(32); let b = self.to_bits(sz)?; Ok(b as u32) } - pub fn to_u64(self) -> EvalResult<'static, u64> { + pub fn to_u64(self) -> InterpResult<'static, u64> { let sz = Size::from_bits(64); let b = self.to_bits(sz)?; Ok(b as u64) } - pub fn to_usize(self, cx: &impl HasDataLayout) -> EvalResult<'static, u64> { + pub fn to_usize(self, cx: &impl HasDataLayout) -> InterpResult<'static, u64> { let b = self.to_bits(cx.data_layout().pointer_size)?; Ok(b as u64) } - pub fn to_i8(self) -> EvalResult<'static, i8> { + pub fn to_i8(self) -> InterpResult<'static, i8> { let sz = Size::from_bits(8); let b = self.to_bits(sz)?; let b = sign_extend(b, sz) as i128; Ok(b as i8) } - pub fn to_i32(self) -> EvalResult<'static, i32> { + pub fn to_i32(self) -> InterpResult<'static, i32> { let sz = Size::from_bits(32); let b = self.to_bits(sz)?; let b = sign_extend(b, sz) as i128; Ok(b as i32) } - pub fn to_i64(self) -> EvalResult<'static, i64> { + pub fn to_i64(self) -> InterpResult<'static, i64> { let sz = Size::from_bits(64); let b = self.to_bits(sz)?; let b = sign_extend(b, sz) as i128; Ok(b as i64) } - pub fn to_isize(self, cx: &impl HasDataLayout) -> EvalResult<'static, i64> { + pub fn to_isize(self, cx: &impl HasDataLayout) -> InterpResult<'static, i64> { let sz = cx.data_layout().pointer_size; let b = self.to_bits(sz)?; let b = sign_extend(b, sz) as i128; @@ -427,13 +428,15 @@ pub fn to_isize(self, cx: &impl HasDataLayout) -> EvalResult<'static, i64> { } #[inline] - pub fn to_f32(self) -> EvalResult<'static, f32> { - Ok(f32::from_bits(self.to_u32()?)) + pub fn to_f32(self) -> InterpResult<'static, Single> { + // Going through `u32` to check size and truncation. + Ok(Single::from_bits(self.to_u32()? as u128)) } #[inline] - pub fn to_f64(self) -> EvalResult<'static, f64> { - Ok(f64::from_bits(self.to_u64()?)) + pub fn to_f64(self) -> InterpResult<'static, Double> { + // Going through `u64` to check size and truncation. + Ok(Double::from_bits(self.to_u64()? as u128)) } } @@ -489,7 +492,7 @@ pub fn erase_tag(self) -> ScalarMaybeUndef } #[inline] - pub fn not_undef(self) -> EvalResult<'static, Scalar> { + pub fn not_undef(self) -> InterpResult<'static, Scalar> { match self { ScalarMaybeUndef::Scalar(scalar) => Ok(scalar), ScalarMaybeUndef::Undef => err!(ReadUndefBytes(Size::from_bytes(0))), @@ -497,72 +500,72 @@ pub fn not_undef(self) -> EvalResult<'static, Scalar> { } #[inline(always)] - pub fn to_ptr(self) -> EvalResult<'tcx, Pointer> { + pub fn to_ptr(self) -> InterpResult<'tcx, Pointer> { self.not_undef()?.to_ptr() } #[inline(always)] - pub fn to_bits(self, target_size: Size) -> EvalResult<'tcx, u128> { + pub fn to_bits(self, target_size: Size) -> InterpResult<'tcx, u128> { self.not_undef()?.to_bits(target_size) } #[inline(always)] - pub fn to_bool(self) -> EvalResult<'tcx, bool> { + pub fn to_bool(self) -> InterpResult<'tcx, bool> { self.not_undef()?.to_bool() } #[inline(always)] - pub fn to_char(self) -> EvalResult<'tcx, char> { + pub fn to_char(self) -> InterpResult<'tcx, char> { self.not_undef()?.to_char() } #[inline(always)] - pub fn to_f32(self) -> EvalResult<'tcx, f32> { + pub fn to_f32(self) -> InterpResult<'tcx, Single> { self.not_undef()?.to_f32() } #[inline(always)] - pub fn to_f64(self) -> EvalResult<'tcx, f64> { + pub fn to_f64(self) -> InterpResult<'tcx, Double> { self.not_undef()?.to_f64() } #[inline(always)] - pub fn to_u8(self) -> EvalResult<'tcx, u8> { + pub fn to_u8(self) -> InterpResult<'tcx, u8> { self.not_undef()?.to_u8() } #[inline(always)] - pub fn to_u32(self) -> EvalResult<'tcx, u32> { + pub fn to_u32(self) -> InterpResult<'tcx, u32> { self.not_undef()?.to_u32() } #[inline(always)] - pub fn to_u64(self) -> EvalResult<'tcx, u64> { + pub fn to_u64(self) -> InterpResult<'tcx, u64> { self.not_undef()?.to_u64() } #[inline(always)] - pub fn to_usize(self, cx: &impl HasDataLayout) -> EvalResult<'tcx, u64> { + pub fn to_usize(self, cx: &impl HasDataLayout) -> InterpResult<'tcx, u64> { self.not_undef()?.to_usize(cx) } #[inline(always)] - pub fn to_i8(self) -> EvalResult<'tcx, i8> { + pub fn to_i8(self) -> InterpResult<'tcx, i8> { self.not_undef()?.to_i8() } #[inline(always)] - pub fn to_i32(self) -> EvalResult<'tcx, i32> { + pub fn to_i32(self) -> InterpResult<'tcx, i32> { self.not_undef()?.to_i32() } #[inline(always)] - pub fn to_i64(self) -> EvalResult<'tcx, i64> { + pub fn to_i64(self) -> InterpResult<'tcx, i64> { self.not_undef()?.to_i64() } #[inline(always)] - pub fn to_isize(self, cx: &impl HasDataLayout) -> EvalResult<'tcx, i64> { + pub fn to_isize(self, cx: &impl HasDataLayout) -> InterpResult<'tcx, i64> { self.not_undef()?.to_isize(cx) } }