@@ -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:: SubstsRef ;
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 ;
@@ -278,7 +278,7 @@ impl<'infcx, 'gcx, 'tcx> CombineFields<'infcx, 'gcx, 'tcx> {
278278 root_ty : ty,
279279 } ;
280280
281- let ty = match generalize . relate ( & ty , & ty ) {
281+ let ty = match ty . fold_with ( & mut generalize ) {
282282 Ok ( ty) => ty,
283283 Err ( e) => {
284284 debug ! ( "generalize: failure {:?}" , e) ;
@@ -351,60 +351,40 @@ struct Generalization<'tcx> {
351351 needs_wf : bool ,
352352}
353353
354- impl < ' cx , ' gcx , ' tcx > TypeRelation < ' cx , ' gcx , ' tcx > for Generalizer < ' cx , ' gcx , ' tcx > {
355- fn tcx ( & self ) -> TyCtxt < ' cx , ' gcx , ' tcx > {
356- self . infcx . tcx
357- }
358-
359- fn tag ( & self ) -> & ' static str {
360- "Generalizer"
361- }
354+ impl < ' cx , ' gcx , ' tcx > TypeFolder < ' gcx , ' tcx > for Generalizer < ' cx , ' gcx , ' tcx > {
355+ type Error = TypeError < ' tcx > ;
362356
363- fn a_is_expected ( & self ) -> bool {
364- true
365- }
366-
367- fn binders < T > ( & mut self , a : & ty:: Binder < T > , b : & ty:: Binder < T > )
368- -> RelateResult < ' tcx , ty:: Binder < T > >
369- where T : Relate < ' tcx >
370- {
371- Ok ( ty:: Binder :: bind ( self . relate ( a. skip_binder ( ) , b. skip_binder ( ) ) ?) )
357+ fn tcx ( & self ) -> TyCtxt < ' _ , ' gcx , ' tcx > {
358+ self . infcx . tcx
372359 }
373360
374- fn relate_item_substs ( & mut self ,
375- item_def_id : DefId ,
376- a_subst : SubstsRef < ' tcx > ,
377- b_subst : SubstsRef < ' tcx > )
378- -> RelateResult < ' tcx , SubstsRef < ' tcx > >
379- {
361+ fn use_variances ( & self ) -> bool {
380362 if self . ambient_variance == ty:: Variance :: Invariant {
381363 // Avoid fetching the variance if we are in an invariant
382364 // context; no need, and it can induce dependency cycles
383365 // (e.g., #41849).
384- relate :: relate_substs ( self , None , a_subst , b_subst )
366+ false
385367 } else {
386- let opt_variances = self . tcx ( ) . variances_of ( item_def_id) ;
387- relate:: relate_substs ( self , Some ( & opt_variances) , a_subst, b_subst)
368+ true
388369 }
389370 }
390371
391- fn relate_with_variance < T : Relate < ' tcx > > ( & mut self ,
392- variance : ty:: Variance ,
393- a : & T ,
394- b : & T )
395- -> RelateResult < ' tcx , T >
372+ fn fold_with_variance < T : TypeFoldable < ' tcx > > ( & mut self ,
373+ variance : ty:: Variance ,
374+ a : & T )
375+ -> RelateResult < ' tcx , T >
396376 {
397377 let old_ambient_variance = self . ambient_variance ;
378+ debug ! ( "Generalize: fold_with_variance({:?}, {:?}, old_variance={:?})" , variance, a, old_ambient_variance) ;
398379 self . ambient_variance = self . ambient_variance . xform ( variance) ;
399380
400- let result = self . relate ( a , b ) ;
381+ let result = a . fold_with ( self ) ;
401382 self . ambient_variance = old_ambient_variance;
402383 result
403384 }
404385
405- fn tys ( & mut self , t : Ty < ' tcx > , t2 : Ty < ' tcx > ) -> RelateResult < ' tcx , Ty < ' tcx > > {
406- assert_eq ! ( t, t2) ; // we are abusing TypeRelation here; both LHS and RHS ought to be ==
407-
386+ fn fold_ty ( & mut self , t : Ty < ' tcx > ) -> RelateResult < ' tcx , Ty < ' tcx > > {
387+ debug ! ( "Generalize: fold_ty({:?}, variance={:?})" , t, self . ambient_variance) ;
408388 debug ! ( "generalize: t={:?}" , t) ;
409389
410390 // Check to see whether the type we are genealizing references
@@ -425,7 +405,7 @@ impl<'cx, 'gcx, 'tcx> TypeRelation<'cx, 'gcx, 'tcx> for Generalizer<'cx, 'gcx, '
425405 TypeVariableValue :: Known { value : u } => {
426406 drop ( variables) ;
427407 debug ! ( "generalize: known value {:?}" , u) ;
428- self . relate ( & u , & u )
408+ u . fold_with ( self )
429409 }
430410 TypeVariableValue :: Unknown { universe } => {
431411 match self . ambient_variance {
@@ -449,7 +429,7 @@ impl<'cx, 'gcx, 'tcx> TypeRelation<'cx, 'gcx, 'tcx> for Generalizer<'cx, 'gcx, '
449429
450430 let origin = * variables. var_origin ( vid) ;
451431 let new_var_id = variables. new_var ( self . for_universe , false , origin) ;
452- let u = self . tcx ( ) . mk_var ( new_var_id) ;
432+ let u = self . infcx . tcx . mk_var ( new_var_id) ;
453433 debug ! ( "generalize: replacing original vid={:?} with new={:?}" ,
454434 vid, u) ;
455435 return Ok ( u) ;
@@ -459,21 +439,33 @@ impl<'cx, 'gcx, 'tcx> TypeRelation<'cx, 'gcx, 'tcx> for Generalizer<'cx, 'gcx, '
459439 }
460440 ty:: Infer ( ty:: IntVar ( _) ) |
461441 ty:: Infer ( ty:: FloatVar ( _) ) => {
462- // No matter what mode we are in,
463- // integer/floating-point types must be equal to be
464- // relatable.
465442 Ok ( t)
466443 }
444+ ty:: Array ( _, sz) => {
445+ // HACK, not sure how desirable this is: propagate errors from
446+ // array lengths to the array type itself. This makes error
447+ // messages a bit nicer, and used to be the case before because
448+ // we used `ty::relate` instead of `TypeFoldable`, so I'll keep
449+ // it here.
450+ //
451+ // This does not serve any functional purpose, but it does
452+ // avoid some "duplicate" errors.
453+ match self . infcx . tcx . force_eval_array_length ( * sz) {
454+ Ok ( _) => t. super_fold_with ( self ) ,
455+ Err ( ErrorReported ) => {
456+ Ok ( self . infcx . tcx . types . err )
457+ }
458+ }
459+ }
467460 _ => {
468- relate :: super_relate_tys ( self , t , t )
461+ t . super_fold_with ( self )
469462 }
470463 }
471464 }
472465
473- fn regions ( & mut self , r : ty :: Region < ' tcx > , r2 : ty:: Region < ' tcx > )
466+ fn fold_region ( & mut self , r : ty:: Region < ' tcx > )
474467 -> RelateResult < ' tcx , ty:: Region < ' tcx > > {
475- assert_eq ! ( r, r2) ; // we are abusing TypeRelation here; both LHS and RHS ought to be ==
476-
468+ debug ! ( "Generalize: fold_region({:?}, variance={:?})" , r, self . ambient_variance) ;
477469 debug ! ( "generalize: regions r={:?}" , r) ;
478470
479471 match * r {
0 commit comments