Skip to content

Commit

Permalink
Auto merge of #5425 - matklad:rename-fingerprint, r=alexcrichton
Browse files Browse the repository at this point in the history
Package renames should affect fingerprints
  • Loading branch information
bors committed Apr 28, 2018
2 parents 0e6edcf + fc72bcb commit 07d022d
Show file tree
Hide file tree
Showing 4 changed files with 91 additions and 35 deletions.
26 changes: 26 additions & 0 deletions src/cargo/core/compiler/context/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -429,6 +429,32 @@ impl<'a, 'cfg> Context<'a, 'cfg> {
self.unit_dependencies[unit].clone()
}

pub fn extern_crate_name(&self, unit: &Unit<'a>, dep: &Unit<'a>) -> CargoResult<String> {
let deps = {
let a = unit.pkg.package_id();
let b = dep.pkg.package_id();
if a == b {
&[]
} else {
self.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());
}
Ok(name.to_string())
}

/// Whether a dependency should be compiled for the host or target platform,
/// specified by `Kind`.
fn dep_platform_activated(&self, dep: &Dependency, kind: Kind) -> bool {
Expand Down
27 changes: 16 additions & 11 deletions src/cargo/core/compiler/fingerprint.rs
Original file line number Diff line number Diff line change
Expand Up @@ -150,33 +150,34 @@ pub struct Fingerprint {
profile: u64,
path: u64,
#[serde(serialize_with = "serialize_deps", deserialize_with = "deserialize_deps")]
deps: Vec<(String, Arc<Fingerprint>)>,
deps: Vec<(String, String, Arc<Fingerprint>)>,
local: Vec<LocalFingerprint>,
#[serde(skip_serializing, skip_deserializing)]
memoized_hash: Mutex<Option<u64>>,
rustflags: Vec<String>,
edition: Edition,
}

fn serialize_deps<S>(deps: &[(String, Arc<Fingerprint>)], ser: S) -> Result<S::Ok, S::Error>
fn serialize_deps<S>(deps: &[(String, String, Arc<Fingerprint>)], ser: S) -> Result<S::Ok, S::Error>
where
S: ser::Serializer,
{
deps.iter()
.map(|&(ref a, ref b)| (a, b.hash()))
.map(|&(ref a, ref b, ref c)| (a, b, c.hash()))
.collect::<Vec<_>>()
.serialize(ser)
}

fn deserialize_deps<'de, D>(d: D) -> Result<Vec<(String, Arc<Fingerprint>)>, D::Error>
fn deserialize_deps<'de, D>(d: D) -> Result<Vec<(String, String, Arc<Fingerprint>)>, D::Error>
where
D: de::Deserializer<'de>,
{
let decoded = <Vec<(String, u64)>>::deserialize(d)?;
let decoded = <Vec<(String, String, u64)>>::deserialize(d)?;
Ok(decoded
.into_iter()
.map(|(name, hash)| {
.map(|(pkg_id, name, hash)| {
(
pkg_id,
name,
Arc::new(Fingerprint {
rustc: 0,
Expand Down Expand Up @@ -330,7 +331,7 @@ impl Fingerprint {
bail!("number of dependencies has changed")
}
for (a, b) in self.deps.iter().zip(old.deps.iter()) {
if a.1.hash() != b.1.hash() {
if a.1 != b.1 || a.2.hash() != b.2.hash() {
bail!("new ({}) != old ({})", a.0, b.0)
}
}
Expand All @@ -357,7 +358,8 @@ impl hash::Hash for Fingerprint {
).hash(h);

h.write_usize(deps.len());
for &(ref name, ref fingerprint) in deps {
for &(ref pkg_id, ref name, ref fingerprint) in deps {
pkg_id.hash(h);
name.hash(h);
// use memoized dep hashes to avoid exponential blowup
h.write_u64(Fingerprint::hash(fingerprint));
Expand Down Expand Up @@ -426,8 +428,11 @@ fn calculate<'a, 'cfg>(
let deps = cx.dep_targets(unit);
let deps = deps.iter()
.filter(|u| !u.target.is_custom_build() && !u.target.is_bin())
.map(|unit| {
calculate(cx, unit).map(|fingerprint| (unit.pkg.package_id().to_string(), fingerprint))
.map(|dep| {
calculate(cx, dep).and_then(|fingerprint| {
let name = cx.extern_crate_name(unit, dep)?;
Ok((dep.pkg.package_id().to_string(), name, fingerprint))
})
})
.collect::<CargoResult<Vec<_>>>()?;

Expand All @@ -441,7 +446,7 @@ fn calculate<'a, 'cfg>(
LocalFingerprint::Precalculated(fingerprint)
};
let mut deps = deps;
deps.sort_by(|&(ref a, _), &(ref b, _)| a.cmp(b));
deps.sort_by(|&(ref a, _, _), &(ref b, _, _)| a.cmp(b));
let extra_flags = if unit.mode.is_doc() {
cx.rustdocflags_args(unit)?
} else {
Expand Down
25 changes: 1 addition & 24 deletions src/cargo/core/compiler/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1097,30 +1097,7 @@ fn build_deps_args<'a, 'cfg>(
continue;
}
let mut v = OsString::new();

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());
}

let name = cx.extern_crate_name(current, dep)?;
v.push(name);
v.push("=");
v.push(cx.files().out_dir(dep));
Expand Down
48 changes: 48 additions & 0 deletions tests/testsuite/rename_deps.rs
Original file line number Diff line number Diff line change
Expand Up @@ -315,3 +315,51 @@ name, but the dependency on `foo v0.1.0` is listed as having different names
")
);
}

#[test]
fn rename_affects_fingerprint() {
Package::new("foo", "0.1.0").publish();

let p = project("foo")
.file(
"Cargo.toml",
r#"
cargo-features = ["rename-dependency"]
[package]
name = "test"
version = "0.1.0"
authors = []
[dependencies]
foo = { version = "0.1", package = "foo" }
"#,
)
.file("src/lib.rs", "extern crate foo;")
.build();

assert_that(
p.cargo("build -v").masquerade_as_nightly_cargo(),
execs().with_status(0),
);

p.change_file(
"Cargo.toml",
r#"
cargo-features = ["rename-dependency"]
[package]
name = "test"
version = "0.1.0"
authors = []
[dependencies]
bar = { version = "0.1", package = "foo" }
"#,
);

assert_that(
p.cargo("build -v").masquerade_as_nightly_cargo(),
execs().with_status(101),
);
}

0 comments on commit 07d022d

Please sign in to comment.