@@ -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