@@ -435,58 +435,56 @@ impl<'a, 'gcx> CheckTypeWellFormedVisitor<'a, 'gcx> {
435435 use ty:: subst:: Subst ;
436436 use rustc:: ty:: TypeFoldable ;
437437
438+ let mut predicates = fcx. tcx . predicates_of ( def_id) ;
439+ let mut substituted_predicates = Vec :: new ( ) ;
440+
438441 let generics = self . tcx . generics_of ( def_id) ;
439442 let defaulted_params = generics. types . iter ( )
440443 . filter ( |def| def. has_default &&
441444 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 ;
444448 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
475478 }
476- _ => ( )
477479 }
478- default_ty
480+ } ) ;
481+ if !skip {
482+ substituted_predicates. push ( pred. subst ( fcx. tcx , substs) ) ;
479483 }
480- } ) ;
481-
482- if skip || no_default {
483- continue ;
484484 }
485-
486- default_predicates. push ( pred. subst ( fcx. tcx , substs) ) ;
487485 }
488486
489- predicates. predicates . extend ( default_predicates ) ;
487+ predicates. predicates . extend ( substituted_predicates ) ;
490488 let predicates = predicates. instantiate_identity ( fcx. tcx ) ;
491489 let predicates = fcx. normalize_associated_types_in ( span, & predicates) ;
492490
0 commit comments