@@ -425,80 +425,87 @@ fn check_trait(tcx: TyCtxt<'_>, item: &hir::Item<'_>) {
425
425
426
426
for_item ( tcx, item) . with_fcx ( |fcx, _| {
427
427
check_where_clauses ( tcx, fcx, item. span , trait_def_id, None ) ;
428
+ check_associated_type_defaults ( fcx, trait_def_id) ;
428
429
429
- // Type-check associated type defaults (if there are any):
430
- // Assuming the defaults are used, check that all predicates (bounds on
431
- // the assoc type and where clauses on the trait) hold.
432
-
433
- let substs = InternalSubsts :: identity_for_item ( tcx, trait_def_id) ;
434
-
435
- // For all assoc. types with defaults, build a map from
436
- // `<Self as Trait<...>>::Assoc` to the default type.
437
- let map = tcx. associated_items ( trait_def_id)
438
- . filter_map ( |item| {
439
- if item. kind == ty:: AssocKind :: Type && item. defaultness . has_value ( ) {
440
- // `<Self as Trait<...>>::Assoc`
441
- let proj = ty:: ProjectionTy {
442
- substs,
443
- item_def_id : item. def_id ,
444
- } ;
445
- let default_ty = tcx. type_of ( item. def_id ) ;
446
- debug ! ( "assoc. type default mapping: {} -> {}" , proj, default_ty) ;
447
- Some ( ( proj, default_ty) )
448
- } else {
449
- None
450
- }
451
- } )
452
- . collect :: < FxHashMap < _ , _ > > ( ) ;
453
-
454
- struct DefaultNormalizer < ' tcx > {
455
- tcx : TyCtxt < ' tcx > ,
456
- map : FxHashMap < ty:: ProjectionTy < ' tcx > , Ty < ' tcx > > ,
457
- }
430
+ vec ! [ ]
431
+ } ) ;
432
+ }
458
433
459
- impl < ' tcx > ty:: fold:: TypeFolder < ' tcx > for DefaultNormalizer < ' tcx > {
460
- fn tcx < ' a > ( & ' a self ) -> TyCtxt < ' tcx > {
461
- self . tcx
434
+ /// Checks all associated type defaults of trait `trait_def_id`.
435
+ ///
436
+ /// Assuming the defaults are used, check that all predicates (bounds on the
437
+ /// assoc type and where clauses on the trait) hold.
438
+ fn check_associated_type_defaults (
439
+ fcx : & FnCtxt < ' _ , ' _ > ,
440
+ trait_def_id : DefId ,
441
+ ) {
442
+ let tcx = fcx. tcx ;
443
+ let substs = InternalSubsts :: identity_for_item ( tcx, trait_def_id) ;
444
+
445
+ // For all assoc. types with defaults, build a map from
446
+ // `<Self as Trait<...>>::Assoc` to the default type.
447
+ let map = tcx. associated_items ( trait_def_id)
448
+ . filter_map ( |item| {
449
+ if item. kind == ty:: AssocKind :: Type && item. defaultness . has_value ( ) {
450
+ // `<Self as Trait<...>>::Assoc`
451
+ let proj = ty:: ProjectionTy {
452
+ substs,
453
+ item_def_id : item. def_id ,
454
+ } ;
455
+ let default_ty = tcx. type_of ( item. def_id ) ;
456
+ debug ! ( "assoc. type default mapping: {} -> {}" , proj, default_ty) ;
457
+ Some ( ( proj, default_ty) )
458
+ } else {
459
+ None
462
460
}
461
+ } )
462
+ . collect :: < FxHashMap < _ , _ > > ( ) ;
463
463
464
- fn fold_ty ( & mut self , t : Ty < ' tcx > ) -> Ty < ' tcx > {
465
- match t. sty {
466
- ty:: Projection ( proj_ty) => {
467
- if let Some ( default) = self . map . get ( & proj_ty) {
468
- default
469
- } else {
470
- t. super_fold_with ( self )
471
- }
464
+ struct DefaultNormalizer < ' tcx > {
465
+ tcx : TyCtxt < ' tcx > ,
466
+ map : FxHashMap < ty:: ProjectionTy < ' tcx > , Ty < ' tcx > > ,
467
+ }
468
+
469
+ impl < ' tcx > ty:: fold:: TypeFolder < ' tcx > for DefaultNormalizer < ' tcx > {
470
+ fn tcx < ' a > ( & ' a self ) -> TyCtxt < ' tcx > {
471
+ self . tcx
472
+ }
473
+
474
+ fn fold_ty ( & mut self , t : Ty < ' tcx > ) -> Ty < ' tcx > {
475
+ match t. sty {
476
+ ty:: Projection ( proj_ty) => {
477
+ if let Some ( default) = self . map . get ( & proj_ty) {
478
+ default
479
+ } else {
480
+ t. super_fold_with ( self )
472
481
}
473
- _ => t. super_fold_with ( self ) ,
474
482
}
483
+ _ => t. super_fold_with ( self ) ,
475
484
}
476
485
}
486
+ }
477
487
478
- // Now take all predicates defined on the trait, replace any mention of
479
- // the assoc. types with their default, and prove them.
480
- // We only consider predicates that directly mention the assoc. type.
481
- let mut norm = DefaultNormalizer { tcx, map } ;
482
- let predicates = fcx. tcx . predicates_of ( trait_def_id) ;
483
- for & ( orig_pred, span) in predicates. predicates . iter ( ) {
484
- let pred = orig_pred. fold_with ( & mut norm) ;
485
- if pred != orig_pred {
486
- // Mentions one of the defaulted assoc. types
487
- debug ! ( "default suitability check: proving predicate: {} -> {}" , orig_pred, pred) ;
488
- let pred = fcx. normalize_associated_types_in ( span, & pred) ;
489
- let cause = traits:: ObligationCause :: new (
490
- span,
491
- fcx. body_id ,
492
- traits:: ItemObligation ( trait_def_id) ,
493
- ) ;
494
- let obligation = traits:: Obligation :: new ( cause, fcx. param_env , pred) ;
488
+ // Now take all predicates defined on the trait, replace any mention of
489
+ // the assoc. types with their default, and prove them.
490
+ // We only consider predicates that directly mention the assoc. type.
491
+ let mut norm = DefaultNormalizer { tcx, map } ;
492
+ let predicates = fcx. tcx . predicates_of ( trait_def_id) ;
493
+ for & ( orig_pred, span) in predicates. predicates . iter ( ) {
494
+ let pred = orig_pred. fold_with ( & mut norm) ;
495
+ if pred != orig_pred {
496
+ // Mentions one of the defaulted assoc. types
497
+ debug ! ( "default suitability check: proving predicate: {} -> {}" , orig_pred, pred) ;
498
+ let pred = fcx. normalize_associated_types_in ( span, & pred) ;
499
+ let cause = traits:: ObligationCause :: new (
500
+ span,
501
+ fcx. body_id ,
502
+ traits:: ItemObligation ( trait_def_id) ,
503
+ ) ;
504
+ let obligation = traits:: Obligation :: new ( cause, fcx. param_env , pred) ;
495
505
496
- fcx. register_predicate ( obligation) ;
497
- }
506
+ fcx. register_predicate ( obligation) ;
498
507
}
499
-
500
- vec ! [ ]
501
- } ) ;
508
+ }
502
509
}
503
510
504
511
fn check_item_fn ( tcx : TyCtxt < ' _ > , item : & hir:: Item < ' _ > ) {
0 commit comments