about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/librustc_mir/interpret/eval_context.rs25
-rw-r--r--src/librustc_mir/transform/validate.rs10
2 files changed, 13 insertions, 22 deletions
diff --git a/src/librustc_mir/interpret/eval_context.rs b/src/librustc_mir/interpret/eval_context.rs
index 56a9355650e..25860c43add 100644
--- a/src/librustc_mir/interpret/eval_context.rs
+++ b/src/librustc_mir/interpret/eval_context.rs
@@ -225,28 +225,17 @@ pub(super) fn mir_assign_valid_types<'tcx>(
     src: TyAndLayout<'tcx>,
     dest: TyAndLayout<'tcx>,
 ) -> bool {
-    if src.ty == dest.ty {
-        // Equal types, all is good. Layout will also be equal.
-        // (Enum variants would be an exception here as they have the type of the enum but different layout.
-        // However, those are never the type of an assignment.)
-        return true;
-    }
-    if src.layout != dest.layout {
-        // Layout differs, definitely not equal.
-        // We do this here because Miri would *do the wrong thing* if we allowed layout-changing
-        // assignments.
-        return false;
-    }
-
     // Type-changing assignments can happen when subtyping is used. While
     // all normal lifetimes are erased, higher-ranked types with their
     // late-bound lifetimes are still around and can lead to type
     // differences. So we compare ignoring lifetimes.
-    //
-    // Note that this is not fully correct (FIXME):
-    // lifetimes in invariant positions could matter (e.g. through associated types).
-    // We rely on the fact that layout was confirmed to be equal above.
-    equal_up_to_regions(tcx, param_env, src.ty, dest.ty)
+    if equal_up_to_regions(tcx, param_env, src.ty, dest.ty) {
+        // Make sure the layout is equal, too -- just to be safe. Miri really needs layout equality.
+        assert_eq!(src.layout, dest.layout);
+        true
+    } else {
+        false
+    }
 }
 
 /// Use the already known layout if given (but sanity check in debug mode),
diff --git a/src/librustc_mir/transform/validate.rs b/src/librustc_mir/transform/validate.rs
index 5f0edd64c47..a293751d5b2 100644
--- a/src/librustc_mir/transform/validate.rs
+++ b/src/librustc_mir/transform/validate.rs
@@ -44,6 +44,11 @@ pub fn equal_up_to_regions(
     src: Ty<'tcx>,
     dest: Ty<'tcx>,
 ) -> bool {
+    // Fast path.
+    if src == dest {
+        return true;
+    }
+
     struct LifetimeIgnoreRelation<'tcx> {
         tcx: TyCtxt<'tcx>,
         param_env: ty::ParamEnv<'tcx>,
@@ -176,6 +181,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
     /// Check if src can be assigned into dest.
     /// This is not precise, it will accept some incorrect assignments.
     fn mir_assign_valid_types(&self, src: Ty<'tcx>, dest: Ty<'tcx>) -> bool {
+        // Fast path before we normalize.
         if src == dest {
             // Equal types, all is good.
             return true;
@@ -186,10 +192,6 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
         let param_env = self.param_env.with_reveal_all();
         let src = self.tcx.normalize_erasing_regions(param_env, src);
         let dest = self.tcx.normalize_erasing_regions(param_env, dest);
-        // It's worth checking equality again.
-        if src == dest {
-            return true;
-        }
 
         // Type-changing assignments can happen when subtyping is used. While
         // all normal lifetimes are erased, higher-ranked types with their