Skip to content

Commit 0c6bb24

Browse files
committed
Auto merge of #6249 - Eh2406:cleanup, r=alexcrichton
Resolver cleanups and a new fuzz test This is the commits from my on going work on pub/priv deps that did not relate to that functionality. Then it also adds a fuzz test that minimal-versions does not change whether resolution is possible. cc #6120
2 parents 90a3c7d + 20f55af commit 0c6bb24

File tree

9 files changed

+213
-84
lines changed

9 files changed

+213
-84
lines changed

src/cargo/core/resolver/context.rs

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@ use core::{Dependency, FeatureValue, PackageId, SourceId, Summary};
66
use util::CargoResult;
77
use util::Graph;
88

9-
use super::types::RegistryQueryer;
10-
use super::types::{ActivateResult, ConflictReason, DepInfo, GraphNode, Method, RcList};
9+
use super::types::{ConflictReason, DepInfo, GraphNode, Method, RcList, RegistryQueryer};
10+
use super::errors::ActivateResult;
1111

1212
pub use super::encode::{EncodableDependency, EncodablePackageId, EncodableResolve};
1313
pub use super::encode::{Metadata, WorkspaceResolve};
@@ -186,11 +186,10 @@ impl Context {
186186
// name.
187187
let base = reqs.deps.get(&dep.name_in_toml()).unwrap_or(&default_dep);
188188
used_features.insert(dep.name_in_toml());
189-
let always_required = !dep.is_optional()
190-
&& !s
191-
.dependencies()
192-
.iter()
193-
.any(|d| d.is_optional() && d.name_in_toml() == dep.name_in_toml());
189+
let always_required = !dep.is_optional() && !s
190+
.dependencies()
191+
.iter()
192+
.any(|d| d.is_optional() && d.name_in_toml() == dep.name_in_toml());
194193
if always_required && base.0 {
195194
self.warnings.push(format!(
196195
"Package `{}` does not have feature `{}`. It has a required dependency \
@@ -230,11 +229,13 @@ impl Context {
230229
"Package `{}` does not have these features: `{}`",
231230
s.package_id(),
232231
features
233-
).into(),
232+
)
233+
.into(),
234234
Some(p) => (
235235
p.package_id().clone(),
236236
ConflictReason::MissingFeatures(features),
237-
).into(),
237+
)
238+
.into(),
238239
});
239240
}
240241

src/cargo/core/resolver/encode.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -377,7 +377,8 @@ impl<'a, 'cfg> ser::Serialize for WorkspaceResolve<'a, 'cfg> {
377377
root: None,
378378
metadata,
379379
patch,
380-
}.serialize(s)
380+
}
381+
.serialize(s)
381382
}
382383
}
383384

src/cargo/core/resolver/errors.rs

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@ use std::fmt;
44
use core::{Dependency, PackageId, Registry, Summary};
55
use failure::{Error, Fail};
66
use semver;
7-
use util::config::Config;
87
use util::lev_distance::lev_distance;
8+
use util::{CargoError, Config};
99

1010
use super::context::Context;
1111
use super::types::{Candidate, ConflictReason};
@@ -49,6 +49,25 @@ impl fmt::Display for ResolveError {
4949
}
5050
}
5151

52+
pub type ActivateResult<T> = Result<T, ActivateError>;
53+
54+
pub enum ActivateError {
55+
Fatal(CargoError),
56+
Conflict(PackageId, ConflictReason),
57+
}
58+
59+
impl From<::failure::Error> for ActivateError {
60+
fn from(t: ::failure::Error) -> Self {
61+
ActivateError::Fatal(t)
62+
}
63+
}
64+
65+
impl From<(PackageId, ConflictReason)> for ActivateError {
66+
fn from(t: (PackageId, ConflictReason)) -> Self {
67+
ActivateError::Conflict(t.0, t.1)
68+
}
69+
}
70+
5271
pub(super) fn activation_error(
5372
cx: &Context,
5473
registry: &mut Registry,

src/cargo/core/resolver/mod.rs

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -62,21 +62,21 @@ use util::errors::CargoResult;
6262
use util::profile;
6363

6464
use self::context::{Activations, Context};
65-
use self::types::{ActivateError, ActivateResult, Candidate, ConflictReason, DepsFrame, GraphNode};
65+
use self::types::{Candidate, ConflictReason, DepsFrame, GraphNode};
6666
use self::types::{RcVecIter, RegistryQueryer, RemainingDeps, ResolverProgress};
6767

6868
pub use self::encode::{EncodableDependency, EncodablePackageId, EncodableResolve};
6969
pub use self::encode::{Metadata, WorkspaceResolve};
70+
pub use self::errors::{ActivateError, ActivateResult, ResolveError};
7071
pub use self::resolve::Resolve;
7172
pub use self::types::Method;
72-
pub use self::errors::ResolveError;
7373

7474
mod conflict_cache;
7575
mod context;
7676
mod encode;
77+
mod errors;
7778
mod resolve;
7879
mod types;
79-
mod errors;
8080

8181
/// Builds the list of all packages required to build the first argument.
8282
///
@@ -403,7 +403,8 @@ fn activate_deps_loop(
403403
.clone()
404404
.filter_map(|(_, (ref new_dep, _, _))| {
405405
past_conflicting_activations.conflicting(&cx, new_dep)
406-
}).next()
406+
})
407+
.next()
407408
{
408409
// If one of our deps is known unresolvable
409410
// then we will not succeed.
@@ -438,12 +439,15 @@ fn activate_deps_loop(
438439
// for deps related to us
439440
.filter(|&(_, ref other_dep)| {
440441
known_related_bad_deps.contains(other_dep)
441-
}).filter_map(|(other_parent, other_dep)| {
442+
})
443+
.filter_map(|(other_parent, other_dep)| {
442444
past_conflicting_activations
443445
.find_conflicting(&cx, &other_dep, |con| {
444446
con.contains_key(&pid)
445-
}).map(|con| (other_parent, con))
446-
}).next()
447+
})
448+
.map(|con| (other_parent, con))
449+
})
450+
.next()
447451
{
448452
let rel = conflict.get(&pid).unwrap().clone();
449453

@@ -485,7 +489,8 @@ fn activate_deps_loop(
485489
&parent,
486490
backtracked,
487491
&conflicting_activations,
488-
).is_none()
492+
)
493+
.is_none()
489494
}
490495
};
491496

src/cargo/core/resolver/resolve.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,10 @@ unable to verify that `{0}` is the same as when the lockfile was generated
171171
self.graph.contains(k)
172172
}
173173

174+
pub fn sort(&self) -> Vec<PackageId> {
175+
self.graph.sort()
176+
}
177+
174178
pub fn iter(&self) -> impl Iterator<Item = &PackageId> {
175179
self.graph.iter()
176180
}

src/cargo/core/resolver/types.rs

Lines changed: 2 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@ use std::time::{Duration, Instant};
66

77
use core::interning::InternedString;
88
use core::{Dependency, PackageId, PackageIdSpec, Registry, Summary};
9-
use util::{CargoError, CargoResult, Config};
9+
use util::errors::CargoResult;
10+
use util::Config;
1011

1112
pub struct ResolverProgress {
1213
ticks: u16,
@@ -348,25 +349,6 @@ impl RemainingDeps {
348349
// (dependency info, candidates, features activated)
349350
pub type DepInfo = (Dependency, Rc<Vec<Candidate>>, Rc<Vec<InternedString>>);
350351

351-
pub type ActivateResult<T> = Result<T, ActivateError>;
352-
353-
pub enum ActivateError {
354-
Fatal(CargoError),
355-
Conflict(PackageId, ConflictReason),
356-
}
357-
358-
impl From<::failure::Error> for ActivateError {
359-
fn from(t: ::failure::Error) -> Self {
360-
ActivateError::Fatal(t)
361-
}
362-
}
363-
364-
impl From<(PackageId, ConflictReason)> for ActivateError {
365-
fn from(t: (PackageId, ConflictReason)) -> Self {
366-
ActivateError::Conflict(t.0, t.1)
367-
}
368-
}
369-
370352
/// All possible reasons that a package might fail to activate.
371353
///
372354
/// We maintain a list of conflicts for error reporting as well as backtracking

src/cargo/util/graph.rs

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use std::borrow::Borrow;
2-
use std::collections::hash_map::HashMap;
2+
use std::collections::{HashMap, HashSet};
33
use std::fmt;
44
use std::hash::Hash;
55

@@ -42,6 +42,30 @@ impl<N: Eq + Hash + Clone, E: Default> Graph<N, E> {
4242
self.nodes.get(from).into_iter().flat_map(|x| x.iter())
4343
}
4444

45+
/// A topological sort of the `Graph`
46+
pub fn sort(&self) -> Vec<N> {
47+
let mut ret = Vec::new();
48+
let mut marks = HashSet::new();
49+
50+
for node in self.nodes.keys() {
51+
self.sort_inner_visit(node, &mut ret, &mut marks);
52+
}
53+
54+
ret
55+
}
56+
57+
fn sort_inner_visit(&self, node: &N, dst: &mut Vec<N>, marks: &mut HashSet<N>) {
58+
if !marks.insert(node.clone()) {
59+
return;
60+
}
61+
62+
for child in self.nodes[node].keys() {
63+
self.sort_inner_visit(child, dst, marks);
64+
}
65+
66+
dst.push(node.clone());
67+
}
68+
4569
pub fn iter(&self) -> impl Iterator<Item = &N> {
4670
self.nodes.keys()
4771
}

0 commit comments

Comments
 (0)