@@ -29,13 +29,13 @@ use super::lub::Lub;
29
29
use super :: sub:: Sub ;
30
30
use super :: type_variable:: TypeVariableValue ;
31
31
32
- use crate :: hir:: def_id:: DefId ;
33
32
use crate :: ty:: { IntType , UintType } ;
34
33
use crate :: ty:: { self , Ty , TyCtxt } ;
34
+ use crate :: ty:: fold:: { TypeFoldable , TypeFolder } ;
35
35
use 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 } ;
38
37
use crate :: traits:: { Obligation , PredicateObligations } ;
38
+ use crate :: util:: common:: ErrorReported ;
39
39
40
40
use syntax:: ast;
41
41
use syntax_pos:: Span ;
@@ -278,7 +278,7 @@ impl<'infcx, 'gcx, 'tcx> CombineFields<'infcx, 'gcx, 'tcx> {
278
278
root_ty : ty,
279
279
} ;
280
280
281
- let ty = match generalize . relate ( & ty , & ty ) {
281
+ let ty = match ty . fold_with ( & mut generalize ) {
282
282
Ok ( ty) => ty,
283
283
Err ( e) => {
284
284
debug ! ( "generalize: failure {:?}" , e) ;
@@ -351,60 +351,41 @@ struct Generalization<'tcx> {
351
351
needs_wf : bool ,
352
352
}
353
353
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 > ;
362
356
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
372
359
}
373
360
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 {
380
362
if self . ambient_variance == ty:: Variance :: Invariant {
381
363
// Avoid fetching the variance if we are in an invariant
382
364
// context; no need, and it can induce dependency cycles
383
365
// (e.g., #41849).
384
- relate :: relate_substs ( self , None , a_subst , b_subst )
366
+ false
385
367
} 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
388
369
}
389
370
}
390
371
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 >
396
376
{
397
377
let old_ambient_variance = self . ambient_variance ;
378
+ debug ! ( "Generalize: fold_with_variance({:?}, {:?}, old_variance={:?})" ,
379
+ variance, a, old_ambient_variance) ;
398
380
self . ambient_variance = self . ambient_variance . xform ( variance) ;
399
381
400
- let result = self . relate ( a , b ) ;
382
+ let result = a . fold_with ( self ) ;
401
383
self . ambient_variance = old_ambient_variance;
402
384
result
403
385
}
404
386
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) ;
408
389
debug ! ( "generalize: t={:?}" , t) ;
409
390
410
391
// 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, '
425
406
TypeVariableValue :: Known { value : u } => {
426
407
drop ( variables) ;
427
408
debug ! ( "generalize: known value {:?}" , u) ;
428
- self . relate ( & u , & u )
409
+ u . fold_with ( self )
429
410
}
430
411
TypeVariableValue :: Unknown { universe } => {
431
412
match self . ambient_variance {
@@ -449,7 +430,7 @@ impl<'cx, 'gcx, 'tcx> TypeRelation<'cx, 'gcx, 'tcx> for Generalizer<'cx, 'gcx, '
449
430
450
431
let origin = * variables. var_origin ( vid) ;
451
432
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) ;
453
434
debug ! ( "generalize: replacing original vid={:?} with new={:?}" ,
454
435
vid, u) ;
455
436
return Ok ( u) ;
@@ -459,21 +440,33 @@ impl<'cx, 'gcx, 'tcx> TypeRelation<'cx, 'gcx, 'tcx> for Generalizer<'cx, 'gcx, '
459
440
}
460
441
ty:: Infer ( ty:: IntVar ( _) ) |
461
442
ty:: Infer ( ty:: FloatVar ( _) ) => {
462
- // No matter what mode we are in,
463
- // integer/floating-point types must be equal to be
464
- // relatable.
465
443
Ok ( t)
466
444
}
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
+ }
467
461
_ => {
468
- relate :: super_relate_tys ( self , t , t )
462
+ t . super_fold_with ( self )
469
463
}
470
464
}
471
465
}
472
466
473
- fn regions ( & mut self , r : ty :: Region < ' tcx > , r2 : ty:: Region < ' tcx > )
467
+ fn fold_region ( & mut self , r : ty:: Region < ' tcx > )
474
468
-> 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) ;
477
470
debug ! ( "generalize: regions r={:?}" , r) ;
478
471
479
472
match * r {
0 commit comments