@@ -23,7 +23,7 @@ use rustc::infer::type_variable::TypeVariableOrigin;
2323use rustc:: util:: nodemap:: FxHashSet ;
2424use rustc:: infer:: { self , InferOk } ;
2525use syntax:: ast;
26- use syntax:: util:: lev_distance:: lev_distance;
26+ use syntax:: util:: lev_distance:: { lev_distance, find_best_match_for_name } ;
2727use syntax_pos:: Span ;
2828use rustc:: hir;
2929use std:: mem;
@@ -248,7 +248,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
248248 return Err ( MethodError :: NoMatch ( NoMatchData :: new ( Vec :: new ( ) ,
249249 Vec :: new ( ) ,
250250 Vec :: new ( ) ,
251- Vec :: new ( ) ,
251+ None ,
252252 mode) ) )
253253 }
254254 }
@@ -806,12 +806,12 @@ impl<'a, 'gcx, 'tcx> ProbeContext<'a, 'gcx, 'tcx> {
806806 if let Some ( def) = private_candidate {
807807 return Err ( MethodError :: PrivateMatch ( def, out_of_scope_traits) ) ;
808808 }
809- let lev_candidates = self . probe_for_lev_candidates ( ) ?;
809+ let lev_candidate = self . probe_for_lev_candidate ( ) ?;
810810
811811 Err ( MethodError :: NoMatch ( NoMatchData :: new ( static_candidates,
812- lev_candidates,
813812 unsatisfied_predicates,
814813 out_of_scope_traits,
814+ lev_candidate,
815815 self . mode ) ) )
816816 }
817817
@@ -1133,9 +1133,10 @@ impl<'a, 'gcx, 'tcx> ProbeContext<'a, 'gcx, 'tcx> {
11331133 } )
11341134 }
11351135
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 > > {
11391140 debug ! ( "Probing for method names similar to {:?}" ,
11401141 self . method_name) ;
11411142
@@ -1149,7 +1150,7 @@ impl<'a, 'gcx, 'tcx> ProbeContext<'a, 'gcx, 'tcx> {
11491150
11501151 let method_names = pcx. candidate_method_names ( ) ;
11511152 pcx. allow_similar_names = false ;
1152- Ok ( method_names
1153+ let applicable_close_candidates : Vec < ty :: AssociatedItem > = method_names
11531154 . iter ( )
11541155 . filter_map ( |& method_name| {
11551156 pcx. reset ( ) ;
@@ -1162,7 +1163,21 @@ impl<'a, 'gcx, 'tcx> ProbeContext<'a, 'gcx, 'tcx> {
11621163 . and_then ( |pick| Some ( pick. item ) )
11631164 } )
11641165 } )
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+ }
11661181 } )
11671182 }
11681183
0 commit comments