@@ -364,15 +364,16 @@ fn check_impl<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
364
364
}
365
365
366
366
/// Checks where clauses and inline bounds that are declared on def_id.
367
- fn check_where_clauses < ' a , ' gcx , ' fcx , ' tcx > ( tcx : TyCtxt < ' a , ' gcx , ' gcx > ,
368
- fcx : & FnCtxt < ' fcx , ' gcx , ' tcx > ,
369
- span : Span ,
370
- def_id : DefId ) {
367
+ fn check_where_clauses < ' a , ' gcx , ' fcx , ' tcx > (
368
+ tcx : TyCtxt < ' a , ' gcx , ' gcx > ,
369
+ fcx : & FnCtxt < ' fcx , ' gcx , ' tcx > ,
370
+ span : Span ,
371
+ def_id : DefId ,
372
+ ) {
371
373
use ty:: subst:: Subst ;
372
374
use rustc:: ty:: TypeFoldable ;
373
375
374
- let mut predicates = fcx. tcx . predicates_of ( def_id) ;
375
- let mut substituted_predicates = Vec :: new ( ) ;
376
+ let predicates = fcx. tcx . predicates_of ( def_id) ;
376
377
377
378
let generics = tcx. generics_of ( def_id) ;
378
379
let is_our_default = |def : & ty:: GenericParamDef | {
@@ -433,7 +434,7 @@ fn check_where_clauses<'a, 'gcx, 'fcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'gcx>,
433
434
}
434
435
} ) ;
435
436
// Now we build the substituted predicates.
436
- for & pred in predicates. predicates . iter ( ) {
437
+ let default_obligations = predicates. predicates . iter ( ) . flat_map ( | & pred| {
437
438
struct CountParams { params : FxHashSet < u32 > }
438
439
impl < ' tcx > ty:: fold:: TypeVisitor < ' tcx > for CountParams {
439
440
fn visit_ty ( & mut self , t : Ty < ' tcx > ) -> bool {
@@ -455,21 +456,37 @@ fn check_where_clauses<'a, 'gcx, 'fcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'gcx>,
455
456
let substituted_pred = pred. subst ( fcx. tcx , substs) ;
456
457
// Don't check non-defaulted params, dependent defaults (including lifetimes)
457
458
// or preds with multiple params.
458
- if substituted_pred. references_error ( ) || param_count. params . len ( ) > 1
459
- || has_region {
460
- continue ;
461
- }
462
- // Avoid duplication of predicates that contain no parameters, for example.
463
- if !predicates. predicates . contains ( & substituted_pred) {
464
- substituted_predicates. push ( substituted_pred) ;
459
+ if {
460
+ substituted_pred. references_error ( ) || param_count. params . len ( ) > 1
461
+ || has_region
462
+ } {
463
+ None
464
+ } else if predicates. predicates . contains ( & substituted_pred) {
465
+ // Avoid duplication of predicates that contain no parameters, for example.
466
+ None
467
+ } else {
468
+ Some ( substituted_pred)
465
469
}
466
- }
470
+ } ) . map ( |pred| {
471
+ // convert each of those into an obligation. So if you have
472
+ // something like `struct Foo<T: Copy = String>`, we would
473
+ // take that predicate `T: Copy`, substitute to `String: Copy`
474
+ // (actually that happens in the previous `flat_map` call),
475
+ // and then try to prove it (in this case, we'll fail).
476
+ //
477
+ // Note the subtle difference from how we handle `predicates`
478
+ // below: there, we are not trying to prove those predicates
479
+ // to be *true* but merely *well-formed*.
480
+ let pred = fcx. normalize_associated_types_in ( span, & pred) ;
481
+ let cause = traits:: ObligationCause :: new ( span, fcx. body_id , traits:: ItemObligation ( def_id) ) ;
482
+ traits:: Obligation :: new ( cause, fcx. param_env , pred)
483
+ } ) ;
467
484
468
- predicates. predicates . extend ( substituted_predicates) ;
469
485
let predicates = predicates. instantiate_identity ( fcx. tcx ) ;
470
486
let predicates = fcx. normalize_associated_types_in ( span, & predicates) ;
471
487
472
- let obligations =
488
+ debug ! ( "check_where_clauses: predicates={:?}" , predicates. predicates) ;
489
+ let wf_obligations =
473
490
predicates. predicates
474
491
. iter ( )
475
492
. flat_map ( |p| ty:: wf:: predicate_obligations ( fcx,
@@ -478,7 +495,8 @@ fn check_where_clauses<'a, 'gcx, 'fcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'gcx>,
478
495
p,
479
496
span) ) ;
480
497
481
- for obligation in obligations {
498
+ for obligation in wf_obligations. chain ( default_obligations) {
499
+ debug ! ( "next obligation cause: {:?}" , obligation. cause) ;
482
500
fcx. register_predicate ( obligation) ;
483
501
}
484
502
}
0 commit comments