99// except according to those terms.
1010
1111use super :: MethodError ;
12+ use super :: NoMatchData ;
1213use super :: ItemIndex ;
13- use super :: { CandidateSource , ImplSource , TraitSource } ;
14+ use super :: { CandidateSource , ImplSource , TraitSource } ;
1415use super :: suggest;
1516
1617use check;
@@ -19,7 +20,7 @@ use middle::fast_reject;
1920use middle:: subst;
2021use middle:: subst:: Subst ;
2122use middle:: traits;
22- use middle:: ty:: { self , RegionEscape , Ty , ToPolyTraitRef } ;
23+ use middle:: ty:: { self , RegionEscape , Ty , ToPolyTraitRef , TraitRef } ;
2324use middle:: ty_fold:: TypeFoldable ;
2425use middle:: infer;
2526use middle:: infer:: InferCtxt ;
@@ -42,7 +43,14 @@ struct ProbeContext<'a, 'tcx:'a> {
4243 inherent_candidates : Vec < Candidate < ' tcx > > ,
4344 extension_candidates : Vec < Candidate < ' tcx > > ,
4445 impl_dups : HashSet < ast:: DefId > ,
46+
47+ /// Collects near misses when the candidate functions are missing a `self` keyword and is only
48+ /// used for error reporting
4549 static_candidates : Vec < CandidateSource > ,
50+
51+ /// Collects near misses when trait bounds for type parameters are unsatisfied and is only used
52+ /// for error reporting
53+ unsatisfied_predicates : Vec < TraitRef < ' tcx > >
4654}
4755
4856#[ derive( Debug ) ]
@@ -104,7 +112,7 @@ pub enum PickKind<'tcx> {
104112 WhereClausePick ( /* Trait */ ty:: PolyTraitRef < ' tcx > , ItemIndex ) ,
105113}
106114
107- pub type PickResult < ' tcx > = Result < Pick < ' tcx > , MethodError > ;
115+ pub type PickResult < ' tcx > = Result < Pick < ' tcx > , MethodError < ' tcx > > ;
108116
109117#[ derive( PartialEq , Eq , Copy , Clone , Debug ) ]
110118pub enum Mode {
@@ -141,7 +149,8 @@ pub fn probe<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
141149 let steps = if mode == Mode :: MethodCall {
142150 match create_steps ( fcx, span, self_ty) {
143151 Some ( steps) => steps,
144- None => return Err ( MethodError :: NoMatch ( Vec :: new ( ) , Vec :: new ( ) , mode) ) ,
152+ None =>return Err ( MethodError :: NoMatch ( NoMatchData :: new ( Vec :: new ( ) , Vec :: new ( ) ,
153+ Vec :: new ( ) , mode) ) ) ,
145154 }
146155 } else {
147156 vec ! [ CandidateStep {
@@ -242,6 +251,7 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> {
242251 steps : Rc :: new ( steps) ,
243252 opt_simplified_steps : opt_simplified_steps,
244253 static_candidates : Vec :: new ( ) ,
254+ unsatisfied_predicates : Vec :: new ( ) ,
245255 }
246256 }
247257
@@ -563,7 +573,7 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> {
563573
564574 fn assemble_extension_candidates_for_traits_in_scope ( & mut self ,
565575 expr_id : ast:: NodeId )
566- -> Result < ( ) , MethodError >
576+ -> Result < ( ) , MethodError < ' tcx > >
567577 {
568578 let mut duplicates = HashSet :: new ( ) ;
569579 let opt_applicable_traits = self . fcx . ccx . trait_map . get ( & expr_id) ;
@@ -577,7 +587,7 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> {
577587 Ok ( ( ) )
578588 }
579589
580- fn assemble_extension_candidates_for_all_traits ( & mut self ) -> Result < ( ) , MethodError > {
590+ fn assemble_extension_candidates_for_all_traits ( & mut self ) -> Result < ( ) , MethodError < ' tcx > > {
581591 let mut duplicates = HashSet :: new ( ) ;
582592 for trait_info in suggest:: all_traits ( self . fcx . ccx ) {
583593 if duplicates. insert ( trait_info. def_id ) {
@@ -589,7 +599,7 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> {
589599
590600 fn assemble_extension_candidates_for_trait ( & mut self ,
591601 trait_def_id : ast:: DefId )
592- -> Result < ( ) , MethodError >
602+ -> Result < ( ) , MethodError < ' tcx > >
593603 {
594604 debug ! ( "assemble_extension_candidates_for_trait(trait_def_id={:?})" ,
595605 trait_def_id) ;
@@ -709,7 +719,7 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> {
709719 trait_def_id : ast:: DefId ,
710720 item : ty:: ImplOrTraitItem < ' tcx > ,
711721 item_index : usize )
712- -> Result < ( ) , MethodError >
722+ -> Result < ( ) , MethodError < ' tcx > >
713723 {
714724 // Check if this is one of the Fn,FnMut,FnOnce traits.
715725 let tcx = self . tcx ( ) ;
@@ -868,6 +878,7 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> {
868878 }
869879
870880 let static_candidates = mem:: replace ( & mut self . static_candidates , vec ! [ ] ) ;
881+ let unsatisfied_predicates = mem:: replace ( & mut self . unsatisfied_predicates , vec ! [ ] ) ;
871882
872883 // things failed, so lets look at all traits, for diagnostic purposes now:
873884 self . reset ( ) ;
@@ -892,7 +903,7 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> {
892903 }
893904 }
894905 } ) . collect ( ) ,
895- Some ( Err ( MethodError :: NoMatch ( _ , others, _ ) ) ) => {
906+ Some ( Err ( MethodError :: NoMatch ( NoMatchData { out_of_scope_traits : others, .. } ) ) ) => {
896907 assert ! ( others. is_empty( ) ) ;
897908 vec ! [ ]
898909 }
@@ -903,7 +914,8 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> {
903914 None => vec ! [ ] ,
904915 } ;
905916
906- Err ( MethodError :: NoMatch ( static_candidates, out_of_scope_traits, self . mode ) )
917+ Err ( MethodError :: NoMatch ( NoMatchData :: new ( static_candidates, unsatisfied_predicates,
918+ out_of_scope_traits, self . mode ) ) )
907919 }
908920
909921 fn pick_core ( & mut self ) -> Option < PickResult < ' tcx > > {
@@ -991,25 +1003,35 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> {
9911003 fn pick_method ( & mut self , self_ty : Ty < ' tcx > ) -> Option < PickResult < ' tcx > > {
9921004 debug ! ( "pick_method(self_ty={})" , self . infcx( ) . ty_to_string( self_ty) ) ;
9931005
1006+ let mut possibly_unsatisfied_predicates = Vec :: new ( ) ;
1007+
9941008 debug ! ( "searching inherent candidates" ) ;
995- match self . consider_candidates ( self_ty, & self . inherent_candidates ) {
1009+ match self . consider_candidates ( self_ty, & self . inherent_candidates ,
1010+ & mut possibly_unsatisfied_predicates) {
9961011 None => { }
9971012 Some ( pick) => {
9981013 return Some ( pick) ;
9991014 }
10001015 }
10011016
10021017 debug ! ( "searching extension candidates" ) ;
1003- self . consider_candidates ( self_ty, & self . extension_candidates )
1018+ let res = self . consider_candidates ( self_ty, & self . extension_candidates ,
1019+ & mut possibly_unsatisfied_predicates) ;
1020+ if let None = res {
1021+ self . unsatisfied_predicates . extend ( possibly_unsatisfied_predicates) ;
1022+ }
1023+ res
10041024 }
10051025
10061026 fn consider_candidates ( & self ,
10071027 self_ty : Ty < ' tcx > ,
1008- probes : & [ Candidate < ' tcx > ] )
1028+ probes : & [ Candidate < ' tcx > ] ,
1029+ possibly_unsatisfied_predicates : & mut Vec < TraitRef < ' tcx > > )
10091030 -> Option < PickResult < ' tcx > > {
10101031 let mut applicable_candidates: Vec < _ > =
10111032 probes. iter ( )
1012- . filter ( |& probe| self . consider_probe ( self_ty, probe) )
1033+ . filter ( |& probe| self . consider_probe ( self_ty,
1034+ probe, possibly_unsatisfied_predicates) )
10131035 . collect ( ) ;
10141036
10151037 debug ! ( "applicable_candidates: {:?}" , applicable_candidates) ;
@@ -1032,7 +1054,8 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> {
10321054 } )
10331055 }
10341056
1035- fn consider_probe ( & self , self_ty : Ty < ' tcx > , probe : & Candidate < ' tcx > ) -> bool {
1057+ fn consider_probe ( & self , self_ty : Ty < ' tcx > , probe : & Candidate < ' tcx > ,
1058+ possibly_unsatisfied_predicates : & mut Vec < TraitRef < ' tcx > > ) -> bool {
10361059 debug ! ( "consider_probe: self_ty={:?} probe={:?}" ,
10371060 self_ty,
10381061 probe) ;
@@ -1071,10 +1094,18 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> {
10711094 debug ! ( "impl_obligations={:?}" , obligations) ;
10721095
10731096 // Evaluate those obligations to see if they might possibly hold.
1074- obligations. iter ( )
1075- . chain ( norm_obligations. iter ( ) ) . chain ( ref_obligations. iter ( ) )
1076- . all ( |o| selcx. evaluate_obligation ( o) )
1077-
1097+ let mut all_true = true ;
1098+ for o in obligations. iter ( )
1099+ . chain ( norm_obligations. iter ( ) )
1100+ . chain ( ref_obligations. iter ( ) ) {
1101+ if !selcx. evaluate_obligation ( o) {
1102+ all_true = false ;
1103+ if let & ty:: Predicate :: Trait ( ref pred) = & o. predicate {
1104+ possibly_unsatisfied_predicates. push ( pred. 0 . trait_ref ) ;
1105+ }
1106+ }
1107+ }
1108+ all_true
10781109 }
10791110
10801111 ProjectionCandidate ( ..) |
0 commit comments