@@ -14,8 +14,7 @@ use rustc::session::config::nightly_options;
1414use rustc:: ty:: subst:: { InternalSubsts , Subst , SubstsRef } ;
1515use rustc:: ty:: GenericParamDefKind ;
1616use rustc:: ty:: {
17- self , ParamEnvAnd , ToPolyTraitRef , ToPredicate , TraitRef , Ty , TyCtxt , TypeFoldable ,
18- WithConstness ,
17+ self , ParamEnvAnd , ToPolyTraitRef , ToPredicate , Ty , TyCtxt , TypeFoldable , WithConstness ,
1918} ;
2019use rustc_data_structures:: fx:: FxHashSet ;
2120use rustc_data_structures:: sync:: Lrc ;
@@ -78,7 +77,7 @@ struct ProbeContext<'a, 'tcx> {
7877
7978 /// Collects near misses when trait bounds for type parameters are unsatisfied and is only used
8079 /// for error reporting
81- unsatisfied_predicates : Vec < TraitRef < ' tcx > > ,
80+ unsatisfied_predicates : Vec < ( ty :: Predicate < ' tcx > , Option < ty :: Predicate < ' tcx > > ) > ,
8281
8382 is_suggestion : IsSuggestion ,
8483}
@@ -1224,7 +1223,10 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
12241223 & self ,
12251224 self_ty : Ty < ' tcx > ,
12261225 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+ ) > ,
12281230 unstable_candidates : Option < & mut Vec < ( & ' b Candidate < ' tcx > , Symbol ) > > ,
12291231 ) -> Option < PickResult < ' tcx > >
12301232 where
@@ -1343,7 +1345,10 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
13431345 & self ,
13441346 self_ty : Ty < ' tcx > ,
13451347 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+ ) > ,
13471352 ) -> ProbeResult {
13481353 debug ! ( "consider_probe: self_ty={:?} probe={:?}" , self_ty, probe) ;
13491354
@@ -1398,21 +1403,45 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
13981403 let predicate = trait_ref. without_const ( ) . to_predicate ( ) ;
13991404 let obligation = traits:: Obligation :: new ( cause, self . param_env , predicate) ;
14001405 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+ } ) {
14021441 // This candidate's primary obligation doesn't even
14031442 // select - don't bother registering anything in
14041443 // `potentially_unsatisfied_predicates`.
14051444 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) ;
14161445 }
14171446 }
14181447 vec ! [ ]
@@ -1429,9 +1458,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
14291458 let o = self . resolve_vars_if_possible ( & o) ;
14301459 if !self . predicate_may_hold ( & o) {
14311460 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 ) ) ;
14351462 }
14361463 }
14371464
0 commit comments