Skip to content

Commit 7e2a3c2

Browse files
committed
Auto merge of #11409 - Muscraft:default-feat-workspace-dep, r=weihanglo
fix(toml): Add `default-features` to `TomlWorkspaceDependency` In #11329 it was noted that `default-features` is ignored when used in a dependency that inherits from a workspace i.e. ```toml [workspace] members = [] [workspace.dependencies] dep = "0.1" [package] name = "bar" version = "0.2.0" authors = [] [dependencies] dep = { workspace = true, default-features = false } ``` This problem is caused by problems with deserializing a `TomlDependency` and not emitting an unused manifest key correctly. When discussed in a recent Cargo team meeting we felt the best course of action was to allow `default-features = false` when inheriting a dependency, but it does not change actually set `default-features`. It will be used to warn when there is a difference between the definition in `[workspace.dependencies]` and `[dependencies]` i.e. ```toml [package] name = "bar" version = "0.2.0" [dependencies] dep = { workspace = true, default-features = false } [workspace] members = [] [workspace.dependencies] dep = { version = "0.1", default-features = true } ``` This does not entirely resolve the problem with unused manifest keys. A follow up PR and issue will be created to address those concerns. close #11329
2 parents 975817b + 49d722c commit 7e2a3c2

File tree

2 files changed

+191
-0
lines changed

2 files changed

+191
-0
lines changed

src/cargo/util/toml/mod.rs

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -272,6 +272,8 @@ impl<'de, P: Deserialize<'de> + Clone> de::Deserialize<'de> for TomlDependency<P
272272
Ok(TomlDependency::Workspace(TomlWorkspaceDependency {
273273
workspace: true,
274274
features: details.features,
275+
default_features: details.default_features,
276+
default_features2: details.default_features2,
275277
optional: details.optional,
276278
}))
277279
} else {
@@ -348,9 +350,13 @@ pub struct IntermediateDependency<P = String> {
348350
}
349351

350352
#[derive(Deserialize, Serialize, Clone, Debug)]
353+
#[serde(rename_all = "kebab-case")]
351354
pub struct TomlWorkspaceDependency {
352355
workspace: bool,
353356
features: Option<Vec<String>>,
357+
default_features: Option<bool>,
358+
#[serde(rename = "default_features")]
359+
default_features2: Option<bool>,
354360
optional: Option<bool>,
355361
}
356362

@@ -2579,21 +2585,41 @@ impl TomlDependency {
25792585
cx: &mut Context<'_, '_>,
25802586
get_inheritable: impl FnOnce() -> CargoResult<&'a InheritableFields>,
25812587
) -> CargoResult<TomlDependency> {
2588+
fn default_features_msg(label: &str, ws_def_feat: Option<bool>, cx: &mut Context<'_, '_>) {
2589+
let ws_def_feat = match ws_def_feat {
2590+
Some(true) => "true",
2591+
Some(false) => "false",
2592+
None => "not specified",
2593+
};
2594+
cx.warnings.push(format!(
2595+
"`default-features` is ignored for {label}, since `default-features` was \
2596+
{ws_def_feat} for `workspace.dependencies.{label}`, \
2597+
this could become a hard error in the future"
2598+
))
2599+
}
25822600
match self {
25832601
TomlDependency::Detailed(d) => Ok(TomlDependency::Detailed(d)),
25842602
TomlDependency::Simple(s) => Ok(TomlDependency::Simple(s)),
25852603
TomlDependency::Workspace(TomlWorkspaceDependency {
25862604
workspace: true,
25872605
features,
25882606
optional,
2607+
default_features,
2608+
default_features2,
25892609
}) => {
2610+
if default_features.is_some() && default_features2.is_some() {
2611+
warn_on_deprecated("default-features", label, "dependency", cx.warnings);
2612+
}
25902613
let inheritable = get_inheritable()?;
25912614
inheritable.get_dependency(label).context(format!(
25922615
"error reading `dependencies.{}` from workspace root manifest's `workspace.dependencies.{}`",
25932616
label, label
25942617
)).map(|dep| {
25952618
match dep {
25962619
TomlDependency::Simple(s) => {
2620+
if let Some(false) = default_features.or(default_features2) {
2621+
default_features_msg(label, None, cx);
2622+
}
25972623
if optional.is_some() || features.is_some() {
25982624
Ok(TomlDependency::Detailed(DetailedTomlDependency {
25992625
version: Some(s),
@@ -2607,6 +2633,29 @@ impl TomlDependency {
26072633
},
26082634
TomlDependency::Detailed(d) => {
26092635
let mut dep = d.clone();
2636+
match (
2637+
default_features.or(default_features2),
2638+
d.default_features.or(d.default_features2)
2639+
) {
2640+
// member: default-features = true and
2641+
// workspace: default-features = false should turn on
2642+
// default-features
2643+
(Some(true), Some(false)) => {
2644+
dep.default_features = Some(true);
2645+
}
2646+
// member: default-features = false and
2647+
// workspace: default-features = true should ignore member
2648+
// default-features
2649+
(Some(false), Some(true)) => {
2650+
default_features_msg(label, Some(true), cx);
2651+
}
2652+
// member: default-features = false and
2653+
// workspace: dep = "1.0" should ignore member default-features
2654+
(Some(false), None) => {
2655+
default_features_msg(label, None, cx);
2656+
}
2657+
_ => {}
2658+
}
26102659
dep.add_features(features);
26112660
dep.update_optional(optional);
26122661
dep.resolve_path(label,inheritable.ws_root(), cx.root)?;

tests/testsuite/inheritable_workspace_fields.rs

Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1356,3 +1356,145 @@ Caused by:
13561356
)
13571357
.run();
13581358
}
1359+
1360+
#[cargo_test]
1361+
fn warn_inherit_def_feat_true_member_def_feat_false() {
1362+
Package::new("dep", "0.1.0")
1363+
.feature("default", &["fancy_dep"])
1364+
.add_dep(Dependency::new("fancy_dep", "0.2").optional(true))
1365+
.file("src/lib.rs", "")
1366+
.publish();
1367+
1368+
Package::new("fancy_dep", "0.2.4").publish();
1369+
1370+
let p = project()
1371+
.file(
1372+
"Cargo.toml",
1373+
r#"
1374+
[package]
1375+
name = "bar"
1376+
version = "0.2.0"
1377+
authors = []
1378+
[dependencies]
1379+
dep = { workspace = true, default-features = false }
1380+
1381+
[workspace]
1382+
members = []
1383+
[workspace.dependencies]
1384+
dep = { version = "0.1.0", default-features = true }
1385+
"#,
1386+
)
1387+
.file("src/main.rs", "fn main() {}")
1388+
.build();
1389+
1390+
p.cargo("check")
1391+
.with_stderr(
1392+
"\
1393+
[WARNING] [CWD]/Cargo.toml: `default-features` is ignored for dep, since `default-features` was \
1394+
true for `workspace.dependencies.dep`, this could become a hard error in the future
1395+
[UPDATING] `dummy-registry` index
1396+
[DOWNLOADING] crates ...
1397+
[DOWNLOADED] fancy_dep v0.2.4 ([..])
1398+
[DOWNLOADED] dep v0.1.0 ([..])
1399+
[CHECKING] fancy_dep v0.2.4
1400+
[CHECKING] dep v0.1.0
1401+
[CHECKING] bar v0.2.0 ([CWD])
1402+
[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
1403+
",
1404+
)
1405+
.run();
1406+
}
1407+
1408+
#[cargo_test]
1409+
fn warn_inherit_simple_member_def_feat_false() {
1410+
Package::new("dep", "0.1.0")
1411+
.feature("default", &["fancy_dep"])
1412+
.add_dep(Dependency::new("fancy_dep", "0.2").optional(true))
1413+
.file("src/lib.rs", "")
1414+
.publish();
1415+
1416+
Package::new("fancy_dep", "0.2.4").publish();
1417+
1418+
let p = project()
1419+
.file(
1420+
"Cargo.toml",
1421+
r#"
1422+
[package]
1423+
name = "bar"
1424+
version = "0.2.0"
1425+
authors = []
1426+
[dependencies]
1427+
dep = { workspace = true, default-features = false }
1428+
1429+
[workspace]
1430+
members = []
1431+
[workspace.dependencies]
1432+
dep = "0.1.0"
1433+
"#,
1434+
)
1435+
.file("src/main.rs", "fn main() {}")
1436+
.build();
1437+
1438+
p.cargo("check")
1439+
.with_stderr(
1440+
"\
1441+
[WARNING] [CWD]/Cargo.toml: `default-features` is ignored for dep, since `default-features` was \
1442+
not specified for `workspace.dependencies.dep`, this could become a hard error in the future
1443+
[UPDATING] `dummy-registry` index
1444+
[DOWNLOADING] crates ...
1445+
[DOWNLOADED] fancy_dep v0.2.4 ([..])
1446+
[DOWNLOADED] dep v0.1.0 ([..])
1447+
[CHECKING] fancy_dep v0.2.4
1448+
[CHECKING] dep v0.1.0
1449+
[CHECKING] bar v0.2.0 ([CWD])
1450+
[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
1451+
",
1452+
)
1453+
.run();
1454+
}
1455+
1456+
#[cargo_test]
1457+
fn inherit_def_feat_false_member_def_feat_true() {
1458+
Package::new("dep", "0.1.0")
1459+
.feature("default", &["fancy_dep"])
1460+
.add_dep(Dependency::new("fancy_dep", "0.2").optional(true))
1461+
.file("src/lib.rs", "")
1462+
.publish();
1463+
1464+
Package::new("fancy_dep", "0.2.4").publish();
1465+
1466+
let p = project()
1467+
.file(
1468+
"Cargo.toml",
1469+
r#"
1470+
[package]
1471+
name = "bar"
1472+
version = "0.2.0"
1473+
authors = []
1474+
[dependencies]
1475+
dep = { workspace = true, default-features = true }
1476+
1477+
[workspace]
1478+
members = []
1479+
[workspace.dependencies]
1480+
dep = { version = "0.1.0", default-features = false }
1481+
"#,
1482+
)
1483+
.file("src/main.rs", "fn main() {}")
1484+
.build();
1485+
1486+
p.cargo("check")
1487+
.with_stderr(
1488+
"\
1489+
[UPDATING] `dummy-registry` index
1490+
[DOWNLOADING] crates ...
1491+
[DOWNLOADED] fancy_dep v0.2.4 ([..])
1492+
[DOWNLOADED] dep v0.1.0 ([..])
1493+
[CHECKING] fancy_dep v0.2.4
1494+
[CHECKING] dep v0.1.0
1495+
[CHECKING] bar v0.2.0 ([CWD])
1496+
[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
1497+
",
1498+
)
1499+
.run();
1500+
}

0 commit comments

Comments
 (0)