@@ -185,10 +185,7 @@ impl<'a, 'gcx> CheckTypeWellFormedVisitor<'a, 'gcx> {
185
185
reject_shadowing_type_parameters ( fcx. tcx , item. def_id ) ;
186
186
let sig = fcx. tcx . fn_sig ( item. def_id ) ;
187
187
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,
192
189
item. def_id , & mut implied_bounds) ;
193
190
let sig_if_method = sig_if_method. expect ( "bad signature for method" ) ;
194
191
this. check_method_receiver ( fcx, sig_if_method, & item, self_ty) ;
@@ -272,20 +269,17 @@ impl<'a, 'gcx> CheckTypeWellFormedVisitor<'a, 'gcx> {
272
269
}
273
270
}
274
271
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) ;
278
273
279
274
vec ! [ ] // no implied bounds in a struct def'n
280
275
} ) ;
281
276
}
282
277
283
278
fn check_trait ( & mut self , item : & hir:: Item ) {
284
279
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
+
281
+ self . for_item ( item) . with_fcx ( |fcx, _| {
282
+ self . check_where_clauses ( fcx, item. span , trait_def_id) ;
289
283
vec ! [ ]
290
284
} ) ;
291
285
}
@@ -295,12 +289,8 @@ impl<'a, 'gcx> CheckTypeWellFormedVisitor<'a, 'gcx> {
295
289
let def_id = fcx. tcx . hir . local_def_id ( item. id ) ;
296
290
let sig = fcx. tcx . fn_sig ( def_id) ;
297
291
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
-
302
292
let mut implied_bounds = vec ! [ ] ;
303
- this. check_fn_or_method ( fcx, item. span , sig, & predicates ,
293
+ this. check_fn_or_method ( fcx, item. span , sig,
304
294
def_id, & mut implied_bounds) ;
305
295
implied_bounds
306
296
} )
@@ -354,19 +344,132 @@ impl<'a, 'gcx> CheckTypeWellFormedVisitor<'a, 'gcx> {
354
344
}
355
345
}
356
346
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) ;
347
+ this. check_where_clauses ( fcx, item. span , item_def_id) ;
360
348
361
349
fcx. impl_implied_bounds ( item_def_id, item. span )
362
350
} ) ;
363
351
}
364
352
353
+ /// Checks where clauses and inline bounds.
365
354
fn check_where_clauses < ' fcx , ' tcx > ( & mut self ,
366
355
fcx : & FnCtxt < ' fcx , ' gcx , ' tcx > ,
367
356
span : Span ,
368
- predicates : & ty :: InstantiatedPredicates < ' tcx > )
357
+ def_id : DefId )
369
358
{
359
+ use ty:: subst:: Subst ;
360
+ use ty:: Predicate ;
361
+
362
+ // Check that each default fulfills the bounds on it's parameter.
363
+ // We go over each predicate and duplicate it, substituting defaults in the self type.
364
+ let mut predicates = fcx. tcx . predicates_of ( def_id) ;
365
+ let mut default_predicates = Vec :: new ( ) ;
366
+ for pred in & predicates. predicates {
367
+ let mut self_ty = match pred {
368
+ Predicate :: Trait ( trait_pred) => trait_pred. skip_binder ( ) . self_ty ( ) ,
369
+ Predicate :: TypeOutlives ( outlives_pred) => ( outlives_pred. 0 ) . 0 ,
370
+ Predicate :: Projection ( proj_pred) => {
371
+ fcx. tcx . mk_ty ( ty:: TyProjection ( proj_pred. skip_binder ( ) . projection_ty ) )
372
+ }
373
+ // Lifetime params can't have defaults.
374
+ Predicate :: RegionOutlives ( ..) => continue ,
375
+ _ => bug ! ( "Predicate {:?} not supported in where clauses." , pred)
376
+ } ;
377
+
378
+ let mut skip = false ;
379
+ let mut no_default = true ;
380
+ let generics = self . tcx . generics_of ( def_id) ;
381
+ let substs = ty:: subst:: Substs :: for_item ( fcx. tcx , def_id, |def, _| {
382
+ // All regions are identity.
383
+ fcx. tcx . mk_region ( ty:: ReEarlyBound ( def. to_early_bound_region_data ( ) ) )
384
+ } , |def, _| {
385
+ // No default or generic comes from parent, identity substitution.
386
+ if !def. has_default || ( def. index as usize ) < generics. parent_count ( ) {
387
+ fcx. tcx . mk_param_from_def ( def)
388
+ } else {
389
+ no_default = false ;
390
+ // Has a default, use it in the substitution.
391
+ let default_ty = fcx. tcx . type_of ( def. def_id ) ;
392
+ // Skip `Self : Self` in traits, it's problematic.
393
+ // This means we probably check less than we could.
394
+ let should_skip = match self_ty. sty {
395
+ ty:: TyParam ( ref p) => {
396
+ // lhs is Self && rhs is Self
397
+ p. is_self ( ) && match pred {
398
+ Predicate :: Trait ( p) => p. def_id ( ) == def_id,
399
+ Predicate :: TypeOutlives ( _) => false ,
400
+ _ => bug ! ( "Unexpected predicate {:?}" , pred)
401
+ }
402
+ }
403
+ ty:: TyProjection ( ref proj) => {
404
+ let mut projection = proj;
405
+ let mut next_typ = & projection. substs [ 0 ] . as_type ( ) . unwrap ( ) . sty ;
406
+ // Dig through projections.
407
+ while let ty:: TyProjection ( ref proj) = next_typ {
408
+ projection = proj;
409
+ next_typ = & projection. substs [ 0 ] . as_type ( ) . unwrap ( ) . sty ;
410
+ }
411
+ let lhs_is_self = match next_typ {
412
+ ty:: TyParam ( ref p) => p. is_self ( ) ,
413
+ _ => false
414
+ } ;
415
+ let rhs = fcx. tcx . associated_item ( projection. item_def_id )
416
+ . container
417
+ . assert_trait ( ) ;
418
+ lhs_is_self && rhs == def_id
419
+ }
420
+ _ => false
421
+ } ;
422
+ skip = skip || should_skip;
423
+
424
+ match default_ty. sty {
425
+ // Skip `Self: Sized` when `Self` is the default. Needed in traits.
426
+ ty:: TyParam ( ref p) if p. is_self ( ) => {
427
+ if let Predicate :: Trait ( p) = pred {
428
+ if Some ( p. def_id ( ) ) == fcx. tcx . lang_items ( ) . sized_trait ( ) {
429
+ skip = true ;
430
+ }
431
+ }
432
+ }
433
+ _ => ( )
434
+ }
435
+ default_ty
436
+ }
437
+ } ) ;
438
+
439
+ if skip || no_default {
440
+ continue ;
441
+ }
442
+
443
+ self_ty = self_ty. subst ( fcx. tcx , substs) ;
444
+ default_predicates. push ( match pred {
445
+ Predicate :: Trait ( trait_pred) => {
446
+ let mut substs = trait_pred. skip_binder ( ) . trait_ref . substs . to_vec ( ) ;
447
+ substs[ 0 ] = self_ty. into ( ) ;
448
+ let substs = fcx. tcx . intern_substs ( & substs) ;
449
+ let trait_ref = ty:: Binder ( ty:: TraitRef :: new ( trait_pred. def_id ( ) , substs) ) ;
450
+ Predicate :: Trait ( trait_ref. to_poly_trait_predicate ( ) )
451
+ }
452
+ Predicate :: TypeOutlives ( pred) => {
453
+ Predicate :: TypeOutlives ( ty:: Binder ( ty:: OutlivesPredicate ( self_ty, ( pred. 0 ) . 1 ) ) )
454
+ }
455
+ Predicate :: Projection ( proj_pred) => {
456
+ let projection_ty = match self_ty. sty {
457
+ ty:: TyProjection ( proj_ty) => proj_ty,
458
+ _ => bug ! ( "self_ty not projection for projection predicate." )
459
+ } ;
460
+ Predicate :: Projection ( ty:: Binder ( ty:: ProjectionPredicate {
461
+ projection_ty,
462
+ ty : proj_pred. ty ( ) . skip_binder ( )
463
+ } ) )
464
+ }
465
+ _ => bug ! ( "Predicate {:?} not supported for type params." , pred)
466
+ } ) ;
467
+ }
468
+
469
+ predicates. predicates . extend ( default_predicates) ;
470
+ let predicates = predicates. instantiate_identity ( fcx. tcx ) ;
471
+ let predicates = fcx. normalize_associated_types_in ( span, & predicates) ;
472
+
370
473
let obligations =
371
474
predicates. predicates
372
475
. iter ( )
@@ -385,7 +488,6 @@ impl<'a, 'gcx> CheckTypeWellFormedVisitor<'a, 'gcx> {
385
488
fcx : & FnCtxt < ' fcx , ' gcx , ' tcx > ,
386
489
span : Span ,
387
490
sig : ty:: PolyFnSig < ' tcx > ,
388
- predicates : & ty:: InstantiatedPredicates < ' tcx > ,
389
491
def_id : DefId ,
390
492
implied_bounds : & mut Vec < Ty < ' tcx > > )
391
493
{
@@ -402,7 +504,7 @@ impl<'a, 'gcx> CheckTypeWellFormedVisitor<'a, 'gcx> {
402
504
// FIXME(#25759) return types should not be implied bounds
403
505
implied_bounds. push ( sig. output ( ) ) ;
404
506
405
- self . check_where_clauses ( fcx, span, predicates ) ;
507
+ self . check_where_clauses ( fcx, span, def_id ) ;
406
508
}
407
509
408
510
fn check_method_receiver < ' fcx , ' tcx > ( & mut self ,
0 commit comments