Skip to content

Commit

Permalink
Auto merge of #5011 - Manishearth:stealing-chickens-off-the-internet,…
Browse files Browse the repository at this point in the history
… r=alexcrichton

Implement RFC 2052: Epoches

Todo:

 - Make epoches affect the fingerprint
 - Tests

cc rust-lang/rust#44581

Rust PR: rust-lang/rust#48014

r? @acrichto
  • Loading branch information
bors committed Feb 6, 2018
2 parents cac9173 + 270f6e2 commit 750df0a
Show file tree
Hide file tree
Showing 7 changed files with 196 additions and 6 deletions.
38 changes: 38 additions & 0 deletions src/cargo/core/features.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,40 @@
//! we'll be sure to update this documentation!

use std::env;
use std::fmt;
use std::str::FromStr;

use util::errors::CargoResult;

/// The epoch of the compiler (RFC 2052)
#[derive(Clone, Copy, Debug, Hash, PartialOrd, Ord, Eq, PartialEq)]
#[derive(Serialize, Deserialize)]
pub enum Epoch {
/// The 2015 epoch
Epoch2015,
/// The 2018 epoch
Epoch2018,
}

impl fmt::Display for Epoch {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self {
Epoch::Epoch2015 => f.write_str("2015"),
Epoch::Epoch2018 => f.write_str("2018"),
}
}
}
impl FromStr for Epoch {
type Err = ();
fn from_str(s: &str) -> Result<Self, ()> {
match s {
"2015" => Ok(Epoch::Epoch2015),
"2018" => Ok(Epoch::Epoch2018),
_ => Err(())
}
}
}

enum Status {
Stable,
Unstable,
Expand Down Expand Up @@ -125,6 +156,9 @@ features! {

// Downloading packages from alternative registry indexes.
[unstable] alternative_registries: bool,

// Using epochs
[unstable] epoch: bool,
}
}

Expand Down Expand Up @@ -201,6 +235,10 @@ impl Features {
bail!("{}", msg);
}
}

pub fn is_enabled(&self, feature: &Feature) -> bool {
feature.is_enabled(self)
}
}

/// A parsed representation of all unstable flags that Cargo accepts.
Expand Down
9 changes: 8 additions & 1 deletion src/cargo/core/manifest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use serde::ser;
use url::Url;

use core::{Dependency, PackageId, Summary, SourceId, PackageIdSpec};
use core::{WorkspaceConfig, Features, Feature};
use core::{WorkspaceConfig, Epoch, Features, Feature};
use util::Config;
use util::toml::TomlManifest;
use util::errors::*;
Expand All @@ -36,6 +36,7 @@ pub struct Manifest {
workspace: WorkspaceConfig,
original: Rc<TomlManifest>,
features: Features,
epoch: Epoch,
im_a_teapot: Option<bool>,
}

Expand Down Expand Up @@ -269,6 +270,7 @@ impl Manifest {
patch: HashMap<Url, Vec<Dependency>>,
workspace: WorkspaceConfig,
features: Features,
epoch: Epoch,
im_a_teapot: Option<bool>,
original: Rc<TomlManifest>) -> Manifest {
Manifest {
Expand All @@ -285,6 +287,7 @@ impl Manifest {
patch: patch,
workspace: workspace,
features: features,
epoch: epoch,
original: original,
im_a_teapot: im_a_teapot,
}
Expand Down Expand Up @@ -356,6 +359,10 @@ impl Manifest {
}
}
}

pub fn epoch(&self) -> Epoch {
self.epoch
}
}

impl VirtualManifest {
Expand Down
2 changes: 1 addition & 1 deletion src/cargo/core/mod.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
pub use self::dependency::Dependency;
pub use self::features::{Features, Feature, CliUnstable};
pub use self::features::{Epoch, Features, Feature, CliUnstable};
pub use self::manifest::{EitherManifest, VirtualManifest};
pub use self::manifest::{Manifest, Target, TargetKind, Profile, LibKind, Profiles};
pub use self::package::{Package, PackageSet};
Expand Down
12 changes: 10 additions & 2 deletions src/cargo/ops/cargo_rustc/fingerprint.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use serde::ser::{self, Serialize};
use serde::de::{self, Deserialize};
use serde_json;

use core::{Package, TargetKind};
use core::{Epoch, Package, TargetKind};
use util;
use util::{Fresh, Dirty, Freshness, internal, profile};
use util::errors::{CargoResult, CargoResultExt};
Expand Down Expand Up @@ -145,6 +145,7 @@ pub struct Fingerprint {
#[serde(skip_serializing, skip_deserializing)]
memoized_hash: Mutex<Option<u64>>,
rustflags: Vec<String>,
epoch: Epoch,
}

fn serialize_deps<S>(deps: &[(String, Arc<Fingerprint>)], ser: S)
Expand All @@ -170,6 +171,7 @@ fn deserialize_deps<'de, D>(d: D) -> Result<Vec<(String, Arc<Fingerprint>)>, D::
features: String::new(),
deps: Vec::new(),
memoized_hash: Mutex::new(Some(hash)),
epoch: Epoch::Epoch2015,
rustflags: Vec::new(),
}))
}).collect())
Expand Down Expand Up @@ -252,6 +254,9 @@ impl Fingerprint {
if self.local.len() != old.local.len() {
bail!("local lens changed");
}
if self.epoch != old.epoch {
bail!("epoch changed")
}
for (new, old) in self.local.iter().zip(&old.local) {
match (new, old) {
(&LocalFingerprint::Precalculated(ref a),
Expand Down Expand Up @@ -315,9 +320,10 @@ impl hash::Hash for Fingerprint {
ref deps,
ref local,
memoized_hash: _,
epoch,
ref rustflags,
} = *self;
(rustc, features, target, path, profile, local, rustflags).hash(h);
(rustc, features, target, path, profile, local, epoch, rustflags).hash(h);

h.write_usize(deps.len());
for &(ref name, ref fingerprint) in deps {
Expand Down Expand Up @@ -416,6 +422,7 @@ fn calculate<'a, 'cfg>(cx: &mut Context<'a, 'cfg>, unit: &Unit<'a>)
deps: deps,
local: vec![local],
memoized_hash: Mutex::new(None),
epoch: unit.pkg.manifest().epoch(),
rustflags: extra_flags,
});
cx.fingerprints.insert(*unit, Arc::clone(&fingerprint));
Expand Down Expand Up @@ -468,6 +475,7 @@ pub fn prepare_build_cmd<'a, 'cfg>(cx: &mut Context<'a, 'cfg>, unit: &Unit<'a>)
deps: Vec::new(),
local: local,
memoized_hash: Mutex::new(None),
epoch: Epoch::Epoch2015,
rustflags: Vec::new(),
};
let compare = compare_old_fingerprint(&loc, &fingerprint);
Expand Down
7 changes: 6 additions & 1 deletion src/cargo/ops/cargo_rustc/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use std::sync::Arc;
use same_file::is_same_file;
use serde_json;

use core::{Package, PackageId, PackageSet, Target, Resolve};
use core::{Feature, Package, PackageId, PackageSet, Target, Resolve};
use core::{Profile, Profiles, Workspace};
use core::manifest::Lto;
use core::shell::ColorChoice;
Expand Down Expand Up @@ -804,6 +804,11 @@ fn build_base_args<'a, 'cfg>(cx: &mut Context<'a, 'cfg>,
cmd.arg("-C").arg(format!("panic={}", panic));
}
}
let manifest = unit.pkg.manifest();

if manifest.features().is_enabled(Feature::epoch()) {
cmd.arg(format!("-Zepoch={}", manifest.epoch()));
}

// Disable LTO for host builds as prefer_dynamic and it are mutually
// exclusive.
Expand Down
17 changes: 16 additions & 1 deletion src/cargo/util/toml/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ use url::Url;

use core::{SourceId, Profiles, PackageIdSpec, GitReference, WorkspaceConfig, WorkspaceRootConfig};
use core::{Summary, Manifest, Target, Dependency, PackageId};
use core::{EitherManifest, VirtualManifest, Features, Feature};
use core::{EitherManifest, Epoch, VirtualManifest, Features, Feature};
use core::dependency::{Kind, Platform};
use core::manifest::{LibKind, Profile, ManifestMetadata, Lto};
use sources::CRATES_IO;
Expand Down Expand Up @@ -441,6 +441,7 @@ pub struct TomlProject {
license_file: Option<String>,
repository: Option<String>,
metadata: Option<toml::Value>,
rust: Option<String>,
}

#[derive(Debug, Deserialize, Serialize)]
Expand Down Expand Up @@ -715,6 +716,19 @@ impl TomlManifest {
Some(VecStringOrBool::Bool(false)) => Some(vec![]),
None | Some(VecStringOrBool::Bool(true)) => None,
};

let epoch = if let Some(ref epoch) = project.rust {
features.require(Feature::epoch()).chain_err(|| {
"epoches are unstable"
})?;
if let Ok(epoch) = epoch.parse() {
epoch
} else {
bail!("the `rust` key must be one of: `2015`, `2018`")
}
} else {
Epoch::Epoch2015
};
let mut manifest = Manifest::new(summary,
targets,
exclude,
Expand All @@ -727,6 +741,7 @@ impl TomlManifest {
patch,
workspace_config,
features,
epoch,
project.im_a_teapot,
Rc::clone(me));
if project.license_file.is_some() && project.license.is_some() {
Expand Down
117 changes: 117 additions & 0 deletions tests/package.rs
Original file line number Diff line number Diff line change
Expand Up @@ -887,3 +887,120 @@ fn package_two_kinds_of_deps() {
assert_that(p.cargo("package").arg("--no-verify"),
execs().with_status(0));
}

#[test]
fn test_epoch() {
let p = project("foo")
.file("Cargo.toml", r#"
cargo-features = ["epoch"]
[package]
name = "foo"
version = "0.0.1"
authors = []
rust = "2018"
"#)
.file("src/lib.rs", r#" "#)
.build();

assert_that(p.cargo("build").arg("-v")
.masquerade_as_nightly_cargo(),
execs()
// -Zepoch is still in flux and we're not passing -Zunstable-options
// from Cargo so it will probably error. Only partially match the output
// until stuff stabilizes
.with_stderr_contains(format!("\
[COMPILING] foo v0.0.1 ({url})
[RUNNING] `rustc --crate-name foo src[/]lib.rs --crate-type lib \
--emit=dep-info,link -Zepoch=2018 -C debuginfo=2 \
-C metadata=[..] \
--out-dir [..] \
-L dependency={dir}[/]target[/]debug[/]deps`
", dir = p.root().display(), url = p.url())));
}

#[test]
fn test_epoch_missing() {
// no epoch = 2015
let p = project("foo")
.file("Cargo.toml", r#"
cargo-features = ["epoch"]
[package]
name = "foo"
version = "0.0.1"
authors = []
"#)
.file("src/lib.rs", r#" "#)
.build();

assert_that(p.cargo("build").arg("-v")
.masquerade_as_nightly_cargo(),
execs()
// -Zepoch is still in flux and we're not passing -Zunstable-options
// from Cargo so it will probably error. Only partially match the output
// until stuff stabilizes
.with_stderr_contains(format!("\
[COMPILING] foo v0.0.1 ({url})
[RUNNING] `rustc --crate-name foo src[/]lib.rs --crate-type lib \
--emit=dep-info,link -Zepoch=2015 -C debuginfo=2 \
-C metadata=[..] \
--out-dir [..] \
-L dependency={dir}[/]target[/]debug[/]deps`
", dir = p.root().display(), url = p.url())));
}

#[test]
fn test_epoch_malformed() {
let p = project("foo")
.file("Cargo.toml", r#"
cargo-features = ["epoch"]
[package]
name = "foo"
version = "0.0.1"
authors = []
rust = "chicken"
"#)
.file("src/lib.rs", r#" "#)
.build();

assert_that(p.cargo("build").arg("-v")
.masquerade_as_nightly_cargo(),
execs()
.with_status(101)
.with_stderr(format!("\
error: failed to parse manifest at `[..]`
Caused by:
the `rust` key must be one of: `2015`, `2018`
")));
}


#[test]
fn test_epoch_nightly() {
let p = project("foo")
.file("Cargo.toml", r#"
[package]
name = "foo"
version = "0.0.1"
authors = []
rust = "2015"
"#)
.file("src/lib.rs", r#" "#)
.build();

assert_that(p.cargo("build").arg("-v")
.masquerade_as_nightly_cargo(),
execs()
.with_status(101)
.with_stderr(format!("\
error: failed to parse manifest at `[..]`
Caused by:
epoches are unstable
Caused by:
feature `epoch` is required
consider adding `cargo-features = [\"epoch\"]` to the manifest
")));
}

0 comments on commit 750df0a

Please sign in to comment.