@@ -435,58 +435,56 @@ impl<'a, 'gcx> CheckTypeWellFormedVisitor<'a, 'gcx> {
435
435
use ty:: subst:: Subst ;
436
436
use rustc:: ty:: TypeFoldable ;
437
437
438
+ let mut predicates = fcx. tcx . predicates_of ( def_id) ;
439
+ let mut substituted_predicates = Vec :: new ( ) ;
440
+
438
441
let generics = self . tcx . generics_of ( def_id) ;
439
442
let defaulted_params = generics. types . iter ( )
440
443
. filter ( |def| def. has_default &&
441
444
def. index >= generics. parent_count ( ) as u32 ) ;
442
- // Defaults must be well-formed.
443
- for d in defaulted_params. map ( |p| p. def_id ) {
445
+ for param_def in defaulted_params {
446
+ // Defaults must be well-formed.
447
+ let d = param_def. def_id ;
444
448
fcx. register_wf_obligation ( fcx. tcx . type_of ( d) , fcx. tcx . def_span ( d) , self . code . clone ( ) ) ;
445
- }
446
- // Check that each default fulfills the bounds on it's parameter.
447
- // We go over each predicate and duplicate it, substituting defaults in the self type.
448
- let mut predicates = fcx. tcx . predicates_of ( def_id) ;
449
- let mut default_predicates = Vec :: new ( ) ;
450
- // In `trait Trait : Super` predicates as `Self: Trait` and `Self: Super` are a problem.
451
- // Therefore we skip such predicates. This means we check less than we could.
452
- for pred in predicates. predicates . iter ( ) . filter ( |p| !( is_trait && p. has_self_ty ( ) ) ) {
453
- let mut skip = false ;
454
- let mut no_default = true ;
455
- let substs = ty:: subst:: Substs :: for_item ( fcx. tcx , def_id, |def, _| {
456
- // All regions are identity.
457
- fcx. tcx . mk_region ( ty:: ReEarlyBound ( def. to_early_bound_region_data ( ) ) )
458
- } , |def, _| {
459
- // No default or generic comes from parent, identity substitution.
460
- if !def. has_default || ( def. index as usize ) < generics. parent_count ( ) {
461
- fcx. tcx . mk_param_from_def ( def)
462
- } else {
463
- no_default = false ;
464
- // Has a default, use it in the substitution.
465
- let default_ty = fcx. tcx . type_of ( def. def_id ) ;
466
-
467
- match default_ty. sty {
468
- // Skip `Self: Sized` when `Self` is the default. Needed in traits.
469
- ty:: TyParam ( ref p) if is_trait && p. is_self ( ) => {
470
- if let ty:: Predicate :: Trait ( p) = pred {
471
- if Some ( p. def_id ( ) ) == fcx. tcx . lang_items ( ) . sized_trait ( ) {
472
- skip = true ;
473
- }
474
- }
449
+ // Check the clauses are well-formed when the param is substituted by it's default.
450
+ // In trait definitions, predicates as `Self: Trait` and `Self: Super` are problematic.
451
+ // Therefore we skip such predicates. This means we check less than we could.
452
+ for pred in predicates. predicates . iter ( ) . filter ( |p| !( is_trait && p. has_self_ty ( ) ) ) {
453
+ let mut skip = true ;
454
+ let substs = ty:: subst:: Substs :: for_item ( fcx. tcx , def_id, |def, _| {
455
+ // All regions are identity.
456
+ fcx. tcx . mk_region ( ty:: ReEarlyBound ( def. to_early_bound_region_data ( ) ) )
457
+ } , |def, _| {
458
+ let identity_substs = fcx. tcx . mk_param_from_def ( def) ;
459
+ if def. index != param_def. index {
460
+ identity_substs
461
+ } else {
462
+ let sized = fcx. tcx . lang_items ( ) . sized_trait ( ) ;
463
+ let pred_is_sized = match pred {
464
+ ty:: Predicate :: Trait ( p) => Some ( p. def_id ( ) ) == sized,
465
+ _ => false ,
466
+ } ;
467
+ let default_ty = fcx. tcx . type_of ( def. def_id ) ;
468
+ let default_is_self = match default_ty. sty {
469
+ ty:: TyParam ( ref p) => p. is_self ( ) ,
470
+ _ => false
471
+ } ;
472
+ // In trait defs, skip `Self: Sized` when `Self` is the default.
473
+ if is_trait && pred_is_sized && default_is_self {
474
+ identity_substs
475
+ } else {
476
+ skip = false ;
477
+ default_ty
475
478
}
476
- _ => ( )
477
479
}
478
- default_ty
480
+ } ) ;
481
+ if !skip {
482
+ substituted_predicates. push ( pred. subst ( fcx. tcx , substs) ) ;
479
483
}
480
- } ) ;
481
-
482
- if skip || no_default {
483
- continue ;
484
484
}
485
-
486
- default_predicates. push ( pred. subst ( fcx. tcx , substs) ) ;
487
485
}
488
486
489
- predicates. predicates . extend ( default_predicates ) ;
487
+ predicates. predicates . extend ( substituted_predicates ) ;
490
488
let predicates = predicates. instantiate_identity ( fcx. tcx ) ;
491
489
let predicates = fcx. normalize_associated_types_in ( span, & predicates) ;
492
490
0 commit comments