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