1
Fork 0

revert #75443 update mir validator

This commit is contained in:
Bastian Kauschke 2020-10-26 20:32:34 +01:00
parent 1d5b7c3c96
commit cc19df627e
4 changed files with 23 additions and 104 deletions

View file

@ -6,6 +6,7 @@ use crate::util::storage::AlwaysLiveLocals;
use super::MirPass; use super::MirPass;
use rustc_index::bit_set::BitSet; use rustc_index::bit_set::BitSet;
use rustc_infer::infer::TyCtxtInferExt;
use rustc_middle::mir::interpret::Scalar; use rustc_middle::mir::interpret::Scalar;
use rustc_middle::mir::traversal; use rustc_middle::mir::traversal;
use rustc_middle::mir::visit::{PlaceContext, Visitor}; use rustc_middle::mir::visit::{PlaceContext, Visitor};
@ -13,8 +14,8 @@ use rustc_middle::mir::{
AggregateKind, BasicBlock, Body, BorrowKind, Local, Location, MirPhase, Operand, PlaceRef, AggregateKind, BasicBlock, Body, BorrowKind, Local, Location, MirPhase, Operand, PlaceRef,
Rvalue, SourceScope, Statement, StatementKind, Terminator, TerminatorKind, VarDebugInfo, Rvalue, SourceScope, Statement, StatementKind, Terminator, TerminatorKind, VarDebugInfo,
}; };
use rustc_middle::ty::relate::{Relate, RelateResult, TypeRelation}; use rustc_middle::ty::fold::BottomUpFolder;
use rustc_middle::ty::{self, ParamEnv, Ty, TyCtxt}; use rustc_middle::ty::{self, ParamEnv, Ty, TyCtxt, TypeFoldable};
use rustc_target::abi::Size; use rustc_target::abi::Size;
#[derive(Copy, Clone, Debug)] #[derive(Copy, Clone, Debug)]
@ -77,79 +78,24 @@ pub fn equal_up_to_regions(
return true; return true;
} }
struct LifetimeIgnoreRelation<'tcx> { // Normalize lifetimes away on both sides, then compare.
tcx: TyCtxt<'tcx>, let param_env = param_env.with_reveal_all_normalized(tcx);
param_env: ty::ParamEnv<'tcx>, let normalize = |ty: Ty<'tcx>| {
} tcx.normalize_erasing_regions(
param_env,
impl TypeRelation<'tcx> for LifetimeIgnoreRelation<'tcx> { ty.fold_with(&mut BottomUpFolder {
fn tcx(&self) -> TyCtxt<'tcx> { tcx,
self.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.
fn param_env(&self) -> ty::ParamEnv<'tcx> { lt_op: |_| tcx.lifetimes.re_erased,
self.param_env // Leave consts and types unchanged.
} ct_op: |ct| ct,
ty_op: |ty| ty,
fn tag(&self) -> &'static str { }),
"librustc_mir::transform::validate" )
} };
tcx.infer_ctxt().enter(|infcx| infcx.can_eq(param_env, normalize(src), normalize(dest)).is_ok())
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()
} }
struct TypeChecker<'a, 'tcx> { struct TypeChecker<'a, 'tcx> {

View file

@ -338,7 +338,7 @@ impl<'a, 'b, 'tcx> TypeFolder<'tcx> for AssocTypeNormalizer<'a, 'b, 'tcx> {
let ty = ty.super_fold_with(self); let ty = ty.super_fold_with(self);
match *ty.kind() { 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. // Only normalize `impl Trait` after type-checking, usually in codegen.
match self.param_env.reveal() { match self.param_env.reveal() {
Reveal::UserFacing => ty, Reveal::UserFacing => ty,

View file

@ -108,7 +108,7 @@ impl<'cx, 'tcx> TypeFolder<'tcx> for QueryNormalizer<'cx, 'tcx> {
let ty = ty.super_fold_with(self); let ty = ty.super_fold_with(self);
let res = (|| match *ty.kind() { 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. // Only normalize `impl Trait` after type-checking, usually in codegen.
match self.param_env.reveal() { match self.param_env.reveal() {
Reveal::UserFacing => ty, Reveal::UserFacing => ty,

View file

@ -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(|_| ());
}