Skip to content

Commit 56ee620

Browse files
committed
Auto merge of #5984 - alexcrichton:stabilize-edition, r=ehuss
Stabilize `edition` key and add `cargo new --edition` 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
2 parents a39c2a3 + 3d02903 commit 56ee620

File tree

13 files changed

+158
-229
lines changed

13 files changed

+158
-229
lines changed

src/bin/cargo/command_prelude.rs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -147,8 +147,14 @@ pub trait AppExt: Sized {
147147
a global configuration.",
148148
).value_name("VCS")
149149
.possible_values(&["git", "hg", "pijul", "fossil", "none"]),
150-
)._arg(opt("bin", "Use a binary (application) template [default]"))
150+
)
151+
._arg(opt("bin", "Use a binary (application) template [default]"))
151152
._arg(opt("lib", "Use a library template"))
153+
._arg(
154+
opt("edition", "Edition to set for the crate generated")
155+
.possible_values(&["2015", "2018"])
156+
.value_name("YEAR")
157+
)
152158
._arg(
153159
opt(
154160
"name",
@@ -339,6 +345,7 @@ pub trait ArgMatchesExt {
339345
self._is_present("lib"),
340346
self.value_of_path("path", config).unwrap(),
341347
self._value_of("name").map(|s| s.to_string()),
348+
self._value_of("edition").map(|s| s.to_string()),
342349
)
343350
}
344351

src/cargo/core/compiler/compilation.rs

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use std::path::PathBuf;
66
use semver::Version;
77
use lazycell::LazyCell;
88

9-
use core::{Feature, Package, PackageId, Target, TargetKind};
9+
use core::{Edition, Package, PackageId, Target, TargetKind};
1010
use util::{self, join_paths, process, CargoResult, Config, ProcessBuilder};
1111
use super::BuildContext;
1212

@@ -131,8 +131,7 @@ impl<'cfg> Compilation<'cfg> {
131131
/// See `process`.
132132
pub fn rustc_process(&self, pkg: &Package, target: &Target) -> CargoResult<ProcessBuilder> {
133133
let mut p = self.fill_env(self.rustc_process.clone(), pkg, true)?;
134-
let manifest = pkg.manifest();
135-
if manifest.features().is_enabled(Feature::edition()) {
134+
if target.edition() != Edition::Edition2015 {
136135
p.arg(format!("--edition={}", target.edition()));
137136
}
138137
Ok(p)
@@ -141,8 +140,7 @@ impl<'cfg> Compilation<'cfg> {
141140
/// See `process`.
142141
pub fn rustdoc_process(&self, pkg: &Package, target: &Target) -> CargoResult<ProcessBuilder> {
143142
let mut p = self.fill_env(process(&*self.config.rustdoc()?), pkg, false)?;
144-
let manifest = pkg.manifest();
145-
if manifest.features().is_enabled(Feature::edition()) {
143+
if target.edition() != Edition::Edition2015 {
146144
p.arg("-Zunstable-options");
147145
p.arg(format!("--edition={}", target.edition()));
148146
}

src/cargo/core/features.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@ impl FromStr for Edition {
8585
}
8686
}
8787

88+
#[derive(PartialEq)]
8889
enum Status {
8990
Stable,
9091
Unstable,
@@ -106,7 +107,7 @@ macro_rules! features {
106107
$(
107108
pub fn $feature() -> &'static Feature {
108109
fn get(features: &Features) -> bool {
109-
features.$feature
110+
stab!($stab) == Status::Stable || features.$feature
110111
}
111112
static FEAT: Feature = Feature {
112113
name: stringify!($feature),
@@ -173,7 +174,7 @@ features! {
173174
[unstable] alternative_registries: bool,
174175

175176
// Using editions
176-
[unstable] edition: bool,
177+
[stable] edition: bool,
177178

178179
// Renaming a package in the manifest via the `package` key
179180
[unstable] rename_dependency: bool,

src/cargo/ops/cargo_new.rs

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ pub struct NewOptions {
3030
/// Absolute path to the directory for the new project
3131
pub path: PathBuf,
3232
pub name: Option<String>,
33+
pub edition: Option<String>,
3334
}
3435

3536
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
@@ -65,6 +66,7 @@ struct MkOptions<'a> {
6566
name: &'a str,
6667
source_files: Vec<SourceFileInformation>,
6768
bin: bool,
69+
edition: Option<&'a str>,
6870
}
6971

7072
impl NewOptions {
@@ -74,6 +76,7 @@ impl NewOptions {
7476
lib: bool,
7577
path: PathBuf,
7678
name: Option<String>,
79+
edition: Option<String>,
7780
) -> CargoResult<NewOptions> {
7881
let kind = match (bin, lib) {
7982
(true, true) => bail!("can't specify both lib and binary outputs"),
@@ -87,6 +90,7 @@ impl NewOptions {
8790
kind,
8891
path,
8992
name,
93+
edition,
9094
};
9195
Ok(opts)
9296
}
@@ -321,6 +325,7 @@ pub fn new(opts: &NewOptions, config: &Config) -> CargoResult<()> {
321325
name,
322326
source_files: vec![plan_new_source_file(opts.kind.is_bin(), name.to_string())],
323327
bin: opts.kind.is_bin(),
328+
edition: opts.edition.as_ref().map(|s| &**s),
324329
};
325330

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

402408
mk(config, &mkopts).chain_err(|| {
@@ -529,12 +535,19 @@ path = {}
529535
r#"[package]
530536
name = "{}"
531537
version = "0.1.0"
532-
authors = [{}]
538+
authors = [{}]{}
533539
534540
[dependencies]
535541
{}"#,
536542
name,
537543
toml::Value::String(author),
544+
match opts.edition {
545+
Some(edition) => {
546+
let edition = toml::Value::String(edition.to_string());
547+
format!("\nedition = {}", edition)
548+
}
549+
None => String::new(),
550+
},
538551
cargotoml_path_specifier
539552
).as_bytes(),
540553
)?;

src/doc/src/reference/manifest.md

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,24 @@ Versioning](http://semver.org/), so make sure you follow some basic rules:
3131
traits, fields, types, functions, methods or anything else.
3232
* Use version numbers with three numeric parts such as 1.0.0 rather than 1.0.
3333

34+
#### The `edition` field (optional)
35+
36+
You can opt in to a specific Rust Edition for your package with the
37+
`edition` key in `Cargo.toml`. If you don't specify the edition, it will
38+
default to 2015.
39+
40+
```toml
41+
[package]
42+
# ...
43+
edition = '2018'
44+
```
45+
46+
The `edition` key affects which edition your package is compiled with. Cargo
47+
will always generate projects via `cargo new` with the `edition` key set to the
48+
latest edition. Setting the `edition` key in `[package]` will affect all
49+
targets/crates in the package, including test suites, benchmarks, binaries,
50+
examples, etc.
51+
3452
#### The `build` field (optional)
3553

3654
This field specifies a file in the project root which is a [build script][1] for
@@ -714,6 +732,12 @@ proc-macro = false
714732
# stops it from generating a test harness. This is useful when the binary being
715733
# built manages the test runner itself.
716734
harness = true
735+
736+
# If set then a target can be configured to use a different edition than the
737+
# `[package]` is configured to use, perhaps only compiling a library with the
738+
# 2018 edition or only compiling one unit test with the 2015 edition. By default
739+
# all targets are compiled with the edition specified in `[package]`.
740+
edition = '2015'
717741
```
718742

719743
The `[package]` also includes the optional `autobins`, `autoexamples`,

src/doc/src/reference/unstable.md

Lines changed: 0 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -199,30 +199,6 @@ cargo +nightly build --out-dir=out -Z unstable-options
199199
```
200200

201201

202-
### Edition
203-
* Tracking Issue: [rust-lang/rust#44581](https://github.com/rust-lang/rust/issues/44581)
204-
* RFC: [#2052](https://github.com/rust-lang/rfcs/blob/master/text/2052-epochs.md)
205-
206-
You can opt in to a specific Rust Edition for your package with the `edition`
207-
key in `Cargo.toml`. If you don't specify the edition, it will default to
208-
2015. You need to include the appropriate `cargo-features`.
209-
210-
You can also specify `edition` on a per-target level, where it will otherwise
211-
default to the package `edition`.
212-
213-
```toml
214-
cargo-features = ["edition"]
215-
216-
[package]
217-
...
218-
edition = "2018"
219-
220-
[[bin]]
221-
...
222-
edition = "2015"
223-
```
224-
225-
226202
### Profile Overrides
227203
* Tracking Issue: [rust-lang/rust#48683](https://github.com/rust-lang/rust/issues/48683)
228204
* RFC: [#2282](https://github.com/rust-lang/rfcs/blob/master/text/2282-profile-dependencies.md)

tests/testsuite/bench.rs

Lines changed: 24 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -549,45 +549,42 @@ fn bench_autodiscover_2015() {
549549
.file(
550550
"Cargo.toml",
551551
r#"
552-
cargo-features = ["edition"]
553-
554-
[project]
555-
name = "foo"
556-
version = "0.0.1"
557-
authors = []
558-
edition = "2015"
559-
560-
[[bench]]
561-
name = "bench_magic"
562-
required-features = ["magic"]
563-
"#,
552+
[project]
553+
name = "foo"
554+
version = "0.0.1"
555+
authors = []
556+
edition = "2015"
557+
558+
[[bench]]
559+
name = "bench_magic"
560+
required-features = ["magic"]
561+
"#,
564562
).file("src/lib.rs", "")
565563
.file(
566564
"benches/bench_basic.rs",
567565
r#"
568-
#![feature(test)]
569-
#[allow(unused_extern_crates)]
570-
extern crate foo;
571-
extern crate test;
566+
#![feature(test)]
567+
#[allow(unused_extern_crates)]
568+
extern crate foo;
569+
extern crate test;
572570
573-
#[bench]
574-
fn bench_basic(_b: &mut test::Bencher) {}
575-
"#,
571+
#[bench]
572+
fn bench_basic(_b: &mut test::Bencher) {}
573+
"#,
576574
).file(
577575
"benches/bench_magic.rs",
578576
r#"
579-
#![feature(test)]
580-
#[allow(unused_extern_crates)]
581-
extern crate foo;
582-
extern crate test;
577+
#![feature(test)]
578+
#[allow(unused_extern_crates)]
579+
extern crate foo;
580+
extern crate test;
583581
584-
#[bench]
585-
fn bench_magic(_b: &mut test::Bencher) {}
586-
"#,
582+
#[bench]
583+
fn bench_magic(_b: &mut test::Bencher) {}
584+
"#,
587585
).build();
588586

589587
p.cargo("bench bench_basic")
590-
.masquerade_as_nightly_cargo()
591588
.with_stderr(
592589
"warning: \
593590
An explicit [[bench]] section is specified in Cargo.toml which currently

tests/testsuite/build.rs

Lines changed: 23 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -3928,19 +3928,17 @@ fn target_edition() {
39283928
.file(
39293929
"Cargo.toml",
39303930
r#"
3931-
cargo-features = ["edition"]
3932-
[package]
3933-
name = "foo"
3934-
version = "0.0.1"
3931+
[package]
3932+
name = "foo"
3933+
version = "0.0.1"
39353934
3936-
[lib]
3937-
edition = "2018"
3938-
"#,
3935+
[lib]
3936+
edition = "2018"
3937+
"#,
39393938
).file("src/lib.rs", "")
39403939
.build();
39413940

39423941
p.cargo("build -v")
3943-
.masquerade_as_nightly_cargo()
39443942
.with_stderr_contains(
39453943
"\
39463944
[COMPILING] foo v0.0.1 ([..])
@@ -3955,62 +3953,26 @@ fn target_edition_override() {
39553953
.file(
39563954
"Cargo.toml",
39573955
r#"
3958-
cargo-features = ["edition"]
3959-
[package]
3960-
name = "foo"
3961-
version = "0.0.1"
3962-
authors = []
3963-
edition = "2018"
3964-
3965-
[lib]
3966-
edition = "2015"
3967-
"#,
3968-
).file("src/lib.rs", "")
3969-
.build();
3970-
3971-
p.cargo("build -v")
3972-
.masquerade_as_nightly_cargo()
3973-
.with_stderr_contains(
3974-
"\
3975-
[COMPILING] foo v0.0.1 ([..])
3976-
[RUNNING] `rustc [..]--edition=2015 [..]
3977-
",
3978-
).run();
3979-
}
3980-
3981-
#[test]
3982-
fn target_edition_feature_gated() {
3983-
let p = project()
3984-
.file(
3985-
"Cargo.toml",
3986-
r#"
3987-
[package]
3988-
name = "foo"
3989-
version = "0.0.1"
3990-
authors = []
3956+
[package]
3957+
name = "foo"
3958+
version = "0.0.1"
3959+
authors = []
3960+
edition = "2018"
39913961
3992-
[lib]
3993-
edition = "2018"
3994-
"#,
3995-
).file("src/lib.rs", "")
3962+
[lib]
3963+
edition = "2015"
3964+
"#,
3965+
).file(
3966+
"src/lib.rs",
3967+
"
3968+
pub fn async() {}
3969+
pub fn try() {}
3970+
pub fn await() {}
3971+
"
3972+
)
39963973
.build();
39973974

3998-
p.cargo("build -v")
3999-
.masquerade_as_nightly_cargo()
4000-
.with_status(101)
4001-
.with_stderr(
4002-
"\
4003-
error: failed to parse manifest at `[..]`
4004-
4005-
Caused by:
4006-
editions are unstable
4007-
4008-
Caused by:
4009-
feature `edition` is required
4010-
4011-
consider adding `cargo-features = [\"edition\"]` to the manifest
4012-
",
4013-
).run();
3975+
p.cargo("build -v").run();
40143976
}
40153977

40163978
#[test]

0 commit comments

Comments
 (0)