revert #75443 update mir validator
This commit is contained in:
parent
1d5b7c3c96
commit
cc19df627e
@ -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> {
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
|
@ -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(|_| ());
|
||||
}
|
Loading…
Reference in New Issue
Block a user