problematic extension and solution
authorEh2406 <YeomanYaacov@gmail.com>
Sun, 18 Mar 2018 03:05:08 +0000 (23:05 -0400)
committerEh2406 <YeomanYaacov@gmail.com>
Sat, 24 Mar 2018 15:31:38 +0000 (11:31 -0400)
src/cargo/core/resolver/mod.rs
tests/testsuite/resolve.rs

index 851af2d534f58e510d5724aeac844323157218d8..726f9557100658c349c5b8dc9d52f50cd50c784a 100644 (file)
@@ -1276,11 +1276,15 @@ fn activate_deps_loop(
                             .flat_map(|x| x)
                             .find(|con| cx.is_conflicting(None, con))
                         {
-                            conflicting_activations.extend(conflicting.clone());
+                            let mut conflicting = conflicting.clone();
+                            conflicting.remove(&pid);
+
+                            conflicting_activations.extend(conflicting);
                             has_past_conflicting_dep = true;
                         }
                     }
                     if !has_past_conflicting_dep {
+                        // TODO: this is ugly and slow, replace!
                         'deps: for debs in remaining_deps.iter() {
                             for (_, (other_dep, _, _)) in debs.remaining_siblings.clone() {
                                 if let Some(conflict) = past_conflicting_activations
index 63cdc8c3debd420d74d7510855cbe526299a8595..80539fec63beb5ed7b3c5d620a364ab8c6c2af53 100644 (file)
@@ -757,6 +757,55 @@ fn resolving_with_deep_traps() {
     assert!(res.is_err());
 }
 
+#[test]
+fn resolving_with_constrained_cousins_backtrack_s1() {
+    // ToDo: Remove when the longer version below passes! DON'T merge
+    let mut reglist = Vec::new();
+
+    const DEPTH: usize = 200;
+    const BRANCHING_FACTOR: usize = 100;
+
+    // Each backtrack_trap depends on the next.
+    // The last depends on a specific ver of constrained.
+    for l in 0..DEPTH {
+        let name = format!("backtrack_trap{}", l);
+        let next = format!("backtrack_trap{}", l + 1);
+        for i in 1..BRANCHING_FACTOR {
+            let vsn = format!("1.0.{}", i);
+            reglist.push(pkg!((name.as_str(), vsn.as_str()) => [dep_req(next.as_str(), "*")]));
+        }
+    }
+    {
+        let name = format!("backtrack_trap{}", DEPTH);
+        for i in 1..BRANCHING_FACTOR {
+            let vsn = format!("1.0.{}", i);
+            reglist.push(pkg!((name.as_str(), vsn.as_str()) => [dep_req("constrained", "=1.0.0")]));
+        }
+    }
+    {
+        // slightly less constrained to make sure `constrained` gets picked last.
+        for i in 0..(BRANCHING_FACTOR + 10) {
+            let vsn = format!("1.0.{}", i);
+            reglist.push(pkg!(("constrained", vsn.as_str())));
+        }
+    }
+
+    let reg = registry(reglist.clone());
+
+    // `backtrack_trap0 = "*"` is a lot of ways of saying `constrained = "=1.0.0"`
+    // Only then to try and solve `constrained= "1.0.1"` which is incompatible.
+    let res = resolve(
+        &pkg_id("root"),
+        vec![
+            dep_req("backtrack_trap0", "*"),
+            dep_req("constrained", "1.0.1"),
+        ],
+        &reg,
+    );
+
+    assert!(res.is_err());
+}
+
 #[test]
 fn resolving_with_constrained_cousins_backtrack() {
     let mut reglist = Vec::new();
@@ -803,6 +852,33 @@ fn resolving_with_constrained_cousins_backtrack() {
     );
 
     assert!(res.is_err());
+
+    // Each level depends on the next but the last depends on incompatible deps.
+    // Let's make sure that we can cache that a dep has incompatible deps.
+    for l in 0..DEPTH {
+        let name = format!("level{}", l);
+        let next = format!("level{}", l + 1);
+        for i in 1..BRANCHING_FACTOR {
+            let vsn = format!("1.0.{}", i);
+            reglist.push(pkg!((name.as_str(), vsn.as_str()) => [dep_req(next.as_str(), "*")]));
+        }
+    }
+    reglist.push(pkg!((format!("level{}", DEPTH).as_str(), "1.0.0") => [dep_req("backtrack_trap0", "*"),
+            dep_req("constrained", "1.0.1")]));
+
+    let reg = registry(reglist.clone());
+
+    // `backtrack_trap0 = "*"` is a lot of ways of saying `constrained = "=1.0.0"`
+    // Only then to try and solve `constrained= "1.0.1"` which is incompatible.
+    let res = resolve(
+        &pkg_id("root"),
+        vec![
+            dep_req("level0", "*"),
+        ],
+        &reg,
+    );
+
+    assert!(res.is_err());
 }
 
 #[test]