@@ -279,7 +279,7 @@ impl<'a, 'gcx> CheckTypeWellFormedVisitor<'a, 'gcx> {
279
279
let trait_def_id = self . tcx . hir . local_def_id ( item. id ) ;
280
280
281
281
self . for_item ( item) . with_fcx ( |fcx, _| {
282
- self . check_where_clauses ( fcx, item. span , trait_def_id) ;
282
+ self . check_trait_where_clauses ( fcx, item. span , trait_def_id) ;
283
283
vec ! [ ]
284
284
} ) ;
285
285
}
@@ -350,41 +350,46 @@ impl<'a, 'gcx> CheckTypeWellFormedVisitor<'a, 'gcx> {
350
350
} ) ;
351
351
}
352
352
353
- /// Checks where clauses and inline bounds.
353
+ /// Checks where clauses and inline bounds that are declared on def_id .
354
354
fn check_where_clauses < ' fcx , ' tcx > ( & mut self ,
355
355
fcx : & FnCtxt < ' fcx , ' gcx , ' tcx > ,
356
356
span : Span ,
357
- def_id : DefId )
357
+ def_id : DefId ) {
358
+ self . inner_check_where_clauses ( fcx, span, def_id, false )
359
+ }
360
+
361
+ fn check_trait_where_clauses < ' fcx , ' tcx > ( & mut self ,
362
+ fcx : & FnCtxt < ' fcx , ' gcx , ' tcx > ,
363
+ span : Span ,
364
+ def_id : DefId ) {
365
+ self . inner_check_where_clauses ( fcx, span, def_id, true )
366
+ }
367
+
368
+ /// Checks where clauses and inline bounds that are declared on def_id.
369
+ fn inner_check_where_clauses < ' fcx , ' tcx > ( & mut self ,
370
+ fcx : & FnCtxt < ' fcx , ' gcx , ' tcx > ,
371
+ span : Span ,
372
+ def_id : DefId ,
373
+ is_trait : bool )
358
374
{
359
375
use ty:: subst:: Subst ;
360
- use ty:: Predicate ;
376
+ use rustc :: ty:: TypeFoldable ;
361
377
362
378
let generics = self . tcx . generics_of ( def_id) ;
363
- let defaults = generics. types . iter ( ) . filter_map ( |p| match p. has_default {
364
- true => Some ( p. def_id ) ,
365
- false => None ,
366
- } ) ;
379
+ let defaulted_params = generics. types . iter ( )
380
+ . filter ( |def| def. has_default &&
381
+ def. index >= generics. parent_count ( ) as u32 ) ;
367
382
// Defaults must be well-formed.
368
- for d in defaults {
383
+ for d in defaulted_params . map ( |p| p . def_id ) {
369
384
fcx. register_wf_obligation ( fcx. tcx . type_of ( d) , fcx. tcx . def_span ( d) , self . code . clone ( ) ) ;
370
385
}
371
-
372
386
// Check that each default fulfills the bounds on it's parameter.
373
387
// We go over each predicate and duplicate it, substituting defaults in the self type.
374
388
let mut predicates = fcx. tcx . predicates_of ( def_id) ;
375
389
let mut default_predicates = Vec :: new ( ) ;
376
- for pred in & predicates. predicates {
377
- let mut self_ty = match pred {
378
- Predicate :: Trait ( trait_pred) => trait_pred. skip_binder ( ) . self_ty ( ) ,
379
- Predicate :: TypeOutlives ( outlives_pred) => ( outlives_pred. 0 ) . 0 ,
380
- Predicate :: Projection ( proj_pred) => {
381
- fcx. tcx . mk_ty ( ty:: TyProjection ( proj_pred. skip_binder ( ) . projection_ty ) )
382
- }
383
- // Lifetime params can't have defaults.
384
- Predicate :: RegionOutlives ( ..) => continue ,
385
- _ => bug ! ( "Predicate {:?} not supported in where clauses." , pred)
386
- } ;
387
-
390
+ // In `trait Trait : Super` predicates as `Self: Trait` and `Self: Super` are a problem.
391
+ // Therefore we skip such predicates. This means we check less than we could.
392
+ for pred in predicates. predicates . iter ( ) . filter ( |p| !( is_trait && p. has_self_ty ( ) ) ) {
388
393
let mut skip = false ;
389
394
let mut no_default = true ;
390
395
let substs = ty:: subst:: Substs :: for_item ( fcx. tcx , def_id, |def, _| {
@@ -398,42 +403,11 @@ impl<'a, 'gcx> CheckTypeWellFormedVisitor<'a, 'gcx> {
398
403
no_default = false ;
399
404
// Has a default, use it in the substitution.
400
405
let default_ty = fcx. tcx . type_of ( def. def_id ) ;
401
- // Skip `Self : Self` in traits, it's problematic.
402
- // This means we probably check less than we could.
403
- let should_skip = match self_ty. sty {
404
- ty:: TyParam ( ref p) => {
405
- // lhs is Self && rhs is Self
406
- p. is_self ( ) && match pred {
407
- Predicate :: Trait ( p) => p. def_id ( ) == def_id,
408
- Predicate :: TypeOutlives ( _) => false ,
409
- _ => bug ! ( "Unexpected predicate {:?}" , pred)
410
- }
411
- }
412
- ty:: TyProjection ( ref proj) => {
413
- let mut projection = proj;
414
- let mut next_typ = & projection. substs [ 0 ] . as_type ( ) . unwrap ( ) . sty ;
415
- // Dig through projections.
416
- while let ty:: TyProjection ( ref proj) = next_typ {
417
- projection = proj;
418
- next_typ = & projection. substs [ 0 ] . as_type ( ) . unwrap ( ) . sty ;
419
- }
420
- let lhs_is_self = match next_typ {
421
- ty:: TyParam ( ref p) => p. is_self ( ) ,
422
- _ => false
423
- } ;
424
- let rhs = fcx. tcx . associated_item ( projection. item_def_id )
425
- . container
426
- . assert_trait ( ) ;
427
- lhs_is_self && rhs == def_id
428
- }
429
- _ => false
430
- } ;
431
- skip = skip || should_skip;
432
406
433
- match default_ty. sty {
407
+ match default_ty. sty {
434
408
// Skip `Self: Sized` when `Self` is the default. Needed in traits.
435
- ty:: TyParam ( ref p) if p. is_self ( ) => {
436
- if let Predicate :: Trait ( p) = pred {
409
+ ty:: TyParam ( ref p) if is_trait && p. is_self ( ) => {
410
+ if let ty :: Predicate :: Trait ( p) = pred {
437
411
if Some ( p. def_id ( ) ) == fcx. tcx . lang_items ( ) . sized_trait ( ) {
438
412
skip = true ;
439
413
}
@@ -449,30 +423,7 @@ impl<'a, 'gcx> CheckTypeWellFormedVisitor<'a, 'gcx> {
449
423
continue ;
450
424
}
451
425
452
- self_ty = self_ty. subst ( fcx. tcx , substs) ;
453
- default_predicates. push ( match pred {
454
- Predicate :: Trait ( trait_pred) => {
455
- let mut substs = trait_pred. skip_binder ( ) . trait_ref . substs . to_vec ( ) ;
456
- substs[ 0 ] = self_ty. into ( ) ;
457
- let substs = fcx. tcx . intern_substs ( & substs) ;
458
- let trait_ref = ty:: Binder ( ty:: TraitRef :: new ( trait_pred. def_id ( ) , substs) ) ;
459
- Predicate :: Trait ( trait_ref. to_poly_trait_predicate ( ) )
460
- }
461
- Predicate :: TypeOutlives ( pred) => {
462
- Predicate :: TypeOutlives ( ty:: Binder ( ty:: OutlivesPredicate ( self_ty, ( pred. 0 ) . 1 ) ) )
463
- }
464
- Predicate :: Projection ( proj_pred) => {
465
- let projection_ty = match self_ty. sty {
466
- ty:: TyProjection ( proj_ty) => proj_ty,
467
- _ => bug ! ( "self_ty not projection for projection predicate." )
468
- } ;
469
- Predicate :: Projection ( ty:: Binder ( ty:: ProjectionPredicate {
470
- projection_ty,
471
- ty : proj_pred. ty ( ) . skip_binder ( )
472
- } ) )
473
- }
474
- _ => bug ! ( "Predicate {:?} not supported for type params." , pred)
475
- } ) ;
426
+ default_predicates. push ( pred. subst ( fcx. tcx , substs) ) ;
476
427
}
477
428
478
429
predicates. predicates . extend ( default_predicates) ;
0 commit comments