better error messages
authorEh2406 <YeomanYaacov@gmail.com>
Thu, 15 Feb 2018 03:28:59 +0000 (22:28 -0500)
committerEh2406 <YeomanYaacov@gmail.com>
Thu, 15 Feb 2018 03:28:59 +0000 (22:28 -0500)
src/cargo/core/resolver/mod.rs
tests/build-script.rs
tests/build.rs

index 45a8747b262f8ad6af4517ebc09679cdb790097d..2345a59da42570c6ff998f015d10f5d11eaa046f 100644 (file)
@@ -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>,
@@ -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)
     }
index 41ffb7eeb7ff97bc104c50f044bc517b0f5d2787..1bd0409cff573d874ed36920ea61db1f4dc6b7d1 100644 (file)
@@ -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
 "));
 }
 
@@ -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
 "));
 }
 
@@ -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
 "));
 }
 
index 7f3e887be49dcd332d425796a3732ea1e735e943..47a7cd4b1e970bf5afef02f0b95de644b49df5f6 100644 (file)
@@ -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]
@@ -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]