Skip to content

Commit cc34b84

Browse files
committed
Auto merge of #13892 - weihanglo:proc-macro-lib, r=epage
fix: proc-macro example from dep no longer affects feature resolution
2 parents d8f9130 + 0ead10e commit cc34b84

File tree

2 files changed

+66
-6
lines changed

2 files changed

+66
-6
lines changed

src/cargo/core/resolver/features.rs

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -426,10 +426,12 @@ pub struct FeatureResolver<'a, 'gctx> {
426426
/// If this is `true`, then a non-default `feature_key` needs to be tracked while
427427
/// traversing the graph.
428428
///
429-
/// This is only here to avoid calling `is_proc_macro` when all feature
430-
/// options are disabled (because `is_proc_macro` can trigger downloads).
431-
/// This has to be separate from `FeatureOpts.decouple_host_deps` because
429+
/// This is only here to avoid calling [`has_any_proc_macro`] when all feature
430+
/// options are disabled (because [`has_any_proc_macro`] can trigger downloads).
431+
/// This has to be separate from [`FeatureOpts::decouple_host_deps`] because
432432
/// `for_host` tracking is also needed for `itarget` to work properly.
433+
///
434+
/// [`has_any_proc_macro`]: FeatureResolver::has_any_proc_macro
433435
track_for_host: bool,
434436
/// `dep_name?/feat_name` features that will be activated if `dep_name` is
435437
/// ever activated.
@@ -490,7 +492,7 @@ impl<'a, 'gctx> FeatureResolver<'a, 'gctx> {
490492
let member_features = self.ws.members_with_features(specs, cli_features)?;
491493
for (member, cli_features) in &member_features {
492494
let fvs = self.fvs_from_requested(member.package_id(), cli_features);
493-
let fk = if self.track_for_host && self.is_proc_macro(member.package_id()) {
495+
let fk = if self.track_for_host && self.has_any_proc_macro(member.package_id()) {
494496
// Also activate for normal dependencies. This is needed if the
495497
// proc-macro includes other targets (like binaries or tests),
496498
// or running in `cargo test`. Note that in a workspace, if
@@ -852,7 +854,7 @@ impl<'a, 'gctx> FeatureResolver<'a, 'gctx> {
852854
// for various targets which are either specified in the manifest
853855
// or on the cargo command-line.
854856
let lib_fk = if fk == FeaturesFor::default() {
855-
(self.track_for_host && (dep.is_build() || self.is_proc_macro(dep_id)))
857+
(self.track_for_host && (dep.is_build() || self.has_proc_macro_lib(dep_id)))
856858
.then(|| FeaturesFor::HostDep)
857859
.unwrap_or_default()
858860
} else {
@@ -957,10 +959,24 @@ impl<'a, 'gctx> FeatureResolver<'a, 'gctx> {
957959
}
958960
}
959961

960-
fn is_proc_macro(&self, package_id: PackageId) -> bool {
962+
/// Whether the given package has any proc macro target, including proc-macro examples.
963+
fn has_any_proc_macro(&self, package_id: PackageId) -> bool {
961964
self.package_set
962965
.get_one(package_id)
963966
.expect("packages downloaded")
964967
.proc_macro()
965968
}
969+
970+
/// Whether the given package is a proc macro lib target.
971+
///
972+
/// This is useful for checking if a dependency is a proc macro,
973+
/// as it is not possible to depend on a non-lib target as a proc-macro.
974+
fn has_proc_macro_lib(&self, package_id: PackageId) -> bool {
975+
self.package_set
976+
.get_one(package_id)
977+
.expect("packages downloaded")
978+
.library()
979+
.map(|lib| lib.proc_macro())
980+
.unwrap_or_default()
981+
}
966982
}

tests/testsuite/features2.rs

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2652,3 +2652,47 @@ fn dep_with_optional_host_deps_activated() {
26522652
)
26532653
.run();
26542654
}
2655+
2656+
#[cargo_test]
2657+
fn dont_unify_proc_macro_example_from_dependency() {
2658+
// See https://github.com/rust-lang/cargo/issues/13726
2659+
let p = project()
2660+
.file(
2661+
"Cargo.toml",
2662+
r#"
2663+
[package]
2664+
name = "foo"
2665+
edition = "2021"
2666+
2667+
[dependencies]
2668+
pm_helper = { path = "pm_helper" }
2669+
"#,
2670+
)
2671+
.file("src/lib.rs", "")
2672+
.file(
2673+
"pm_helper/Cargo.toml",
2674+
r#"
2675+
[package]
2676+
name = "pm_helper"
2677+
2678+
[[example]]
2679+
name = "pm"
2680+
proc-macro = true
2681+
crate-type = ["proc-macro"]
2682+
"#,
2683+
)
2684+
.file("pm_helper/src/lib.rs", "")
2685+
.file("pm_helper/examples/pm.rs", "")
2686+
.build();
2687+
2688+
p.cargo("check")
2689+
.with_stderr(
2690+
"\
2691+
[LOCKING] 2 packages to latest compatible versions
2692+
[CHECKING] pm_helper v0.0.0 ([CWD]/pm_helper)
2693+
[CHECKING] foo v0.0.0 ([CWD])
2694+
[FINISHED] `dev` [..]
2695+
",
2696+
)
2697+
.run();
2698+
}

0 commit comments

Comments
 (0)