@@ -4,7 +4,7 @@ use std::task::Poll;
44use crate :: core:: { Dependency , PackageId , Registry , Summary } ;
55use crate :: sources:: source:: QueryKind ;
66use crate :: util:: edit_distance:: edit_distance;
7- use crate :: util:: { Config , VersionExt } ;
7+ use crate :: util:: { Config , OptVersionReq , VersionExt } ;
88use anyhow:: Error ;
99
1010use super :: context:: Context ;
@@ -224,9 +224,8 @@ pub(super) fn activation_error(
224224 // Maybe the user mistyped the ver_req? Like `dep="2"` when `dep="0.2"`
225225 // was meant. So we re-query the registry with `dep="*"` so we can
226226 // list a few versions that were actually found.
227- let all_req = semver:: VersionReq :: parse ( "*" ) . unwrap ( ) ;
228227 let mut new_dep = dep. clone ( ) ;
229- new_dep. set_version_req ( all_req ) ;
228+ new_dep. set_version_req ( OptVersionReq :: Any ) ;
230229
231230 let mut candidates = loop {
232231 match registry. query_vec ( & new_dep, QueryKind :: Exact ) {
@@ -241,127 +240,122 @@ pub(super) fn activation_error(
241240
242241 candidates. sort_unstable_by ( |a, b| b. version ( ) . cmp ( a. version ( ) ) ) ;
243242
244- let mut msg =
245- if !candidates. is_empty ( ) {
246- let versions = {
247- let mut versions = candidates
248- . iter ( )
249- . take ( 3 )
250- . map ( |cand| cand. version ( ) . to_string ( ) )
251- . collect :: < Vec < _ > > ( ) ;
252-
253- if candidates. len ( ) > 3 {
254- versions. push ( "..." . into ( ) ) ;
255- }
243+ let mut msg = if !candidates. is_empty ( ) {
244+ let versions = {
245+ let mut versions = candidates
246+ . iter ( )
247+ . take ( 3 )
248+ . map ( |cand| cand. version ( ) . to_string ( ) )
249+ . collect :: < Vec < _ > > ( ) ;
256250
257- versions. join ( ", " )
258- } ;
251+ if candidates. len ( ) > 3 {
252+ versions. push ( "..." . into ( ) ) ;
253+ }
259254
260- let locked_version = dep
261- . version_req ( )
262- . locked_version ( )
263- . map ( |v| format ! ( " (locked to {})" , v) )
264- . unwrap_or_default ( ) ;
255+ versions. join ( ", " )
256+ } ;
257+
258+ let locked_version = dep
259+ . version_req ( )
260+ . locked_version ( )
261+ . map ( |v| format ! ( " (locked to {})" , v) )
262+ . unwrap_or_default ( ) ;
263+
264+ let mut msg = format ! (
265+ "failed to select a version for the requirement `{} = \" {}\" `{}\n \
266+ candidate versions found which didn't match: {}\n \
267+ location searched: {}\n ",
268+ dep. package_name( ) ,
269+ dep. version_req( ) ,
270+ locked_version,
271+ versions,
272+ registry. describe_source( dep. source_id( ) ) ,
273+ ) ;
274+ msg. push_str ( "required by " ) ;
275+ msg. push_str ( & describe_path_in_context ( cx, & parent. package_id ( ) ) ) ;
265276
266- let mut msg = format ! (
267- "failed to select a version for the requirement `{} = \" {}\" `{}\n \
268- candidate versions found which didn't match: {}\n \
269- location searched: {}\n ",
270- dep. package_name( ) ,
271- dep. version_req( ) ,
272- locked_version,
273- versions,
274- registry. describe_source( dep. source_id( ) ) ,
277+ // If we have a pre-release candidate, then that may be what our user is looking for
278+ if let Some ( pre) = candidates. iter ( ) . find ( |c| c. version ( ) . is_prerelease ( ) ) {
279+ msg. push_str ( "\n if you are looking for the prerelease package it needs to be specified explicitly" ) ;
280+ msg. push_str ( & format ! (
281+ "\n {} = {{ version = \" {}\" }}" ,
282+ pre. name( ) ,
283+ pre. version( )
284+ ) ) ;
285+ }
286+
287+ // If we have a path dependency with a locked version, then this may
288+ // indicate that we updated a sub-package and forgot to run `cargo
289+ // update`. In this case try to print a helpful error!
290+ if dep. source_id ( ) . is_path ( ) && dep. version_req ( ) . is_locked ( ) {
291+ msg. push_str (
292+ "\n consider running `cargo update` to update \
293+ a path dependency's locked version",
275294 ) ;
276- msg. push_str ( "required by " ) ;
277- msg. push_str ( & describe_path_in_context ( cx, & parent. package_id ( ) ) ) ;
278-
279- // If we have a path dependency with a locked version, then this may
280- // indicate that we updated a sub-package and forgot to run `cargo
281- // update`. In this case try to print a helpful error!
282- if dep. source_id ( ) . is_path ( ) && dep. version_req ( ) . is_locked ( ) {
283- msg. push_str (
284- "\n consider running `cargo update` to update \
285- a path dependency's locked version",
286- ) ;
287- }
295+ }
296+
297+ if registry. is_replaced ( dep. source_id ( ) ) {
298+ msg. push_str ( "\n perhaps a crate was updated and forgotten to be re-vendored?" ) ;
299+ }
288300
289- if registry. is_replaced ( dep. source_id ( ) ) {
290- msg. push_str ( "\n perhaps a crate was updated and forgotten to be re-vendored?" ) ;
301+ msg
302+ } else {
303+ // Maybe the user mistyped the name? Like `dep-thing` when `Dep_Thing`
304+ // was meant. So we try asking the registry for a `fuzzy` search for suggestions.
305+ let mut candidates = loop {
306+ match registry. query_vec ( & new_dep, QueryKind :: Fuzzy ) {
307+ Poll :: Ready ( Ok ( candidates) ) => break candidates,
308+ Poll :: Ready ( Err ( e) ) => return to_resolve_err ( e) ,
309+ Poll :: Pending => match registry. block_until_ready ( ) {
310+ Ok ( ( ) ) => continue ,
311+ Err ( e) => return to_resolve_err ( e) ,
312+ } ,
291313 }
314+ } ;
292315
293- msg
316+ candidates. sort_unstable_by_key ( |a| a. name ( ) ) ;
317+ candidates. dedup_by ( |a, b| a. name ( ) == b. name ( ) ) ;
318+ let mut candidates: Vec < _ > = candidates
319+ . iter ( )
320+ . filter_map ( |n| Some ( ( edit_distance ( & * new_dep. package_name ( ) , & * n. name ( ) , 3 ) ?, n) ) )
321+ . collect ( ) ;
322+ candidates. sort_by_key ( |o| o. 0 ) ;
323+ let mut msg: String ;
324+ if candidates. is_empty ( ) {
325+ msg = format ! ( "no matching package named `{}` found\n " , dep. package_name( ) ) ;
294326 } else {
295- // Maybe the user mistyped the name? Like `dep-thing` when `Dep_Thing`
296- // was meant. So we try asking the registry for a `fuzzy` search for suggestions.
297- let mut candidates = loop {
298- match registry. query_vec ( & new_dep, QueryKind :: Fuzzy ) {
299- Poll :: Ready ( Ok ( candidates) ) => break candidates,
300- Poll :: Ready ( Err ( e) ) => return to_resolve_err ( e) ,
301- Poll :: Pending => match registry. block_until_ready ( ) {
302- Ok ( ( ) ) => continue ,
303- Err ( e) => return to_resolve_err ( e) ,
304- } ,
305- }
306- } ;
307-
308- candidates. sort_unstable_by_key ( |a| a. name ( ) ) ;
309- candidates. dedup_by ( |a, b| a. name ( ) == b. name ( ) ) ;
310- let mut candidates: Vec < _ > = candidates
327+ msg = format ! (
328+ "no matching package found\n searched package name: `{}`\n " ,
329+ dep. package_name( )
330+ ) ;
331+ let mut names = candidates
311332 . iter ( )
312- . filter_map ( |n| Some ( ( edit_distance ( & * new_dep. package_name ( ) , & * n. name ( ) , 3 ) ?, n) ) )
313- . collect ( ) ;
314- candidates. sort_by_key ( |o| o. 0 ) ;
315- let mut msg: String ;
316- if candidates. is_empty ( ) {
317- msg = format ! ( "no matching package named `{}` found\n " , dep. package_name( ) ) ;
318- } else {
319- msg = format ! (
320- "no matching package found\n searched package name: `{}`\n " ,
321- dep. package_name( )
322- ) ;
323-
324- // If dependency package name is equal to the name of the candidate here
325- // it may be a prerelease package which hasn't been specified correctly
326- if dep. package_name ( ) == candidates[ 0 ] . 1 . name ( )
327- && candidates[ 0 ] . 1 . package_id ( ) . version ( ) . is_prerelease ( )
328- {
329- msg. push_str ( "prerelease package needs to be specified explicitly\n " ) ;
330- msg. push_str ( & format ! (
331- "{name} = {{ version = \" {version}\" }}" ,
332- name = candidates[ 0 ] . 1 . name( ) ,
333- version = candidates[ 0 ] . 1 . package_id( ) . version( )
334- ) ) ;
335- } else {
336- let mut names = candidates
337- . iter ( )
338- . take ( 3 )
339- . map ( |c| c. 1 . name ( ) . as_str ( ) )
340- . collect :: < Vec < _ > > ( ) ;
341-
342- if candidates. len ( ) > 3 {
343- names. push ( "..." ) ;
344- }
345- // Vertically align first suggestion with missing crate name
346- // so a typo jumps out at you.
347- msg. push_str ( "perhaps you meant: " ) ;
348- msg. push_str ( & names. iter ( ) . enumerate ( ) . fold (
349- String :: default ( ) ,
350- |acc, ( i, el) | match i {
351- 0 => acc + el,
352- i if names. len ( ) - 1 == i && candidates. len ( ) <= 3 => acc + " or " + el,
353- _ => acc + ", " + el,
354- } ,
355- ) ) ;
356- }
357- msg. push ( '\n' ) ;
333+ . take ( 3 )
334+ . map ( |c| c. 1 . name ( ) . as_str ( ) )
335+ . collect :: < Vec < _ > > ( ) ;
336+
337+ if candidates. len ( ) > 3 {
338+ names. push ( "..." ) ;
358339 }
359- msg. push_str ( & format ! ( "location searched: {}\n " , dep. source_id( ) ) ) ;
360- msg. push_str ( "required by " ) ;
361- msg. push_str ( & describe_path_in_context ( cx, & parent. package_id ( ) ) ) ;
340+ // Vertically align first suggestion with missing crate name
341+ // so a typo jumps out at you.
342+ msg. push_str ( "perhaps you meant: " ) ;
343+ msg. push_str ( & names. iter ( ) . enumerate ( ) . fold (
344+ String :: default ( ) ,
345+ |acc, ( i, el) | match i {
346+ 0 => acc + el,
347+ i if names. len ( ) - 1 == i && candidates. len ( ) <= 3 => acc + " or " + el,
348+ _ => acc + ", " + el,
349+ } ,
350+ ) ) ;
351+ msg. push ( '\n' ) ;
352+ }
353+ msg. push_str ( & format ! ( "location searched: {}\n " , dep. source_id( ) ) ) ;
354+ msg. push_str ( "required by " ) ;
355+ msg. push_str ( & describe_path_in_context ( cx, & parent. package_id ( ) ) ) ;
362356
363- msg
364- } ;
357+ msg
358+ } ;
365359
366360 if let Some ( config) = config {
367361 if config. offline ( ) {
0 commit comments