@@ -29,13 +29,13 @@ use super::lub::Lub;
2929use super :: sub:: Sub ;
3030use super :: type_variable:: TypeVariableValue ;
3131
32- use crate :: hir:: def_id:: DefId ;
3332use crate :: ty:: { IntType , UintType } ;
3433use crate :: ty:: { self , Ty , TyCtxt } ;
34+ use crate :: ty:: fold:: { TypeFoldable , TypeFolder } ;
3535use crate :: ty:: error:: TypeError ;
36- use crate :: ty:: relate:: { self , Relate , RelateResult , TypeRelation } ;
37- use crate :: ty:: subst:: Substs ;
36+ use crate :: ty:: relate:: { RelateResult , TypeRelation } ;
3837use crate :: traits:: { Obligation , PredicateObligations } ;
38+ use crate :: util:: common:: ErrorReported ;
3939
4040use syntax:: ast;
4141use syntax_pos:: Span ;
@@ -264,7 +264,7 @@ impl<'infcx, 'gcx, 'tcx> CombineFields<'infcx, 'gcx, 'tcx> {
264264 root_ty : ty,
265265 } ;
266266
267- let ty = match generalize . relate ( & ty , & ty ) {
267+ let ty = match ty . fold_with ( & mut generalize ) {
268268 Ok ( ty) => ty,
269269 Err ( e) => {
270270 debug ! ( "generalize: failure {:?}" , e) ;
@@ -332,60 +332,40 @@ struct Generalization<'tcx> {
332332 needs_wf : bool ,
333333}
334334
335- impl < ' cx , ' gcx , ' tcx > TypeRelation < ' cx , ' gcx , ' tcx > for Generalizer < ' cx , ' gcx , ' tcx > {
336- fn tcx ( & self ) -> TyCtxt < ' cx , ' gcx , ' tcx > {
337- self . infcx . tcx
338- }
339-
340- fn tag ( & self ) -> & ' static str {
341- "Generalizer"
342- }
335+ impl < ' cx , ' gcx , ' tcx > TypeFolder < ' gcx , ' tcx > for Generalizer < ' cx , ' gcx , ' tcx > {
336+ type Error = TypeError < ' tcx > ;
343337
344- fn a_is_expected ( & self ) -> bool {
345- true
346- }
347-
348- fn binders < T > ( & mut self , a : & ty:: Binder < T > , b : & ty:: Binder < T > )
349- -> RelateResult < ' tcx , ty:: Binder < T > >
350- where T : Relate < ' tcx >
351- {
352- Ok ( ty:: Binder :: bind ( self . relate ( a. skip_binder ( ) , b. skip_binder ( ) ) ?) )
338+ fn tcx ( & self ) -> TyCtxt < ' _ , ' gcx , ' tcx > {
339+ self . infcx . tcx
353340 }
354341
355- fn relate_item_substs ( & mut self ,
356- item_def_id : DefId ,
357- a_subst : & ' tcx Substs < ' tcx > ,
358- b_subst : & ' tcx Substs < ' tcx > )
359- -> RelateResult < ' tcx , & ' tcx Substs < ' tcx > >
360- {
342+ fn use_variances ( & self ) -> bool {
361343 if self . ambient_variance == ty:: Variance :: Invariant {
362344 // Avoid fetching the variance if we are in an invariant
363345 // context; no need, and it can induce dependency cycles
364346 // (e.g., #41849).
365- relate :: relate_substs ( self , None , a_subst , b_subst )
347+ false
366348 } else {
367- let opt_variances = self . tcx ( ) . variances_of ( item_def_id) ;
368- relate:: relate_substs ( self , Some ( & opt_variances) , a_subst, b_subst)
349+ true
369350 }
370351 }
371352
372- fn relate_with_variance < T : Relate < ' tcx > > ( & mut self ,
373- variance : ty:: Variance ,
374- a : & T ,
375- b : & T )
376- -> RelateResult < ' tcx , T >
353+ fn fold_with_variance < T : TypeFoldable < ' tcx > > ( & mut self ,
354+ variance : ty:: Variance ,
355+ a : & T )
356+ -> RelateResult < ' tcx , T >
377357 {
378358 let old_ambient_variance = self . ambient_variance ;
359+ debug ! ( "Generalize: fold_with_variance({:?}, {:?}, old_variance={:?})" , variance, a, old_ambient_variance) ;
379360 self . ambient_variance = self . ambient_variance . xform ( variance) ;
380361
381- let result = self . relate ( a , b ) ;
362+ let result = a . fold_with ( self ) ;
382363 self . ambient_variance = old_ambient_variance;
383364 result
384365 }
385366
386- fn tys ( & mut self , t : Ty < ' tcx > , t2 : Ty < ' tcx > ) -> RelateResult < ' tcx , Ty < ' tcx > > {
387- assert_eq ! ( t, t2) ; // we are abusing TypeRelation here; both LHS and RHS ought to be ==
388-
367+ fn fold_ty ( & mut self , t : Ty < ' tcx > ) -> RelateResult < ' tcx , Ty < ' tcx > > {
368+ debug ! ( "Generalize: fold_ty({:?}, variance={:?})" , t, self . ambient_variance) ;
389369 // Check to see whether the type we are genealizing references
390370 // any other type variable related to `vid` via
391371 // subtyping. This is basically our "occurs check", preventing
@@ -403,7 +383,7 @@ impl<'cx, 'gcx, 'tcx> TypeRelation<'cx, 'gcx, 'tcx> for Generalizer<'cx, 'gcx, '
403383 match variables. probe ( vid) {
404384 TypeVariableValue :: Known { value : u } => {
405385 drop ( variables) ;
406- self . relate ( & u , & u )
386+ u . fold_with ( self )
407387 }
408388 TypeVariableValue :: Unknown { universe } => {
409389 match self . ambient_variance {
@@ -423,7 +403,7 @@ impl<'cx, 'gcx, 'tcx> TypeRelation<'cx, 'gcx, 'tcx> for Generalizer<'cx, 'gcx, '
423403
424404 let origin = * variables. var_origin ( vid) ;
425405 let new_var_id = variables. new_var ( universe, false , origin) ;
426- let u = self . tcx ( ) . mk_var ( new_var_id) ;
406+ let u = self . infcx . tcx . mk_var ( new_var_id) ;
427407 debug ! ( "generalize: replacing original vid={:?} with new={:?}" ,
428408 vid, u) ;
429409 return Ok ( u) ;
@@ -433,21 +413,33 @@ impl<'cx, 'gcx, 'tcx> TypeRelation<'cx, 'gcx, 'tcx> for Generalizer<'cx, 'gcx, '
433413 }
434414 ty:: Infer ( ty:: IntVar ( _) ) |
435415 ty:: Infer ( ty:: FloatVar ( _) ) => {
436- // No matter what mode we are in,
437- // integer/floating-point types must be equal to be
438- // relatable.
439416 Ok ( t)
440417 }
418+ ty:: Array ( _, sz) => {
419+ // HACK, not sure how desirable this is: propagate errors from
420+ // array lengths to the array type itself. This makes error
421+ // messages a bit nicer, and used to be the case before because
422+ // we used `ty::relate` instead of `TypeFoldable`, so I'll keep
423+ // it here.
424+ //
425+ // This does not serve any functional purpose, but it does
426+ // avoid some "duplicate" errors.
427+ match self . infcx . tcx . force_eval_array_length ( * sz) {
428+ Ok ( _) => t. super_fold_with ( self ) ,
429+ Err ( ErrorReported ) => {
430+ Ok ( self . infcx . tcx . types . err )
431+ }
432+ }
433+ }
441434 _ => {
442- relate :: super_relate_tys ( self , t , t )
435+ t . super_fold_with ( self )
443436 }
444437 }
445438 }
446439
447- fn regions ( & mut self , r : ty :: Region < ' tcx > , r2 : ty:: Region < ' tcx > )
440+ fn fold_region ( & mut self , r : ty:: Region < ' tcx > )
448441 -> RelateResult < ' tcx , ty:: Region < ' tcx > > {
449- assert_eq ! ( r, r2) ; // we are abusing TypeRelation here; both LHS and RHS ought to be ==
450-
442+ debug ! ( "Generalize: fold_region({:?}, variance={:?})" , r, self . ambient_variance) ;
451443 match * r {
452444 // Never make variables for regions bound within the type itself,
453445 // nor for erased regions.
0 commit comments