Skip to content

Commit

Permalink
Stabilize edition key and add cargo new --edition
Browse files Browse the repository at this point in the history
This commit stabilizes the `edition` key in `Cargo.toml`, both in the
`[package]` section and inside subtargets. Additionally the `cargo new` and
`cargo init` subcommands have been enhanced with a `--edition` flag to allow
explicitly specifying the edition to be generated.

This commit does not yet change the default edition that's generated.

Closes #5980
  • Loading branch information
alexcrichton committed Sep 6, 2018
1 parent 065e3ef commit 3d02903
Show file tree
Hide file tree
Showing 13 changed files with 158 additions and 229 deletions.
9 changes: 8 additions & 1 deletion src/bin/cargo/command_prelude.rs
Original file line number Diff line number Diff line change
Expand Up @@ -147,8 +147,14 @@ pub trait AppExt: Sized {
a global configuration.",
).value_name("VCS")
.possible_values(&["git", "hg", "pijul", "fossil", "none"]),
)._arg(opt("bin", "Use a binary (application) template [default]"))
)
._arg(opt("bin", "Use a binary (application) template [default]"))
._arg(opt("lib", "Use a library template"))
._arg(
opt("edition", "Edition to set for the crate generated")
.possible_values(&["2015", "2018"])
.value_name("YEAR")
)
._arg(
opt(
"name",
Expand Down Expand Up @@ -339,6 +345,7 @@ pub trait ArgMatchesExt {
self._is_present("lib"),
self.value_of_path("path", config).unwrap(),
self._value_of("name").map(|s| s.to_string()),
self._value_of("edition").map(|s| s.to_string()),
)
}

Expand Down
8 changes: 3 additions & 5 deletions src/cargo/core/compiler/compilation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use std::path::PathBuf;
use semver::Version;
use lazycell::LazyCell;

use core::{Feature, Package, PackageId, Target, TargetKind};
use core::{Edition, Package, PackageId, Target, TargetKind};
use util::{self, join_paths, process, CargoResult, Config, ProcessBuilder};
use super::BuildContext;

Expand Down Expand Up @@ -123,8 +123,7 @@ impl<'cfg> Compilation<'cfg> {
/// See `process`.
pub fn rustc_process(&self, pkg: &Package, target: &Target) -> CargoResult<ProcessBuilder> {
let mut p = self.fill_env(self.rustc_process.clone(), pkg, true)?;
let manifest = pkg.manifest();
if manifest.features().is_enabled(Feature::edition()) {
if target.edition() != Edition::Edition2015 {
p.arg(format!("--edition={}", target.edition()));
}
Ok(p)
Expand All @@ -133,8 +132,7 @@ impl<'cfg> Compilation<'cfg> {
/// See `process`.
pub fn rustdoc_process(&self, pkg: &Package, target: &Target) -> CargoResult<ProcessBuilder> {
let mut p = self.fill_env(process(&*self.config.rustdoc()?), pkg, false)?;
let manifest = pkg.manifest();
if manifest.features().is_enabled(Feature::edition()) {
if target.edition() != Edition::Edition2015 {
p.arg("-Zunstable-options");
p.arg(format!("--edition={}", target.edition()));
}
Expand Down
5 changes: 3 additions & 2 deletions src/cargo/core/features.rs
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ impl FromStr for Edition {
}
}

#[derive(PartialEq)]
enum Status {
Stable,
Unstable,
Expand All @@ -106,7 +107,7 @@ macro_rules! features {
$(
pub fn $feature() -> &'static Feature {
fn get(features: &Features) -> bool {
features.$feature
stab!($stab) == Status::Stable || features.$feature
}
static FEAT: Feature = Feature {
name: stringify!($feature),
Expand Down Expand Up @@ -173,7 +174,7 @@ features! {
[unstable] alternative_registries: bool,

// Using editions
[unstable] edition: bool,
[stable] edition: bool,

// Renaming a package in the manifest via the `package` key
[unstable] rename_dependency: bool,
Expand Down
15 changes: 14 additions & 1 deletion src/cargo/ops/cargo_new.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ pub struct NewOptions {
/// Absolute path to the directory for the new project
pub path: PathBuf,
pub name: Option<String>,
pub edition: Option<String>,
}

#[derive(Clone, Copy, Debug, PartialEq, Eq)]
Expand Down Expand Up @@ -65,6 +66,7 @@ struct MkOptions<'a> {
name: &'a str,
source_files: Vec<SourceFileInformation>,
bin: bool,
edition: Option<&'a str>,
}

impl NewOptions {
Expand All @@ -74,6 +76,7 @@ impl NewOptions {
lib: bool,
path: PathBuf,
name: Option<String>,
edition: Option<String>,
) -> CargoResult<NewOptions> {
let kind = match (bin, lib) {
(true, true) => bail!("can't specify both lib and binary outputs"),
Expand All @@ -87,6 +90,7 @@ impl NewOptions {
kind,
path,
name,
edition,
};
Ok(opts)
}
Expand Down Expand Up @@ -321,6 +325,7 @@ pub fn new(opts: &NewOptions, config: &Config) -> CargoResult<()> {
name,
source_files: vec![plan_new_source_file(opts.kind.is_bin(), name.to_string())],
bin: opts.kind.is_bin(),
edition: opts.edition.as_ref().map(|s| &**s),
};

mk(config, &mkopts).chain_err(|| {
Expand Down Expand Up @@ -397,6 +402,7 @@ pub fn init(opts: &NewOptions, config: &Config) -> CargoResult<()> {
name,
bin: src_paths_types.iter().any(|x| x.bin),
source_files: src_paths_types,
edition: opts.edition.as_ref().map(|s| &**s),
};

mk(config, &mkopts).chain_err(|| {
Expand Down Expand Up @@ -529,12 +535,19 @@ path = {}
r#"[package]
name = "{}"
version = "0.1.0"
authors = [{}]
authors = [{}]{}
[dependencies]
{}"#,
name,
toml::Value::String(author),
match opts.edition {
Some(edition) => {
let edition = toml::Value::String(edition.to_string());
format!("\nedition = {}", edition)
}
None => String::new(),
},
cargotoml_path_specifier
).as_bytes(),
)?;
Expand Down
24 changes: 24 additions & 0 deletions src/doc/src/reference/manifest.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,24 @@ Versioning](http://semver.org/), so make sure you follow some basic rules:
traits, fields, types, functions, methods or anything else.
* Use version numbers with three numeric parts such as 1.0.0 rather than 1.0.

#### The `edition` field (optional)

You can opt in to a specific Rust Edition for your package with the
`edition` key in `Cargo.toml`. If you don't specify the edition, it will
default to 2015.

```toml
[package]
# ...
edition = '2018'
```

The `edition` key affects which edition your package is compiled with. Cargo
will always generate projects via `cargo new` with the `edition` key set to the
latest edition. Setting the `edition` key in `[package]` will affect all
targets/crates in the package, including test suites, benchmarks, binaries,
examples, etc.

#### The `build` field (optional)

This field specifies a file in the project root which is a [build script][1] for
Expand Down Expand Up @@ -714,6 +732,12 @@ proc-macro = false
# stops it from generating a test harness. This is useful when the binary being
# built manages the test runner itself.
harness = true

# If set then a target can be configured to use a different edition than the
# `[package]` is configured to use, perhaps only compiling a library with the
# 2018 edition or only compiling one unit test with the 2015 edition. By default
# all targets are compiled with the edition specified in `[package]`.
edition = '2015'
```

The `[package]` also includes the optional `autobins`, `autoexamples`,
Expand Down
24 changes: 0 additions & 24 deletions src/doc/src/reference/unstable.md
Original file line number Diff line number Diff line change
Expand Up @@ -199,30 +199,6 @@ cargo +nightly build --out-dir=out -Z unstable-options
```


### Edition
* Tracking Issue: [rust-lang/rust#44581](https://github.com/rust-lang/rust/issues/44581)
* RFC: [#2052](https://github.com/rust-lang/rfcs/blob/master/text/2052-epochs.md)

You can opt in to a specific Rust Edition for your package with the `edition`
key in `Cargo.toml`. If you don't specify the edition, it will default to
2015. You need to include the appropriate `cargo-features`.

You can also specify `edition` on a per-target level, where it will otherwise
default to the package `edition`.

```toml
cargo-features = ["edition"]

[package]
...
edition = "2018"

[[bin]]
...
edition = "2015"
```


### Profile Overrides
* Tracking Issue: [rust-lang/rust#48683](https://github.com/rust-lang/rust/issues/48683)
* RFC: [#2282](https://github.com/rust-lang/rfcs/blob/master/text/2282-profile-dependencies.md)
Expand Down
51 changes: 24 additions & 27 deletions tests/testsuite/bench.rs
Original file line number Diff line number Diff line change
Expand Up @@ -549,45 +549,42 @@ fn bench_autodiscover_2015() {
.file(
"Cargo.toml",
r#"
cargo-features = ["edition"]
[project]
name = "foo"
version = "0.0.1"
authors = []
edition = "2015"
[[bench]]
name = "bench_magic"
required-features = ["magic"]
"#,
[project]
name = "foo"
version = "0.0.1"
authors = []
edition = "2015"
[[bench]]
name = "bench_magic"
required-features = ["magic"]
"#,
).file("src/lib.rs", "")
.file(
"benches/bench_basic.rs",
r#"
#![feature(test)]
#[allow(unused_extern_crates)]
extern crate foo;
extern crate test;
#![feature(test)]
#[allow(unused_extern_crates)]
extern crate foo;
extern crate test;
#[bench]
fn bench_basic(_b: &mut test::Bencher) {}
"#,
#[bench]
fn bench_basic(_b: &mut test::Bencher) {}
"#,
).file(
"benches/bench_magic.rs",
r#"
#![feature(test)]
#[allow(unused_extern_crates)]
extern crate foo;
extern crate test;
#![feature(test)]
#[allow(unused_extern_crates)]
extern crate foo;
extern crate test;
#[bench]
fn bench_magic(_b: &mut test::Bencher) {}
"#,
#[bench]
fn bench_magic(_b: &mut test::Bencher) {}
"#,
).build();

p.cargo("bench bench_basic")
.masquerade_as_nightly_cargo()
.with_stderr(
"warning: \
An explicit [[bench]] section is specified in Cargo.toml which currently
Expand Down
84 changes: 23 additions & 61 deletions tests/testsuite/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3928,19 +3928,17 @@ fn target_edition() {
.file(
"Cargo.toml",
r#"
cargo-features = ["edition"]
[package]
name = "foo"
version = "0.0.1"
[package]
name = "foo"
version = "0.0.1"
[lib]
edition = "2018"
"#,
[lib]
edition = "2018"
"#,
).file("src/lib.rs", "")
.build();

p.cargo("build -v")
.masquerade_as_nightly_cargo()
.with_stderr_contains(
"\
[COMPILING] foo v0.0.1 ([..])
Expand All @@ -3955,62 +3953,26 @@ fn target_edition_override() {
.file(
"Cargo.toml",
r#"
cargo-features = ["edition"]
[package]
name = "foo"
version = "0.0.1"
authors = []
edition = "2018"
[lib]
edition = "2015"
"#,
).file("src/lib.rs", "")
.build();

p.cargo("build -v")
.masquerade_as_nightly_cargo()
.with_stderr_contains(
"\
[COMPILING] foo v0.0.1 ([..])
[RUNNING] `rustc [..]--edition=2015 [..]
",
).run();
}

#[test]
fn target_edition_feature_gated() {
let p = project()
.file(
"Cargo.toml",
r#"
[package]
name = "foo"
version = "0.0.1"
authors = []
[package]
name = "foo"
version = "0.0.1"
authors = []
edition = "2018"
[lib]
edition = "2018"
"#,
).file("src/lib.rs", "")
[lib]
edition = "2015"
"#,
).file(
"src/lib.rs",
"
pub fn async() {}
pub fn try() {}
pub fn await() {}
"
)
.build();

p.cargo("build -v")
.masquerade_as_nightly_cargo()
.with_status(101)
.with_stderr(
"\
error: failed to parse manifest at `[..]`
Caused by:
editions are unstable
Caused by:
feature `edition` is required
consider adding `cargo-features = [\"edition\"]` to the manifest
",
).run();
p.cargo("build -v").run();
}

#[test]
Expand Down
Loading

0 comments on commit 3d02903

Please sign in to comment.