From 0bce91ff0b3252b736040087f9b768027422f3f0 Mon Sep 17 00:00:00 2001 From: Christian Poveda Date: Sat, 14 Dec 2019 12:13:10 -0500 Subject: [PATCH 1/4] add Scalar::try_from_(u)int methods --- src/librustc/mir/interpret/value.rs | 34 +++++++++++++++++++---------- 1 file changed, 22 insertions(+), 12 deletions(-) diff --git a/src/librustc/mir/interpret/value.rs b/src/librustc/mir/interpret/value.rs index a038ca23ae92d..4f196cda5ae2a 100644 --- a/src/librustc/mir/interpret/value.rs +++ b/src/librustc/mir/interpret/value.rs @@ -237,13 +237,18 @@ impl<'tcx, Tag> Scalar { } #[inline] - pub fn from_uint(i: impl Into, size: Size) -> Self { + pub fn try_from_uint(i: impl Into, size: Size) -> InterpResult<'tcx, 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 } + if truncate(i, size) == i { + Ok(Scalar::Raw { data: i, size: size.bytes() as u8 }) + } else { + throw_unsup_format!("Unsigned value {:#x} does not fit in {} bits", i, size.bits()) + } + } + + #[inline] + pub fn from_uint(i: impl Into, size: Size) -> Self { + Self::try_from_uint(i, size).unwrap() } #[inline] @@ -267,15 +272,20 @@ impl<'tcx, Tag> Scalar { } #[inline] - pub fn from_int(i: impl Into, size: Size) -> Self { + pub fn try_from_int(i: impl Into, size: Size) -> InterpResult<'tcx, 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 { + Ok(Scalar::Raw { data: truncated, size: size.bytes() as u8 }) + } else { + throw_unsup_format!("Signed value {:#x} does not fit in {} bits", i, size.bits()) + } + } + + #[inline] + pub fn from_int(i: impl Into, size: Size) -> Self { + Self::try_from_int(i, size).unwrap() } #[inline] From 90686ded25ee4f7f6676141a0413c066a2a4d393 Mon Sep 17 00:00:00 2001 From: Christian Poveda Date: Sat, 14 Dec 2019 12:13:26 -0500 Subject: [PATCH 2/4] add ImmTy::try_from_(u)int methods --- src/librustc_mir/interpret/operand.rs | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/librustc_mir/interpret/operand.rs b/src/librustc_mir/interpret/operand.rs index 48e7193ec39d4..072152a388775 100644 --- a/src/librustc_mir/interpret/operand.rs +++ b/src/librustc_mir/interpret/operand.rs @@ -218,14 +218,23 @@ impl<'tcx, Tag: Copy> ImmTy<'tcx, Tag> { ImmTy { imm: val.into(), layout } } + #[inline] + pub fn try_from_uint(i: impl Into, layout: TyLayout<'tcx>) -> InterpResult<'tcx, Self> { + Ok(Self::from_scalar(Scalar::try_from_uint(i, layout.size)?, layout)) + } #[inline] pub fn from_uint(i: impl Into, layout: TyLayout<'tcx>) -> Self { - Self::from_scalar(Scalar::from_uint(i, layout.size), layout) + Self::try_from_uint(i, layout).unwrap() + } + + #[inline] + pub fn try_from_int(i: impl Into, layout: TyLayout<'tcx>) -> InterpResult<'tcx, Self> { + Ok(Self::from_scalar(Scalar::try_from_int(i, layout.size)?, layout)) } #[inline] pub fn from_int(i: impl Into, layout: TyLayout<'tcx>) -> Self { - Self::from_scalar(Scalar::from_int(i, layout.size), layout) + Self::try_from_int(i, layout).unwrap() } #[inline] From 309f437e1d20ce93597eec0514a9cb80150d8861 Mon Sep 17 00:00:00 2001 From: Christian Poveda Date: Sat, 21 Dec 2019 10:27:58 -0500 Subject: [PATCH 3/4] Change results to options --- src/librustc/mir/interpret/value.rs | 12 ++++++------ src/librustc_mir/interpret/operand.rs | 8 ++++---- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/librustc/mir/interpret/value.rs b/src/librustc/mir/interpret/value.rs index 4f196cda5ae2a..8f5fab4b00291 100644 --- a/src/librustc/mir/interpret/value.rs +++ b/src/librustc/mir/interpret/value.rs @@ -237,12 +237,12 @@ impl<'tcx, Tag> Scalar { } #[inline] - pub fn try_from_uint(i: impl Into, size: Size) -> InterpResult<'tcx, Self> { + pub fn try_from_uint(i: impl Into, size: Size) -> Option { let i = i.into(); if truncate(i, size) == i { - Ok(Scalar::Raw { data: i, size: size.bytes() as u8 }) + Some(Scalar::Raw { data: i, size: size.bytes() as u8 }) } else { - throw_unsup_format!("Unsigned value {:#x} does not fit in {} bits", i, size.bits()) + None } } @@ -272,14 +272,14 @@ impl<'tcx, Tag> Scalar { } #[inline] - pub fn try_from_int(i: impl Into, size: Size) -> InterpResult<'tcx, Self> { + pub fn try_from_int(i: impl Into, size: Size) -> Option { let i = i.into(); // `into` performed sign extension, we have to truncate let truncated = truncate(i as u128, size); if sign_extend(truncated, size) as i128 == i { - Ok(Scalar::Raw { data: truncated, size: size.bytes() as u8 }) + Some(Scalar::Raw { data: truncated, size: size.bytes() as u8 }) } else { - throw_unsup_format!("Signed value {:#x} does not fit in {} bits", i, size.bits()) + None } } diff --git a/src/librustc_mir/interpret/operand.rs b/src/librustc_mir/interpret/operand.rs index 072152a388775..8dd50958350bb 100644 --- a/src/librustc_mir/interpret/operand.rs +++ b/src/librustc_mir/interpret/operand.rs @@ -219,8 +219,8 @@ impl<'tcx, Tag: Copy> ImmTy<'tcx, Tag> { } #[inline] - pub fn try_from_uint(i: impl Into, layout: TyLayout<'tcx>) -> InterpResult<'tcx, Self> { - Ok(Self::from_scalar(Scalar::try_from_uint(i, layout.size)?, layout)) + pub fn try_from_uint(i: impl Into, layout: TyLayout<'tcx>) -> Option { + Some(Self::from_scalar(Scalar::try_from_uint(i, layout.size)?, layout)) } #[inline] pub fn from_uint(i: impl Into, layout: TyLayout<'tcx>) -> Self { @@ -228,8 +228,8 @@ impl<'tcx, Tag: Copy> ImmTy<'tcx, Tag> { } #[inline] - pub fn try_from_int(i: impl Into, layout: TyLayout<'tcx>) -> InterpResult<'tcx, Self> { - Ok(Self::from_scalar(Scalar::try_from_int(i, layout.size)?, layout)) + pub fn try_from_int(i: impl Into, layout: TyLayout<'tcx>) -> Option { + Some(Self::from_scalar(Scalar::try_from_int(i, layout.size)?, layout)) } #[inline] From 683c4c788f36d67fbc873629b431105c7758dd68 Mon Sep 17 00:00:00 2001 From: Christian Poveda Date: Sun, 22 Dec 2019 08:22:14 -0500 Subject: [PATCH 4/4] Add error message if `Scalar::from_(u)int` fails --- src/librustc/mir/interpret/value.rs | 10 ++++++++-- src/librustc_mir/interpret/operand.rs | 4 ++-- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/src/librustc/mir/interpret/value.rs b/src/librustc/mir/interpret/value.rs index 8f5fab4b00291..f48d22291c6a4 100644 --- a/src/librustc/mir/interpret/value.rs +++ b/src/librustc/mir/interpret/value.rs @@ -248,7 +248,10 @@ impl<'tcx, Tag> Scalar { #[inline] pub fn from_uint(i: impl Into, size: Size) -> Self { - Self::try_from_uint(i, size).unwrap() + let i = i.into(); + Self::try_from_uint(i, size).unwrap_or_else(|| { + bug!("Unsigned value {:#x} does not fit in {} bits", i, size.bits()) + }) } #[inline] @@ -285,7 +288,10 @@ impl<'tcx, Tag> Scalar { #[inline] pub fn from_int(i: impl Into, size: Size) -> Self { - Self::try_from_int(i, size).unwrap() + 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 8dd50958350bb..294b361ee2721 100644 --- a/src/librustc_mir/interpret/operand.rs +++ b/src/librustc_mir/interpret/operand.rs @@ -224,7 +224,7 @@ impl<'tcx, Tag: Copy> ImmTy<'tcx, Tag> { } #[inline] pub fn from_uint(i: impl Into, layout: TyLayout<'tcx>) -> Self { - Self::try_from_uint(i, layout).unwrap() + Self::from_scalar(Scalar::from_uint(i, layout.size), layout) } #[inline] @@ -234,7 +234,7 @@ impl<'tcx, Tag: Copy> ImmTy<'tcx, Tag> { #[inline] pub fn from_int(i: impl Into, layout: TyLayout<'tcx>) -> Self { - Self::try_from_int(i, layout).unwrap() + Self::from_scalar(Scalar::from_int(i, layout.size), layout) } #[inline]