From 09f7f915327b8877ea6025e71dc028ffdbd2369c Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Tue, 23 Feb 2021 14:11:29 +0000 Subject: [PATCH] Add convenience conversion methods for ScalarInt --- .../rustc_middle/src/mir/interpret/value.rs | 31 ++++++++++++++----- compiler/rustc_middle/src/ty/consts/int.rs | 19 ++++++++++++ compiler/rustc_middle/src/ty/consts/kind.rs | 13 ++++++-- 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 { + self.try_to_scalar()?.to_int().ok() + } + pub fn try_to_bits(&self, size: Size) -> Option { - self.try_to_scalar()?.to_bits(size).ok() + self.try_to_scalar_int()?.to_bits(size).ok() } pub fn try_to_bool(&self) -> Option { - 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 { - 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 From> for Scalar { } } +impl TryFrom for ScalarInt { + type Error = super::InterpErrorInfo<'static>; + #[inline] + fn try_from(scalar: Scalar) -> InterpResult<'static, Self> { + scalar.to_int() + } +} + +impl From for Scalar { + #[inline(always)] + fn from(ptr: ScalarInt) -> Self { + Scalar::Int(ptr) + } +} + #[derive(Clone, Copy, Eq, PartialEq, TyEncodable, TyDecodable, HashStable, Hash)] pub enum ScalarMaybeUninit { Scalar(Scalar), 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 { + 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 for bool { + type Error = Size; + #[inline] + fn try_from(int: ScalarInt) -> Result { + 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 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)] @@ -51,14 +55,19 @@ impl<'tcx> ConstKind<'tcx> { self.try_to_value()?.try_to_scalar() } + #[inline] + pub fn try_to_scalar_int(self) -> Option { + self.try_to_value()?.try_to_scalar()?.to_int().ok() + } + #[inline] pub fn try_to_bits(self, size: Size) -> Option { - 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 { - self.try_to_value()?.try_to_bool() + self.try_to_scalar_int()?.try_into().ok() } #[inline]