From a593728fc753f85df575b54aadc64c3fd2c06d11 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Mon, 22 Jun 2020 11:07:39 +0200 Subject: [PATCH] make layout check a mere sanity check --- src/librustc_mir/interpret/eval_context.rs | 25 ++++++---------------- src/librustc_mir/transform/validate.rs | 10 +++++---- 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 56a9355650e2..25860c43add4 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 5f0edd64c47e..a293751d5b27 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