From 2bc59c7ae2631863e947ccdba42b989feeec6b36 Mon Sep 17 00:00:00 2001 From: b-naber Date: Tue, 12 Apr 2022 13:08:47 +0200 Subject: [PATCH] add some helper methods to ScalarInt --- compiler/rustc_middle/src/ty/consts/int.rs | 92 ++++++++++++++++++++++ 1 file changed, 92 insertions(+) diff --git a/compiler/rustc_middle/src/ty/consts/int.rs b/compiler/rustc_middle/src/ty/consts/int.rs index 72623ba54ee..a3ce674c115 100644 --- a/compiler/rustc_middle/src/ty/consts/int.rs +++ b/compiler/rustc_middle/src/ty/consts/int.rs @@ -237,6 +237,98 @@ impl ScalarInt { pub fn try_to_machine_usize<'tcx>(&self, tcx: TyCtxt<'tcx>) -> Result { Ok(self.to_bits(tcx.data_layout.pointer_size)? as u64) } + + /// Tries to convert the `ScalarInt` to an unsigned integer of the given size. + /// Fails if the size of the `ScalarInt` is unequal to `size` and returns the + /// `ScalarInt`s size in that case. + #[inline] + pub fn try_to_uint(self, size: Size) -> Result { + self.to_bits(size) + } + + // Tries to convert the `ScalarInt` to `u8`. Fails if the `size` of the `ScalarInt` + // in not equal to `Size { raw: 1 }` and returns the `size` value of the `ScalarInt` in + // that case. + #[inline] + pub fn try_to_u8(self) -> Result { + self.to_bits(Size::from_bits(8)).map(|v| u8::try_from(v).unwrap()) + } + + /// Tries to convert the `ScalarInt` to `u16`. Fails if the size of the `ScalarInt` + /// in not equal to `Size { raw: 2 }` and returns the `size` value of the `ScalarInt` in + /// that case. + #[inline] + pub fn try_to_u16(self) -> Result { + self.to_bits(Size::from_bits(16)).map(|v| u16::try_from(v).unwrap()) + } + + /// Tries to convert the `ScalarInt` to `u32`. Fails if the `size` of the `ScalarInt` + /// in not equal to `Size { raw: 4 }` and returns the `size` value of the `ScalarInt` in + /// that case. + #[inline] + pub fn try_to_u32(self) -> Result { + self.to_bits(Size::from_bits(32)).map(|v| u32::try_from(v).unwrap()) + } + + /// Tries to convert the `ScalarInt` to `u64`. Fails if the `size` of the `ScalarInt` + /// in not equal to `Size { raw: 8 }` and returns the `size` value of the `ScalarInt` in + /// that case. + #[inline] + pub fn try_to_u64(self) -> Result { + self.to_bits(Size::from_bits(64)).map(|v| u64::try_from(v).unwrap()) + } + + /// Tries to convert the `ScalarInt` to `u128`. Fails if the `size` of the `ScalarInt` + /// in not equal to `Size { raw: 16 }` and returns the `size` value of the `ScalarInt` in + /// that case. + #[inline] + pub fn try_to_u128(self) -> Result { + self.to_bits(Size::from_bits(128)) + } + + /// Tries to convert the `ScalarInt` to a signed integer of the given size. + /// Fails if the size of the `ScalarInt` is unequal to `size` and returns the + /// `ScalarInt`s size in that case. + #[inline] + pub fn try_to_int(self, size: Size) -> Result { + let b = self.to_bits(size)?; + Ok(size.sign_extend(b) as i128) + } + + /// Tries to convert the `ScalarInt` to i8. + /// Fails if the size of the `ScalarInt` is unequal to `Size { raw: 1 }` + /// and returns the `ScalarInt`s size in that case. + pub fn try_to_i8(self) -> Result { + self.try_to_int(Size::from_bits(8)).map(|v| i8::try_from(v).unwrap()) + } + + /// Tries to convert the `ScalarInt` to i16. + /// Fails if the size of the `ScalarInt` is unequal to `Size { raw: 2 }` + /// and returns the `ScalarInt`s size in that case. + pub fn try_to_i16(self) -> Result { + self.try_to_int(Size::from_bits(16)).map(|v| i16::try_from(v).unwrap()) + } + + /// Tries to convert the `ScalarInt` to i32. + /// Fails if the size of the `ScalarInt` is unequal to `Size { raw: 4 }` + /// and returns the `ScalarInt`s size in that case. + pub fn try_to_i32(self) -> Result { + self.try_to_int(Size::from_bits(32)).map(|v| i32::try_from(v).unwrap()) + } + + /// Tries to convert the `ScalarInt` to i64. + /// Fails if the size of the `ScalarInt` is unequal to `Size { raw: 8 }` + /// and returns the `ScalarInt`s size in that case. + pub fn try_to_i64(self) -> Result { + self.try_to_int(Size::from_bits(64)).map(|v| i64::try_from(v).unwrap()) + } + + /// Tries to convert the `ScalarInt` to i128. + /// Fails if the size of the `ScalarInt` is unequal to `Size { raw: 16 }` + /// and returns the `ScalarInt`s size in that case. + pub fn try_to_i128(self) -> Result { + self.try_to_int(Size::from_bits(128)).map(|v| i128::try_from(v).unwrap()) + } } macro_rules! from {