Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix renaming crates as they come from 2 sources #5415

Merged
merged 1 commit into from
Apr 27, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 28 additions & 29 deletions src/cargo/core/compiler/context/unit_dependencies.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,54 +64,55 @@ fn compute_deps<'a, 'b, 'cfg>(

let id = unit.pkg.package_id();
let deps = cx.resolve.deps(id);
let mut ret = deps.filter(|dep| {
unit.pkg
.dependencies()
.iter()
.filter(|d| d.name() == dep.name() && d.version_req().matches(dep.version()))
.any(|d| {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice simplification here!

let mut ret = deps
.filter(|&(_id, deps)| {
assert!(deps.len() > 0);
deps.iter().any(|dep| {
// If this target is a build command, then we only want build
// dependencies, otherwise we want everything *other than* build
// dependencies.
if unit.target.is_custom_build() != d.is_build() {
if unit.target.is_custom_build() != dep.is_build() {
return false;
}

// If this dependency is *not* a transitive dependency, then it
// only applies to test/example targets
if !d.is_transitive() && !unit.target.is_test() && !unit.target.is_example()
if !dep.is_transitive() && !unit.target.is_test() && !unit.target.is_example()
&& !unit.profile.test
{
return false;
}

// If this dependency is only available for certain platforms,
// make sure we're only enabling it for that platform.
if !cx.dep_platform_activated(d, unit.kind) {
if !cx.dep_platform_activated(dep, unit.kind) {
return false;
}

// If the dependency is optional, then we're only activating it
// if the corresponding feature was activated
if d.is_optional() && !cx.resolve.features(id).contains(&*d.name()) {
if dep.is_optional() && !cx.resolve.features(id).contains(&*dep.name()) {
return false;
}

// If we've gotten past all that, then this dependency is
// actually used!
true
})
}).filter_map(|id| match cx.get_package(id) {
Ok(pkg) => pkg.targets().iter().find(|t| t.is_lib()).map(|t| {
let unit = Unit {
pkg,
target: t,
profile: lib_or_check_profile(unit, t, cx),
kind: unit.kind.for_target(t),
};
Ok(unit)
}),
Err(e) => Some(Err(e)),
})
.filter_map(|(id, _)| {
match cx.get_package(id) {
Ok(pkg) => pkg.targets().iter().find(|t| t.is_lib()).map(|t| {
let unit = Unit {
pkg,
target: t,
profile: lib_or_check_profile(unit, t, cx),
kind: unit.kind.for_target(t),
};
Ok(unit)
}),
Err(e) => Some(Err(e)),
}
})
.collect::<CargoResult<Vec<_>>>()?;

Expand Down Expand Up @@ -205,17 +206,15 @@ fn compute_deps_doc<'a, 'cfg>(
) -> CargoResult<Vec<Unit<'a>>> {
let deps = cx.resolve
.deps(unit.pkg.package_id())
.filter(|dep| {
unit.pkg
.dependencies()
.iter()
.filter(|d| d.name() == dep.name() && d.version_req().matches(dep.version()))
.any(|dep| match dep.kind() {
.filter(|&(_id, deps)| {
deps.iter().any(|dep| {
match dep.kind() {
DepKind::Normal => cx.dep_platform_activated(dep, unit.kind),
_ => false,
})
}
})
})
.map(|dep| cx.get_package(dep));
.map(|(id, _deps)| cx.get_package(id));

// To document a library, we depend on dependencies actually being
// built. If we're documenting *all* libraries, then we also depend on
Expand Down
41 changes: 24 additions & 17 deletions src/cargo/core/compiler/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1094,23 +1094,30 @@ fn build_deps_args<'a, 'cfg>(
}
let mut v = OsString::new();

// Unfortunately right now Cargo doesn't have a great way to get a
// 1:1 mapping of entries in `dependencies()` to the actual crate
// we're depending on. Instead we're left to do some guesswork here
// to figure out what `Dependency` the `dep` unit corresponds to in
// `current` to see if we're renaming it.
//
// This I believe mostly works out for now, but we'll likely want
// to tighten up this in the future.
let name = current
.pkg
.dependencies()
.iter()
.filter(|d| d.matches_ignoring_source(dep.pkg.package_id()))
.filter_map(|d| d.rename())
.next();

v.push(name.unwrap_or(&dep.target.crate_name()));
let deps = {
let a = current.pkg.package_id();
let b = dep.pkg.package_id();
if a == b {
&[]
} else {
cx.resolve.dependencies_listed(a, b)
}
};

let crate_name = dep.target.crate_name();
let mut names = deps.iter()
.map(|d| d.rename().unwrap_or(&crate_name));
let name = names.next().unwrap_or(&crate_name);
for n in names {
if n == name {
continue
}
bail!("multiple dependencies listed for the same crate must \
all have the same name, but the dependency on `{}` \
is listed as having different names", dep.pkg.package_id());
}

v.push(name);
v.push("=");
v.push(cx.files().out_dir(dep));
v.push(&path::MAIN_SEPARATOR.to_string());
Expand Down
16 changes: 12 additions & 4 deletions src/cargo/core/resolver/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -269,17 +269,25 @@ impl Context {
replacements
}

pub fn graph(&self) -> Graph<PackageId> {
pub fn graph(&self)
-> (Graph<PackageId>, HashMap<(PackageId, PackageId), Vec<Dependency>>)
{
let mut graph = Graph::new();
let mut deps = HashMap::new();
let mut cur = &self.resolve_graph;
while let Some(ref node) = cur.head {
match node.0 {
GraphNode::Add(ref p) => graph.add(p.clone(), &[]),
GraphNode::Link(ref a, ref b) => graph.link(a.clone(), b.clone()),
GraphNode::Add(ref p) => graph.add(p.clone()),
GraphNode::Link(ref a, ref b, ref dep) => {
graph.link(a.clone(), b.clone());
deps.entry((a.clone(), b.clone()))
.or_insert(Vec::new())
.push(dep.clone());
}
}
cur = &node.1;
}
graph
(graph, deps)
}
}

Expand Down
23 changes: 10 additions & 13 deletions src/cargo/core/resolver/encode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ impl EncodableResolve {
let mut g = Graph::new();

for &(ref id, _) in live_pkgs.values() {
g.add(id.clone(), &[]);
g.add(id.clone());
}

for &(ref id, pkg) in live_pkgs.values() {
Expand Down Expand Up @@ -177,15 +177,15 @@ impl EncodableResolve {
unused_patches.push(id);
}

Ok(Resolve {
graph: g,
empty_features: HashSet::new(),
features: HashMap::new(),
Ok(Resolve::new(
g,
HashMap::new(),
replacements,
HashMap::new(),
checksums,
metadata,
unused_patches,
})
))
}
}

Expand Down Expand Up @@ -347,17 +347,17 @@ impl<'a, 'cfg> ser::Serialize for WorkspaceResolve<'a, 'cfg> {
where
S: ser::Serializer,
{
let mut ids: Vec<&PackageId> = self.resolve.graph.iter().collect();
let mut ids: Vec<_> = self.resolve.iter().collect();
ids.sort();

let encodable = ids.iter()
.filter_map(|&id| Some(encodable_resolve_node(id, self.resolve)))
.collect::<Vec<_>>();

let mut metadata = self.resolve.metadata.clone();
let mut metadata = self.resolve.metadata().clone();

for id in ids.iter().filter(|id| !id.source_id().is_path()) {
let checksum = match self.resolve.checksums[*id] {
let checksum = match self.resolve.checksums()[*id] {
Some(ref s) => &s[..],
None => "<none>",
};
Expand Down Expand Up @@ -398,10 +398,7 @@ fn encodable_resolve_node(id: &PackageId, resolve: &Resolve) -> EncodableDepende
Some(id) => (Some(encodable_package_id(id)), None),
None => {
let mut deps = resolve
.graph
.edges(id)
.into_iter()
.flat_map(|a| a)
.deps_not_replaced(id)
.map(encodable_package_id)
.collect::<Vec<_>>();
deps.sort();
Expand Down
Loading