@@ -23,7 +23,7 @@ use rustc::infer::type_variable::TypeVariableOrigin;
23
23
use rustc:: util:: nodemap:: FxHashSet ;
24
24
use rustc:: infer:: { self , InferOk } ;
25
25
use syntax:: ast;
26
- use syntax:: util:: lev_distance:: lev_distance;
26
+ use syntax:: util:: lev_distance:: { lev_distance, find_best_match_for_name } ;
27
27
use syntax_pos:: Span ;
28
28
use rustc:: hir;
29
29
use std:: mem;
@@ -248,7 +248,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
248
248
return Err ( MethodError :: NoMatch ( NoMatchData :: new ( Vec :: new ( ) ,
249
249
Vec :: new ( ) ,
250
250
Vec :: new ( ) ,
251
- Vec :: new ( ) ,
251
+ None ,
252
252
mode) ) )
253
253
}
254
254
}
@@ -806,12 +806,12 @@ impl<'a, 'gcx, 'tcx> ProbeContext<'a, 'gcx, 'tcx> {
806
806
if let Some ( def) = private_candidate {
807
807
return Err ( MethodError :: PrivateMatch ( def, out_of_scope_traits) ) ;
808
808
}
809
- let lev_candidates = self . probe_for_lev_candidates ( ) ?;
809
+ let lev_candidate = self . probe_for_lev_candidate ( ) ?;
810
810
811
811
Err ( MethodError :: NoMatch ( NoMatchData :: new ( static_candidates,
812
- lev_candidates,
813
812
unsatisfied_predicates,
814
813
out_of_scope_traits,
814
+ lev_candidate,
815
815
self . mode ) ) )
816
816
}
817
817
@@ -1133,9 +1133,10 @@ impl<'a, 'gcx, 'tcx> ProbeContext<'a, 'gcx, 'tcx> {
1133
1133
} )
1134
1134
}
1135
1135
1136
- /// Similarly to `probe_for_return_type`, this method attempts to find candidate methods where
1137
- /// the method name may have been misspelt.
1138
- fn probe_for_lev_candidates ( & mut self ) -> Result < Vec < ty:: AssociatedItem > , MethodError < ' tcx > > {
1136
+ /// Similarly to `probe_for_return_type`, this method attempts to find the best matching
1137
+ /// candidate method where the method name may have been misspelt. Similarly to other
1138
+ /// Levenshtein based suggestions, we provide at most one such suggestion.
1139
+ fn probe_for_lev_candidate ( & mut self ) -> Result < Option < ty:: AssociatedItem > , MethodError < ' tcx > > {
1139
1140
debug ! ( "Probing for method names similar to {:?}" ,
1140
1141
self . method_name) ;
1141
1142
@@ -1149,7 +1150,7 @@ impl<'a, 'gcx, 'tcx> ProbeContext<'a, 'gcx, 'tcx> {
1149
1150
1150
1151
let method_names = pcx. candidate_method_names ( ) ;
1151
1152
pcx. allow_similar_names = false ;
1152
- Ok ( method_names
1153
+ let applicable_close_candidates : Vec < ty :: AssociatedItem > = method_names
1153
1154
. iter ( )
1154
1155
. filter_map ( |& method_name| {
1155
1156
pcx. reset ( ) ;
@@ -1162,7 +1163,21 @@ impl<'a, 'gcx, 'tcx> ProbeContext<'a, 'gcx, 'tcx> {
1162
1163
. and_then ( |pick| Some ( pick. item ) )
1163
1164
} )
1164
1165
} )
1165
- . collect ( ) )
1166
+ . collect ( ) ;
1167
+
1168
+ if applicable_close_candidates. is_empty ( ) {
1169
+ Ok ( None )
1170
+ } else {
1171
+ let best_name = {
1172
+ let names = applicable_close_candidates. iter ( ) . map ( |cand| & cand. name ) ;
1173
+ find_best_match_for_name ( names,
1174
+ & self . method_name . unwrap ( ) . as_str ( ) ,
1175
+ None )
1176
+ } . unwrap ( ) ;
1177
+ Ok ( applicable_close_candidates
1178
+ . into_iter ( )
1179
+ . find ( |method| method. name == best_name) )
1180
+ }
1166
1181
} )
1167
1182
}
1168
1183
0 commit comments