@@ -4,12 +4,41 @@ use rustc_middle::infer::unify_key::{ConstVarValue, ConstVariableValue};
4
4
use rustc_middle:: ty:: error:: TypeError ;
5
5
use rustc_middle:: ty:: relate:: { self , Relate , RelateResult , TypeRelation } ;
6
6
use rustc_middle:: ty:: { self , InferConst , Ty , TyCtxt , TypeVisitableExt } ;
7
+ use rustc_span:: Span ;
7
8
8
- use crate :: infer:: combine:: CombineFields ;
9
9
use crate :: infer:: nll_relate:: TypeRelatingDelegate ;
10
10
use crate :: infer:: type_variable:: TypeVariableValue ;
11
11
use crate :: infer:: { InferCtxt , RegionVariableOrigin } ;
12
12
13
+ pub ( super ) fn generalize < ' tcx , D : GeneralizerDelegate < ' tcx > > (
14
+ infcx : & InferCtxt < ' tcx > ,
15
+ delegate : & mut D ,
16
+ ty : Ty < ' tcx > ,
17
+ for_vid : ty:: TyVid ,
18
+ ambient_variance : ty:: Variance ,
19
+ ) -> RelateResult < ' tcx , Generalization < Ty < ' tcx > > > {
20
+ let for_universe = infcx. probe_ty_var ( for_vid) . unwrap_err ( ) ;
21
+ let for_vid_sub_root = infcx. inner . borrow_mut ( ) . type_variables ( ) . sub_root_var ( for_vid) ;
22
+
23
+ let mut generalizer = Generalizer {
24
+ infcx,
25
+ delegate,
26
+ ambient_variance,
27
+ for_vid_sub_root,
28
+ for_universe,
29
+ root_ty : ty,
30
+ needs_wf : false ,
31
+ cache : Default :: default ( ) ,
32
+ } ;
33
+
34
+ assert ! ( !ty. has_escaping_bound_vars( ) ) ;
35
+ let value = generalizer. relate ( ty, ty) ?;
36
+ let needs_wf = generalizer. needs_wf ;
37
+ Ok ( Generalization { value, needs_wf } )
38
+ }
39
+
40
+ /// Abstracts the handling of region vars between HIR and MIR/NLL typechecking
41
+ /// in the generalizer code.
13
42
pub trait GeneralizerDelegate < ' tcx > {
14
43
fn param_env ( & self ) -> ty:: ParamEnv < ' tcx > ;
15
44
@@ -18,7 +47,13 @@ pub trait GeneralizerDelegate<'tcx> {
18
47
fn generalize_existential ( & mut self , universe : ty:: UniverseIndex ) -> ty:: Region < ' tcx > ;
19
48
}
20
49
21
- impl < ' tcx > GeneralizerDelegate < ' tcx > for CombineFields < ' _ , ' tcx > {
50
+ pub struct CombineDelegate < ' cx , ' tcx > {
51
+ pub infcx : & ' cx InferCtxt < ' tcx > ,
52
+ pub param_env : ty:: ParamEnv < ' tcx > ,
53
+ pub span : Span ,
54
+ }
55
+
56
+ impl < ' tcx > GeneralizerDelegate < ' tcx > for CombineDelegate < ' _ , ' tcx > {
22
57
fn param_env ( & self ) -> ty:: ParamEnv < ' tcx > {
23
58
self . param_env
24
59
}
@@ -28,10 +63,8 @@ impl<'tcx> GeneralizerDelegate<'tcx> for CombineFields<'_, 'tcx> {
28
63
}
29
64
30
65
fn generalize_existential ( & mut self , universe : ty:: UniverseIndex ) -> ty:: Region < ' tcx > {
31
- self . infcx . next_region_var_in_universe (
32
- RegionVariableOrigin :: MiscVariable ( self . trace . span ( ) ) ,
33
- universe,
34
- )
66
+ self . infcx
67
+ . next_region_var_in_universe ( RegionVariableOrigin :: MiscVariable ( self . span ) , universe)
35
68
}
36
69
}
37
70
66
99
/// establishes `'0: 'x` as a constraint.
67
100
///
68
101
/// [blog post]: https://is.gd/0hKvIr
69
- pub ( super ) struct Generalizer < ' me , ' tcx , D >
102
+ struct Generalizer < ' me , ' tcx , D >
70
103
where
71
104
D : GeneralizerDelegate < ' tcx > ,
72
105
{
@@ -98,18 +131,6 @@ where
98
131
needs_wf : bool ,
99
132
}
100
133
101
- impl < ' tcx , D : GeneralizerDelegate < ' tcx > > Generalizer < ' _ , ' tcx , D > {
102
- pub fn generalize < T > ( mut self , value : T ) -> RelateResult < ' tcx , Generalization < T > >
103
- where
104
- T : Relate < ' tcx > ,
105
- {
106
- assert ! ( !value. has_escaping_bound_vars( ) ) ;
107
- let value = self . relate ( value, value) ?;
108
- let needs_wf = self . needs_wf ;
109
- Ok ( Generalization { value, needs_wf } )
110
- }
111
- }
112
-
113
134
impl < ' tcx , D > TypeRelation < ' tcx > for Generalizer < ' _ , ' tcx , D >
114
135
where
115
136
D : GeneralizerDelegate < ' tcx > ,
@@ -202,17 +223,19 @@ where
202
223
}
203
224
204
225
ty:: Infer ( ty:: TyVar ( vid) ) => {
205
- let vid = self . infcx . inner . borrow_mut ( ) . type_variables ( ) . root_var ( vid) ;
206
- let sub_vid = self . infcx . inner . borrow_mut ( ) . type_variables ( ) . sub_root_var ( vid) ;
226
+ let mut inner = self . infcx . inner . borrow_mut ( ) ;
227
+ let vid = inner. type_variables ( ) . root_var ( vid) ;
228
+ let sub_vid = inner. type_variables ( ) . sub_root_var ( vid) ;
207
229
if sub_vid == self . for_vid_sub_root {
208
230
// If sub-roots are equal, then `for_vid` and
209
231
// `vid` are related via subtyping.
210
232
Err ( TypeError :: CyclicTy ( self . root_ty ) )
211
233
} else {
212
- let probe = self . infcx . inner . borrow_mut ( ) . type_variables ( ) . probe ( vid) ;
234
+ let probe = inner. type_variables ( ) . probe ( vid) ;
213
235
match probe {
214
236
TypeVariableValue :: Known { value : u } => {
215
237
debug ! ( "generalize: known value {:?}" , u) ;
238
+ drop ( inner) ;
216
239
self . relate ( u, u)
217
240
}
218
241
TypeVariableValue :: Unknown { universe } => {
@@ -235,20 +258,15 @@ where
235
258
ty:: Covariant | ty:: Contravariant => ( ) ,
236
259
}
237
260
238
- let origin =
239
- * self . infcx . inner . borrow_mut ( ) . type_variables ( ) . var_origin ( vid) ;
240
- let new_var_id = self
241
- . infcx
242
- . inner
243
- . borrow_mut ( )
244
- . type_variables ( )
245
- . new_var ( self . for_universe , origin) ;
261
+ let origin = * inner. type_variables ( ) . var_origin ( vid) ;
262
+ let new_var_id =
263
+ inner. type_variables ( ) . new_var ( self . for_universe , origin) ;
246
264
let u = self . tcx ( ) . mk_ty_var ( new_var_id) ;
247
265
248
266
// Record that we replaced `vid` with `new_var_id` as part of a generalization
249
267
// operation. This is needed to detect cyclic types. To see why, see the
250
268
// docs in the `type_variables` module.
251
- self . infcx . inner . borrow_mut ( ) . type_variables ( ) . sub ( vid, new_var_id) ;
269
+ inner. type_variables ( ) . sub ( vid, new_var_id) ;
252
270
debug ! ( "generalize: replacing original vid={:?} with new={:?}" , vid, u) ;
253
271
Ok ( u)
254
272
}
@@ -278,7 +296,7 @@ where
278
296
279
297
ty:: Alias ( ty:: Opaque , ty:: AliasTy { def_id, substs, .. } ) => {
280
298
let s = self . relate ( substs, substs) ?;
281
- Ok ( if s == substs { t } else { self . infcx . tcx . mk_opaque ( def_id, s) } )
299
+ Ok ( if s == substs { t } else { self . tcx ( ) . mk_opaque ( def_id, s) } )
282
300
}
283
301
_ => relate:: super_relate_tys ( self , t, t) ,
284
302
} ?;
0 commit comments