Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 27 additions & 11 deletions src/librustc/mir/interpret/value.rs
Original file line number Diff line number Diff line change
Expand Up @@ -236,14 +236,22 @@ impl<'tcx, Tag> Scalar<Tag> {
Scalar::Raw { data: c as u128, size: 4 }
}

#[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]
Expand All @@ -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]
Expand Down
9 changes: 9 additions & 0 deletions src/librustc_mir/interpret/operand.rs
Original file line number Diff line number Diff line change
Expand Up @@ -218,11 +218,20 @@ impl<'tcx, Tag: Copy> ImmTy<'tcx, Tag> {
ImmTy { imm: val.into(), layout }
}

#[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)
Expand Down