Skip to content

Commit 70152d8

Browse files
committed
Only compile activated optional dependencies
Development dependencies are traversed during the resolution process, causing them to be returned as the list of dependencies for a package in terms of resolution. The compilation phase would then filter these out depending on the dependency's transitivity, but this was incorrectly accounted for when the dependency showed up multiple times in a few lists. This commit fixes this behavior by updating the filtering logic to ensure that only activated optional dependencies (those whose feature names are listed) are compiled. Closes #1805
1 parent 25644b7 commit 70152d8

File tree

2 files changed

+36
-2
lines changed

2 files changed

+36
-2
lines changed

src/cargo/ops/cargo_rustc/context.rs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -351,7 +351,6 @@ impl<'a, 'cfg> Context<'a, 'cfg> {
351351
pkg.dependencies().iter().filter(|d| {
352352
d.name() == dep.name()
353353
}).any(|d| {
354-
355354
// If this target is a build command, then we only want build
356355
// dependencies, otherwise we want everything *other than* build
357356
// dependencies.
@@ -364,7 +363,14 @@ impl<'a, 'cfg> Context<'a, 'cfg> {
364363
target.is_example() ||
365364
profile.test;
366365

367-
is_correct_dep && is_actual_dep
366+
// If the dependency is optional, then we're only activating it
367+
// if the corresponding feature was activated
368+
let activated = !d.is_optional() ||
369+
self.resolve.features(pkg.package_id()).map(|f| {
370+
f.contains(d.name())
371+
}).unwrap_or(false);
372+
373+
is_correct_dep && is_actual_dep && activated
368374
})
369375
}).filter_map(|pkg| {
370376
pkg.targets().iter().find(|t| t.is_lib()).map(|t| {

tests/test_cargo_features.rs

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -741,3 +741,31 @@ test!(unions_work_with_no_default_features {
741741
assert_that(p.cargo("build"), execs().with_status(0).with_stdout(""));
742742
assert_that(p.cargo("build"), execs().with_status(0).with_stdout(""));
743743
});
744+
745+
test!(optional_and_dev_dep {
746+
let p = project("foo")
747+
.file("Cargo.toml", r#"
748+
[package]
749+
name = "test"
750+
version = "0.1.0"
751+
authors = []
752+
753+
[dependencies]
754+
foo = { path = "foo", optional = true }
755+
[dev-dependencies]
756+
foo = { path = "foo" }
757+
"#)
758+
.file("src/lib.rs", "")
759+
.file("foo/Cargo.toml", r#"
760+
[package]
761+
name = "foo"
762+
version = "0.1.0"
763+
authors = []
764+
"#)
765+
.file("foo/src/lib.rs", "");
766+
767+
assert_that(p.cargo_process("build"),
768+
execs().with_status(0).with_stdout(format!("\
769+
{compiling} test v0.1.0 ([..])
770+
", compiling = COMPILING)));
771+
});

0 commit comments

Comments
 (0)