From cc19df627ea87e199163e0e487a251976ea7897e Mon Sep 17 00:00:00 2001 From: Bastian Kauschke Date: Mon, 26 Oct 2020 20:32:34 +0100 Subject: [PATCH 1/2] revert #75443 update mir validator --- compiler/rustc_mir/src/transform/validate.rs | 96 ++++--------------- .../src/traits/project.rs | 2 +- .../src/traits/query/normalize.rs | 2 +- .../ui/type-alias-impl-trait/issue-72793.rs | 27 ------ 4 files changed, 23 insertions(+), 104 deletions(-) delete mode 100644 src/test/ui/type-alias-impl-trait/issue-72793.rs diff --git a/compiler/rustc_mir/src/transform/validate.rs b/compiler/rustc_mir/src/transform/validate.rs index 1868d3b47f2ab..c9905b34a12ed 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>( - &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( - &mut self, - a: ty::Binder, - b: ty::Binder, - ) -> RelateResult<'tcx, ty::Binder> - 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 827b1d35f1c22..a85ffd3c961b7 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 d748fc8235e7f..42a598ce3a008 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 e643a8cab5b02..0000000000000 --- 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; - -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(|_| ()); -} From e06785b676bb639fef071feca302432c61fbddcc Mon Sep 17 00:00:00 2001 From: Bastian Kauschke Date: Fri, 6 Nov 2020 19:21:17 +0100 Subject: [PATCH 2/2] improve fixme --- compiler/rustc_mir/src/transform/validate.rs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/compiler/rustc_mir/src/transform/validate.rs b/compiler/rustc_mir/src/transform/validate.rs index c9905b34a12ed..e1e6e71acb5a8 100644 --- a/compiler/rustc_mir/src/transform/validate.rs +++ b/compiler/rustc_mir/src/transform/validate.rs @@ -85,9 +85,12 @@ pub fn equal_up_to_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. + // FIXME: We erase all late-bound lifetimes, but this is not fully correct. + // If you have a type like ` fn(&'a u32) as SomeTrait>::Assoc`, + // this is not necessarily equivalent to `::Assoc`, + // since one may have an `impl SomeTrait for fn(&32)` and + // `impl SomeTrait for fn(&'static u32)` at the same time which + // specify distinct values for Assoc. (See also #56105) lt_op: |_| tcx.lifetimes.re_erased, // Leave consts and types unchanged. ct_op: |ct| ct,