diff options
| author | Ralf Jung <post@ralfj.de> | 2019-07-24 19:01:12 +0200 |
|---|---|---|
| committer | Ralf Jung <post@ralfj.de> | 2019-08-02 22:33:36 +0200 |
| commit | ec1e71895aa450606d99d7705dac20d689a330d1 (patch) | |
| tree | 6b897f1f6f92ddae1d40e28892629764ce3aa4a0 | |
| parent | 48b87c6f275069e5c885b54e3d968056a5563db9 (diff) | |
turn cast_immediate into its own function
| -rw-r--r-- | src/librustc_mir/interpret/cast.rs | 75 | ||||
| -rw-r--r-- | src/librustc_mir/interpret/operand.rs | 14 |
2 files changed, 54 insertions, 35 deletions
diff --git a/src/librustc_mir/interpret/cast.rs b/src/librustc_mir/interpret/cast.rs index e1842e72e3c..7e752e2edc4 100644 --- a/src/librustc_mir/interpret/cast.rs +++ b/src/librustc_mir/interpret/cast.rs @@ -11,7 +11,7 @@ use rustc::mir::interpret::{ }; use rustc::mir::CastKind; -use super::{InterpCx, Machine, PlaceTy, OpTy, Immediate, FnVal}; +use super::{InterpCx, Machine, PlaceTy, OpTy, ImmTy, Immediate, FnVal}; impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { fn type_is_fat_ptr(&self, ty: Ty<'tcx>) -> bool { @@ -37,40 +37,8 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { Misc | Pointer(PointerCast::MutToConstPointer) => { let src = self.read_immediate(src)?; - - if self.type_is_fat_ptr(src.layout.ty) { - match (*src, self.type_is_fat_ptr(dest.layout.ty)) { - // pointers to extern types - (Immediate::Scalar(_),_) | - // slices and trait objects to other slices/trait objects - (Immediate::ScalarPair(..), true) => { - // No change to immediate - self.write_immediate(*src, dest)?; - } - // slices and trait objects to thin pointers (dropping the metadata) - (Immediate::ScalarPair(data, _), false) => { - self.write_scalar(data, dest)?; - } - } - } else { - match src.layout.variants { - layout::Variants::Single { index } => { - if let Some(discr) = - src.layout.ty.discriminant_for_variant(*self.tcx, index) - { - // Cast from a univariant enum - assert!(src.layout.is_zst()); - return self.write_scalar( - Scalar::from_uint(discr.val, dest.layout.size), - dest); - } - } - layout::Variants::Multiple { .. } => {}, - } - - let dest_val = self.cast_scalar(src.to_scalar()?, src.layout, dest.layout)?; - self.write_scalar(dest_val, dest)?; - } + let res = self.cast_immediate(src, dest.layout)?; + self.write_immediate(res, dest)?; } Pointer(PointerCast::ReifyFnPointer) => { @@ -126,6 +94,43 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { Ok(()) } + fn cast_immediate( + &self, + src: ImmTy<'tcx, M::PointerTag>, + dest_layout: TyLayout<'tcx>, + ) -> InterpResult<'tcx, Immediate<M::PointerTag>> { + if self.type_is_fat_ptr(src.layout.ty) { + return match (*src, self.type_is_fat_ptr(dest_layout.ty)) { + // pointers to extern types + (Immediate::Scalar(_),_) | + // slices and trait objects to other slices/trait objects + (Immediate::ScalarPair(..), true) => { + // No change to immediate + Ok(*src) + } + // slices and trait objects to thin pointers (dropping the metadata) + (Immediate::ScalarPair(data, _), false) => { + Ok(data.into()) + } + }; + } else { + match src.layout.variants { + layout::Variants::Single { index } => { + if let Some(discr) = + src.layout.ty.discriminant_for_variant(*self.tcx, index) + { + // Cast from a univariant enum + assert!(src.layout.is_zst()); + return Ok(Scalar::from_uint(discr.val, dest_layout.size).into()); + } + } + layout::Variants::Multiple { .. } => {}, + } + + return Ok(self.cast_scalar(src.to_scalar()?, src.layout, dest_layout)?.into()); + } + } + fn cast_scalar( &self, val: Scalar<M::PointerTag>, diff --git a/src/librustc_mir/interpret/operand.rs b/src/librustc_mir/interpret/operand.rs index e64a474b4ca..4742d53d0ba 100644 --- a/src/librustc_mir/interpret/operand.rs +++ b/src/librustc_mir/interpret/operand.rs @@ -32,6 +32,20 @@ pub enum Immediate<Tag=(), Id=AllocId> { ScalarPair(ScalarMaybeUndef<Tag, Id>, ScalarMaybeUndef<Tag, Id>), } +impl<Tag> From<ScalarMaybeUndef<Tag>> for Immediate<Tag> { + #[inline(always)] + fn from(val: ScalarMaybeUndef<Tag>) -> Self { + Immediate::Scalar(val) + } +} + +impl<Tag> From<Scalar<Tag>> for Immediate<Tag> { + #[inline(always)] + fn from(val: Scalar<Tag>) -> Self { + Immediate::Scalar(val.into()) + } +} + impl<'tcx, Tag> Immediate<Tag> { #[inline] pub fn from_scalar(val: Scalar<Tag>) -> Self { |
