@@ -180,10 +180,7 @@ impl<'a, 'gcx> CheckTypeWellFormedVisitor<'a, 'gcx> {
180
180
reject_shadowing_type_parameters ( fcx. tcx , item. def_id ) ;
181
181
let sig = fcx. tcx . fn_sig ( item. def_id ) ;
182
182
let sig = fcx. normalize_associated_types_in ( span, & sig) ;
183
- let predicates = fcx. tcx . predicates_of ( item. def_id )
184
- . instantiate_identity ( fcx. tcx ) ;
185
- let predicates = fcx. normalize_associated_types_in ( span, & predicates) ;
186
- this. check_fn_or_method ( fcx, span, sig, & predicates,
183
+ this. check_fn_or_method ( fcx, span, sig,
187
184
item. def_id , & mut implied_bounds) ;
188
185
let sig_if_method = sig_if_method. expect ( "bad signature for method" ) ;
189
186
this. check_method_receiver ( fcx, sig_if_method, & item, self_ty) ;
@@ -267,9 +264,7 @@ impl<'a, 'gcx> CheckTypeWellFormedVisitor<'a, 'gcx> {
267
264
}
268
265
}
269
266
270
- let predicates = fcx. tcx . predicates_of ( def_id) . instantiate_identity ( fcx. tcx ) ;
271
- let predicates = fcx. normalize_associated_types_in ( item. span , & predicates) ;
272
- this. check_where_clauses ( fcx, item. span , & predicates) ;
267
+ self . check_where_clauses ( fcx, item. span , def_id) ;
273
268
274
269
vec ! [ ] // no implied bounds in a struct def'n
275
270
} ) ;
@@ -343,10 +338,8 @@ impl<'a, 'gcx> CheckTypeWellFormedVisitor<'a, 'gcx> {
343
338
self . check_auto_trait ( trait_def_id, item. span ) ;
344
339
}
345
340
346
- self . for_item ( item) . with_fcx ( |fcx, this| {
347
- let predicates = fcx. tcx . predicates_of ( trait_def_id) . instantiate_identity ( fcx. tcx ) ;
348
- let predicates = fcx. normalize_associated_types_in ( item. span , & predicates) ;
349
- this. check_where_clauses ( fcx, item. span , & predicates) ;
341
+ self . for_item ( item) . with_fcx ( |fcx, _| {
342
+ self . check_where_clauses ( fcx, item. span , trait_def_id) ;
350
343
vec ! [ ]
351
344
} ) ;
352
345
}
@@ -356,12 +349,8 @@ impl<'a, 'gcx> CheckTypeWellFormedVisitor<'a, 'gcx> {
356
349
let def_id = fcx. tcx . hir . local_def_id ( item. id ) ;
357
350
let sig = fcx. tcx . fn_sig ( def_id) ;
358
351
let sig = fcx. normalize_associated_types_in ( item. span , & sig) ;
359
-
360
- let predicates = fcx. tcx . predicates_of ( def_id) . instantiate_identity ( fcx. tcx ) ;
361
- let predicates = fcx. normalize_associated_types_in ( item. span , & predicates) ;
362
-
363
352
let mut implied_bounds = vec ! [ ] ;
364
- this. check_fn_or_method ( fcx, item. span , sig, & predicates ,
353
+ this. check_fn_or_method ( fcx, item. span , sig,
365
354
def_id, & mut implied_bounds) ;
366
355
implied_bounds
367
356
} )
@@ -415,19 +404,132 @@ impl<'a, 'gcx> CheckTypeWellFormedVisitor<'a, 'gcx> {
415
404
}
416
405
}
417
406
418
- let predicates = fcx. tcx . predicates_of ( item_def_id) . instantiate_identity ( fcx. tcx ) ;
419
- let predicates = fcx. normalize_associated_types_in ( item. span , & predicates) ;
420
- this. check_where_clauses ( fcx, item. span , & predicates) ;
407
+ this. check_where_clauses ( fcx, item. span , item_def_id) ;
421
408
422
409
fcx. impl_implied_bounds ( item_def_id, item. span )
423
410
} ) ;
424
411
}
425
412
413
+ /// Checks where clauses and inline bounds.
426
414
fn check_where_clauses < ' fcx , ' tcx > ( & mut self ,
427
415
fcx : & FnCtxt < ' fcx , ' gcx , ' tcx > ,
428
416
span : Span ,
429
- predicates : & ty :: InstantiatedPredicates < ' tcx > )
417
+ def_id : DefId )
430
418
{
419
+ use ty:: subst:: Subst ;
420
+ use ty:: Predicate ;
421
+
422
+ // Check that each default fulfills the bounds on it's parameter.
423
+ // We go over each predicate and duplicate it, substituting defaults in the self type.
424
+ let mut predicates = fcx. tcx . predicates_of ( def_id) ;
425
+ let mut default_predicates = Vec :: new ( ) ;
426
+ for pred in & predicates. predicates {
427
+ let mut self_ty = match pred {
428
+ Predicate :: Trait ( trait_pred) => trait_pred. skip_binder ( ) . self_ty ( ) ,
429
+ Predicate :: TypeOutlives ( outlives_pred) => ( outlives_pred. 0 ) . 0 ,
430
+ Predicate :: Projection ( proj_pred) => {
431
+ fcx. tcx . mk_ty ( ty:: TyProjection ( proj_pred. skip_binder ( ) . projection_ty ) )
432
+ }
433
+ // Lifetime params can't have defaults.
434
+ Predicate :: RegionOutlives ( ..) => continue ,
435
+ _ => bug ! ( "Predicate {:?} not supported in where clauses." , pred)
436
+ } ;
437
+
438
+ let mut skip = false ;
439
+ let mut no_default = true ;
440
+ let generics = self . tcx . generics_of ( def_id) ;
441
+ let substs = ty:: subst:: Substs :: for_item ( fcx. tcx , def_id, |def, _| {
442
+ // All regions are identity.
443
+ fcx. tcx . mk_region ( ty:: ReEarlyBound ( def. to_early_bound_region_data ( ) ) )
444
+ } , |def, _| {
445
+ // No default or generic comes from parent, identity substitution.
446
+ if !def. has_default || ( def. index as usize ) < generics. parent_count ( ) {
447
+ fcx. tcx . mk_param_from_def ( def)
448
+ } else {
449
+ no_default = false ;
450
+ // Has a default, use it in the substitution.
451
+ let default_ty = fcx. tcx . type_of ( def. def_id ) ;
452
+ // Skip `Self : Self` in traits, it's problematic.
453
+ // This means we probably check less than we could.
454
+ let should_skip = match self_ty. sty {
455
+ ty:: TyParam ( ref p) => {
456
+ // lhs is Self && rhs is Self
457
+ p. is_self ( ) && match pred {
458
+ Predicate :: Trait ( p) => p. def_id ( ) == def_id,
459
+ Predicate :: TypeOutlives ( _) => false ,
460
+ _ => bug ! ( "Unexpected predicate {:?}" , pred)
461
+ }
462
+ }
463
+ ty:: TyProjection ( ref proj) => {
464
+ let mut projection = proj;
465
+ let mut next_typ = & projection. substs [ 0 ] . as_type ( ) . unwrap ( ) . sty ;
466
+ // Dig through projections.
467
+ while let ty:: TyProjection ( ref proj) = next_typ {
468
+ projection = proj;
469
+ next_typ = & projection. substs [ 0 ] . as_type ( ) . unwrap ( ) . sty ;
470
+ }
471
+ let lhs_is_self = match next_typ {
472
+ ty:: TyParam ( ref p) => p. is_self ( ) ,
473
+ _ => false
474
+ } ;
475
+ let rhs = fcx. tcx . associated_item ( projection. item_def_id )
476
+ . container
477
+ . assert_trait ( ) ;
478
+ lhs_is_self && rhs == def_id
479
+ }
480
+ _ => false
481
+ } ;
482
+ skip = skip || should_skip;
483
+
484
+ match default_ty. sty {
485
+ // Skip `Self: Sized` when `Self` is the default. Needed in traits.
486
+ ty:: TyParam ( ref p) if p. is_self ( ) => {
487
+ if let Predicate :: Trait ( p) = pred {
488
+ if Some ( p. def_id ( ) ) == fcx. tcx . lang_items ( ) . sized_trait ( ) {
489
+ skip = true ;
490
+ }
491
+ }
492
+ }
493
+ _ => ( )
494
+ }
495
+ default_ty
496
+ }
497
+ } ) ;
498
+
499
+ if skip || no_default {
500
+ continue ;
501
+ }
502
+
503
+ self_ty = self_ty. subst ( fcx. tcx , substs) ;
504
+ default_predicates. push ( match pred {
505
+ Predicate :: Trait ( trait_pred) => {
506
+ let mut substs = trait_pred. skip_binder ( ) . trait_ref . substs . to_vec ( ) ;
507
+ substs[ 0 ] = self_ty. into ( ) ;
508
+ let substs = fcx. tcx . intern_substs ( & substs) ;
509
+ let trait_ref = ty:: Binder ( ty:: TraitRef :: new ( trait_pred. def_id ( ) , substs) ) ;
510
+ Predicate :: Trait ( trait_ref. to_poly_trait_predicate ( ) )
511
+ }
512
+ Predicate :: TypeOutlives ( pred) => {
513
+ Predicate :: TypeOutlives ( ty:: Binder ( ty:: OutlivesPredicate ( self_ty, ( pred. 0 ) . 1 ) ) )
514
+ }
515
+ Predicate :: Projection ( proj_pred) => {
516
+ let projection_ty = match self_ty. sty {
517
+ ty:: TyProjection ( proj_ty) => proj_ty,
518
+ _ => bug ! ( "self_ty not projection for projection predicate." )
519
+ } ;
520
+ Predicate :: Projection ( ty:: Binder ( ty:: ProjectionPredicate {
521
+ projection_ty,
522
+ ty : proj_pred. ty ( ) . skip_binder ( )
523
+ } ) )
524
+ }
525
+ _ => bug ! ( "Predicate {:?} not supported for type params." , pred)
526
+ } ) ;
527
+ }
528
+
529
+ predicates. predicates . extend ( default_predicates) ;
530
+ let predicates = predicates. instantiate_identity ( fcx. tcx ) ;
531
+ let predicates = fcx. normalize_associated_types_in ( span, & predicates) ;
532
+
431
533
let obligations =
432
534
predicates. predicates
433
535
. iter ( )
@@ -446,7 +548,6 @@ impl<'a, 'gcx> CheckTypeWellFormedVisitor<'a, 'gcx> {
446
548
fcx : & FnCtxt < ' fcx , ' gcx , ' tcx > ,
447
549
span : Span ,
448
550
sig : ty:: PolyFnSig < ' tcx > ,
449
- predicates : & ty:: InstantiatedPredicates < ' tcx > ,
450
551
def_id : DefId ,
451
552
implied_bounds : & mut Vec < Ty < ' tcx > > )
452
553
{
@@ -463,7 +564,7 @@ impl<'a, 'gcx> CheckTypeWellFormedVisitor<'a, 'gcx> {
463
564
// FIXME(#25759) return types should not be implied bounds
464
565
implied_bounds. push ( sig. output ( ) ) ;
465
566
466
- self . check_where_clauses ( fcx, span, predicates ) ;
567
+ self . check_where_clauses ( fcx, span, def_id ) ;
467
568
}
468
569
469
570
fn check_method_receiver < ' fcx , ' tcx > ( & mut self ,
0 commit comments