diff --git a/src/cargo/core/workspace.rs b/src/cargo/core/workspace.rs index d15dfa22c90..7b57b749e34 100644 --- a/src/cargo/core/workspace.rs +++ b/src/cargo/core/workspace.rs @@ -1662,6 +1662,7 @@ pub struct InheritableFields { publish: Option, edition: Option, badges: Option>>, + rust_version: Option, ws_root: PathBuf, } @@ -1682,6 +1683,7 @@ impl InheritableFields { publish: Option, edition: Option, badges: Option>>, + rust_version: Option, ws_root: PathBuf, ) -> InheritableFields { Self { @@ -1700,6 +1702,7 @@ impl InheritableFields { publish, edition, badges, + rust_version, ws_root, } } @@ -1828,6 +1831,13 @@ impl InheritableFields { }) } + pub fn rust_version(&self) -> CargoResult { + self.rust_version.clone().map_or( + Err(anyhow!("`workspace.rust-version` was not defined")), + |d| Ok(d), + ) + } + pub fn badges(&self) -> CargoResult>> { self.badges .clone() diff --git a/src/cargo/util/toml/mod.rs b/src/cargo/util/toml/mod.rs index 78553de8972..7778878bead 100644 --- a/src/cargo/util/toml/mod.rs +++ b/src/cargo/util/toml/mod.rs @@ -1046,7 +1046,7 @@ pub struct TomlWorkspaceField { #[serde(rename_all = "kebab-case")] pub struct TomlProject { edition: Option>, - rust_version: Option, + rust_version: Option>, name: InternedString, #[serde(deserialize_with = "version_trim_whitespace")] version: MaybeWorkspace, @@ -1111,6 +1111,8 @@ pub struct TomlWorkspace { publish: Option, edition: Option, badges: Option>>, + #[serde(rename = "rust-version")] + rust_version: Option, // Note that this field must come last due to the way toml serialization // works which requires tables to be emitted after all values. @@ -1376,6 +1378,7 @@ impl TomlManifest { config.publish.clone(), config.edition.clone(), config.badges.clone(), + config.rust_version.clone(), package_root.to_path_buf(), ); @@ -1441,7 +1444,12 @@ impl TomlManifest { } let rust_version = if let Some(rust_version) = &project.rust_version { - let req = match semver::VersionReq::parse(rust_version) { + let rust_version = rust_version + .clone() + .resolve(&features, "rust_version", || { + get_ws(config, resolved_path.clone(), workspace_config.clone())?.rust_version() + })?; + let req = match semver::VersionReq::parse(&rust_version) { // Exclude semver operators like `^` and pre-release identifiers Ok(req) if rust_version.chars().all(|c| c.is_ascii_digit() || c == '.') => req, _ => bail!("`rust-version` must be a value like \"1.32\""), @@ -1843,6 +1851,7 @@ impl TomlManifest { .categories .as_ref() .map(|_| MaybeWorkspace::Defined(metadata.categories.clone())); + project.rust_version = rust_version.clone().map(|rv| MaybeWorkspace::Defined(rv)); let profiles = me.profile.clone(); if let Some(profiles) = &profiles { @@ -2064,6 +2073,7 @@ impl TomlManifest { config.publish.clone(), config.edition.clone(), config.badges.clone(), + config.rust_version.clone(), root.to_path_buf(), ); WorkspaceConfig::Root(WorkspaceRootConfig::new( diff --git a/tests/testsuite/inheritable_workspace_fields.rs b/tests/testsuite/inheritable_workspace_fields.rs index 1b68e17116d..dc192942f14 100644 --- a/tests/testsuite/inheritable_workspace_fields.rs +++ b/tests/testsuite/inheritable_workspace_fields.rs @@ -25,6 +25,7 @@ fn permit_additional_workspace_fields() { categories = ["development-tools"] publish = false edition = "2018" + rust-version = "1.60" [workspace.badges] gitlab = { repository = "https://gitlab.com/rust-lang/rust", branch = "master" } @@ -130,6 +131,7 @@ fn inherit_own_workspace_fields() { categories = { workspace = true } publish = { workspace = true } edition = { workspace = true } + rust-version = { workspace = true } [workspace] members = [] @@ -144,6 +146,7 @@ fn inherit_own_workspace_fields() { categories = ["development-tools"] publish = true edition = "2018" + rust-version = "1.60" [workspace.badges] gitlab = { repository = "https://gitlab.com/rust-lang/rust", branch = "master" } "#, @@ -194,6 +197,7 @@ cargo-features = ["workspace-inheritance"] [package] edition = "2018" +rust-version = "1.60" name = "foo" version = "1.2.3" authors = ["Rustaceans"] @@ -590,6 +594,7 @@ fn inherit_workspace_fields() { categories = ["development-tools"] publish = true edition = "2018" + rust-version = "1.60" [workspace.badges] gitlab = { repository = "https://gitlab.com/rust-lang/rust", branch = "master" } "#, @@ -616,6 +621,7 @@ fn inherit_workspace_fields() { categories = { workspace = true } publish = { workspace = true } edition = { workspace = true } + rust-version = { workspace = true } "#, ) .file("LICENSE", "license") @@ -669,6 +675,7 @@ cargo-features = ["workspace-inheritance"] [package] edition = "2018" +rust-version = "1.60" name = "bar" version = "1.2.3" authors = ["Rustaceans"]