about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/librustc_mir/interpret/eval_context.rs44
-rw-r--r--src/librustc_mir/interpret/mod.rs18
-rw-r--r--src/librustc_mir/interpret/operand.rs35
-rw-r--r--src/librustc_mir/interpret/place.rs24
4 files changed, 58 insertions, 63 deletions
diff --git a/src/librustc_mir/interpret/eval_context.rs b/src/librustc_mir/interpret/eval_context.rs
index 9aa42e107dc..ce098f583d0 100644
--- a/src/librustc_mir/interpret/eval_context.rs
+++ b/src/librustc_mir/interpret/eval_context.rs
@@ -210,6 +210,48 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> LayoutOf for InterpCx<'mir, 'tcx, M> {
     }
 }
 
+/// Test if it is valid for a MIR assignment to assign `src`-typed place to `dest`-typed value.
+/// This test should be symmetric, as it is primarily about layout compatibility.
+pub(super) fn mir_assign_valid_types<'tcx>(src: Ty<'tcx>, dest: Ty<'tcx>) -> bool {
+    src == dest
+        || match (&src.kind, &dest.kind) {
+            (ty::Ref(_, src_pointee, _), ty::Ref(_, dest_pointee, _)) => {
+                // After optimizations, there can be assignments that change reference mutability.
+                // This does not affect reference layout, so that is fine.
+                src_pointee == dest_pointee
+            }
+            (ty::FnPtr(_), ty::FnPtr(_)) => {
+                // All function pointers have equal layout, and thus can be assigned.
+                true
+            }
+            _ => false,
+        }
+}
+
+/// Use the already known layout if given (but sanity check in debug mode),
+/// or compute the layout.
+#[cfg_attr(not(debug_assertions), inline(always))]
+pub(super) fn from_known_layout<'tcx>(
+    known_layout: Option<TyAndLayout<'tcx>>,
+    compute: impl FnOnce() -> InterpResult<'tcx, TyAndLayout<'tcx>>,
+) -> InterpResult<'tcx, TyAndLayout<'tcx>> {
+    match known_layout {
+        None => compute(),
+        Some(known_layout) => {
+            if cfg!(debug_assertions) {
+                let check_layout = compute()?;
+                assert!(
+                    mir_assign_valid_types(check_layout.ty, known_layout.ty),
+                    "expected type differs from actual type.\nexpected: {:?}\nactual: {:?}",
+                    known_layout.ty,
+                    check_layout.ty,
+                );
+            }
+            Ok(known_layout)
+        }
+    }
+}
+
 impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
     pub fn new(
         tcx: TyCtxtAt<'tcx>,
@@ -377,7 +419,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
         // have to support that case (mostly by skipping all caching).
         match frame.locals.get(local).and_then(|state| state.layout.get()) {
             None => {
-                let layout = crate::interpret::operand::from_known_layout(layout, || {
+                let layout = from_known_layout(layout, || {
                     let local_ty = frame.body.local_decls[local].ty;
                     let local_ty =
                         self.subst_from_frame_and_normalize_erasing_regions(frame, local_ty);
diff --git a/src/librustc_mir/interpret/mod.rs b/src/librustc_mir/interpret/mod.rs
index 4e30da82907..fb59a177b97 100644
--- a/src/librustc_mir/interpret/mod.rs
+++ b/src/librustc_mir/interpret/mod.rs
@@ -18,19 +18,13 @@ mod visitor;
 pub use rustc_middle::mir::interpret::*; // have all the `interpret` symbols in one place: here
 
 pub use self::eval_context::{Frame, InterpCx, LocalState, LocalValue, StackPopCleanup};
-
-pub use self::place::{MPlaceTy, MemPlace, MemPlaceMeta, Place, PlaceTy};
-
-pub use self::memory::{AllocCheck, FnVal, Memory, MemoryKind};
-
+pub use self::intern::{intern_const_alloc_recursive, InternKind};
 pub use self::machine::{AllocMap, Machine, MayLeak, StackPopJump};
-
-pub use self::operand::{ImmTy, Immediate, OpTy, Operand, ScalarMaybeUndef};
-
-pub use self::visitor::{MutValueVisitor, ValueVisitor};
-
+pub use self::memory::{AllocCheck, FnVal, Memory, MemoryKind};
+pub use self::operand::{ImmTy, Immediate, OpTy, Operand};
+pub use self::place::{MPlaceTy, MemPlace, MemPlaceMeta, Place, PlaceTy};
 pub use self::validity::RefTracking;
-
-pub use self::intern::{intern_const_alloc_recursive, InternKind};
+pub use self::visitor::{MutValueVisitor, ValueVisitor};
 
 crate use self::intrinsics::eval_nullary_intrinsic;
+use eval_context::{from_known_layout, mir_assign_valid_types};
diff --git a/src/librustc_mir/interpret/operand.rs b/src/librustc_mir/interpret/operand.rs
index 999d0d26ab3..12595e4e4d9 100644
--- a/src/librustc_mir/interpret/operand.rs
+++ b/src/librustc_mir/interpret/operand.rs
@@ -2,21 +2,21 @@
 //! All high-level functions to read from memory work on operands as sources.
 
 use std::convert::TryFrom;
+use std::fmt::Write;
 
-use super::{InterpCx, MPlaceTy, Machine, MemPlace, Place, PlaceTy};
 use rustc_hir::def::Namespace;
 use rustc_macros::HashStable;
-pub use rustc_middle::mir::interpret::ScalarMaybeUndef;
-use rustc_middle::mir::interpret::{
-    sign_extend, truncate, AllocId, ConstValue, GlobalId, InterpResult, Pointer, Scalar,
-};
 use rustc_middle::ty::layout::{IntegerExt, PrimitiveExt, TyAndLayout};
 use rustc_middle::ty::print::{FmtPrinter, PrettyPrinter, Printer};
 use rustc_middle::ty::Ty;
 use rustc_middle::{mir, ty};
 use rustc_target::abi::{Abi, DiscriminantKind, HasDataLayout, Integer, LayoutOf, Size};
 use rustc_target::abi::{VariantIdx, Variants};
-use std::fmt::Write;
+
+use super::{
+    from_known_layout, sign_extend, truncate, AllocId, ConstValue, GlobalId, InterpCx,
+    InterpResult, MPlaceTy, Machine, MemPlace, Place, PlaceTy, Pointer, Scalar, ScalarMaybeUndef,
+};
 
 /// An `Immediate` represents a single immediate self-contained Rust value.
 ///
@@ -203,29 +203,6 @@ impl<'tcx, Tag: Copy> ImmTy<'tcx, Tag> {
     }
 }
 
-// Use the existing layout if given (but sanity check in debug mode),
-// or compute the layout.
-#[inline(always)]
-pub(super) fn from_known_layout<'tcx>(
-    layout: Option<TyAndLayout<'tcx>>,
-    compute: impl FnOnce() -> InterpResult<'tcx, TyAndLayout<'tcx>>,
-) -> InterpResult<'tcx, TyAndLayout<'tcx>> {
-    match layout {
-        None => compute(),
-        Some(layout) => {
-            if cfg!(debug_assertions) {
-                let layout2 = compute()?;
-                assert_eq!(
-                    layout.layout, layout2.layout,
-                    "mismatch in layout of supposedly equal-layout types {:?} and {:?}",
-                    layout.ty, layout2.ty
-                );
-            }
-            Ok(layout)
-        }
-    }
-}
-
 impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
     /// Normalice `place.ptr` to a `Pointer` if this is a place and not a ZST.
     /// Can be helpful to avoid lots of `force_ptr` calls later, if this place is used a lot.
diff --git a/src/librustc_mir/interpret/place.rs b/src/librustc_mir/interpret/place.rs
index 5d4976c09bb..c9999ef7c95 100644
--- a/src/librustc_mir/interpret/place.rs
+++ b/src/librustc_mir/interpret/place.rs
@@ -7,16 +7,15 @@ use std::hash::Hash;
 
 use rustc_macros::HashStable;
 use rustc_middle::mir;
-use rustc_middle::mir::interpret::truncate;
 use rustc_middle::ty::layout::{PrimitiveExt, TyAndLayout};
 use rustc_middle::ty::{self, Ty};
 use rustc_target::abi::{Abi, Align, DiscriminantKind, FieldsShape};
 use rustc_target::abi::{HasDataLayout, LayoutOf, Size, VariantIdx, Variants};
 
 use super::{
-    AllocId, AllocMap, Allocation, AllocationExtra, ImmTy, Immediate, InterpCx, InterpResult,
-    LocalValue, Machine, MemoryKind, OpTy, Operand, Pointer, PointerArithmetic, RawConst, Scalar,
-    ScalarMaybeUndef,
+    mir_assign_valid_types, truncate, AllocId, AllocMap, Allocation, AllocationExtra, ImmTy,
+    Immediate, InterpCx, InterpResult, LocalValue, Machine, MemoryKind, OpTy, Operand, Pointer,
+    PointerArithmetic, RawConst, Scalar, ScalarMaybeUndef,
 };
 
 #[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, HashStable)]
@@ -283,23 +282,6 @@ impl<'tcx, Tag: ::std::fmt::Debug> PlaceTy<'tcx, Tag> {
     }
 }
 
-/// Test if it is valid for a MIR assignment to assign `src`-typed place to `dest`-typed value.
-fn mir_assign_valid_types<'tcx>(src: Ty<'tcx>, dest: Ty<'tcx>) -> bool {
-    src == dest
-        || match (&src.kind, &dest.kind) {
-            (ty::Ref(_, src_pointee, _), ty::Ref(_, dest_pointee, _)) => {
-                // After optimizations, there can be assignments that change reference mutability.
-                // This does not affect reference layout, so that is fine.
-                src_pointee == dest_pointee
-            }
-            (ty::FnPtr(_), ty::FnPtr(_)) => {
-                // All function pointers have equal layout, and thus can be assigned.
-                true
-            }
-            _ => false,
-        }
-}
-
 // separating the pointer tag for `impl Trait`, see https://github.com/rust-lang/rust/issues/54385
 impl<'mir, 'tcx, Tag, M> InterpCx<'mir, 'tcx, M>
 where