Skip to content

Commit

Permalink
Auto merge of #1709 - alexcrichton:fix-some-overrides, r=brson
Browse files Browse the repository at this point in the history
The fix in #1697 was to alter the `Hash` implementation of `Package` to take
into account the source root instead of just the package id (so packages at the
same source would have the same hash). There's a spot, however, where we
normalize some paths and not others, causing two paths which logically point the
same location end up having different hashes, so the same package ended up being
stored multiple times, later leading to an assertion that there was only one
stored.

This commit alters the behavior of read_packages to keep a hash map of ID =>
Package instead of just a hash set of Package as the deduplication/equality
needs to be based on the ID, not the literal path to the source root.

This specific bug shows up when you have an override and a normal dependency
pointing at the same location (and the override has some inter-dependencies).
Not exactly a normal use case, but it showed up in Servo's build!
  • Loading branch information
bors committed Jun 12, 2015
2 parents f98100f + 06a0605 commit d406d25
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 6 deletions.
12 changes: 6 additions & 6 deletions src/cargo/ops/cargo_read_manifest.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
use std::collections::HashSet;
use std::collections::{HashMap, HashSet};
use std::fs::{self, File};
use std::io::prelude::*;
use std::io;
use std::path::{Path, PathBuf};

use core::{Package,Manifest,SourceId};
use core::{Package, Manifest, SourceId, PackageId};
use util::{self, CargoResult, human, Config, ChainError};
use util::important_paths::find_project_manifest_exact;
use util::toml::{Layout, project_layout};
Expand Down Expand Up @@ -35,7 +35,7 @@ pub fn read_package(path: &Path, source_id: &SourceId, config: &Config)

pub fn read_packages(path: &Path, source_id: &SourceId, config: &Config)
-> CargoResult<Vec<Package>> {
let mut all_packages = HashSet::new();
let mut all_packages = HashMap::new();
let mut visited = HashSet::<PathBuf>::new();

trace!("looking for root package: {}, source_id={}", path.display(), source_id);
Expand Down Expand Up @@ -69,7 +69,7 @@ pub fn read_packages(path: &Path, source_id: &SourceId, config: &Config)
if all_packages.is_empty() {
Err(human(format!("Could not find Cargo.toml in `{}`", path.display())))
} else {
Ok(all_packages.into_iter().collect())
Ok(all_packages.into_iter().map(|(_, v)| v).collect())
}
}

Expand Down Expand Up @@ -103,7 +103,7 @@ fn has_manifest(path: &Path) -> bool {
}

fn read_nested_packages(path: &Path,
all_packages: &mut HashSet<Package>,
all_packages: &mut HashMap<PackageId, Package>,
source_id: &SourceId,
config: &Config,
visited: &mut HashSet<PathBuf>) -> CargoResult<()> {
Expand All @@ -112,7 +112,7 @@ fn read_nested_packages(path: &Path,
let manifest = try!(find_project_manifest_exact(path, "Cargo.toml"));

let (pkg, nested) = try!(read_package(&manifest, source_id, config));
all_packages.insert(pkg);
all_packages.insert(pkg.package_id().clone(), pkg);

// Registry sources are not allowed to have `path=` dependencies because
// they're all translated to actual registry dependencies.
Expand Down
41 changes: 41 additions & 0 deletions tests/test_cargo_compile_path_deps.rs
Original file line number Diff line number Diff line change
Expand Up @@ -793,3 +793,44 @@ test!(custom_target_no_rebuild {
{compiling} b v0.5.0 ([..])
", compiling = COMPILING)));
});

test!(override_and_depend {
let p = project("foo")
.file("a/a1/Cargo.toml", r#"
[project]
name = "a1"
version = "0.5.0"
authors = []
[dependencies]
a2 = { path = "../a2" }
"#)
.file("a/a1/src/lib.rs", "")
.file("a/a2/Cargo.toml", r#"
[project]
name = "a2"
version = "0.5.0"
authors = []
"#)
.file("a/a2/src/lib.rs", "")
.file("b/Cargo.toml", r#"
[project]
name = "b"
version = "0.5.0"
authors = []
[dependencies]
a1 = { path = "../a/a1" }
a2 = { path = "../a/a2" }
"#)
.file("b/src/lib.rs", "")
.file("b/.cargo/config", r#"
paths = ["../a"]
"#);
p.build();
assert_that(p.cargo("build").cwd(p.root().join("b")),
execs().with_status(0)
.with_stdout(&format!("\
{compiling} a2 v0.5.0 ([..])
{compiling} a1 v0.5.0 ([..])
{compiling} b v0.5.0 ([..])
", compiling = COMPILING)));
});

0 comments on commit d406d25

Please sign in to comment.