@@ -14,8 +14,7 @@ use rustc::session::config::nightly_options;
14
14
use rustc:: ty:: subst:: { InternalSubsts , Subst , SubstsRef } ;
15
15
use rustc:: ty:: GenericParamDefKind ;
16
16
use rustc:: ty:: {
17
- self , ParamEnvAnd , ToPolyTraitRef , ToPredicate , TraitRef , Ty , TyCtxt , TypeFoldable ,
18
- WithConstness ,
17
+ self , ParamEnvAnd , ToPolyTraitRef , ToPredicate , Ty , TyCtxt , TypeFoldable , WithConstness ,
19
18
} ;
20
19
use rustc_data_structures:: fx:: FxHashSet ;
21
20
use rustc_data_structures:: sync:: Lrc ;
@@ -78,7 +77,7 @@ struct ProbeContext<'a, 'tcx> {
78
77
79
78
/// Collects near misses when trait bounds for type parameters are unsatisfied and is only used
80
79
/// for error reporting
81
- unsatisfied_predicates : Vec < TraitRef < ' tcx > > ,
80
+ unsatisfied_predicates : Vec < ( ty :: Predicate < ' tcx > , Option < ty :: Predicate < ' tcx > > ) > ,
82
81
83
82
is_suggestion : IsSuggestion ,
84
83
}
@@ -1224,7 +1223,10 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
1224
1223
& self ,
1225
1224
self_ty : Ty < ' tcx > ,
1226
1225
probes : ProbesIter ,
1227
- possibly_unsatisfied_predicates : & mut Vec < TraitRef < ' tcx > > ,
1226
+ possibly_unsatisfied_predicates : & mut Vec < (
1227
+ ty:: Predicate < ' tcx > ,
1228
+ Option < ty:: Predicate < ' tcx > > ,
1229
+ ) > ,
1228
1230
unstable_candidates : Option < & mut Vec < ( & ' b Candidate < ' tcx > , Symbol ) > > ,
1229
1231
) -> Option < PickResult < ' tcx > >
1230
1232
where
@@ -1343,7 +1345,10 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
1343
1345
& self ,
1344
1346
self_ty : Ty < ' tcx > ,
1345
1347
probe : & Candidate < ' tcx > ,
1346
- possibly_unsatisfied_predicates : & mut Vec < TraitRef < ' tcx > > ,
1348
+ possibly_unsatisfied_predicates : & mut Vec < (
1349
+ ty:: Predicate < ' tcx > ,
1350
+ Option < ty:: Predicate < ' tcx > > ,
1351
+ ) > ,
1347
1352
) -> ProbeResult {
1348
1353
debug ! ( "consider_probe: self_ty={:?} probe={:?}" , self_ty, probe) ;
1349
1354
@@ -1398,21 +1403,45 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
1398
1403
let predicate = trait_ref. without_const ( ) . to_predicate ( ) ;
1399
1404
let obligation = traits:: Obligation :: new ( cause, self . param_env , predicate) ;
1400
1405
if !self . predicate_may_hold ( & obligation) {
1401
- if self . probe ( |_| self . select_trait_candidate ( trait_ref) . is_err ( ) ) {
1406
+ if self . probe ( |_| {
1407
+ match self . select_trait_candidate ( trait_ref) {
1408
+ Err ( _) => return true ,
1409
+ Ok ( Some ( vtable) )
1410
+ if !vtable. borrow_nested_obligations ( ) . is_empty ( ) =>
1411
+ {
1412
+ for obligation in vtable. borrow_nested_obligations ( ) {
1413
+ // Determine exactly which obligation wasn't met, so
1414
+ // that we can give more context in the error.
1415
+ if !self . predicate_may_hold ( & obligation) {
1416
+ result = ProbeResult :: NoMatch ;
1417
+ let o = self . resolve_vars_if_possible ( obligation) ;
1418
+ let predicate =
1419
+ self . resolve_vars_if_possible ( & predicate) ;
1420
+ let p = if predicate == o. predicate {
1421
+ // Avoid "`MyStruct: Foo` which is required by
1422
+ // `MyStruct: Foo`" in E0599.
1423
+ None
1424
+ } else {
1425
+ Some ( predicate)
1426
+ } ;
1427
+ possibly_unsatisfied_predicates. push ( ( o. predicate , p) ) ;
1428
+ }
1429
+ }
1430
+ }
1431
+ _ => {
1432
+ // Some nested subobligation of this predicate
1433
+ // failed.
1434
+ result = ProbeResult :: NoMatch ;
1435
+ let predicate = self . resolve_vars_if_possible ( & predicate) ;
1436
+ possibly_unsatisfied_predicates. push ( ( predicate, None ) ) ;
1437
+ }
1438
+ }
1439
+ false
1440
+ } ) {
1402
1441
// This candidate's primary obligation doesn't even
1403
1442
// select - don't bother registering anything in
1404
1443
// `potentially_unsatisfied_predicates`.
1405
1444
return ProbeResult :: NoMatch ;
1406
- } else {
1407
- // Some nested subobligation of this predicate
1408
- // failed.
1409
- //
1410
- // FIXME: try to find the exact nested subobligation
1411
- // and point at it rather than reporting the entire
1412
- // trait-ref?
1413
- result = ProbeResult :: NoMatch ;
1414
- let trait_ref = self . resolve_vars_if_possible ( & trait_ref) ;
1415
- possibly_unsatisfied_predicates. push ( trait_ref) ;
1416
1445
}
1417
1446
}
1418
1447
vec ! [ ]
@@ -1429,9 +1458,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
1429
1458
let o = self . resolve_vars_if_possible ( & o) ;
1430
1459
if !self . predicate_may_hold ( & o) {
1431
1460
result = ProbeResult :: NoMatch ;
1432
- if let & ty:: Predicate :: Trait ( ref pred, _) = & o. predicate {
1433
- possibly_unsatisfied_predicates. push ( pred. skip_binder ( ) . trait_ref ) ;
1434
- }
1461
+ possibly_unsatisfied_predicates. push ( ( o. predicate , None ) ) ;
1435
1462
}
1436
1463
}
1437
1464
0 commit comments