9
9
// except according to those terms.
10
10
11
11
use super :: MethodError ;
12
+ use super :: NoMatchData ;
12
13
use super :: ItemIndex ;
13
- use super :: { CandidateSource , ImplSource , TraitSource } ;
14
+ use super :: { CandidateSource , ImplSource , TraitSource } ;
14
15
use super :: suggest;
15
16
16
17
use check;
@@ -19,7 +20,7 @@ use middle::fast_reject;
19
20
use middle:: subst;
20
21
use middle:: subst:: Subst ;
21
22
use middle:: traits;
22
- use middle:: ty:: { self , RegionEscape , Ty , ToPolyTraitRef } ;
23
+ use middle:: ty:: { self , RegionEscape , Ty , ToPolyTraitRef , TraitRef } ;
23
24
use middle:: ty_fold:: TypeFoldable ;
24
25
use middle:: infer;
25
26
use middle:: infer:: InferCtxt ;
@@ -42,7 +43,14 @@ struct ProbeContext<'a, 'tcx:'a> {
42
43
inherent_candidates : Vec < Candidate < ' tcx > > ,
43
44
extension_candidates : Vec < Candidate < ' tcx > > ,
44
45
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
45
49
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 > >
46
54
}
47
55
48
56
#[ derive( Debug ) ]
@@ -104,7 +112,7 @@ pub enum PickKind<'tcx> {
104
112
WhereClausePick ( /* Trait */ ty:: PolyTraitRef < ' tcx > , ItemIndex ) ,
105
113
}
106
114
107
- pub type PickResult < ' tcx > = Result < Pick < ' tcx > , MethodError > ;
115
+ pub type PickResult < ' tcx > = Result < Pick < ' tcx > , MethodError < ' tcx > > ;
108
116
109
117
#[ derive( PartialEq , Eq , Copy , Clone , Debug ) ]
110
118
pub enum Mode {
@@ -141,7 +149,8 @@ pub fn probe<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
141
149
let steps = if mode == Mode :: MethodCall {
142
150
match create_steps ( fcx, span, self_ty) {
143
151
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) ) ) ,
145
154
}
146
155
} else {
147
156
vec ! [ CandidateStep {
@@ -242,6 +251,7 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> {
242
251
steps : Rc :: new ( steps) ,
243
252
opt_simplified_steps : opt_simplified_steps,
244
253
static_candidates : Vec :: new ( ) ,
254
+ unsatisfied_predicates : Vec :: new ( ) ,
245
255
}
246
256
}
247
257
@@ -563,7 +573,7 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> {
563
573
564
574
fn assemble_extension_candidates_for_traits_in_scope ( & mut self ,
565
575
expr_id : ast:: NodeId )
566
- -> Result < ( ) , MethodError >
576
+ -> Result < ( ) , MethodError < ' tcx > >
567
577
{
568
578
let mut duplicates = HashSet :: new ( ) ;
569
579
let opt_applicable_traits = self . fcx . ccx . trait_map . get ( & expr_id) ;
@@ -577,7 +587,7 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> {
577
587
Ok ( ( ) )
578
588
}
579
589
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 > > {
581
591
let mut duplicates = HashSet :: new ( ) ;
582
592
for trait_info in suggest:: all_traits ( self . fcx . ccx ) {
583
593
if duplicates. insert ( trait_info. def_id ) {
@@ -589,7 +599,7 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> {
589
599
590
600
fn assemble_extension_candidates_for_trait ( & mut self ,
591
601
trait_def_id : ast:: DefId )
592
- -> Result < ( ) , MethodError >
602
+ -> Result < ( ) , MethodError < ' tcx > >
593
603
{
594
604
debug ! ( "assemble_extension_candidates_for_trait(trait_def_id={:?})" ,
595
605
trait_def_id) ;
@@ -709,7 +719,7 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> {
709
719
trait_def_id : ast:: DefId ,
710
720
item : ty:: ImplOrTraitItem < ' tcx > ,
711
721
item_index : usize )
712
- -> Result < ( ) , MethodError >
722
+ -> Result < ( ) , MethodError < ' tcx > >
713
723
{
714
724
// Check if this is one of the Fn,FnMut,FnOnce traits.
715
725
let tcx = self . tcx ( ) ;
@@ -868,6 +878,7 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> {
868
878
}
869
879
870
880
let static_candidates = mem:: replace ( & mut self . static_candidates , vec ! [ ] ) ;
881
+ let unsatisfied_predicates = mem:: replace ( & mut self . unsatisfied_predicates , vec ! [ ] ) ;
871
882
872
883
// things failed, so lets look at all traits, for diagnostic purposes now:
873
884
self . reset ( ) ;
@@ -892,7 +903,7 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> {
892
903
}
893
904
}
894
905
} ) . collect ( ) ,
895
- Some ( Err ( MethodError :: NoMatch ( _ , others, _ ) ) ) => {
906
+ Some ( Err ( MethodError :: NoMatch ( NoMatchData { out_of_scope_traits : others, .. } ) ) ) => {
896
907
assert ! ( others. is_empty( ) ) ;
897
908
vec ! [ ]
898
909
}
@@ -903,7 +914,8 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> {
903
914
None => vec ! [ ] ,
904
915
} ;
905
916
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 ) ) )
907
919
}
908
920
909
921
fn pick_core ( & mut self ) -> Option < PickResult < ' tcx > > {
@@ -991,25 +1003,35 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> {
991
1003
fn pick_method ( & mut self , self_ty : Ty < ' tcx > ) -> Option < PickResult < ' tcx > > {
992
1004
debug ! ( "pick_method(self_ty={})" , self . infcx( ) . ty_to_string( self_ty) ) ;
993
1005
1006
+ let mut possibly_unsatisfied_predicates = Vec :: new ( ) ;
1007
+
994
1008
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) {
996
1011
None => { }
997
1012
Some ( pick) => {
998
1013
return Some ( pick) ;
999
1014
}
1000
1015
}
1001
1016
1002
1017
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
1004
1024
}
1005
1025
1006
1026
fn consider_candidates ( & self ,
1007
1027
self_ty : Ty < ' tcx > ,
1008
- probes : & [ Candidate < ' tcx > ] )
1028
+ probes : & [ Candidate < ' tcx > ] ,
1029
+ possibly_unsatisfied_predicates : & mut Vec < TraitRef < ' tcx > > )
1009
1030
-> Option < PickResult < ' tcx > > {
1010
1031
let mut applicable_candidates: Vec < _ > =
1011
1032
probes. iter ( )
1012
- . filter ( |& probe| self . consider_probe ( self_ty, probe) )
1033
+ . filter ( |& probe| self . consider_probe ( self_ty,
1034
+ probe, possibly_unsatisfied_predicates) )
1013
1035
. collect ( ) ;
1014
1036
1015
1037
debug ! ( "applicable_candidates: {:?}" , applicable_candidates) ;
@@ -1032,7 +1054,8 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> {
1032
1054
} )
1033
1055
}
1034
1056
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 {
1036
1059
debug ! ( "consider_probe: self_ty={:?} probe={:?}" ,
1037
1060
self_ty,
1038
1061
probe) ;
@@ -1071,10 +1094,18 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> {
1071
1094
debug ! ( "impl_obligations={:?}" , obligations) ;
1072
1095
1073
1096
// 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
1078
1109
}
1079
1110
1080
1111
ProjectionCandidate ( ..) |
0 commit comments