Skip to content

Commit 24439f8

Browse files
committed
Auto merge of #7010 - alexcrichton:less-features, r=ehuss
Don't synthesize feature diretives for non-optional deps Currently when Cargo is invoked on the command like `cargo build --features foo/bar` then it will actually always compile the current crate with `feature = "foo"` even if `foo` is a non-optional dependency. This isn't intended because the crate doesn't actually have a `foo` feature as so no directive should be emitted or passed to the compiler. This was discovered in rust-lang/rust where Cargo is being built with the `rustc-workspace-hack` feature but when the RLS depends on Cargo it doesn't enable the same feature. This feature, however, doesn't actually exist for Cargo!
2 parents afcd5ef + dbc2c2b commit 24439f8

File tree

2 files changed

+54
-1
lines changed

2 files changed

+54
-1
lines changed

src/cargo/core/resolver/dep_cache.rs

+13-1
Original file line numberDiff line numberDiff line change
@@ -415,7 +415,19 @@ impl Requirements<'_> {
415415
}
416416

417417
fn require_crate_feature(&mut self, package: InternedString, feat: InternedString) {
418-
self.used.insert(package);
418+
// If `package` is indeed an optional dependency then we activate the
419+
// feature named `package`, but otherwise if `package` is a required
420+
// dependency then there's no feature associated with it.
421+
if let Some(dep) = self
422+
.summary
423+
.dependencies()
424+
.iter()
425+
.find(|p| p.name_in_toml() == package)
426+
{
427+
if dep.is_optional() {
428+
self.used.insert(package);
429+
}
430+
}
419431
self.deps
420432
.entry(package)
421433
.or_insert((false, BTreeSet::new()))

tests/testsuite/features.rs

+41
Original file line numberDiff line numberDiff line change
@@ -1870,3 +1870,44 @@ fn warn_if_default_features() {
18701870
"#.trim(),
18711871
).run();
18721872
}
1873+
1874+
#[test]
1875+
fn no_feature_for_non_optional_dep() {
1876+
let p = project()
1877+
.file(
1878+
"Cargo.toml",
1879+
r#"
1880+
[project]
1881+
name = "foo"
1882+
version = "0.0.1"
1883+
authors = []
1884+
1885+
[dependencies]
1886+
bar = { path = "bar" }
1887+
"#,
1888+
)
1889+
.file(
1890+
"src/main.rs",
1891+
r#"
1892+
#[cfg(not(feature = "bar"))]
1893+
fn main() {
1894+
}
1895+
"#,
1896+
)
1897+
.file(
1898+
"bar/Cargo.toml",
1899+
r#"
1900+
[project]
1901+
name = "bar"
1902+
version = "0.0.1"
1903+
authors = []
1904+
1905+
[features]
1906+
a = []
1907+
"#,
1908+
)
1909+
.file("bar/src/lib.rs", "pub fn bar() {}")
1910+
.build();
1911+
1912+
p.cargo("build --features bar/a").run();
1913+
}

0 commit comments

Comments
 (0)