@@ -26,96 +26,6 @@ use tracing::{debug, instrument};
26
26
use super :: StructurallyRelateAliases ;
27
27
use super :: combine:: { CombineFields , PredicateEmittingRelation } ;
28
28
use crate :: infer:: { DefineOpaqueTypes , InferCtxt , SubregionOrigin } ;
29
- use crate :: traits:: ObligationCause ;
30
-
31
- /// Trait for returning data about a lattice, and for abstracting
32
- /// over the "direction" of the lattice operation (LUB/GLB).
33
- ///
34
- /// GLB moves "down" the lattice (to smaller values); LUB moves
35
- /// "up" the lattice (to bigger values).
36
- trait LatticeDir < ' f , ' tcx > : PredicateEmittingRelation < InferCtxt < ' tcx > > {
37
- fn infcx ( & self ) -> & ' f InferCtxt < ' tcx > ;
38
-
39
- fn cause ( & self ) -> & ObligationCause < ' tcx > ;
40
-
41
- fn define_opaque_types ( & self ) -> DefineOpaqueTypes ;
42
-
43
- // Relates the type `v` to `a` and `b` such that `v` represents
44
- // the LUB/GLB of `a` and `b` as appropriate.
45
- //
46
- // Subtle hack: ordering *may* be significant here. This method
47
- // relates `v` to `a` first, which may help us to avoid unnecessary
48
- // type variable obligations. See caller for details.
49
- fn relate_bound ( & mut self , v : Ty < ' tcx > , a : Ty < ' tcx > , b : Ty < ' tcx > ) -> RelateResult < ' tcx , ( ) > ;
50
- }
51
-
52
- /// Relates two types using a given lattice.
53
- #[ instrument( skip( this) , level = "debug" ) ]
54
- fn super_lattice_tys < ' a , ' tcx : ' a , L > (
55
- this : & mut L ,
56
- a : Ty < ' tcx > ,
57
- b : Ty < ' tcx > ,
58
- ) -> RelateResult < ' tcx , Ty < ' tcx > >
59
- where
60
- L : LatticeDir < ' a , ' tcx > ,
61
- {
62
- if a == b {
63
- return Ok ( a) ;
64
- }
65
-
66
- let infcx = this. infcx ( ) ;
67
-
68
- let a = infcx. shallow_resolve ( a) ;
69
- let b = infcx. shallow_resolve ( b) ;
70
-
71
- match ( a. kind ( ) , b. kind ( ) ) {
72
- // If one side is known to be a variable and one is not,
73
- // create a variable (`v`) to represent the LUB. Make sure to
74
- // relate `v` to the non-type-variable first (by passing it
75
- // first to `relate_bound`). Otherwise, we would produce a
76
- // subtype obligation that must then be processed.
77
- //
78
- // Example: if the LHS is a type variable, and RHS is
79
- // `Box<i32>`, then we current compare `v` to the RHS first,
80
- // which will instantiate `v` with `Box<i32>`. Then when `v`
81
- // is compared to the LHS, we instantiate LHS with `Box<i32>`.
82
- // But if we did in reverse order, we would create a `v <:
83
- // LHS` (or vice versa) constraint and then instantiate
84
- // `v`. This would require further processing to achieve same
85
- // end-result; in particular, this screws up some of the logic
86
- // in coercion, which expects LUB to figure out that the LHS
87
- // is (e.g.) `Box<i32>`. A more obvious solution might be to
88
- // iterate on the subtype obligations that are returned, but I
89
- // think this suffices. -nmatsakis
90
- ( & ty:: Infer ( TyVar ( ..) ) , _) => {
91
- let v = infcx. next_ty_var ( this. cause ( ) . span ) ;
92
- this. relate_bound ( v, b, a) ?;
93
- Ok ( v)
94
- }
95
- ( _, & ty:: Infer ( TyVar ( ..) ) ) => {
96
- let v = infcx. next_ty_var ( this. cause ( ) . span ) ;
97
- this. relate_bound ( v, a, b) ?;
98
- Ok ( v)
99
- }
100
-
101
- (
102
- & ty:: Alias ( ty:: Opaque , ty:: AliasTy { def_id : a_def_id, .. } ) ,
103
- & ty:: Alias ( ty:: Opaque , ty:: AliasTy { def_id : b_def_id, .. } ) ,
104
- ) if a_def_id == b_def_id => infcx. super_combine_tys ( this, a, b) ,
105
-
106
- ( & ty:: Alias ( ty:: Opaque , ty:: AliasTy { def_id, .. } ) , _)
107
- | ( _, & ty:: Alias ( ty:: Opaque , ty:: AliasTy { def_id, .. } ) )
108
- if this. define_opaque_types ( ) == DefineOpaqueTypes :: Yes
109
- && def_id. is_local ( )
110
- && !this. infcx ( ) . next_trait_solver ( ) =>
111
- {
112
- this. register_goals ( infcx. handle_opaque_type ( a, b, this. span ( ) , this. param_env ( ) ) ?) ;
113
- Ok ( a)
114
- }
115
-
116
- _ => infcx. super_combine_tys ( this, a, b) ,
117
- }
118
- }
119
29
120
30
#[ derive( Clone , Copy ) ]
121
31
pub ( crate ) enum LatticeOpKind {
@@ -173,9 +83,70 @@ impl<'tcx> TypeRelation<TyCtxt<'tcx>> for LatticeOp<'_, '_, 'tcx> {
173
83
}
174
84
}
175
85
86
+ /// Relates two types using a given lattice.
176
87
#[ instrument( skip( self ) , level = "trace" ) ]
177
88
fn tys ( & mut self , a : Ty < ' tcx > , b : Ty < ' tcx > ) -> RelateResult < ' tcx , Ty < ' tcx > > {
178
- super_lattice_tys ( self , a, b)
89
+ if a == b {
90
+ return Ok ( a) ;
91
+ }
92
+
93
+ let infcx = self . fields . infcx ;
94
+
95
+ let a = infcx. shallow_resolve ( a) ;
96
+ let b = infcx. shallow_resolve ( b) ;
97
+
98
+ match ( a. kind ( ) , b. kind ( ) ) {
99
+ // If one side is known to be a variable and one is not,
100
+ // create a variable (`v`) to represent the LUB. Make sure to
101
+ // relate `v` to the non-type-variable first (by passing it
102
+ // first to `relate_bound`). Otherwise, we would produce a
103
+ // subtype obligation that must then be processed.
104
+ //
105
+ // Example: if the LHS is a type variable, and RHS is
106
+ // `Box<i32>`, then we current compare `v` to the RHS first,
107
+ // which will instantiate `v` with `Box<i32>`. Then when `v`
108
+ // is compared to the LHS, we instantiate LHS with `Box<i32>`.
109
+ // But if we did in reverse order, we would create a `v <:
110
+ // LHS` (or vice versa) constraint and then instantiate
111
+ // `v`. This would require further processing to achieve same
112
+ // end-result; in particular, this screws up some of the logic
113
+ // in coercion, which expects LUB to figure out that the LHS
114
+ // is (e.g.) `Box<i32>`. A more obvious solution might be to
115
+ // iterate on the subtype obligations that are returned, but I
116
+ // think this suffices. -nmatsakis
117
+ ( & ty:: Infer ( TyVar ( ..) ) , _) => {
118
+ let v = infcx. next_ty_var ( self . fields . trace . cause . span ) ;
119
+ self . relate_bound ( v, b, a) ?;
120
+ Ok ( v)
121
+ }
122
+ ( _, & ty:: Infer ( TyVar ( ..) ) ) => {
123
+ let v = infcx. next_ty_var ( self . fields . trace . cause . span ) ;
124
+ self . relate_bound ( v, a, b) ?;
125
+ Ok ( v)
126
+ }
127
+
128
+ (
129
+ & ty:: Alias ( ty:: Opaque , ty:: AliasTy { def_id : a_def_id, .. } ) ,
130
+ & ty:: Alias ( ty:: Opaque , ty:: AliasTy { def_id : b_def_id, .. } ) ,
131
+ ) if a_def_id == b_def_id => infcx. super_combine_tys ( self , a, b) ,
132
+
133
+ ( & ty:: Alias ( ty:: Opaque , ty:: AliasTy { def_id, .. } ) , _)
134
+ | ( _, & ty:: Alias ( ty:: Opaque , ty:: AliasTy { def_id, .. } ) )
135
+ if self . fields . define_opaque_types == DefineOpaqueTypes :: Yes
136
+ && def_id. is_local ( )
137
+ && !infcx. next_trait_solver ( ) =>
138
+ {
139
+ self . register_goals ( infcx. handle_opaque_type (
140
+ a,
141
+ b,
142
+ self . span ( ) ,
143
+ self . param_env ( ) ,
144
+ ) ?) ;
145
+ Ok ( a)
146
+ }
147
+
148
+ _ => infcx. super_combine_tys ( self , a, b) ,
149
+ }
179
150
}
180
151
181
152
#[ instrument( skip( self ) , level = "trace" ) ]
@@ -231,15 +202,13 @@ impl<'tcx> TypeRelation<TyCtxt<'tcx>> for LatticeOp<'_, '_, 'tcx> {
231
202
}
232
203
}
233
204
234
- impl < ' combine , ' infcx , ' tcx > LatticeDir < ' infcx , ' tcx > for LatticeOp < ' combine , ' infcx , ' tcx > {
235
- fn infcx ( & self ) -> & ' infcx InferCtxt < ' tcx > {
236
- self . fields . infcx
237
- }
238
-
239
- fn cause ( & self ) -> & ObligationCause < ' tcx > {
240
- & self . fields . trace . cause
241
- }
242
-
205
+ impl < ' combine , ' infcx , ' tcx > LatticeOp < ' combine , ' infcx , ' tcx > {
206
+ // Relates the type `v` to `a` and `b` such that `v` represents
207
+ // the LUB/GLB of `a` and `b` as appropriate.
208
+ //
209
+ // Subtle hack: ordering *may* be significant here. This method
210
+ // relates `v` to `a` first, which may help us to avoid unnecessary
211
+ // type variable obligations. See caller for details.
243
212
fn relate_bound ( & mut self , v : Ty < ' tcx > , a : Ty < ' tcx > , b : Ty < ' tcx > ) -> RelateResult < ' tcx , ( ) > {
244
213
let mut sub = self . fields . sub ( ) ;
245
214
match self . kind {
@@ -254,10 +223,6 @@ impl<'combine, 'infcx, 'tcx> LatticeDir<'infcx, 'tcx> for LatticeOp<'combine, 'i
254
223
}
255
224
Ok ( ( ) )
256
225
}
257
-
258
- fn define_opaque_types ( & self ) -> DefineOpaqueTypes {
259
- self . fields . define_opaque_types
260
- }
261
226
}
262
227
263
228
impl < ' tcx > PredicateEmittingRelation < InferCtxt < ' tcx > > for LatticeOp < ' _ , ' _ , ' tcx > {
0 commit comments