about summary refs log tree commit diff
diff options
context:
space:
mode:
authorOli Scherer <github35764891676564198441@oli-obk.de>2021-02-23 14:11:29 +0000
committerOli Scherer <github35764891676564198441@oli-obk.de>2021-03-12 12:20:54 +0000
commit09f7f915327b8877ea6025e71dc028ffdbd2369c (patch)
treea3fce375d3fe0f1f7726b61c39c83ce09512378b
parent858216cabf9cd1521e55c675502426bdd5262c73 (diff)
downloadrust-09f7f915327b8877ea6025e71dc028ffdbd2369c.tar.gz
rust-09f7f915327b8877ea6025e71dc028ffdbd2369c.zip
Add convenience conversion methods for ScalarInt
-rw-r--r--compiler/rustc_middle/src/mir/interpret/value.rs31
-rw-r--r--compiler/rustc_middle/src/ty/consts/int.rs19
-rw-r--r--compiler/rustc_middle/src/ty/consts/kind.rs13
3 files changed, 53 insertions, 10 deletions
diff --git a/compiler/rustc_middle/src/mir/interpret/value.rs b/compiler/rustc_middle/src/mir/interpret/value.rs
index 3dd905b35b2..c7b1005fffc 100644
--- a/compiler/rustc_middle/src/mir/interpret/value.rs
+++ b/compiler/rustc_middle/src/mir/interpret/value.rs
@@ -1,4 +1,4 @@
-use std::convert::TryFrom;
+use std::convert::{TryFrom, TryInto};
 use std::fmt;
 
 use rustc_apfloat::{
@@ -56,20 +56,20 @@ impl<'tcx> ConstValue<'tcx> {
         }
     }
 
+    pub fn try_to_scalar_int(&self) -> Option<ScalarInt> {
+        self.try_to_scalar()?.to_int().ok()
+    }
+
     pub fn try_to_bits(&self, size: Size) -> Option<u128> {
-        self.try_to_scalar()?.to_bits(size).ok()
+        self.try_to_scalar_int()?.to_bits(size).ok()
     }
 
     pub fn try_to_bool(&self) -> Option<bool> {
-        match self.try_to_bits(Size::from_bytes(1))? {
-            0 => Some(false),
-            1 => Some(true),
-            _ => None,
-        }
+        self.try_to_scalar_int()?.try_into().ok()
     }
 
     pub fn try_to_machine_usize(&self, tcx: TyCtxt<'tcx>) -> Option<u64> {
-        Some(self.try_to_bits(tcx.data_layout.pointer_size)? as u64)
+        self.try_to_scalar_int()?.try_to_machine_usize(tcx).ok()
     }
 
     pub fn try_to_bits_for_ty(
@@ -505,6 +505,21 @@ impl<Tag> From<Pointer<Tag>> for Scalar<Tag> {
     }
 }
 
+impl TryFrom<Scalar> for ScalarInt {
+    type Error = super::InterpErrorInfo<'static>;
+    #[inline]
+    fn try_from(scalar: Scalar) -> InterpResult<'static, Self> {
+        scalar.to_int()
+    }
+}
+
+impl<Tag> From<ScalarInt> for Scalar<Tag> {
+    #[inline(always)]
+    fn from(ptr: ScalarInt) -> Self {
+        Scalar::Int(ptr)
+    }
+}
+
 #[derive(Clone, Copy, Eq, PartialEq, TyEncodable, TyDecodable, HashStable, Hash)]
 pub enum ScalarMaybeUninit<Tag = ()> {
     Scalar(Scalar<Tag>),
diff --git a/compiler/rustc_middle/src/ty/consts/int.rs b/compiler/rustc_middle/src/ty/consts/int.rs
index 63e95f25bb7..8ed8ea6a0bc 100644
--- a/compiler/rustc_middle/src/ty/consts/int.rs
+++ b/compiler/rustc_middle/src/ty/consts/int.rs
@@ -5,6 +5,8 @@ use rustc_target::abi::{Size, TargetDataLayout};
 use std::convert::{TryFrom, TryInto};
 use std::fmt;
 
+use crate::ty::TyCtxt;
+
 #[derive(Copy, Clone)]
 /// A type for representing any integer. Only used for printing.
 pub struct ConstInt {
@@ -239,6 +241,11 @@ impl ScalarInt {
             Err(self.size())
         }
     }
+
+    #[inline]
+    pub fn try_to_machine_usize(&self, tcx: TyCtxt<'tcx>) -> Result<u64, Size> {
+        Ok(self.to_bits(tcx.data_layout.pointer_size)? as u64)
+    }
 }
 
 macro_rules! from {
@@ -277,6 +284,18 @@ macro_rules! try_from {
 from!(u8, u16, u32, u64, u128, bool);
 try_from!(u8, u16, u32, u64, u128);
 
+impl TryFrom<ScalarInt> for bool {
+    type Error = Size;
+    #[inline]
+    fn try_from(int: ScalarInt) -> Result<Self, Size> {
+        int.to_bits(Size::from_bytes(1)).and_then(|u| match u {
+            0 => Ok(false),
+            1 => Ok(true),
+            _ => Err(Size::from_bytes(1)),
+        })
+    }
+}
+
 impl From<char> for ScalarInt {
     #[inline]
     fn from(c: char) -> Self {
diff --git a/compiler/rustc_middle/src/ty/consts/kind.rs b/compiler/rustc_middle/src/ty/consts/kind.rs
index 98c215407a8..5a6f219a413 100644
--- a/compiler/rustc_middle/src/ty/consts/kind.rs
+++ b/compiler/rustc_middle/src/ty/consts/kind.rs
@@ -1,3 +1,5 @@
+use std::convert::TryInto;
+
 use crate::mir::interpret::ConstValue;
 use crate::mir::interpret::Scalar;
 use crate::mir::Promoted;
@@ -9,6 +11,8 @@ use rustc_hir::def_id::DefId;
 use rustc_macros::HashStable;
 use rustc_target::abi::Size;
 
+use super::ScalarInt;
+
 /// Represents a constant in Rust.
 #[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord, TyEncodable, TyDecodable, Hash)]
 #[derive(HashStable)]
@@ -52,13 +56,18 @@ impl<'tcx> ConstKind<'tcx> {
     }
 
     #[inline]
+    pub fn try_to_scalar_int(self) -> Option<ScalarInt> {
+        self.try_to_value()?.try_to_scalar()?.to_int().ok()
+    }
+
+    #[inline]
     pub fn try_to_bits(self, size: Size) -> Option<u128> {
-        self.try_to_value()?.try_to_bits(size)
+        self.try_to_scalar_int()?.to_bits(size).ok()
     }
 
     #[inline]
     pub fn try_to_bool(self) -> Option<bool> {
-        self.try_to_value()?.try_to_bool()
+        self.try_to_scalar_int()?.try_into().ok()
     }
 
     #[inline]