@@ -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,41 @@ 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={:?})" ,
379+ variance, a, old_ambient_variance) ;
398380 self . ambient_variance = self . ambient_variance . xform ( variance) ;
399381
400- let result = self . relate ( a , b ) ;
382+ let result = a . fold_with ( self ) ;
401383 self . ambient_variance = old_ambient_variance;
402384 result
403385 }
404386
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-
387+ fn fold_ty ( & mut self , t : Ty < ' tcx > ) -> RelateResult < ' tcx , Ty < ' tcx > > {
388+ debug ! ( "Generalize: fold_ty({:?}, variance={:?})" , t, self . ambient_variance) ;
408389 debug ! ( "generalize: t={:?}" , t) ;
409390
410391 // Check to see whether the type we are genealizing references
@@ -425,7 +406,7 @@ impl<'cx, 'gcx, 'tcx> TypeRelation<'cx, 'gcx, 'tcx> for Generalizer<'cx, 'gcx, '
425406 TypeVariableValue :: Known { value : u } => {
426407 drop ( variables) ;
427408 debug ! ( "generalize: known value {:?}" , u) ;
428- self . relate ( & u , & u )
409+ u . fold_with ( self )
429410 }
430411 TypeVariableValue :: Unknown { universe } => {
431412 match self . ambient_variance {
@@ -449,7 +430,7 @@ impl<'cx, 'gcx, 'tcx> TypeRelation<'cx, 'gcx, 'tcx> for Generalizer<'cx, 'gcx, '
449430
450431 let origin = * variables. var_origin ( vid) ;
451432 let new_var_id = variables. new_var ( self . for_universe , false , origin) ;
452- let u = self . tcx ( ) . mk_var ( new_var_id) ;
433+ let u = self . infcx . tcx . mk_var ( new_var_id) ;
453434 debug ! ( "generalize: replacing original vid={:?} with new={:?}" ,
454435 vid, u) ;
455436 return Ok ( u) ;
@@ -459,21 +440,33 @@ impl<'cx, 'gcx, 'tcx> TypeRelation<'cx, 'gcx, 'tcx> for Generalizer<'cx, 'gcx, '
459440 }
460441 ty:: Infer ( ty:: IntVar ( _) ) |
461442 ty:: Infer ( ty:: FloatVar ( _) ) => {
462- // No matter what mode we are in,
463- // integer/floating-point types must be equal to be
464- // relatable.
465443 Ok ( t)
466444 }
445+ ty:: Array ( _, sz) => {
446+ // HACK, not sure how desirable this is: propagate errors from
447+ // array lengths to the array type itself. This makes error
448+ // messages a bit nicer, and used to be the case before because
449+ // we used `ty::relate` instead of `TypeFoldable`, so I'll keep
450+ // it here.
451+ //
452+ // This does not serve any functional purpose, but it does
453+ // avoid some "duplicate" errors.
454+ match self . infcx . tcx . force_eval_array_length ( * sz) {
455+ Ok ( _) => t. super_fold_with ( self ) ,
456+ Err ( ErrorReported ) => {
457+ Ok ( self . infcx . tcx . types . err )
458+ }
459+ }
460+ }
467461 _ => {
468- relate :: super_relate_tys ( self , t , t )
462+ t . super_fold_with ( self )
469463 }
470464 }
471465 }
472466
473- fn regions ( & mut self , r : ty :: Region < ' tcx > , r2 : ty:: Region < ' tcx > )
467+ fn fold_region ( & mut self , r : ty:: Region < ' tcx > )
474468 -> RelateResult < ' tcx , ty:: Region < ' tcx > > {
475- assert_eq ! ( r, r2) ; // we are abusing TypeRelation here; both LHS and RHS ought to be ==
476-
469+ debug ! ( "Generalize: fold_region({:?}, variance={:?})" , r, self . ambient_variance) ;
477470 debug ! ( "generalize: regions r={:?}" , r) ;
478471
479472 match * r {
0 commit comments