@@ -339,7 +339,7 @@ impl<'a, 'gcx> CheckTypeWellFormedVisitor<'a, 'gcx> {
339
339
}
340
340
341
341
self . for_item ( item) . with_fcx ( |fcx, _| {
342
- self . check_where_clauses ( fcx, item. span , trait_def_id) ;
342
+ self . check_trait_where_clauses ( fcx, item. span , trait_def_id) ;
343
343
vec ! [ ]
344
344
} ) ;
345
345
}
@@ -410,41 +410,46 @@ impl<'a, 'gcx> CheckTypeWellFormedVisitor<'a, 'gcx> {
410
410
} ) ;
411
411
}
412
412
413
- /// Checks where clauses and inline bounds.
413
+ /// Checks where clauses and inline bounds that are declared on def_id .
414
414
fn check_where_clauses < ' fcx , ' tcx > ( & mut self ,
415
415
fcx : & FnCtxt < ' fcx , ' gcx , ' tcx > ,
416
416
span : Span ,
417
- def_id : DefId )
417
+ def_id : DefId ) {
418
+ self . inner_check_where_clauses ( fcx, span, def_id, false )
419
+ }
420
+
421
+ fn check_trait_where_clauses < ' fcx , ' tcx > ( & mut self ,
422
+ fcx : & FnCtxt < ' fcx , ' gcx , ' tcx > ,
423
+ span : Span ,
424
+ def_id : DefId ) {
425
+ self . inner_check_where_clauses ( fcx, span, def_id, true )
426
+ }
427
+
428
+ /// Checks where clauses and inline bounds that are declared on def_id.
429
+ fn inner_check_where_clauses < ' fcx , ' tcx > ( & mut self ,
430
+ fcx : & FnCtxt < ' fcx , ' gcx , ' tcx > ,
431
+ span : Span ,
432
+ def_id : DefId ,
433
+ is_trait : bool )
418
434
{
419
435
use ty:: subst:: Subst ;
420
- use ty:: Predicate ;
436
+ use rustc :: ty:: TypeFoldable ;
421
437
422
438
let generics = self . tcx . generics_of ( def_id) ;
423
- let defaults = generics. types . iter ( ) . filter_map ( |p| match p. has_default {
424
- true => Some ( p. def_id ) ,
425
- false => None ,
426
- } ) ;
439
+ let defaulted_params = generics. types . iter ( )
440
+ . filter ( |def| def. has_default &&
441
+ def. index >= generics. parent_count ( ) as u32 ) ;
427
442
// Defaults must be well-formed.
428
- for d in defaults {
443
+ for d in defaulted_params . map ( |p| p . def_id ) {
429
444
fcx. register_wf_obligation ( fcx. tcx . type_of ( d) , fcx. tcx . def_span ( d) , self . code . clone ( ) ) ;
430
445
}
431
-
432
446
// Check that each default fulfills the bounds on it's parameter.
433
447
// We go over each predicate and duplicate it, substituting defaults in the self type.
434
448
let mut predicates = fcx. tcx . predicates_of ( def_id) ;
435
449
let mut default_predicates = Vec :: new ( ) ;
436
- for pred in & predicates. predicates {
437
- let mut self_ty = match pred {
438
- Predicate :: Trait ( trait_pred) => trait_pred. skip_binder ( ) . self_ty ( ) ,
439
- Predicate :: TypeOutlives ( outlives_pred) => ( outlives_pred. 0 ) . 0 ,
440
- Predicate :: Projection ( proj_pred) => {
441
- fcx. tcx . mk_ty ( ty:: TyProjection ( proj_pred. skip_binder ( ) . projection_ty ) )
442
- }
443
- // Lifetime params can't have defaults.
444
- Predicate :: RegionOutlives ( ..) => continue ,
445
- _ => bug ! ( "Predicate {:?} not supported in where clauses." , pred)
446
- } ;
447
-
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 ( ) ) ) {
448
453
let mut skip = false ;
449
454
let mut no_default = true ;
450
455
let substs = ty:: subst:: Substs :: for_item ( fcx. tcx , def_id, |def, _| {
@@ -458,42 +463,11 @@ impl<'a, 'gcx> CheckTypeWellFormedVisitor<'a, 'gcx> {
458
463
no_default = false ;
459
464
// Has a default, use it in the substitution.
460
465
let default_ty = fcx. tcx . type_of ( def. def_id ) ;
461
- // Skip `Self : Self` in traits, it's problematic.
462
- // This means we probably check less than we could.
463
- let should_skip = match self_ty. sty {
464
- ty:: TyParam ( ref p) => {
465
- // lhs is Self && rhs is Self
466
- p. is_self ( ) && match pred {
467
- Predicate :: Trait ( p) => p. def_id ( ) == def_id,
468
- Predicate :: TypeOutlives ( _) => false ,
469
- _ => bug ! ( "Unexpected predicate {:?}" , pred)
470
- }
471
- }
472
- ty:: TyProjection ( ref proj) => {
473
- let mut projection = proj;
474
- let mut next_typ = & projection. substs [ 0 ] . as_type ( ) . unwrap ( ) . sty ;
475
- // Dig through projections.
476
- while let ty:: TyProjection ( ref proj) = next_typ {
477
- projection = proj;
478
- next_typ = & projection. substs [ 0 ] . as_type ( ) . unwrap ( ) . sty ;
479
- }
480
- let lhs_is_self = match next_typ {
481
- ty:: TyParam ( ref p) => p. is_self ( ) ,
482
- _ => false
483
- } ;
484
- let rhs = fcx. tcx . associated_item ( projection. item_def_id )
485
- . container
486
- . assert_trait ( ) ;
487
- lhs_is_self && rhs == def_id
488
- }
489
- _ => false
490
- } ;
491
- skip = skip || should_skip;
492
466
493
- match default_ty. sty {
467
+ match default_ty. sty {
494
468
// Skip `Self: Sized` when `Self` is the default. Needed in traits.
495
- ty:: TyParam ( ref p) if p. is_self ( ) => {
496
- if let Predicate :: Trait ( p) = pred {
469
+ ty:: TyParam ( ref p) if is_trait && p. is_self ( ) => {
470
+ if let ty :: Predicate :: Trait ( p) = pred {
497
471
if Some ( p. def_id ( ) ) == fcx. tcx . lang_items ( ) . sized_trait ( ) {
498
472
skip = true ;
499
473
}
@@ -509,30 +483,7 @@ impl<'a, 'gcx> CheckTypeWellFormedVisitor<'a, 'gcx> {
509
483
continue ;
510
484
}
511
485
512
- self_ty = self_ty. subst ( fcx. tcx , substs) ;
513
- default_predicates. push ( match pred {
514
- Predicate :: Trait ( trait_pred) => {
515
- let mut substs = trait_pred. skip_binder ( ) . trait_ref . substs . to_vec ( ) ;
516
- substs[ 0 ] = self_ty. into ( ) ;
517
- let substs = fcx. tcx . intern_substs ( & substs) ;
518
- let trait_ref = ty:: Binder ( ty:: TraitRef :: new ( trait_pred. def_id ( ) , substs) ) ;
519
- Predicate :: Trait ( trait_ref. to_poly_trait_predicate ( ) )
520
- }
521
- Predicate :: TypeOutlives ( pred) => {
522
- Predicate :: TypeOutlives ( ty:: Binder ( ty:: OutlivesPredicate ( self_ty, ( pred. 0 ) . 1 ) ) )
523
- }
524
- Predicate :: Projection ( proj_pred) => {
525
- let projection_ty = match self_ty. sty {
526
- ty:: TyProjection ( proj_ty) => proj_ty,
527
- _ => bug ! ( "self_ty not projection for projection predicate." )
528
- } ;
529
- Predicate :: Projection ( ty:: Binder ( ty:: ProjectionPredicate {
530
- projection_ty,
531
- ty : proj_pred. ty ( ) . skip_binder ( )
532
- } ) )
533
- }
534
- _ => bug ! ( "Predicate {:?} not supported for type params." , pred)
535
- } ) ;
486
+ default_predicates. push ( pred. subst ( fcx. tcx , substs) ) ;
536
487
}
537
488
538
489
predicates. predicates . extend ( default_predicates) ;
0 commit comments