Skip to content

Commit 7d8d028

Browse files
committed
Auto merge of #11331 - weihanglo:revert-11183, r=ehuss
Revert #11183 This reverts commit d4c38af, reversing changes made to 92d8826. Fixes #11330 --- The root cause is that [`map_to_features_for`] takes care of `unit_for.host_features` from parent unit, but [here] we only want to know whether the dependency is for host or not. We could have an ad-hoc `FeaturesFor` construction there, but I'd rather revert it at this moment. The interaction between `UnitFor` and `FeaturesFor` bites me every time 😭. After this revert, if we want to resolve #10526 again. The fastest way is doing the following: ```diff diff --git a/src/cargo/core/compiler/unit_dependencies.rs b/src/cargo/core/compiler/unit_dependencies.rs index 9319a19..14cc84941 100644 --- a/src/cargo/core/compiler/unit_dependencies.rs +++ b/src/cargo/core/compiler/unit_dependencies.rs `@@` -1103,7 +1103,7 `@@` impl<'a, 'cfg> State<'a, 'cfg> { // If this is an optional dependency, and the new feature resolver // did not enable it, don't include it. if dep.is_optional() { - let features_for = unit_for.map_to_features_for(dep.artifact()); + let features_for = FeaturesFor::from_for_host(unit_for.is_for_host()); if !self.is_dep_activated(pkg_id, features_for, dep.name_in_toml()) { return false; } ``` [`map_to_features_for`]: https://github.com/rust-lang/cargo/blob/810cbad9a123ad4ee0a55a96171b8f8478ff1c03/src/cargo/core/profiles.rs#L1043 [here]: https://github.com/rust-lang/cargo/blob/810cbad9a123ad4ee0a55a96171b8f8478ff1c03/src/cargo/core/compiler/unit_dependencies.rs#L1102
2 parents 2d70754 + 5fe2732 commit 7d8d028

File tree

4 files changed

+43
-94
lines changed

4 files changed

+43
-94
lines changed

src/cargo/core/compiler/unit_dependencies.rs

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1040,7 +1040,6 @@ impl<'a, 'cfg> State<'a, 'cfg> {
10401040
}
10411041
}
10421042

1043-
/// See [`ResolvedFeatures::activated_features`].
10441043
fn activated_features(
10451044
&self,
10461045
pkg_id: PackageId,
@@ -1050,9 +1049,14 @@ impl<'a, 'cfg> State<'a, 'cfg> {
10501049
features.activated_features(pkg_id, features_for)
10511050
}
10521051

1053-
/// See [`ResolvedFeatures::is_activated`].
1054-
fn is_activated(&self, pkg_id: PackageId, features_for: FeaturesFor) -> bool {
1055-
self.features().is_activated(pkg_id, features_for)
1052+
fn is_dep_activated(
1053+
&self,
1054+
pkg_id: PackageId,
1055+
features_for: FeaturesFor,
1056+
dep_name: InternedString,
1057+
) -> bool {
1058+
self.features()
1059+
.is_dep_activated(pkg_id, features_for, dep_name)
10561060
}
10571061

10581062
fn get(&self, id: PackageId) -> &'a Package {
@@ -1067,7 +1071,7 @@ impl<'a, 'cfg> State<'a, 'cfg> {
10671071
let kind = unit.kind;
10681072
self.resolve()
10691073
.deps(pkg_id)
1070-
.filter_map(|(dep_id, deps)| {
1074+
.filter_map(|(id, deps)| {
10711075
assert!(!deps.is_empty());
10721076
let deps: Vec<_> = deps
10731077
.iter()
@@ -1099,8 +1103,8 @@ impl<'a, 'cfg> State<'a, 'cfg> {
10991103
// If this is an optional dependency, and the new feature resolver
11001104
// did not enable it, don't include it.
11011105
if dep.is_optional() {
1102-
let dep_features_for = unit_for.map_to_features_for(dep.artifact());
1103-
if !self.is_activated(dep_id, dep_features_for) {
1106+
let features_for = unit_for.map_to_features_for(dep.artifact());
1107+
if !self.is_dep_activated(pkg_id, features_for, dep.name_in_toml()) {
11041108
return false;
11051109
}
11061110
}
@@ -1113,7 +1117,7 @@ impl<'a, 'cfg> State<'a, 'cfg> {
11131117
if deps.is_empty() {
11141118
None
11151119
} else {
1116-
Some((dep_id, deps))
1120+
Some((id, deps))
11171121
}
11181122
})
11191123
.collect()

src/cargo/core/resolver/features.rs

Lines changed: 25 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -56,12 +56,11 @@ type ActivateMap = HashMap<PackageFeaturesKey, BTreeSet<InternedString>>;
5656

5757
/// Set of all activated features for all packages in the resolve graph.
5858
pub struct ResolvedFeatures {
59-
/// Map of features activated for each package.
60-
///
61-
/// The presence of each key also means the package itself is activated,
62-
/// even its associated set contains no features.
6359
activated_features: ActivateMap,
64-
/// Options that change how the feature resolver operates.
60+
/// Optional dependencies that should be built.
61+
///
62+
/// The value is the `name_in_toml` of the dependencies.
63+
activated_dependencies: ActivateMap,
6564
opts: FeatureOpts,
6665
}
6766

@@ -322,14 +321,21 @@ impl ResolvedFeatures {
322321
.expect("activated_features for invalid package")
323322
}
324323

325-
/// Asks the resolved features if the given package should be included.
324+
/// Returns if the given dependency should be included.
326325
///
327-
/// One scenario to use this function is to deteremine a optional dependency
328-
/// should be built or not.
329-
pub fn is_activated(&self, pkg_id: PackageId, features_for: FeaturesFor) -> bool {
330-
log::trace!("is_activated {} {features_for}", pkg_id.name());
331-
self.activated_features_unverified(pkg_id, features_for.apply_opts(&self.opts))
332-
.is_some()
326+
/// This handles dependencies disabled via `cfg` expressions and optional
327+
/// dependencies which are not enabled.
328+
pub fn is_dep_activated(
329+
&self,
330+
pkg_id: PackageId,
331+
features_for: FeaturesFor,
332+
dep_name: InternedString,
333+
) -> bool {
334+
let key = features_for.apply_opts(&self.opts);
335+
self.activated_dependencies
336+
.get(&(pkg_id, key))
337+
.map(|deps| deps.contains(&dep_name))
338+
.unwrap_or(false)
333339
}
334340

335341
/// Variant of `activated_features` that returns `None` if this is
@@ -409,14 +415,8 @@ pub struct FeatureResolver<'a, 'cfg> {
409415
/// Options that change how the feature resolver operates.
410416
opts: FeatureOpts,
411417
/// Map of features activated for each package.
412-
///
413-
/// The presence of each key also means the package itself is activated,
414-
/// even its associated set contains no features.
415418
activated_features: ActivateMap,
416419
/// Map of optional dependencies activated for each package.
417-
///
418-
/// The key is the package having their dependencies activated.
419-
/// The value comes from `dep_name` part of the feature syntax `dep:dep_name`.
420420
activated_dependencies: ActivateMap,
421421
/// Keeps track of which packages have had its dependencies processed.
422422
/// Used to avoid cycles, and to speed up processing.
@@ -475,6 +475,7 @@ impl<'a, 'cfg> FeatureResolver<'a, 'cfg> {
475475
}
476476
Ok(ResolvedFeatures {
477477
activated_features: r.activated_features,
478+
activated_dependencies: r.activated_dependencies,
478479
opts: r.opts,
479480
})
480481
}
@@ -506,24 +507,20 @@ impl<'a, 'cfg> FeatureResolver<'a, 'cfg> {
506507
Ok(())
507508
}
508509

509-
/// Activates a list of [`FeatureValue`] for a given package.
510+
/// Activates [`FeatureValue`]s on the given package.
510511
///
511-
/// This is the main entrance into the recursion of feature activation for a package.
512-
/// Other `activate_*` functions would be called inside this function accordingly.
512+
/// This is the main entrance into the recursion of feature activation
513+
/// for a package.
513514
fn activate_pkg(
514515
&mut self,
515516
pkg_id: PackageId,
516517
fk: FeaturesFor,
517518
fvs: &[FeatureValue],
518519
) -> CargoResult<()> {
519520
log::trace!("activate_pkg {} {}", pkg_id.name(), fk);
520-
// Cargo must insert an empty set here as the presence of an (empty) set
521-
// also means that the dependency is activated.
522-
// This `is_activated` behavior for dependencies was previously depends on field
523-
// `activated_dependencies`, which is less useful after rust-lang/cargo#11183.
524-
//
525-
// That is, we may keep or remove `activated_dependencies` in the future
526-
// if figuring out it can completely be replaced with `activated_features`.
521+
// Add an empty entry to ensure everything is covered. This is intended for
522+
// finding bugs where the resolver missed something it should have visited.
523+
// Remove this in the future if `activated_features` uses an empty default.
527524
self.activated_features
528525
.entry((pkg_id, fk.apply_opts(&self.opts)))
529526
.or_insert_with(BTreeSet::new);

src/cargo/ops/tree/graph.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -365,7 +365,11 @@ fn add_pkg(
365365
if dep.is_optional() {
366366
// If the new feature resolver does not enable this
367367
// optional dep, then don't use it.
368-
if !resolved_features.is_activated(dep_id, features_for) {
368+
if !resolved_features.is_dep_activated(
369+
package_id,
370+
features_for,
371+
dep.name_in_toml(),
372+
) {
369373
return false;
370374
}
371375
}

tests/testsuite/artifact_dep.rs

Lines changed: 1 addition & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ fn check_with_invalid_artifact_dependency() {
2020
version = "0.0.0"
2121
authors = []
2222
resolver = "2"
23-
23+
2424
[dependencies]
2525
bar = { path = "bar/", artifact = "unknown" }
2626
"#,
@@ -2276,59 +2276,3 @@ fn build_script_features_for_shared_dependency() {
22762276
.masquerade_as_nightly_cargo(&["bindeps"])
22772277
.run();
22782278
}
2279-
2280-
#[cargo_test]
2281-
fn build_with_target_and_optional() {
2282-
// This is a incorrect behaviour got to be fixed.
2283-
// See rust-lang/cargo#10526
2284-
if cross_compile::disabled() {
2285-
return;
2286-
}
2287-
let target = cross_compile::alternate();
2288-
let p = project()
2289-
.file(
2290-
"Cargo.toml",
2291-
&r#"
2292-
[package]
2293-
name = "foo"
2294-
version = "0.0.1"
2295-
edition = "2021"
2296-
2297-
[dependencies]
2298-
d1 = { path = "d1", artifact = "bin", optional = true, target = "$TARGET" }
2299-
"#
2300-
.replace("$TARGET", target),
2301-
)
2302-
.file(
2303-
"src/main.rs",
2304-
r#"
2305-
fn main() {
2306-
let _b = include_bytes!(env!("CARGO_BIN_FILE_D1"));
2307-
}
2308-
"#,
2309-
)
2310-
.file(
2311-
"d1/Cargo.toml",
2312-
r#"
2313-
[package]
2314-
name = "d1"
2315-
version = "0.0.1"
2316-
edition = "2021"
2317-
"#,
2318-
)
2319-
.file("d1/src/main.rs", "fn main() {}")
2320-
.build();
2321-
2322-
p.cargo("build -Z bindeps -F d1 -v")
2323-
.masquerade_as_nightly_cargo(&["bindeps"])
2324-
.with_stderr(
2325-
"\
2326-
[COMPILING] d1 v0.0.1 [..]
2327-
[RUNNING] `rustc --crate-name d1 [..]--crate-type bin[..]
2328-
[COMPILING] foo v0.0.1 [..]
2329-
[RUNNING] `rustc --crate-name foo [..]--cfg[..]d1[..]
2330-
[FINISHED] dev [..]
2331-
",
2332-
)
2333-
.run();
2334-
}

0 commit comments

Comments
 (0)