Skip to content

Commit

Permalink
better error messages
Browse files Browse the repository at this point in the history
  • Loading branch information
Eh2406 committed Feb 15, 2018
1 parent e8ed405 commit 70dada8
Show file tree
Hide file tree
Showing 3 changed files with 79 additions and 36 deletions.
60 changes: 44 additions & 16 deletions src/cargo/core/resolver/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -538,6 +538,15 @@ enum ConflictReason {
Links(String),
}

impl ConflictReason {
fn is_links(&self) -> bool {
match self {
&ConflictReason::Semver => false,
&ConflictReason::Links(_) => true,
}
}
}

struct BacktrackFrame<'a> {
cur: usize,
context_backup: Context<'a>,
Expand Down Expand Up @@ -835,33 +844,52 @@ fn activation_error(cx: &Context,
dep_path_desc
};
if !candidates.is_empty() {
let mut msg = format!("failed to select a version for `{}`.\n\
all possible versions conflict with \
previously selected packages.\n",
dep.name());
msg.push_str("required by ");
let mut msg = format!("failed to select a version for `{}`.", dep.name());
msg.push_str("\n ... required by ");
msg.push_str(&describe_path(parent.package_id()));

msg.push_str("\nversions that meet the requirements `");
msg.push_str(&dep.version_req().to_string());
msg.push_str("` are: ");
msg.push_str(&candidates.iter()
.map(|v| v.summary.version())
.map(|v| v.to_string())
.collect::<Vec<_>>()
.join(", "));

let mut conflicting_activations: Vec<_> = conflicting_activations.iter().collect();
conflicting_activations.sort_unstable();
for &(p, r) in conflicting_activations.iter().rev() {
let (links_errors, other_errors): (Vec<_>, Vec<_>) = conflicting_activations.drain(..).rev().partition(|&(_, r)| r.is_links());

for &(p, r) in &links_errors {
match r {
&ConflictReason::Links(ref link) => {
msg.push_str("\n multiple packages link to native library `");
msg.push_str(link);
msg.push_str("`, but a native library can be linked only once.")
msg.push_str("\n\nthe package `");
msg.push_str(dep.name());
msg.push_str("` links to the native library `");
msg.push_str(&link);
msg.push_str("`, but it conflicts with a previous package which links to `");
msg.push_str(&link);
msg.push_str("` as well:\n");
},
_ => (),
}
msg.push_str("\n previously selected ");
msg.push_str(&describe_path(p));
}

msg.push_str("\n possible versions to select: ");
msg.push_str(&candidates.iter()
.map(|v| v.summary.version())
.map(|v| v.to_string())
.collect::<Vec<_>>()
.join(", "));
if links_errors.is_empty() {
msg.push_str("\n\nall possible versions conflict with \
previously selected packages.");
}

for &(p, _) in &other_errors {
msg.push_str("\n\n previously selected ");
msg.push_str(&describe_path(p));
}

msg.push_str("\n\nfailed to select a version for `");
msg.push_str(dep.name());
msg.push_str("` which could resolve this conflict");

return format_err!("{}", msg)
}
Expand Down
36 changes: 21 additions & 15 deletions tests/build-script.rs
Original file line number Diff line number Diff line change
Expand Up @@ -258,11 +258,13 @@ fn links_duplicates() {
execs().with_status(101)
.with_stderr("\
error: failed to select a version for `a-sys`.
all possible versions conflict with previously selected packages.
required by package `foo v0.5.0 ([..])`
multiple packages link to native library `a`, but a native library can be linked only once.
previously selected package `foo v0.5.0 ([..])`
possible versions to select: 0.5.0
... required by package `foo v0.5.0 ([..])`
versions that meet the requirements `*` are: 0.5.0
the package `a-sys` links to the native library `a`, but it conflicts with a previous package which links to `a` as well:
package `foo v0.5.0 ([..])`
failed to select a version for `a-sys` which could resolve this conflict
"));
}

Expand Down Expand Up @@ -311,12 +313,14 @@ fn links_duplicates_deep_dependency() {
execs().with_status(101)
.with_stderr("\
error: failed to select a version for `a-sys`.
all possible versions conflict with previously selected packages.
required by package `a v0.5.0 ([..])`
... required by package `a v0.5.0 ([..])`
... which is depended on by `foo v0.5.0 ([..])`
multiple packages link to native library `a`, but a native library can be linked only once.
previously selected package `foo v0.5.0 ([..])`
possible versions to select: 0.5.0
versions that meet the requirements `*` are: 0.5.0
the package `a-sys` links to the native library `a`, but it conflicts with a previous package which links to `a` as well:
package `foo v0.5.0 ([..])`
failed to select a version for `a-sys` which could resolve this conflict
"));
}

Expand Down Expand Up @@ -2781,11 +2785,13 @@ fn links_duplicates_with_cycle() {
execs().with_status(101)
.with_stderr("\
error: failed to select a version for `a`.
all possible versions conflict with previously selected packages.
required by package `foo v0.5.0 ([..])`
multiple packages link to native library `a`, but a native library can be linked only once.
previously selected package `foo v0.5.0 ([..])`
possible versions to select: 0.5.0
... required by package `foo v0.5.0 ([..])`
versions that meet the requirements `*` are: 0.5.0
the package `a` links to the native library `a`, but it conflicts with a previous package which links to `a` as well:
package `foo v0.5.0 ([..])`
failed to select a version for `a` which could resolve this conflict
"));
}

Expand Down
19 changes: 14 additions & 5 deletions tests/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1027,13 +1027,17 @@ fn incompatible_dependencies() {
execs().with_status(101)
.with_stderr_contains("\
error: failed to select a version for `bad`.
all possible versions conflict with previously selected packages.
required by package `baz v0.1.0`
... required by package `baz v0.1.0`
... which is depended on by `incompatible_dependencies v0.0.1 ([..])`
versions that meet the requirements `>= 1.0.1` are: 1.0.2, 1.0.1
all possible versions conflict with previously selected packages.
previously selected package `bad v1.0.0`
... which is depended on by `bar v0.1.0`
... which is depended on by `incompatible_dependencies v0.0.1 ([..])`
possible versions to select: 1.0.2, 1.0.1"));
failed to select a version for `bad` which could resolve this conflict"));
}

#[test]
Expand Down Expand Up @@ -1063,15 +1067,20 @@ fn incompatible_dependencies_with_multi_semver() {
execs().with_status(101)
.with_stderr_contains("\
error: failed to select a version for `bad`.
... required by package `incompatible_dependencies v0.0.1 ([..])`
versions that meet the requirements `>= 1.0.1, <= 2.0.0` are: 2.0.0, 1.0.1
all possible versions conflict with previously selected packages.
required by package `incompatible_dependencies v0.0.1 ([..])`
previously selected package `bad v2.0.1`
... which is depended on by `baz v0.1.0`
... which is depended on by `incompatible_dependencies v0.0.1 ([..])`
previously selected package `bad v1.0.0`
... which is depended on by `bar v0.1.0`
... which is depended on by `incompatible_dependencies v0.0.1 ([..])`
possible versions to select: 2.0.0, 1.0.1"));
failed to select a version for `bad` which could resolve this conflict"));
}

#[test]
Expand Down

0 comments on commit 70dada8

Please sign in to comment.