@@ -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:: Substs ;
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 ;
@@ -264,7 +264,7 @@ impl<'infcx, 'gcx, 'tcx> CombineFields<'infcx, 'gcx, 'tcx> {
264
264
root_ty : ty,
265
265
} ;
266
266
267
- let ty = match generalize . relate ( & ty , & ty ) {
267
+ let ty = match ty . fold_with ( & mut generalize ) {
268
268
Ok ( ty) => ty,
269
269
Err ( e) => {
270
270
debug ! ( "generalize: failure {:?}" , e) ;
@@ -332,60 +332,41 @@ struct Generalization<'tcx> {
332
332
needs_wf : bool ,
333
333
}
334
334
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 > ;
343
337
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
353
340
}
354
341
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 {
361
343
if self . ambient_variance == ty:: Variance :: Invariant {
362
344
// Avoid fetching the variance if we are in an invariant
363
345
// context; no need, and it can induce dependency cycles
364
346
// (e.g., #41849).
365
- relate :: relate_substs ( self , None , a_subst , b_subst )
347
+ false
366
348
} 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
369
350
}
370
351
}
371
352
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 >
377
357
{
378
358
let old_ambient_variance = self . ambient_variance ;
359
+ debug ! ( "Generalize: fold_with_variance({:?}, {:?}, old_variance={:?})" ,
360
+ variance, a, old_ambient_variance) ;
379
361
self . ambient_variance = self . ambient_variance . xform ( variance) ;
380
362
381
- let result = self . relate ( a , b ) ;
363
+ let result = a . fold_with ( self ) ;
382
364
self . ambient_variance = old_ambient_variance;
383
365
result
384
366
}
385
367
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
-
368
+ fn fold_ty ( & mut self , t : Ty < ' tcx > ) -> RelateResult < ' tcx , Ty < ' tcx > > {
369
+ debug ! ( "Generalize: fold_ty({:?}, variance={:?})" , t, self . ambient_variance) ;
389
370
// Check to see whether the type we are genealizing references
390
371
// any other type variable related to `vid` via
391
372
// subtyping. This is basically our "occurs check", preventing
@@ -403,7 +384,7 @@ impl<'cx, 'gcx, 'tcx> TypeRelation<'cx, 'gcx, 'tcx> for Generalizer<'cx, 'gcx, '
403
384
match variables. probe ( vid) {
404
385
TypeVariableValue :: Known { value : u } => {
405
386
drop ( variables) ;
406
- self . relate ( & u , & u )
387
+ u . fold_with ( self )
407
388
}
408
389
TypeVariableValue :: Unknown { universe } => {
409
390
match self . ambient_variance {
@@ -423,7 +404,7 @@ impl<'cx, 'gcx, 'tcx> TypeRelation<'cx, 'gcx, 'tcx> for Generalizer<'cx, 'gcx, '
423
404
424
405
let origin = * variables. var_origin ( vid) ;
425
406
let new_var_id = variables. new_var ( universe, false , origin) ;
426
- let u = self . tcx ( ) . mk_var ( new_var_id) ;
407
+ let u = self . infcx . tcx . mk_var ( new_var_id) ;
427
408
debug ! ( "generalize: replacing original vid={:?} with new={:?}" ,
428
409
vid, u) ;
429
410
return Ok ( u) ;
@@ -433,21 +414,33 @@ impl<'cx, 'gcx, 'tcx> TypeRelation<'cx, 'gcx, 'tcx> for Generalizer<'cx, 'gcx, '
433
414
}
434
415
ty:: Infer ( ty:: IntVar ( _) ) |
435
416
ty:: Infer ( ty:: FloatVar ( _) ) => {
436
- // No matter what mode we are in,
437
- // integer/floating-point types must be equal to be
438
- // relatable.
439
417
Ok ( t)
440
418
}
419
+ ty:: Array ( _, sz) => {
420
+ // HACK, not sure how desirable this is: propagate errors from
421
+ // array lengths to the array type itself. This makes error
422
+ // messages a bit nicer, and used to be the case before because
423
+ // we used `ty::relate` instead of `TypeFoldable`, so I'll keep
424
+ // it here.
425
+ //
426
+ // This does not serve any functional purpose, but it does
427
+ // avoid some "duplicate" errors.
428
+ match self . infcx . tcx . force_eval_array_length ( * sz) {
429
+ Ok ( _) => t. super_fold_with ( self ) ,
430
+ Err ( ErrorReported ) => {
431
+ Ok ( self . infcx . tcx . types . err )
432
+ }
433
+ }
434
+ }
441
435
_ => {
442
- relate :: super_relate_tys ( self , t , t )
436
+ t . super_fold_with ( self )
443
437
}
444
438
}
445
439
}
446
440
447
- fn regions ( & mut self , r : ty :: Region < ' tcx > , r2 : ty:: Region < ' tcx > )
441
+ fn fold_region ( & mut self , r : ty:: Region < ' tcx > )
448
442
-> RelateResult < ' tcx , ty:: Region < ' tcx > > {
449
- assert_eq ! ( r, r2) ; // we are abusing TypeRelation here; both LHS and RHS ought to be ==
450
-
443
+ debug ! ( "Generalize: fold_region({:?}, variance={:?})" , r, self . ambient_variance) ;
451
444
match * r {
452
445
// Never make variables for regions bound within the type itself,
453
446
// nor for erased regions.
0 commit comments