@@ -6,15 +6,16 @@ use crate::util::storage::AlwaysLiveLocals;
66
77use super :: MirPass ;
88use rustc_index:: bit_set:: BitSet ;
9+ use rustc_infer:: infer:: TyCtxtInferExt ;
910use rustc_middle:: mir:: interpret:: Scalar ;
1011use rustc_middle:: mir:: traversal;
1112use rustc_middle:: mir:: visit:: { PlaceContext , Visitor } ;
1213use rustc_middle:: mir:: {
1314 AggregateKind , BasicBlock , Body , BorrowKind , Local , Location , MirPhase , Operand , PlaceRef ,
1415 Rvalue , 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 ) ]
@@ -77,79 +78,27 @@ pub fn equal_up_to_regions(
7778 return true ;
7879 }
7980
80- struct LifetimeIgnoreRelation < ' tcx > {
81- tcx : TyCtxt < ' tcx > ,
82- param_env : ty:: ParamEnv < ' tcx > ,
83- }
84-
85- impl TypeRelation < ' tcx > for LifetimeIgnoreRelation < ' tcx > {
86- fn tcx ( & self ) -> TyCtxt < ' tcx > {
87- self . tcx
88- }
89-
90- fn param_env ( & self ) -> ty:: ParamEnv < ' tcx > {
91- self . param_env
92- }
93-
94- fn tag ( & self ) -> & ' static str {
95- "librustc_mir::transform::validate"
96- }
97-
98- fn a_is_expected ( & self ) -> bool {
99- true
100- }
101-
102- fn relate_with_variance < T : Relate < ' tcx > > (
103- & mut self ,
104- _: ty:: Variance ,
105- a : T ,
106- b : T ,
107- ) -> RelateResult < ' tcx , T > {
108- // Ignore variance, require types to be exactly the same.
109- self . relate ( a, b)
110- }
111-
112- fn tys ( & mut self , a : Ty < ' tcx > , b : Ty < ' tcx > ) -> RelateResult < ' tcx , Ty < ' tcx > > {
113- if a == b {
114- // Short-circuit.
115- return Ok ( a) ;
116- }
117- ty:: relate:: super_relate_tys ( self , a, b)
118- }
119-
120- fn regions (
121- & mut self ,
122- a : ty:: Region < ' tcx > ,
123- _b : ty:: Region < ' tcx > ,
124- ) -> RelateResult < ' tcx , ty:: Region < ' tcx > > {
125- // Ignore regions.
126- Ok ( a)
127- }
128-
129- fn consts (
130- & mut self ,
131- a : & ' tcx ty:: Const < ' tcx > ,
132- b : & ' tcx ty:: Const < ' tcx > ,
133- ) -> RelateResult < ' tcx , & ' tcx ty:: Const < ' tcx > > {
134- ty:: relate:: super_relate_consts ( self , a, b)
135- }
136-
137- fn binders < T > (
138- & mut self ,
139- a : ty:: Binder < T > ,
140- b : ty:: Binder < T > ,
141- ) -> RelateResult < ' tcx , ty:: Binder < T > >
142- where
143- T : Relate < ' tcx > ,
144- {
145- self . relate ( a. skip_binder ( ) , b. skip_binder ( ) ) ?;
146- Ok ( a)
147- }
148- }
149-
150- // Instantiate and run relation.
151- let mut relator: LifetimeIgnoreRelation < ' tcx > = LifetimeIgnoreRelation { tcx : tcx, param_env } ;
152- relator. relate ( src, dest) . is_ok ( )
81+ // Normalize lifetimes away on both sides, then compare.
82+ let param_env = param_env. with_reveal_all_normalized ( tcx) ;
83+ let normalize = |ty : Ty < ' tcx > | {
84+ tcx. normalize_erasing_regions (
85+ param_env,
86+ ty. fold_with ( & mut BottomUpFolder {
87+ tcx,
88+ // FIXME: We erase all late-bound lifetimes, but this is not fully correct.
89+ // If you have a type like `<for<'a> fn(&'a u32) as SomeTrait>::Assoc`,
90+ // this is not necessarily equivalent to `<fn(&'static u32) as SomeTrait>::Assoc`,
91+ // since one may have an `impl SomeTrait for fn(&32)` and
92+ // `impl SomeTrait for fn(&'static u32)` at the same time which
93+ // specify distinct values for Assoc. (See also #56105)
94+ lt_op : |_| tcx. lifetimes . re_erased ,
95+ // Leave consts and types unchanged.
96+ ct_op : |ct| ct,
97+ ty_op : |ty| ty,
98+ } ) ,
99+ )
100+ } ;
101+ tcx. infer_ctxt ( ) . enter ( |infcx| infcx. can_eq ( param_env, normalize ( src) , normalize ( dest) ) . is_ok ( ) )
153102}
154103
155104struct TypeChecker < ' a , ' tcx > {
0 commit comments