about summary refs log tree commit diff
diff options
context:
space:
mode:
authorBastian Kauschke <bastian_kauschke@hotmail.de>2020-10-26 20:32:34 +0100
committerBastian Kauschke <bastian_kauschke@hotmail.de>2020-11-02 23:57:03 +0100
commitcc19df627ea87e199163e0e487a251976ea7897e (patch)
treeb094dabf8bd8320f7528028d99991bd3882a6dc9
parent1d5b7c3c96a86c96f1fbf1441475028df94d165a (diff)
downloadrust-cc19df627ea87e199163e0e487a251976ea7897e.tar.gz
rust-cc19df627ea87e199163e0e487a251976ea7897e.zip
revert #75443 update mir validator
-rw-r--r--compiler/rustc_mir/src/transform/validate.rs96
-rw-r--r--compiler/rustc_trait_selection/src/traits/project.rs2
-rw-r--r--compiler/rustc_trait_selection/src/traits/query/normalize.rs2
-rw-r--r--src/test/ui/type-alias-impl-trait/issue-72793.rs27
4 files changed, 23 insertions, 104 deletions
diff --git a/compiler/rustc_mir/src/transform/validate.rs b/compiler/rustc_mir/src/transform/validate.rs
index 1868d3b47f2..c9905b34a12 100644
--- a/compiler/rustc_mir/src/transform/validate.rs
+++ b/compiler/rustc_mir/src/transform/validate.rs
@@ -6,6 +6,7 @@ use crate::util::storage::AlwaysLiveLocals;
 
 use super::MirPass;
 use rustc_index::bit_set::BitSet;
+use rustc_infer::infer::TyCtxtInferExt;
 use rustc_middle::mir::interpret::Scalar;
 use rustc_middle::mir::traversal;
 use rustc_middle::mir::visit::{PlaceContext, Visitor};
@@ -13,8 +14,8 @@ use rustc_middle::mir::{
     AggregateKind, BasicBlock, Body, BorrowKind, Local, Location, MirPhase, Operand, PlaceRef,
     Rvalue, SourceScope, Statement, StatementKind, Terminator, TerminatorKind, VarDebugInfo,
 };
-use rustc_middle::ty::relate::{Relate, RelateResult, TypeRelation};
-use rustc_middle::ty::{self, ParamEnv, Ty, TyCtxt};
+use rustc_middle::ty::fold::BottomUpFolder;
+use rustc_middle::ty::{self, ParamEnv, Ty, TyCtxt, TypeFoldable};
 use rustc_target::abi::Size;
 
 #[derive(Copy, Clone, Debug)]
@@ -77,79 +78,24 @@ pub fn equal_up_to_regions(
         return true;
     }
 
-    struct LifetimeIgnoreRelation<'tcx> {
-        tcx: TyCtxt<'tcx>,
-        param_env: ty::ParamEnv<'tcx>,
-    }
-
-    impl TypeRelation<'tcx> for LifetimeIgnoreRelation<'tcx> {
-        fn tcx(&self) -> TyCtxt<'tcx> {
-            self.tcx
-        }
-
-        fn param_env(&self) -> ty::ParamEnv<'tcx> {
-            self.param_env
-        }
-
-        fn tag(&self) -> &'static str {
-            "librustc_mir::transform::validate"
-        }
-
-        fn a_is_expected(&self) -> bool {
-            true
-        }
-
-        fn relate_with_variance<T: Relate<'tcx>>(
-            &mut self,
-            _: ty::Variance,
-            a: T,
-            b: T,
-        ) -> RelateResult<'tcx, T> {
-            // Ignore variance, require types to be exactly the same.
-            self.relate(a, b)
-        }
-
-        fn tys(&mut self, a: Ty<'tcx>, b: Ty<'tcx>) -> RelateResult<'tcx, Ty<'tcx>> {
-            if a == b {
-                // Short-circuit.
-                return Ok(a);
-            }
-            ty::relate::super_relate_tys(self, a, b)
-        }
-
-        fn regions(
-            &mut self,
-            a: ty::Region<'tcx>,
-            _b: ty::Region<'tcx>,
-        ) -> RelateResult<'tcx, ty::Region<'tcx>> {
-            // Ignore regions.
-            Ok(a)
-        }
-
-        fn consts(
-            &mut self,
-            a: &'tcx ty::Const<'tcx>,
-            b: &'tcx ty::Const<'tcx>,
-        ) -> RelateResult<'tcx, &'tcx ty::Const<'tcx>> {
-            ty::relate::super_relate_consts(self, a, b)
-        }
-
-        fn binders<T>(
-            &mut self,
-            a: ty::Binder<T>,
-            b: ty::Binder<T>,
-        ) -> RelateResult<'tcx, ty::Binder<T>>
-        where
-            T: Relate<'tcx>,
-        {
-            self.relate(a.skip_binder(), b.skip_binder())?;
-            Ok(a)
-        }
-    }
-
-    // Instantiate and run relation.
-    let mut relator: LifetimeIgnoreRelation<'tcx> = LifetimeIgnoreRelation { tcx: tcx, param_env };
-    relator.relate(src, dest).is_ok()
+    // Normalize lifetimes away on both sides, then compare.
+    let param_env = param_env.with_reveal_all_normalized(tcx);
+    let normalize = |ty: Ty<'tcx>| {
+        tcx.normalize_erasing_regions(
+            param_env,
+            ty.fold_with(&mut BottomUpFolder {
+                tcx,
+                // We just erase all late-bound lifetimes, but 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.
+                lt_op: |_| tcx.lifetimes.re_erased,
+                // Leave consts and types unchanged.
+                ct_op: |ct| ct,
+                ty_op: |ty| ty,
+            }),
+        )
+    };
+    tcx.infer_ctxt().enter(|infcx| infcx.can_eq(param_env, normalize(src), normalize(dest)).is_ok())
 }
 
 struct TypeChecker<'a, 'tcx> {
diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs
index 827b1d35f1c..a85ffd3c961 100644
--- a/compiler/rustc_trait_selection/src/traits/project.rs
+++ b/compiler/rustc_trait_selection/src/traits/project.rs
@@ -338,7 +338,7 @@ impl<'a, 'b, 'tcx> TypeFolder<'tcx> for AssocTypeNormalizer<'a, 'b, 'tcx> {
 
         let ty = ty.super_fold_with(self);
         match *ty.kind() {
-            ty::Opaque(def_id, substs) => {
+            ty::Opaque(def_id, substs) if !substs.has_escaping_bound_vars() => {
                 // Only normalize `impl Trait` after type-checking, usually in codegen.
                 match self.param_env.reveal() {
                     Reveal::UserFacing => ty,
diff --git a/compiler/rustc_trait_selection/src/traits/query/normalize.rs b/compiler/rustc_trait_selection/src/traits/query/normalize.rs
index d748fc8235e..42a598ce3a0 100644
--- a/compiler/rustc_trait_selection/src/traits/query/normalize.rs
+++ b/compiler/rustc_trait_selection/src/traits/query/normalize.rs
@@ -108,7 +108,7 @@ impl<'cx, 'tcx> TypeFolder<'tcx> for QueryNormalizer<'cx, 'tcx> {
 
         let ty = ty.super_fold_with(self);
         let res = (|| match *ty.kind() {
-            ty::Opaque(def_id, substs) => {
+            ty::Opaque(def_id, substs) if !substs.has_escaping_bound_vars() => {
                 // Only normalize `impl Trait` after type-checking, usually in codegen.
                 match self.param_env.reveal() {
                     Reveal::UserFacing => ty,
diff --git a/src/test/ui/type-alias-impl-trait/issue-72793.rs b/src/test/ui/type-alias-impl-trait/issue-72793.rs
deleted file mode 100644
index e643a8cab5b..00000000000
--- a/src/test/ui/type-alias-impl-trait/issue-72793.rs
+++ /dev/null
@@ -1,27 +0,0 @@
-// build-pass
-
-// Regression test for #72793.
-// FIXME: This still shows ICE with `-Zmir-opt-level=2`.
-
-#![feature(type_alias_impl_trait)]
-
-trait T { type Item; }
-
-type Alias<'a> = impl T<Item = &'a ()>;
-
-struct S;
-impl<'a> T for &'a S {
-    type Item = &'a ();
-}
-
-fn filter_positive<'a>() -> Alias<'a> {
-    &S
-}
-
-fn with_positive(fun: impl Fn(Alias<'_>)) {
-    fun(filter_positive());
-}
-
-fn main() {
-    with_positive(|_| ());
-}