@@ -185,10 +185,7 @@ impl<'a, 'gcx> CheckTypeWellFormedVisitor<'a, 'gcx> {
185185 reject_shadowing_type_parameters ( fcx. tcx , item. def_id ) ;
186186 let sig = fcx. tcx . fn_sig ( item. def_id ) ;
187187 let sig = fcx. normalize_associated_types_in ( span, & sig) ;
188- let predicates = fcx. tcx . predicates_of ( item. def_id )
189- . instantiate_identity ( fcx. tcx ) ;
190- let predicates = fcx. normalize_associated_types_in ( span, & predicates) ;
191- this. check_fn_or_method ( fcx, span, sig, & predicates,
188+ this. check_fn_or_method ( fcx, span, sig,
192189 item. def_id , & mut implied_bounds) ;
193190 let sig_if_method = sig_if_method. expect ( "bad signature for method" ) ;
194191 this. check_method_receiver ( fcx, sig_if_method, & item, self_ty) ;
@@ -272,20 +269,16 @@ impl<'a, 'gcx> CheckTypeWellFormedVisitor<'a, 'gcx> {
272269 }
273270 }
274271
275- let predicates = fcx. tcx . predicates_of ( def_id) . instantiate_identity ( fcx. tcx ) ;
276- let predicates = fcx. normalize_associated_types_in ( item. span , & predicates) ;
277- this. check_where_clauses ( fcx, item. span , & predicates) ;
272+ self . check_where_clauses ( fcx, item. span , def_id) ;
278273
279274 vec ! [ ] // no implied bounds in a struct def'n
280275 } ) ;
281276 }
282277
283278 fn check_trait ( & mut self , item : & hir:: Item ) {
284279 let trait_def_id = self . tcx . hir . local_def_id ( item. id ) ;
285- self . for_item ( item) . with_fcx ( |fcx, this| {
286- let predicates = fcx. tcx . predicates_of ( trait_def_id) . instantiate_identity ( fcx. tcx ) ;
287- let predicates = fcx. normalize_associated_types_in ( item. span , & predicates) ;
288- this. check_where_clauses ( fcx, item. span , & predicates) ;
280+ self . for_item ( item) . with_fcx ( |fcx, _| {
281+ self . check_where_clauses ( fcx, item. span , trait_def_id) ;
289282 vec ! [ ]
290283 } ) ;
291284 }
@@ -295,12 +288,8 @@ impl<'a, 'gcx> CheckTypeWellFormedVisitor<'a, 'gcx> {
295288 let def_id = fcx. tcx . hir . local_def_id ( item. id ) ;
296289 let sig = fcx. tcx . fn_sig ( def_id) ;
297290 let sig = fcx. normalize_associated_types_in ( item. span , & sig) ;
298-
299- let predicates = fcx. tcx . predicates_of ( def_id) . instantiate_identity ( fcx. tcx ) ;
300- let predicates = fcx. normalize_associated_types_in ( item. span , & predicates) ;
301-
302291 let mut implied_bounds = vec ! [ ] ;
303- this. check_fn_or_method ( fcx, item. span , sig, & predicates ,
292+ this. check_fn_or_method ( fcx, item. span , sig,
304293 def_id, & mut implied_bounds) ;
305294 implied_bounds
306295 } )
@@ -354,19 +343,96 @@ impl<'a, 'gcx> CheckTypeWellFormedVisitor<'a, 'gcx> {
354343 }
355344 }
356345
357- let predicates = fcx. tcx . predicates_of ( item_def_id) . instantiate_identity ( fcx. tcx ) ;
358- let predicates = fcx. normalize_associated_types_in ( item. span , & predicates) ;
359- this. check_where_clauses ( fcx, item. span , & predicates) ;
346+ this. check_where_clauses ( fcx, item. span , item_def_id) ;
360347
361348 fcx. impl_implied_bounds ( item_def_id, item. span )
362349 } ) ;
363350 }
364351
352+ /// Checks where clauses and inline bounds that are declared on def_id.
365353 fn check_where_clauses < ' fcx , ' tcx > ( & mut self ,
366354 fcx : & FnCtxt < ' fcx , ' gcx , ' tcx > ,
367355 span : Span ,
368- predicates : & ty:: InstantiatedPredicates < ' tcx > )
369- {
356+ def_id : DefId ) {
357+ use ty:: subst:: Subst ;
358+ use rustc:: ty:: TypeFoldable ;
359+
360+ let mut predicates = fcx. tcx . predicates_of ( def_id) ;
361+ let mut substituted_predicates = Vec :: new ( ) ;
362+
363+ let generics = self . tcx . generics_of ( def_id) ;
364+ let is_our_default = |def : & ty:: TypeParameterDef |
365+ def. has_default && def. index >= generics. parent_count ( ) as u32 ;
366+
367+ // Check that concrete defaults are well-formed. See test `type-check-defaults.rs`.
368+ // For example this forbids the declaration:
369+ // struct Foo<T = Vec<[u32]>> { .. }
370+ // Here the default `Vec<[u32]>` is not WF because `[u32]: Sized` does not hold.
371+ for d in generics. types . iter ( ) . cloned ( ) . filter ( is_our_default) . map ( |p| p. def_id ) {
372+ let ty = fcx. tcx . type_of ( d) ;
373+ // ignore dependent defaults -- that is, where the default of one type
374+ // parameter includes another (e.g., <T, U = T>). In those cases, we can't
375+ // be sure if it will error or not as user might always specify the other.
376+ if !ty. needs_subst ( ) {
377+ fcx. register_wf_obligation ( ty, fcx. tcx . def_span ( d) , self . code . clone ( ) ) ;
378+ }
379+ }
380+
381+ // Check that trait predicates are WF when params are substituted by their defaults.
382+ // We don't want to overly constrain the predicates that may be written but we want to
383+ // catch cases where a default my never be applied such as `struct Foo<T: Copy = String>`.
384+ // Therefore we check if a predicate which contains a single type param
385+ // with a concrete default is WF with that default substituted.
386+ // For more examples see tests `defaults-well-formedness.rs` and `type-check-defaults.rs`.
387+ //
388+ // First we build the defaulted substitution.
389+ let substs = ty:: subst:: Substs :: for_item ( fcx. tcx , def_id, |def, _| {
390+ // All regions are identity.
391+ fcx. tcx . mk_region ( ty:: ReEarlyBound ( def. to_early_bound_region_data ( ) ) )
392+ } , |def, _| {
393+ // If the param has a default,
394+ if is_our_default ( def) {
395+ let default_ty = fcx. tcx . type_of ( def. def_id ) ;
396+ // and it's not a dependent default
397+ if !default_ty. needs_subst ( ) {
398+ // then substitute with the default.
399+ return default_ty;
400+ }
401+ }
402+ // Mark unwanted params as err.
403+ fcx. tcx . types . err
404+ } ) ;
405+ // Now we build the substituted predicates.
406+ for & pred in predicates. predicates . iter ( ) {
407+ struct CountParams { params : FxHashSet < u32 > }
408+ impl < ' tcx > ty:: fold:: TypeVisitor < ' tcx > for CountParams {
409+ fn visit_ty ( & mut self , t : Ty < ' tcx > ) -> bool {
410+ match t. sty {
411+ ty:: TyParam ( p) => {
412+ self . params . insert ( p. idx ) ;
413+ t. super_visit_with ( self )
414+ }
415+ _ => t. super_visit_with ( self )
416+ }
417+ }
418+ }
419+ let mut param_count = CountParams { params : FxHashSet ( ) } ;
420+ pred. visit_with ( & mut param_count) ;
421+ let substituted_pred = pred. subst ( fcx. tcx , substs) ;
422+ // Don't check non-defaulted params, dependent defaults or preds with multiple params.
423+ if substituted_pred. references_error ( ) || param_count. params . len ( ) > 1 {
424+ continue ;
425+ }
426+ // Avoid duplication of predicates that contain no parameters, for example.
427+ if !predicates. predicates . contains ( & substituted_pred) {
428+ substituted_predicates. push ( substituted_pred) ;
429+ }
430+ }
431+
432+ predicates. predicates . extend ( substituted_predicates) ;
433+ let predicates = predicates. instantiate_identity ( fcx. tcx ) ;
434+ let predicates = fcx. normalize_associated_types_in ( span, & predicates) ;
435+
370436 let obligations =
371437 predicates. predicates
372438 . iter ( )
@@ -385,7 +451,6 @@ impl<'a, 'gcx> CheckTypeWellFormedVisitor<'a, 'gcx> {
385451 fcx : & FnCtxt < ' fcx , ' gcx , ' tcx > ,
386452 span : Span ,
387453 sig : ty:: PolyFnSig < ' tcx > ,
388- predicates : & ty:: InstantiatedPredicates < ' tcx > ,
389454 def_id : DefId ,
390455 implied_bounds : & mut Vec < Ty < ' tcx > > )
391456 {
@@ -402,7 +467,7 @@ impl<'a, 'gcx> CheckTypeWellFormedVisitor<'a, 'gcx> {
402467 // FIXME(#25759) return types should not be implied bounds
403468 implied_bounds. push ( sig. output ( ) ) ;
404469
405- self . check_where_clauses ( fcx, span, predicates ) ;
470+ self . check_where_clauses ( fcx, span, def_id ) ;
406471 }
407472
408473 fn check_method_receiver < ' fcx , ' tcx > ( & mut self ,
0 commit comments