Skip to content

Commit dcde7eb

Browse files
committed
move pre-release specific error message
1 parent 7880215 commit dcde7eb

File tree

3 files changed

+109
-110
lines changed

3 files changed

+109
-110
lines changed

src/cargo/core/resolver/errors.rs

Lines changed: 105 additions & 110 deletions
Original file line numberDiff line numberDiff line change
@@ -240,127 +240,122 @@ pub(super) fn activation_error(
240240

241241
candidates.sort_unstable_by(|a, b| b.version().cmp(a.version()));
242242

243-
let mut msg =
244-
if !candidates.is_empty() {
245-
let versions = {
246-
let mut versions = candidates
247-
.iter()
248-
.take(3)
249-
.map(|cand| cand.version().to_string())
250-
.collect::<Vec<_>>();
251-
252-
if candidates.len() > 3 {
253-
versions.push("...".into());
254-
}
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<_>>();
255250

256-
versions.join(", ")
257-
};
251+
if candidates.len() > 3 {
252+
versions.push("...".into());
253+
}
258254

259-
let locked_version = dep
260-
.version_req()
261-
.locked_version()
262-
.map(|v| format!(" (locked to {})", v))
263-
.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()));
264276

265-
let mut msg = format!(
266-
"failed to select a version for the requirement `{} = \"{}\"`{}\n\
267-
candidate versions found which didn't match: {}\n\
268-
location searched: {}\n",
269-
dep.package_name(),
270-
dep.version_req(),
271-
locked_version,
272-
versions,
273-
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("\nif 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+
"\nconsider running `cargo update` to update \
293+
a path dependency's locked version",
274294
);
275-
msg.push_str("required by ");
276-
msg.push_str(&describe_path_in_context(cx, &parent.package_id()));
277-
278-
// If we have a path dependency with a locked version, then this may
279-
// indicate that we updated a sub-package and forgot to run `cargo
280-
// update`. In this case try to print a helpful error!
281-
if dep.source_id().is_path() && dep.version_req().is_locked() {
282-
msg.push_str(
283-
"\nconsider running `cargo update` to update \
284-
a path dependency's locked version",
285-
);
286-
}
295+
}
296+
297+
if registry.is_replaced(dep.source_id()) {
298+
msg.push_str("\nperhaps a crate was updated and forgotten to be re-vendored?");
299+
}
287300

288-
if registry.is_replaced(dep.source_id()) {
289-
msg.push_str("\nperhaps 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+
},
290313
}
314+
};
291315

292-
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());
293326
} else {
294-
// Maybe the user mistyped the name? Like `dep-thing` when `Dep_Thing`
295-
// was meant. So we try asking the registry for a `fuzzy` search for suggestions.
296-
let mut candidates = loop {
297-
match registry.query_vec(&new_dep, QueryKind::Fuzzy) {
298-
Poll::Ready(Ok(candidates)) => break candidates,
299-
Poll::Ready(Err(e)) => return to_resolve_err(e),
300-
Poll::Pending => match registry.block_until_ready() {
301-
Ok(()) => continue,
302-
Err(e) => return to_resolve_err(e),
303-
},
304-
}
305-
};
306-
307-
candidates.sort_unstable_by_key(|a| a.name());
308-
candidates.dedup_by(|a, b| a.name() == b.name());
309-
let mut candidates: Vec<_> = candidates
327+
msg = format!(
328+
"no matching package found\nsearched package name: `{}`\n",
329+
dep.package_name()
330+
);
331+
let mut names = candidates
310332
.iter()
311-
.filter_map(|n| Some((edit_distance(&*new_dep.package_name(), &*n.name(), 3)?, n)))
312-
.collect();
313-
candidates.sort_by_key(|o| o.0);
314-
let mut msg: String;
315-
if candidates.is_empty() {
316-
msg = format!("no matching package named `{}` found\n", dep.package_name());
317-
} else {
318-
msg = format!(
319-
"no matching package found\nsearched package name: `{}`\n",
320-
dep.package_name()
321-
);
322-
323-
// If dependency package name is equal to the name of the candidate here
324-
// it may be a prerelease package which hasn't been specified correctly
325-
if dep.package_name() == candidates[0].1.name()
326-
&& candidates[0].1.package_id().version().is_prerelease()
327-
{
328-
msg.push_str("prerelease package needs to be specified explicitly\n");
329-
msg.push_str(&format!(
330-
"{name} = {{ version = \"{version}\" }}",
331-
name = candidates[0].1.name(),
332-
version = candidates[0].1.package_id().version()
333-
));
334-
} else {
335-
let mut names = candidates
336-
.iter()
337-
.take(3)
338-
.map(|c| c.1.name().as_str())
339-
.collect::<Vec<_>>();
340-
341-
if candidates.len() > 3 {
342-
names.push("...");
343-
}
344-
// Vertically align first suggestion with missing crate name
345-
// so a typo jumps out at you.
346-
msg.push_str("perhaps you meant: ");
347-
msg.push_str(&names.iter().enumerate().fold(
348-
String::default(),
349-
|acc, (i, el)| match i {
350-
0 => acc + el,
351-
i if names.len() - 1 == i && candidates.len() <= 3 => acc + " or " + el,
352-
_ => acc + ", " + el,
353-
},
354-
));
355-
}
356-
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("...");
357339
}
358-
msg.push_str(&format!("location searched: {}\n", dep.source_id()));
359-
msg.push_str("required by ");
360-
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()));
361356

362-
msg
363-
};
357+
msg
358+
};
364359

365360
if let Some(config) = config {
366361
if config.offline() {

tests/testsuite/patch.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2694,6 +2694,8 @@ fn mismatched_version_with_prerelease() {
26942694
candidate versions found which didn't match: 0.1.1-pre1, 0.0.1
26952695
location searched: `dummy-registry` index (which is replacing registry `crates-io`)
26962696
required by package `foo v0.1.0 [..]`
2697+
if you are looking for the prerelease package it needs to be specified explicitly
2698+
prerelease-deps = { version = "0.1.1-pre1" }
26972699
perhaps a crate was updated and forgotten to be re-vendored?"#,
26982700
)
26992701
.run();

tests/testsuite/registry.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1760,6 +1760,8 @@ error: failed to select a version for the requirement `a = \"^0.1\"`
17601760
candidate versions found which didn't match: 0.1.1-alpha.0
17611761
location searched: [..]
17621762
required by package `b v0.1.0 ([..])`
1763+
if you are looking for the prerelease package it needs to be specified explicitly
1764+
a = { version = \"0.1.1-alpha.0\" }
17631765
",
17641766
)
17651767
.run();

0 commit comments

Comments
 (0)