about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/librustc/mir/interpret/value.rs38
-rw-r--r--src/librustc_mir/interpret/operand.rs9
2 files changed, 36 insertions, 11 deletions
diff --git a/src/librustc/mir/interpret/value.rs b/src/librustc/mir/interpret/value.rs
index a038ca23ae9..f48d22291c6 100644
--- a/src/librustc/mir/interpret/value.rs
+++ b/src/librustc/mir/interpret/value.rs
@@ -237,13 +237,21 @@ impl<'tcx, Tag> Scalar<Tag> {
     }
 
     #[inline]
+    pub fn try_from_uint(i: impl Into<u128>, size: Size) -> Option<Self> {
+        let i = i.into();
+        if truncate(i, size) == i {
+            Some(Scalar::Raw { data: i, size: size.bytes() as u8 })
+        } else {
+            None
+        }
+    }
+
+    #[inline]
     pub fn from_uint(i: impl Into<u128>, size: Size) -> Self {
         let i = i.into();
-        assert_eq!(
-            truncate(i, size), i,
-            "Unsigned value {:#x} does not fit in {} bits", i, size.bits()
-        );
-        Scalar::Raw { data: i, size: size.bytes() as u8 }
+        Self::try_from_uint(i, size).unwrap_or_else(|| {
+            bug!("Unsigned value {:#x} does not fit in {} bits", i, size.bits())
+        })
     }
 
     #[inline]
@@ -267,15 +275,23 @@ impl<'tcx, Tag> Scalar<Tag> {
     }
 
     #[inline]
-    pub fn from_int(i: impl Into<i128>, size: Size) -> Self {
+    pub fn try_from_int(i: impl Into<i128>, size: Size) -> Option<Self> {
         let i = i.into();
         // `into` performed sign extension, we have to truncate
         let truncated = truncate(i as u128, size);
-        assert_eq!(
-            sign_extend(truncated, size) as i128, i,
-            "Signed value {:#x} does not fit in {} bits", i, size.bits()
-        );
-        Scalar::Raw { data: truncated, size: size.bytes() as u8 }
+        if sign_extend(truncated, size) as i128 == i {
+            Some(Scalar::Raw { data: truncated, size: size.bytes() as u8 })
+        } else {
+            None
+        }
+    }
+
+    #[inline]
+    pub fn from_int(i: impl Into<i128>, size: Size) -> Self {
+        let i = i.into();
+        Self::try_from_int(i, size).unwrap_or_else(|| {
+            bug!("Signed value {:#x} does not fit in {} bits", i, size.bits())
+        })
     }
 
     #[inline]
diff --git a/src/librustc_mir/interpret/operand.rs b/src/librustc_mir/interpret/operand.rs
index 93ab7b9aab7..0af203079b1 100644
--- a/src/librustc_mir/interpret/operand.rs
+++ b/src/librustc_mir/interpret/operand.rs
@@ -219,11 +219,20 @@ impl<'tcx, Tag: Copy> ImmTy<'tcx, Tag> {
     }
 
     #[inline]
+    pub fn try_from_uint(i: impl Into<u128>, layout: TyLayout<'tcx>) -> Option<Self> {
+        Some(Self::from_scalar(Scalar::try_from_uint(i, layout.size)?, layout))
+    }
+    #[inline]
     pub fn from_uint(i: impl Into<u128>, layout: TyLayout<'tcx>) -> Self {
         Self::from_scalar(Scalar::from_uint(i, layout.size), layout)
     }
 
     #[inline]
+    pub fn try_from_int(i: impl Into<i128>, layout: TyLayout<'tcx>) -> Option<Self> {
+        Some(Self::from_scalar(Scalar::try_from_int(i, layout.size)?, layout))
+    }
+
+    #[inline]
     pub fn from_int(i: impl Into<i128>, layout: TyLayout<'tcx>) -> Self {
         Self::from_scalar(Scalar::from_int(i, layout.size), layout)
     }