Skip to content

Commit 70dada8

Browse files
committed
better error messages
1 parent e8ed405 commit 70dada8

File tree

3 files changed

+79
-36
lines changed

3 files changed

+79
-36
lines changed

src/cargo/core/resolver/mod.rs

Lines changed: 44 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -538,6 +538,15 @@ enum ConflictReason {
538538
Links(String),
539539
}
540540

541+
impl ConflictReason {
542+
fn is_links(&self) -> bool {
543+
match self {
544+
&ConflictReason::Semver => false,
545+
&ConflictReason::Links(_) => true,
546+
}
547+
}
548+
}
549+
541550
struct BacktrackFrame<'a> {
542551
cur: usize,
543552
context_backup: Context<'a>,
@@ -835,33 +844,52 @@ fn activation_error(cx: &Context,
835844
dep_path_desc
836845
};
837846
if !candidates.is_empty() {
838-
let mut msg = format!("failed to select a version for `{}`.\n\
839-
all possible versions conflict with \
840-
previously selected packages.\n",
841-
dep.name());
842-
msg.push_str("required by ");
847+
let mut msg = format!("failed to select a version for `{}`.", dep.name());
848+
msg.push_str("\n ... required by ");
843849
msg.push_str(&describe_path(parent.package_id()));
850+
851+
msg.push_str("\nversions that meet the requirements `");
852+
msg.push_str(&dep.version_req().to_string());
853+
msg.push_str("` are: ");
854+
msg.push_str(&candidates.iter()
855+
.map(|v| v.summary.version())
856+
.map(|v| v.to_string())
857+
.collect::<Vec<_>>()
858+
.join(", "));
859+
844860
let mut conflicting_activations: Vec<_> = conflicting_activations.iter().collect();
845861
conflicting_activations.sort_unstable();
846-
for &(p, r) in conflicting_activations.iter().rev() {
862+
let (links_errors, other_errors): (Vec<_>, Vec<_>) = conflicting_activations.drain(..).rev().partition(|&(_, r)| r.is_links());
863+
864+
for &(p, r) in &links_errors {
847865
match r {
848866
&ConflictReason::Links(ref link) => {
849-
msg.push_str("\n multiple packages link to native library `");
850-
msg.push_str(link);
851-
msg.push_str("`, but a native library can be linked only once.")
867+
msg.push_str("\n\nthe package `");
868+
msg.push_str(dep.name());
869+
msg.push_str("` links to the native library `");
870+
msg.push_str(&link);
871+
msg.push_str("`, but it conflicts with a previous package which links to `");
872+
msg.push_str(&link);
873+
msg.push_str("` as well:\n");
852874
},
853875
_ => (),
854876
}
855-
msg.push_str("\n previously selected ");
856877
msg.push_str(&describe_path(p));
857878
}
858879

859-
msg.push_str("\n possible versions to select: ");
860-
msg.push_str(&candidates.iter()
861-
.map(|v| v.summary.version())
862-
.map(|v| v.to_string())
863-
.collect::<Vec<_>>()
864-
.join(", "));
880+
if links_errors.is_empty() {
881+
msg.push_str("\n\nall possible versions conflict with \
882+
previously selected packages.");
883+
}
884+
885+
for &(p, _) in &other_errors {
886+
msg.push_str("\n\n previously selected ");
887+
msg.push_str(&describe_path(p));
888+
}
889+
890+
msg.push_str("\n\nfailed to select a version for `");
891+
msg.push_str(dep.name());
892+
msg.push_str("` which could resolve this conflict");
865893

866894
return format_err!("{}", msg)
867895
}

tests/build-script.rs

Lines changed: 21 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -258,11 +258,13 @@ fn links_duplicates() {
258258
execs().with_status(101)
259259
.with_stderr("\
260260
error: failed to select a version for `a-sys`.
261-
all possible versions conflict with previously selected packages.
262-
required by package `foo v0.5.0 ([..])`
263-
multiple packages link to native library `a`, but a native library can be linked only once.
264-
previously selected package `foo v0.5.0 ([..])`
265-
possible versions to select: 0.5.0
261+
... required by package `foo v0.5.0 ([..])`
262+
versions that meet the requirements `*` are: 0.5.0
263+
264+
the package `a-sys` links to the native library `a`, but it conflicts with a previous package which links to `a` as well:
265+
package `foo v0.5.0 ([..])`
266+
267+
failed to select a version for `a-sys` which could resolve this conflict
266268
"));
267269
}
268270

@@ -311,12 +313,14 @@ fn links_duplicates_deep_dependency() {
311313
execs().with_status(101)
312314
.with_stderr("\
313315
error: failed to select a version for `a-sys`.
314-
all possible versions conflict with previously selected packages.
315-
required by package `a v0.5.0 ([..])`
316+
... required by package `a v0.5.0 ([..])`
316317
... which is depended on by `foo v0.5.0 ([..])`
317-
multiple packages link to native library `a`, but a native library can be linked only once.
318-
previously selected package `foo v0.5.0 ([..])`
319-
possible versions to select: 0.5.0
318+
versions that meet the requirements `*` are: 0.5.0
319+
320+
the package `a-sys` links to the native library `a`, but it conflicts with a previous package which links to `a` as well:
321+
package `foo v0.5.0 ([..])`
322+
323+
failed to select a version for `a-sys` which could resolve this conflict
320324
"));
321325
}
322326

@@ -2781,11 +2785,13 @@ fn links_duplicates_with_cycle() {
27812785
execs().with_status(101)
27822786
.with_stderr("\
27832787
error: failed to select a version for `a`.
2784-
all possible versions conflict with previously selected packages.
2785-
required by package `foo v0.5.0 ([..])`
2786-
multiple packages link to native library `a`, but a native library can be linked only once.
2787-
previously selected package `foo v0.5.0 ([..])`
2788-
possible versions to select: 0.5.0
2788+
... required by package `foo v0.5.0 ([..])`
2789+
versions that meet the requirements `*` are: 0.5.0
2790+
2791+
the package `a` links to the native library `a`, but it conflicts with a previous package which links to `a` as well:
2792+
package `foo v0.5.0 ([..])`
2793+
2794+
failed to select a version for `a` which could resolve this conflict
27892795
"));
27902796
}
27912797

tests/build.rs

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1027,13 +1027,17 @@ fn incompatible_dependencies() {
10271027
execs().with_status(101)
10281028
.with_stderr_contains("\
10291029
error: failed to select a version for `bad`.
1030-
all possible versions conflict with previously selected packages.
1031-
required by package `baz v0.1.0`
1030+
... required by package `baz v0.1.0`
10321031
... which is depended on by `incompatible_dependencies v0.0.1 ([..])`
1032+
versions that meet the requirements `>= 1.0.1` are: 1.0.2, 1.0.1
1033+
1034+
all possible versions conflict with previously selected packages.
1035+
10331036
previously selected package `bad v1.0.0`
10341037
... which is depended on by `bar v0.1.0`
10351038
... which is depended on by `incompatible_dependencies v0.0.1 ([..])`
1036-
possible versions to select: 1.0.2, 1.0.1"));
1039+
1040+
failed to select a version for `bad` which could resolve this conflict"));
10371041
}
10381042

10391043
#[test]
@@ -1063,15 +1067,20 @@ fn incompatible_dependencies_with_multi_semver() {
10631067
execs().with_status(101)
10641068
.with_stderr_contains("\
10651069
error: failed to select a version for `bad`.
1070+
... required by package `incompatible_dependencies v0.0.1 ([..])`
1071+
versions that meet the requirements `>= 1.0.1, <= 2.0.0` are: 2.0.0, 1.0.1
1072+
10661073
all possible versions conflict with previously selected packages.
1067-
required by package `incompatible_dependencies v0.0.1 ([..])`
1074+
10681075
previously selected package `bad v2.0.1`
10691076
... which is depended on by `baz v0.1.0`
10701077
... which is depended on by `incompatible_dependencies v0.0.1 ([..])`
1078+
10711079
previously selected package `bad v1.0.0`
10721080
... which is depended on by `bar v0.1.0`
10731081
... which is depended on by `incompatible_dependencies v0.0.1 ([..])`
1074-
possible versions to select: 2.0.0, 1.0.1"));
1082+
1083+
failed to select a version for `bad` which could resolve this conflict"));
10751084
}
10761085

10771086
#[test]

0 commit comments

Comments
 (0)