@@ -59,6 +59,7 @@ use core::PackageIdSpec;
5959use core:: { Dependency , PackageId , Registry , Summary } ;
6060use util:: config:: Config ;
6161use util:: errors:: { CargoError , CargoResult } ;
62+ use util:: lev_distance:: lev_distance;
6263use util:: profile;
6364
6465use self :: context:: { Activations , Context } ;
@@ -230,7 +231,9 @@ fn activate_deps_loop(
230231 // to amortize the cost of the current time lookup.
231232 ticks += 1 ;
232233 if let Some ( config) = config {
233- if config. shell ( ) . is_err_tty ( ) && !printed && ticks % 1000 == 0
234+ if config. shell ( ) . is_err_tty ( )
235+ && !printed
236+ && ticks % 1000 == 0
234237 && start. elapsed ( ) - deps_time > time_to_print
235238 {
236239 printed = true ;
@@ -857,12 +860,14 @@ fn activation_error(
857860 msg. push_str ( "\n versions that meet the requirements `" ) ;
858861 msg. push_str ( & dep. version_req ( ) . to_string ( ) ) ;
859862 msg. push_str ( "` are: " ) ;
860- msg. push_str ( & candidates
861- . iter ( )
862- . map ( |v| v. summary . version ( ) )
863- . map ( |v| v. to_string ( ) )
864- . collect :: < Vec < _ > > ( )
865- . join ( ", " ) ) ;
863+ msg. push_str (
864+ & candidates
865+ . iter ( )
866+ . map ( |v| v. summary . version ( ) )
867+ . map ( |v| v. to_string ( ) )
868+ . collect :: < Vec < _ > > ( )
869+ . join ( ", " ) ,
870+ ) ;
866871
867872 let mut conflicting_activations: Vec < _ > = conflicting_activations. iter ( ) . collect ( ) ;
868873 conflicting_activations. sort_unstable ( ) ;
@@ -922,17 +927,16 @@ fn activation_error(
922927 return format_err ! ( "{}" , msg) ;
923928 }
924929
925- // Once we're all the way down here, we're definitely lost in the
926- // weeds! We didn't actually find any candidates, so we need to
930+ // We didn't actually find any candidates, so we need to
927931 // give an error message that nothing was found.
928932 //
929- // Note that we re-query the registry with a new dependency that
930- // allows any version so we can give some nicer error reporting
931- // which indicates a few versions that were actually found.
933+ // Maybe the user mistyped the ver_req? Like `dep="2"` when `dep="0.2"`
934+ // was meant. So we re-query the registry with `deb="*"` so we can
935+ // list a few versions that were actually found.
932936 let all_req = semver:: VersionReq :: parse ( "*" ) . unwrap ( ) ;
933937 let mut new_dep = dep. clone ( ) ;
934938 new_dep. set_version_req ( all_req) ;
935- let mut candidates = match registry. query_vec ( & new_dep) {
939+ let mut candidates = match registry. query_vec ( & new_dep, false ) {
936940 Ok ( candidates) => candidates,
937941 Err ( e) => return e,
938942 } ;
@@ -977,12 +981,41 @@ fn activation_error(
977981
978982 msg
979983 } else {
984+ // Maybe the user mistyped the name? Like `dep-thing` when `Dep_Thing`
985+ // was meant. So we try asking the registry for a `fuzzy` search for suggestions.
986+ let mut candidates = Vec :: new ( ) ;
987+ if let Err ( e) = registry. query ( & new_dep, & mut |s| candidates. push ( s. name ( ) ) , true ) {
988+ return e;
989+ } ;
990+ candidates. sort_unstable ( ) ;
991+ candidates. dedup ( ) ;
992+ let mut candidates: Vec < _ > = candidates
993+ . iter ( )
994+ . map ( |n| ( lev_distance ( & * new_dep. name ( ) , & * n) , n) )
995+ . filter ( |& ( d, _) | d < 4 )
996+ . collect ( ) ;
997+ candidates. sort_by_key ( |o| o. 0 ) ;
980998 let mut msg = format ! (
981999 "no matching package named `{}` found\n \
9821000 location searched: {}\n ",
9831001 dep. name( ) ,
9841002 dep. source_id( )
9851003 ) ;
1004+ if !candidates. is_empty ( ) {
1005+ let mut names = candidates
1006+ . iter ( )
1007+ . take ( 3 )
1008+ . map ( |c| c. 1 . as_str ( ) )
1009+ . collect :: < Vec < _ > > ( ) ;
1010+
1011+ if candidates. len ( ) > 3 {
1012+ names. push ( "..." ) ;
1013+ }
1014+
1015+ msg. push_str ( "did you mean: " ) ;
1016+ msg. push_str ( & names. join ( ", " ) ) ;
1017+ msg. push_str ( "\n " ) ;
1018+ }
9861019 msg. push_str ( "required by " ) ;
9871020 msg. push_str ( & describe_path ( & graph. path_to_top ( parent. package_id ( ) ) ) ) ;
9881021
0 commit comments