@@ -425,80 +425,87 @@ fn check_trait(tcx: TyCtxt<'_>, item: &hir::Item<'_>) {
425425
426426 for_item ( tcx, item) . with_fcx ( |fcx, _| {
427427 check_where_clauses ( tcx, fcx, item. span , trait_def_id, None ) ;
428+ check_associated_type_defaults ( fcx, trait_def_id) ;
428429
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+ }
458433
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
462460 }
461+ } )
462+ . collect :: < FxHashMap < _ , _ > > ( ) ;
463463
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 )
472481 }
473- _ => t. super_fold_with ( self ) ,
474482 }
483+ _ => t. super_fold_with ( self ) ,
475484 }
476485 }
486+ }
477487
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) ;
495505
496- fcx. register_predicate ( obligation) ;
497- }
506+ fcx. register_predicate ( obligation) ;
498507 }
499-
500- vec ! [ ]
501- } ) ;
508+ }
502509}
503510
504511fn check_item_fn ( tcx : TyCtxt < ' _ > , item : & hir:: Item < ' _ > ) {
0 commit comments