@@ -5,13 +5,14 @@ use crate::dataflow::{Analysis, ResultsCursor};
5
5
use crate :: util:: storage:: AlwaysLiveLocals ;
6
6
7
7
use super :: { MirPass , MirSource } ;
8
+ use rustc_infer:: infer:: TyCtxtInferExt ;
8
9
use rustc_middle:: mir:: visit:: { PlaceContext , Visitor } ;
9
10
use rustc_middle:: mir:: {
10
11
AggregateKind , BasicBlock , Body , BorrowKind , Local , Location , MirPhase , Operand , Rvalue ,
11
12
Statement , StatementKind , Terminator , TerminatorKind , VarDebugInfo ,
12
13
} ;
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 } ;
15
16
16
17
#[ derive( Copy , Clone , Debug ) ]
17
18
enum EdgeKind {
@@ -64,79 +65,24 @@ pub fn equal_up_to_regions(
64
65
return true ;
65
66
}
66
67
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 ( ) )
140
86
}
141
87
142
88
struct TypeChecker < ' a , ' tcx > {
0 commit comments