@@ -47,7 +47,6 @@ use ty::relate::{RelateResult, TypeRelation};
4747use traits:: PredicateObligations ;
4848
4949use syntax:: ast;
50- use syntax:: util:: small_vector:: SmallVector ;
5150use syntax_pos:: Span ;
5251
5352#[ derive( Clone ) ]
@@ -174,6 +173,15 @@ impl<'infcx, 'gcx, 'tcx> CombineFields<'infcx, 'gcx, 'tcx> {
174173 Glb :: new ( self , a_is_expected)
175174 }
176175
176+ /// Here dir is either EqTo, SubtypeOf, or SupertypeOf. The
177+ /// idea is that we should ensure that the type `a_ty` is equal
178+ /// to, a subtype of, or a supertype of (respectively) the type
179+ /// to which `b_vid` is bound.
180+ ///
181+ /// Since `b_vid` has not yet been instantiated with a type, we
182+ /// will first instantiate `b_vid` with a *generalized* version
183+ /// of `a_ty`. Generalization introduces other inference
184+ /// variables wherever subtyping could occur.
177185 pub fn instantiate ( & mut self ,
178186 a_ty : Ty < ' tcx > ,
179187 dir : RelationDir ,
@@ -183,109 +191,64 @@ impl<'infcx, 'gcx, 'tcx> CombineFields<'infcx, 'gcx, 'tcx> {
183191 {
184192 use self :: RelationDir :: * ;
185193
186- // We use SmallVector here instead of Vec because this code is hot and
187- // it's rare that the stack length exceeds 1.
188- let mut stack = SmallVector :: new ( ) ;
189- stack. push ( ( a_ty, dir, b_vid) ) ;
190- loop {
191- // For each turn of the loop, we extract a tuple
192- //
193- // (a_ty, dir, b_vid)
194- //
195- // to relate. Here dir is either SubtypeOf or
196- // SupertypeOf. The idea is that we should ensure that
197- // the type `a_ty` is a subtype or supertype (respectively) of the
198- // type to which `b_vid` is bound.
199- //
200- // If `b_vid` has not yet been instantiated with a type
201- // (which is always true on the first iteration, but not
202- // necessarily true on later iterations), we will first
203- // instantiate `b_vid` with a *generalized* version of
204- // `a_ty`. Generalization introduces other inference
205- // variables wherever subtyping could occur (at time of
206- // this writing, this means replacing free regions with
207- // region variables).
208- let ( a_ty, dir, b_vid) = match stack. pop ( ) {
209- None => break ,
210- Some ( e) => e,
211- } ;
212- // Get the actual variable that b_vid has been inferred to
213- let ( b_vid, b_ty) = {
214- let mut variables = self . infcx . type_variables . borrow_mut ( ) ;
215- let b_vid = variables. root_var ( b_vid) ;
216- ( b_vid, variables. probe_root ( b_vid) )
217- } ;
218-
219- debug ! ( "instantiate(a_ty={:?} dir={:?} b_vid={:?})" ,
220- a_ty,
221- dir,
222- b_vid) ;
223-
224- // Check whether `vid` has been instantiated yet. If not,
225- // make a generalized form of `ty` and instantiate with
226- // that.
227- //
228- // FIXME(#18653) -- we need to generalize nested type
229- // variables too.
230- let b_ty = match b_ty {
231- Some ( t) => t, // ...already instantiated.
232- None => { // ...not yet instantiated:
233- // Generalize type if necessary.
234- let generalized_ty = match dir {
235- EqTo => self . generalize ( a_ty, b_vid, false ) ,
236- SupertypeOf | SubtypeOf => self . generalize ( a_ty, b_vid, true ) ,
237- } ?;
238- debug ! ( "instantiate(a_ty={:?}, dir={:?}, \
239- b_vid={:?}, generalized_ty={:?})",
240- a_ty, dir, b_vid,
241- generalized_ty) ;
242- self . infcx . type_variables
243- . borrow_mut ( )
244- . instantiate ( b_vid, generalized_ty) ;
245- generalized_ty
246- }
247- } ;
248-
249- // The original triple was `(a_ty, dir, b_vid)` -- now we have
250- // resolved `b_vid` to `b_ty`, so apply `(a_ty, dir, b_ty)`:
251- //
252- // FIXME(#16847): This code is non-ideal because all these subtype
253- // relations wind up attributed to the same spans. We need
254- // to associate causes/spans with each of the relations in
255- // the stack to get this right.
256- match dir {
257- EqTo => self . equate ( a_is_expected) . relate ( & a_ty, & b_ty) ,
258- SubtypeOf => self . sub ( a_is_expected) . relate ( & a_ty, & b_ty) ,
259- SupertypeOf => self . sub ( a_is_expected) . relate_with_variance (
260- ty:: Contravariant , & a_ty, & b_ty) ,
261- } ?;
262- }
194+ // Get the actual variable that b_vid has been inferred to
195+ debug_assert ! ( self . infcx. type_variables. borrow_mut( ) . probe( b_vid) . is_none( ) ) ;
196+
197+ debug ! ( "instantiate(a_ty={:?} dir={:?} b_vid={:?})" , a_ty, dir, b_vid) ;
198+
199+ // Generalize type of `a_ty` appropriately depending on the
200+ // direction. As an example, assume:
201+ //
202+ // - `a_ty == &'x ?1`, where `'x` is some free region and `?1` is an
203+ // inference variable,
204+ // - and `dir` == `SubtypeOf`.
205+ //
206+ // Then the generalized form `b_ty` would be `&'?2 ?3`, where
207+ // `'?2` and `?3` are fresh region/type inference
208+ // variables. (Down below, we will relate `a_ty <: b_ty`,
209+ // adding constraints like `'x: '?2` and `?1 <: ?3`.)
210+ let b_ty = self . generalize ( a_ty, b_vid, dir == EqTo ) ?;
211+ debug ! ( "instantiate(a_ty={:?}, dir={:?}, b_vid={:?}, generalized b_ty={:?})" ,
212+ a_ty, dir, b_vid, b_ty) ;
213+ self . infcx . type_variables . borrow_mut ( ) . instantiate ( b_vid, b_ty) ;
214+
215+ // Finally, relate `b_ty` to `a_ty`, as described in previous comment.
216+ //
217+ // FIXME(#16847): This code is non-ideal because all these subtype
218+ // relations wind up attributed to the same spans. We need
219+ // to associate causes/spans with each of the relations in
220+ // the stack to get this right.
221+ match dir {
222+ EqTo => self . equate ( a_is_expected) . relate ( & a_ty, & b_ty) ,
223+ SubtypeOf => self . sub ( a_is_expected) . relate ( & a_ty, & b_ty) ,
224+ SupertypeOf => self . sub ( a_is_expected) . relate_with_variance (
225+ ty:: Contravariant , & a_ty, & b_ty) ,
226+ } ?;
263227
264228 Ok ( ( ) )
265229 }
266230
267231 /// Attempts to generalize `ty` for the type variable `for_vid`.
268232 /// This checks for cycle -- that is, whether the type `ty`
269- /// references `for_vid`. If `make_region_vars` is true, it will
270- /// also replace all regions with fresh variables. Returns
271- /// `TyError` in the case of a cycle, `Ok` otherwise.
233+ /// references `for_vid`. If `is_eq_relation` is false, it will
234+ /// also replace all regions/unbound-type-variables with fresh
235+ /// variables. Returns `TyError` in the case of a cycle, `Ok`
236+ /// otherwise.
272237 ///
273238 /// Preconditions:
274239 ///
275240 /// - `for_vid` is a "root vid"
276241 fn generalize ( & self ,
277242 ty : Ty < ' tcx > ,
278243 for_vid : ty:: TyVid ,
279- make_region_vars : bool )
244+ is_eq_relation : bool )
280245 -> RelateResult < ' tcx , Ty < ' tcx > >
281246 {
282- debug_assert ! ( self . infcx. type_variables. borrow_mut( ) . root_var( for_vid) == for_vid) ;
283-
284247 let mut generalize = Generalizer {
285248 infcx : self . infcx ,
286249 span : self . trace . cause . span ,
287250 for_vid_sub_root : self . infcx . type_variables . borrow_mut ( ) . sub_root_var ( for_vid) ,
288- make_region_vars : make_region_vars ,
251+ is_eq_relation : is_eq_relation ,
289252 cycle_detected : false
290253 } ;
291254 let u = ty. fold_with ( & mut generalize) ;
@@ -301,7 +264,7 @@ struct Generalizer<'cx, 'gcx: 'cx+'tcx, 'tcx: 'cx> {
301264 infcx : & ' cx InferCtxt < ' cx , ' gcx , ' tcx > ,
302265 span : Span ,
303266 for_vid_sub_root : ty:: TyVid ,
304- make_region_vars : bool ,
267+ is_eq_relation : bool ,
305268 cycle_detected : bool ,
306269}
307270
@@ -332,7 +295,7 @@ impl<'cx, 'gcx, 'tcx> ty::fold::TypeFolder<'gcx, 'tcx> for Generalizer<'cx, 'gcx
332295 self . fold_ty ( u)
333296 }
334297 None => {
335- if self . make_region_vars {
298+ if ! self . is_eq_relation {
336299 let origin = variables. origin ( vid) ;
337300 let new_var_id = variables. new_var ( false , origin, None ) ;
338301 let u = self . tcx ( ) . mk_var ( new_var_id) ;
@@ -379,7 +342,7 @@ impl<'cx, 'gcx, 'tcx> ty::fold::TypeFolder<'gcx, 'tcx> for Generalizer<'cx, 'gcx
379342 ty:: ReScope ( ..) |
380343 ty:: ReVar ( ..) |
381344 ty:: ReFree ( ..) => {
382- if ! self . make_region_vars {
345+ if self . is_eq_relation {
383346 return r;
384347 }
385348 }
0 commit comments