@@ -5,13 +5,14 @@ use crate::dataflow::{Analysis, ResultsCursor};
55use crate :: util:: storage:: AlwaysLiveLocals ;
66
77use super :: { MirPass , MirSource } ;
8+ use rustc_infer:: infer:: TyCtxtInferExt ;
89use rustc_middle:: mir:: visit:: { PlaceContext , Visitor } ;
910use rustc_middle:: mir:: {
1011 AggregateKind , BasicBlock , Body , BorrowKind , Local , Location , MirPhase , Operand , Rvalue ,
1112 Statement , StatementKind , Terminator , TerminatorKind , VarDebugInfo ,
1213} ;
13- use rustc_middle:: ty:: relate :: { Relate , RelateResult , TypeRelation } ;
14- use rustc_middle:: ty:: { self , ParamEnv , Ty , TyCtxt } ;
14+ use rustc_middle:: ty:: fold :: BottomUpFolder ;
15+ use rustc_middle:: ty:: { self , ParamEnv , Ty , TyCtxt , TypeFoldable } ;
1516
1617#[ derive( Copy , Clone , Debug ) ]
1718enum EdgeKind {
@@ -64,79 +65,24 @@ pub fn equal_up_to_regions(
6465 return true ;
6566 }
6667
67- struct LifetimeIgnoreRelation < ' tcx > {
68- tcx : TyCtxt < ' tcx > ,
69- param_env : ty:: ParamEnv < ' tcx > ,
70- }
71-
72- impl TypeRelation < ' tcx > for LifetimeIgnoreRelation < ' tcx > {
73- fn tcx ( & self ) -> TyCtxt < ' tcx > {
74- self . tcx
75- }
76-
77- fn param_env ( & self ) -> ty:: ParamEnv < ' tcx > {
78- self . param_env
79- }
80-
81- fn tag ( & self ) -> & ' static str {
82- "librustc_mir::transform::validate"
83- }
84-
85- fn a_is_expected ( & self ) -> bool {
86- true
87- }
88-
89- fn relate_with_variance < T : Relate < ' tcx > > (
90- & mut self ,
91- _: ty:: Variance ,
92- a : T ,
93- b : T ,
94- ) -> RelateResult < ' tcx , T > {
95- // Ignore variance, require types to be exactly the same.
96- self . relate ( a, b)
97- }
98-
99- fn tys ( & mut self , a : Ty < ' tcx > , b : Ty < ' tcx > ) -> RelateResult < ' tcx , Ty < ' tcx > > {
100- if a == b {
101- // Short-circuit.
102- return Ok ( a) ;
103- }
104- ty:: relate:: super_relate_tys ( self , a, b)
105- }
106-
107- fn regions (
108- & mut self ,
109- a : ty:: Region < ' tcx > ,
110- _b : ty:: Region < ' tcx > ,
111- ) -> RelateResult < ' tcx , ty:: Region < ' tcx > > {
112- // Ignore regions.
113- Ok ( a)
114- }
115-
116- fn consts (
117- & mut self ,
118- a : & ' tcx ty:: Const < ' tcx > ,
119- b : & ' tcx ty:: Const < ' tcx > ,
120- ) -> RelateResult < ' tcx , & ' tcx ty:: Const < ' tcx > > {
121- ty:: relate:: super_relate_consts ( self , a, b)
122- }
123-
124- fn binders < T > (
125- & mut self ,
126- a : ty:: Binder < T > ,
127- b : ty:: Binder < T > ,
128- ) -> RelateResult < ' tcx , ty:: Binder < T > >
129- where
130- T : Relate < ' tcx > ,
131- {
132- self . relate ( a. skip_binder ( ) , b. skip_binder ( ) ) ?;
133- Ok ( a)
134- }
135- }
136-
137- // Instantiate and run relation.
138- let mut relator: LifetimeIgnoreRelation < ' tcx > = LifetimeIgnoreRelation { tcx : tcx, param_env } ;
139- relator. relate ( src, dest) . is_ok ( )
68+ // Normalize lifetimes away on both sides, then compare.
69+ let param_env = param_env. with_reveal_all_normalized ( tcx) ;
70+ let normalize = |ty : Ty < ' tcx > | {
71+ tcx. normalize_erasing_regions (
72+ param_env,
73+ ty. fold_with ( & mut BottomUpFolder {
74+ tcx,
75+ // We just erase all late-bound lifetimes, but this is not fully correct (FIXME):
76+ // lifetimes in invariant positions could matter (e.g. through associated types).
77+ // We rely on the fact that layout was confirmed to be equal above.
78+ lt_op : |_| tcx. lifetimes . re_erased ,
79+ // Leave consts and types unchanged.
80+ ct_op : |ct| ct,
81+ ty_op : |ty| ty,
82+ } ) ,
83+ )
84+ } ;
85+ tcx. infer_ctxt ( ) . enter ( |infcx| infcx. can_eq ( param_env, normalize ( src) , normalize ( dest) ) . is_ok ( ) )
14086}
14187
14288struct TypeChecker < ' a , ' tcx > {
0 commit comments