Skip to content

Commit f772ec0

Browse files
committed
Auto merge of #13505 - epage:edition-warn, r=weihanglo
feat(toml): Warn on unset Edition ### What does this PR try to resolve? On [Internals](https://internals.rust-lang.org/t/idea-rustc-cargo-should-warn-on-unspecified-edition/20309), the idea came up for warning on unset Edition. Besides helping people who forget to set the Edition, this creates symmetry between `Cargo.toml` and cargo scripts (#12207). While the default is different in each case, we are making the default obvious and guiding people away from it. ### How should we test and review this PR? There are separate commits for adding tests (and refactors) so the changes in behavior will be more obvious ### Additional information This builds on - #13499 - #13504
2 parents db609a5 + 768c70a commit f772ec0

File tree

10 files changed

+200
-25
lines changed

10 files changed

+200
-25
lines changed

src/cargo/core/features.rs

+10-1
Original file line numberDiff line numberDiff line change
@@ -180,9 +180,12 @@ pub type AllowFeatures = BTreeSet<String>;
180180
/// [`is_stable`]: Edition::is_stable
181181
/// [`toml::to_real_manifest`]: crate::util::toml::to_real_manifest
182182
/// [`features!`]: macro.features.html
183-
#[derive(Clone, Copy, Debug, Hash, PartialOrd, Ord, Eq, PartialEq, Serialize, Deserialize)]
183+
#[derive(
184+
Default, Clone, Copy, Debug, Hash, PartialOrd, Ord, Eq, PartialEq, Serialize, Deserialize,
185+
)]
184186
pub enum Edition {
185187
/// The 2015 edition
188+
#[default]
186189
Edition2015,
187190
/// The 2018 edition
188191
Edition2018,
@@ -199,6 +202,12 @@ impl Edition {
199202
pub const LATEST_UNSTABLE: Option<Edition> = Some(Edition::Edition2024);
200203
/// The latest stable edition.
201204
pub const LATEST_STABLE: Edition = Edition::Edition2021;
205+
pub const ALL: &'static [Edition] = &[
206+
Self::Edition2015,
207+
Self::Edition2018,
208+
Self::Edition2021,
209+
Self::Edition2024,
210+
];
202211
/// Possible values allowed for the `--edition` CLI flag.
203212
///
204213
/// This requires a static value due to the way clap works, otherwise I

src/cargo/util/toml/mod.rs

+57-24
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ use crate::AlreadyPrintedError;
99
use anyhow::{anyhow, bail, Context as _};
1010
use cargo_platform::Platform;
1111
use cargo_util::paths;
12+
use cargo_util_schemas::core::PartialVersion;
1213
use cargo_util_schemas::manifest;
1314
use cargo_util_schemas::manifest::RustVersion;
1415
use itertools::Itertools;
@@ -563,14 +564,69 @@ pub fn to_real_manifest(
563564
source_id,
564565
);
565566

567+
let rust_version = if let Some(rust_version) = &package.rust_version {
568+
let rust_version = field_inherit_with(rust_version.clone(), "rust_version", || {
569+
inherit()?.rust_version()
570+
})?;
571+
Some(rust_version)
572+
} else {
573+
None
574+
};
575+
566576
let edition = if let Some(edition) = package.edition.clone() {
567577
let edition: Edition = field_inherit_with(edition, "edition", || inherit()?.edition())?
568578
.parse()
569579
.with_context(|| "failed to parse the `edition` key")?;
570580
package.edition = Some(manifest::InheritableField::Value(edition.to_string()));
581+
if let Some(rust_version) = &rust_version {
582+
let req = rust_version.to_caret_req();
583+
if let Some(first_version) = edition.first_version() {
584+
let unsupported =
585+
semver::Version::new(first_version.major, first_version.minor - 1, 9999);
586+
if req.matches(&unsupported) {
587+
bail!(
588+
"rust-version {} is older than first version ({}) required by \
589+
the specified edition ({})",
590+
rust_version,
591+
first_version,
592+
edition,
593+
)
594+
}
595+
}
596+
}
571597
edition
572598
} else {
573-
Edition::Edition2015
599+
let msrv_edition = if let Some(rust_version) = &rust_version {
600+
Edition::ALL
601+
.iter()
602+
.filter(|e| {
603+
e.first_version()
604+
.map(|e| {
605+
let e = PartialVersion::from(e);
606+
e <= **rust_version
607+
})
608+
.unwrap_or_default()
609+
})
610+
.max()
611+
.copied()
612+
} else {
613+
None
614+
}
615+
.unwrap_or_default();
616+
let default_edition = Edition::default();
617+
let latest_edition = Edition::LATEST_STABLE;
618+
619+
let tip = if msrv_edition == default_edition {
620+
String::new()
621+
} else if msrv_edition == latest_edition {
622+
format!(" while the latest is {latest_edition}")
623+
} else {
624+
format!(" while {msrv_edition} is compatible with `rust-version`")
625+
};
626+
warnings.push(format!(
627+
"no edition set: defaulting to the {default_edition} edition{tip}",
628+
));
629+
default_edition
574630
};
575631
// Add these lines if start a new unstable edition.
576632
// ```
@@ -588,29 +644,6 @@ pub fn to_real_manifest(
588644
)));
589645
}
590646

591-
let rust_version = if let Some(rust_version) = &package.rust_version {
592-
let rust_version = field_inherit_with(rust_version.clone(), "rust_version", || {
593-
inherit()?.rust_version()
594-
})?;
595-
let req = rust_version.to_caret_req();
596-
if let Some(first_version) = edition.first_version() {
597-
let unsupported =
598-
semver::Version::new(first_version.major, first_version.minor - 1, 9999);
599-
if req.matches(&unsupported) {
600-
bail!(
601-
"rust-version {} is older than first version ({}) required by \
602-
the specified edition ({})",
603-
rust_version,
604-
first_version,
605-
edition,
606-
)
607-
}
608-
}
609-
Some(rust_version)
610-
} else {
611-
None
612-
};
613-
614647
if package.metabuild.is_some() {
615648
features.require(Feature::metabuild())?;
616649
}

tests/testsuite/bench.rs

+17
Original file line numberDiff line numberDiff line change
@@ -331,6 +331,7 @@ fn bench_with_lib_dep() {
331331
[package]
332332
name = "foo"
333333
version = "0.0.1"
334+
edition = "2015"
334335
authors = []
335336
336337
[[bin]]
@@ -396,6 +397,7 @@ fn bench_with_deep_lib_dep() {
396397
[package]
397398
name = "bar"
398399
version = "0.0.1"
400+
edition = "2015"
399401
authors = []
400402
401403
[dependencies.foo]
@@ -454,6 +456,7 @@ fn external_bench_explicit() {
454456
[package]
455457
name = "foo"
456458
version = "0.0.1"
459+
edition = "2015"
457460
authors = []
458461
459462
[[bench]]
@@ -697,6 +700,7 @@ fn lib_bin_same_name() {
697700
[package]
698701
name = "foo"
699702
version = "0.0.1"
703+
edition = "2015"
700704
authors = []
701705
702706
[lib]
@@ -796,6 +800,7 @@ fn lib_with_standard_name2() {
796800
[package]
797801
name = "syntax"
798802
version = "0.0.1"
803+
edition = "2015"
799804
authors = []
800805
801806
[lib]
@@ -842,6 +847,7 @@ fn bench_dylib() {
842847
[package]
843848
name = "foo"
844849
version = "0.0.1"
850+
edition = "2015"
845851
authors = []
846852
847853
[lib]
@@ -883,6 +889,7 @@ fn bench_dylib() {
883889
[package]
884890
name = "bar"
885891
version = "0.0.1"
892+
edition = "2015"
886893
authors = []
887894
888895
[lib]
@@ -932,6 +939,7 @@ fn bench_twice_with_build_cmd() {
932939
[package]
933940
name = "foo"
934941
version = "0.0.1"
942+
edition = "2015"
935943
authors = []
936944
build = "build.rs"
937945
"#,
@@ -977,6 +985,7 @@ fn bench_with_examples() {
977985
[package]
978986
name = "foo"
979987
version = "6.6.6"
988+
edition = "2015"
980989
authors = []
981990
982991
[[example]]
@@ -1061,6 +1070,7 @@ fn test_a_bench() {
10611070
name = "foo"
10621071
authors = []
10631072
version = "0.1.0"
1073+
edition = "2015"
10641074
10651075
[lib]
10661076
name = "foo"
@@ -1219,6 +1229,7 @@ fn test_bench_multiple_packages() {
12191229
name = "foo"
12201230
authors = []
12211231
version = "0.1.0"
1232+
edition = "2015"
12221233
12231234
[dependencies.bar]
12241235
path = "../bar"
@@ -1239,6 +1250,7 @@ fn test_bench_multiple_packages() {
12391250
name = "bar"
12401251
authors = []
12411252
version = "0.1.0"
1253+
edition = "2015"
12421254
12431255
[[bench]]
12441256
name = "bbar"
@@ -1269,6 +1281,7 @@ fn test_bench_multiple_packages() {
12691281
name = "baz"
12701282
authors = []
12711283
version = "0.1.0"
1284+
edition = "2015"
12721285
12731286
[[bench]]
12741287
name = "bbaz"
@@ -1307,6 +1320,7 @@ fn bench_all_workspace() {
13071320
[package]
13081321
name = "foo"
13091322
version = "0.1.0"
1323+
edition = "2015"
13101324
13111325
[dependencies]
13121326
bar = { path = "bar" }
@@ -1360,6 +1374,7 @@ fn bench_all_exclude() {
13601374
[package]
13611375
name = "foo"
13621376
version = "0.1.0"
1377+
edition = "2015"
13631378
13641379
[workspace]
13651380
members = ["bar", "baz"]
@@ -1405,6 +1420,7 @@ fn bench_all_exclude_glob() {
14051420
[package]
14061421
name = "foo"
14071422
version = "0.1.0"
1423+
edition = "2015"
14081424
14091425
[workspace]
14101426
members = ["bar", "baz"]
@@ -1549,6 +1565,7 @@ fn legacy_bench_name() {
15491565
[package]
15501566
name = "foo"
15511567
version = "0.1.0"
1568+
edition = "2015"
15521569
15531570
[[bench]]
15541571
name = "bench"

0 commit comments

Comments
 (0)