@@ -4,12 +4,41 @@ use rustc_middle::infer::unify_key::{ConstVarValue, ConstVariableValue};
44use rustc_middle:: ty:: error:: TypeError ;
55use rustc_middle:: ty:: relate:: { self , Relate , RelateResult , TypeRelation } ;
66use rustc_middle:: ty:: { self , InferConst , Ty , TyCtxt , TypeVisitableExt } ;
7+ use rustc_span:: Span ;
78
8- use crate :: infer:: combine:: CombineFields ;
99use crate :: infer:: nll_relate:: TypeRelatingDelegate ;
1010use crate :: infer:: type_variable:: TypeVariableValue ;
1111use crate :: infer:: { InferCtxt , RegionVariableOrigin } ;
1212
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.
1342pub trait GeneralizerDelegate < ' tcx > {
1443 fn param_env ( & self ) -> ty:: ParamEnv < ' tcx > ;
1544
@@ -18,7 +47,13 @@ pub trait GeneralizerDelegate<'tcx> {
1847 fn generalize_existential ( & mut self , universe : ty:: UniverseIndex ) -> ty:: Region < ' tcx > ;
1948}
2049
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 > {
2257 fn param_env ( & self ) -> ty:: ParamEnv < ' tcx > {
2358 self . param_env
2459 }
@@ -28,10 +63,8 @@ impl<'tcx> GeneralizerDelegate<'tcx> for CombineFields<'_, 'tcx> {
2863 }
2964
3065 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)
3568 }
3669}
3770
6699/// establishes `'0: 'x` as a constraint.
67100///
68101/// [blog post]: https://is.gd/0hKvIr
69- pub ( super ) struct Generalizer < ' me , ' tcx , D >
102+ struct Generalizer < ' me , ' tcx , D >
70103where
71104 D : GeneralizerDelegate < ' tcx > ,
72105{
@@ -98,18 +131,6 @@ where
98131 needs_wf : bool ,
99132}
100133
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-
113134impl < ' tcx , D > TypeRelation < ' tcx > for Generalizer < ' _ , ' tcx , D >
114135where
115136 D : GeneralizerDelegate < ' tcx > ,
@@ -202,17 +223,19 @@ where
202223 }
203224
204225 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) ;
207229 if sub_vid == self . for_vid_sub_root {
208230 // If sub-roots are equal, then `for_vid` and
209231 // `vid` are related via subtyping.
210232 Err ( TypeError :: CyclicTy ( self . root_ty ) )
211233 } else {
212- let probe = self . infcx . inner . borrow_mut ( ) . type_variables ( ) . probe ( vid) ;
234+ let probe = inner. type_variables ( ) . probe ( vid) ;
213235 match probe {
214236 TypeVariableValue :: Known { value : u } => {
215237 debug ! ( "generalize: known value {:?}" , u) ;
238+ drop ( inner) ;
216239 self . relate ( u, u)
217240 }
218241 TypeVariableValue :: Unknown { universe } => {
@@ -235,20 +258,15 @@ where
235258 ty:: Covariant | ty:: Contravariant => ( ) ,
236259 }
237260
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) ;
246264 let u = self . tcx ( ) . mk_ty_var ( new_var_id) ;
247265
248266 // Record that we replaced `vid` with `new_var_id` as part of a generalization
249267 // operation. This is needed to detect cyclic types. To see why, see the
250268 // 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) ;
252270 debug ! ( "generalize: replacing original vid={:?} with new={:?}" , vid, u) ;
253271 Ok ( u)
254272 }
@@ -278,7 +296,7 @@ where
278296
279297 ty:: Alias ( ty:: Opaque , ty:: AliasTy { def_id, substs, .. } ) => {
280298 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) } )
282300 }
283301 _ => relate:: super_relate_tys ( self , t, t) ,
284302 } ?;
0 commit comments