Skip to content

Commit 92d0ce8

Browse files
committed
Auto merge of #8003 - ehuss:proc-macro-index, r=alexcrichton
Add proc-macro to index, and new feature resolver. This adds the "pm" field to the index so that Cargo can detect which packages contain a proc-macro without downloading the package. The second commit builds on that to support proc-macros in the new "de-unification" of the new feature resolver. This prevents dependencies shared between proc-macros and other dependency kinds from having features unified. cc #7915
2 parents 7019b3e + 1c28d89 commit 92d0ce8

File tree

20 files changed

+467
-125
lines changed

20 files changed

+467
-125
lines changed

Cargo.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ path = "src/cargo/lib.rs"
2222
atty = "0.2"
2323
bytesize = "1.0"
2424
cargo-platform = { path = "crates/cargo-platform", version = "0.1.1" }
25-
crates-io = { path = "crates/crates-io", version = "0.31" }
25+
crates-io = { path = "crates/crates-io", version = "0.32" }
2626
crossbeam-utils = "0.7"
2727
crypto-hash = "0.3.1"
2828
curl = { version = "0.4.23", features = ["http2"] }

crates/cargo-test-support/src/registry.rs

+12
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,7 @@ pub struct Package {
144144
local: bool,
145145
alternative: bool,
146146
invalid_json: bool,
147+
proc_macro: bool,
147148
}
148149

149150
#[derive(Clone)]
@@ -242,6 +243,7 @@ impl Package {
242243
local: false,
243244
alternative: false,
244245
invalid_json: false,
246+
proc_macro: false,
245247
}
246248
}
247249

@@ -345,6 +347,12 @@ impl Package {
345347
self
346348
}
347349

350+
/// Specifies whether or not this is a proc macro.
351+
pub fn proc_macro(&mut self, proc_macro: bool) -> &mut Package {
352+
self.proc_macro = proc_macro;
353+
self
354+
}
355+
348356
/// Adds an entry in the `[features]` section.
349357
pub fn feature(&mut self, name: &str, deps: &[&str]) -> &mut Package {
350358
let deps = deps.iter().map(|s| s.to_string()).collect();
@@ -412,6 +420,7 @@ impl Package {
412420
"cksum": cksum,
413421
"features": self.features,
414422
"yanked": self.yanked,
423+
"pm": self.proc_macro,
415424
})
416425
.to_string();
417426

@@ -497,6 +506,9 @@ impl Package {
497506
manifest.push_str(&format!("registry-index = \"{}\"", alt_registry_url()));
498507
}
499508
}
509+
if self.proc_macro {
510+
manifest.push_str("[lib]\nproc-macro = true\n");
511+
}
500512

501513
let dst = self.archive_dst();
502514
t!(fs::create_dir_all(dst.parent().unwrap()));

crates/crates-io/Cargo.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "crates-io"
3-
version = "0.31.0"
3+
version = "0.32.0"
44
edition = "2018"
55
authors = ["Alex Crichton <[email protected]>"]
66
license = "MIT OR Apache-2.0"

crates/crates-io/lib.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -54,8 +54,8 @@ pub struct NewCrate {
5454
pub license_file: Option<String>,
5555
pub repository: Option<String>,
5656
pub badges: BTreeMap<String, BTreeMap<String, String>>,
57-
#[serde(default)]
5857
pub links: Option<String>,
58+
pub proc_macro: bool,
5959
}
6060

6161
#[derive(Serialize)]

crates/resolver-tests/src/lib.rs

+4
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,7 @@ pub fn resolve_with_config_raw(
176176
&BTreeMap::<String, Vec<String>>::new(),
177177
None::<&String>,
178178
false,
179+
false,
179180
)
180181
.unwrap();
181182
let opts = ResolveOpts::everything();
@@ -577,6 +578,7 @@ pub fn pkg_dep<T: ToPkgId>(name: T, dep: Vec<Dependency>) -> Summary {
577578
&BTreeMap::<String, Vec<String>>::new(),
578579
link,
579580
false,
581+
false,
580582
)
581583
.unwrap()
582584
}
@@ -605,6 +607,7 @@ pub fn pkg_loc(name: &str, loc: &str) -> Summary {
605607
&BTreeMap::<String, Vec<String>>::new(),
606608
link,
607609
false,
610+
false,
608611
)
609612
.unwrap()
610613
}
@@ -619,6 +622,7 @@ pub fn remove_dep(sum: &Summary, ind: usize) -> Summary {
619622
&BTreeMap::<String, Vec<String>>::new(),
620623
sum.links().map(|a| a.as_str()),
621624
sum.namespaced_features(),
625+
sum.proc_macro(),
622626
)
623627
.unwrap()
624628
}

src/cargo/core/compiler/unit_dependencies.rs

+19-14
Original file line numberDiff line numberDiff line change
@@ -160,9 +160,11 @@ fn deps_of_roots<'a, 'cfg>(roots: &[Unit<'a>], mut state: &mut State<'a, 'cfg>)
160160
} else if unit.target.is_custom_build() {
161161
// This normally doesn't happen, except `clean` aggressively
162162
// generates all units.
163-
UnitFor::new_build(false)
163+
UnitFor::new_host(false)
164+
} else if unit.target.proc_macro() {
165+
UnitFor::new_host(true)
164166
} else if unit.target.for_host() {
165-
// Proc macro / plugin should never have panic set.
167+
// Plugin should never have panic set.
166168
UnitFor::new_compiler()
167169
} else {
168170
UnitFor::new_normal()
@@ -279,7 +281,7 @@ fn compute_deps<'a, 'cfg>(
279281
let dep_unit_for = unit_for
280282
.with_for_host(lib.for_host())
281283
// If it is a custom build script, then it *only* has build dependencies.
282-
.with_build_dep(unit.target.is_custom_build());
284+
.with_host_features(unit.target.is_custom_build() || lib.proc_macro());
283285

284286
if bcx.config.cli_unstable().dual_proc_macros && lib.proc_macro() && !unit.kind.is_host() {
285287
let unit_dep = new_unit_dep(state, unit, pkg, lib, dep_unit_for, unit.kind, mode)?;
@@ -370,9 +372,10 @@ fn compute_deps_custom_build<'a, 'cfg>(
370372
return Ok(Vec::new());
371373
}
372374
}
373-
// All dependencies of this unit should use profiles for custom
374-
// builds.
375-
let script_unit_for = UnitFor::new_build(unit_for.is_for_build_dep());
375+
// All dependencies of this unit should use profiles for custom builds.
376+
// If this is a build script of a proc macro, make sure it uses host
377+
// features.
378+
let script_unit_for = UnitFor::new_host(unit_for.is_for_host_features());
376379
// When not overridden, then the dependencies to run a build script are:
377380
//
378381
// 1. Compiling the build script itself.
@@ -427,7 +430,9 @@ fn compute_deps_doc<'a, 'cfg>(
427430
// Rustdoc only needs rmeta files for regular dependencies.
428431
// However, for plugins/proc macros, deps should be built like normal.
429432
let mode = check_or_build_mode(unit.mode, lib);
430-
let dep_unit_for = UnitFor::new_normal().with_for_host(lib.for_host());
433+
let dep_unit_for = UnitFor::new_normal()
434+
.with_for_host(lib.for_host())
435+
.with_host_features(lib.proc_macro());
431436
let lib_unit_dep = new_unit_dep(
432437
state,
433438
unit,
@@ -510,32 +515,32 @@ fn dep_build_script<'a>(
510515
.bcx
511516
.profiles
512517
.get_profile_run_custom_build(&unit.profile);
513-
// UnitFor::new_build is used because we want the `host` flag set
518+
// UnitFor::new_host is used because we want the `host` flag set
514519
// for all of our build dependencies (so they all get
515520
// build-override profiles), including compiling the build.rs
516521
// script itself.
517522
//
518-
// If `is_for_build_dep` here is `false`, that means we are a
523+
// If `is_for_host_features` here is `false`, that means we are a
519524
// build.rs script for a normal dependency and we want to set the
520525
// CARGO_FEATURE_* environment variables to the features as a
521526
// normal dep.
522527
//
523-
// If `is_for_build_dep` here is `true`, that means that this
524-
// package is being used as a build dependency, and so we only
525-
// want to set CARGO_FEATURE_* variables for the build-dependency
528+
// If `is_for_host_features` here is `true`, that means that this
529+
// package is being used as a build dependency or proc-macro, and
530+
// so we only want to set CARGO_FEATURE_* variables for the host
526531
// side of the graph.
527532
//
528533
// Keep in mind that the RunCustomBuild unit and the Compile
529534
// build.rs unit use the same features. This is because some
530535
// people use `cfg!` and `#[cfg]` expressions to check for enabled
531536
// features instead of just checking `CARGO_FEATURE_*` at runtime.
532-
// In the case with `-Zfeatures=build_dep`, and a shared
537+
// In the case with `-Zfeatures=host_dep`, and a shared
533538
// dependency has different features enabled for normal vs. build,
534539
// then the build.rs script will get compiled twice. I believe it
535540
// is not feasible to only build it once because it would break a
536541
// large number of scripts (they would think they have the wrong
537542
// set of features enabled).
538-
let script_unit_for = UnitFor::new_build(unit_for.is_for_build_dep());
543+
let script_unit_for = UnitFor::new_host(unit_for.is_for_host_features());
539544
new_unit_dep_with_profile(
540545
state,
541546
unit,

src/cargo/core/profiles.rs

+45-40
Original file line numberDiff line numberDiff line change
@@ -783,7 +783,7 @@ pub struct UnitFor {
783783
/// any of its dependencies. This enables `build-override` profiles for
784784
/// these targets.
785785
///
786-
/// An invariant is that if `build_dep` is true, `host` must be true.
786+
/// An invariant is that if `host_features` is true, `host` must be true.
787787
///
788788
/// Note that this is `true` for `RunCustomBuild` units, even though that
789789
/// unit should *not* use build-override profiles. This is a bit of a
@@ -794,16 +794,16 @@ pub struct UnitFor {
794794
/// sticky (and forced to `true` for all further dependencies) — which is
795795
/// the whole point of `UnitFor`.
796796
host: bool,
797-
/// A target for a build dependency (or any of its dependencies). This is
798-
/// used for computing features of build dependencies independently of
799-
/// other dependency kinds.
797+
/// A target for a build dependency or proc-macro (or any of its
798+
/// dependencies). This is used for computing features of build
799+
/// dependencies and proc-macros independently of other dependency kinds.
800800
///
801801
/// The subtle difference between this and `host` is that the build script
802802
/// for a non-host package sets this to `false` because it wants the
803803
/// features of the non-host package (whereas `host` is true because the
804-
/// build script is being built for the host). `build_dep` becomes `true`
805-
/// for build-dependencies, or any of their dependencies. For example, with
806-
/// this dependency tree:
804+
/// build script is being built for the host). `host_features` becomes
805+
/// `true` for build-dependencies or proc-macros, or any of their
806+
/// dependencies. For example, with this dependency tree:
807807
///
808808
/// ```text
809809
/// foo
@@ -814,17 +814,18 @@ pub struct UnitFor {
814814
/// └── shared_dep build.rs
815815
/// ```
816816
///
817-
/// In this example, `foo build.rs` is HOST=true, BUILD_DEP=false. This is
818-
/// so that `foo build.rs` gets the profile settings for build scripts
819-
/// (HOST=true) and features of foo (BUILD_DEP=false) because build scripts
820-
/// need to know which features their package is being built with.
817+
/// In this example, `foo build.rs` is HOST=true, HOST_FEATURES=false.
818+
/// This is so that `foo build.rs` gets the profile settings for build
819+
/// scripts (HOST=true) and features of foo (HOST_FEATURES=false) because
820+
/// build scripts need to know which features their package is being built
821+
/// with.
821822
///
822823
/// But in the case of `shared_dep`, when built as a build dependency,
823824
/// both flags are true (it only wants the build-dependency features).
824825
/// When `shared_dep` is built as a normal dependency, then `shared_dep
825-
/// build.rs` is HOST=true, BUILD_DEP=false for the same reasons that
826+
/// build.rs` is HOST=true, HOST_FEATURES=false for the same reasons that
826827
/// foo's build script is set that way.
827-
build_dep: bool,
828+
host_features: bool,
828829
/// How Cargo processes the `panic` setting or profiles. This is done to
829830
/// handle test/benches inheriting from dev/release, as well as forcing
830831
/// `for_host` units to always unwind.
@@ -852,32 +853,35 @@ impl UnitFor {
852853
pub fn new_normal() -> UnitFor {
853854
UnitFor {
854855
host: false,
855-
build_dep: false,
856+
host_features: false,
856857
panic_setting: PanicSetting::ReadProfile,
857858
}
858859
}
859860

860-
/// A unit for a custom build script or its dependencies.
861+
/// A unit for a custom build script or proc-macro or its dependencies.
861862
///
862-
/// The `build_dep` parameter is whether or not this is for a build
863-
/// dependency. Build scripts for non-host units should use `false`
864-
/// because they want to use the features of the package they are running
865-
/// for.
866-
pub fn new_build(build_dep: bool) -> UnitFor {
863+
/// The `host_features` parameter is whether or not this is for a build
864+
/// dependency or proc-macro (something that requires being built "on the
865+
/// host"). Build scripts for non-host units should use `false` because
866+
/// they want to use the features of the package they are running for.
867+
pub fn new_host(host_features: bool) -> UnitFor {
867868
UnitFor {
868869
host: true,
869-
build_dep,
870+
host_features,
870871
// Force build scripts to always use `panic=unwind` for now to
871872
// maximally share dependencies with procedural macros.
872873
panic_setting: PanicSetting::AlwaysUnwind,
873874
}
874875
}
875876

876-
/// A unit for a proc macro or compiler plugin or their dependencies.
877+
/// A unit for a compiler plugin or their dependencies.
877878
pub fn new_compiler() -> UnitFor {
878879
UnitFor {
879880
host: false,
880-
build_dep: false,
881+
// The feature resolver doesn't know which dependencies are
882+
// plugins, so for now plugins don't split features. Since plugins
883+
// are mostly deprecated, just leave this as false.
884+
host_features: false,
881885
// Force plugins to use `panic=abort` so panics in the compiler do
882886
// not abort the process but instead end with a reasonable error
883887
// message that involves catching the panic in the compiler.
@@ -894,7 +898,7 @@ impl UnitFor {
894898
pub fn new_test(config: &Config) -> UnitFor {
895899
UnitFor {
896900
host: false,
897-
build_dep: false,
901+
host_features: false,
898902
// We're testing out an unstable feature (`-Zpanic-abort-tests`)
899903
// which inherits the panic setting from the dev/release profile
900904
// (basically avoid recompiles) but historical defaults required
@@ -917,7 +921,7 @@ impl UnitFor {
917921
pub fn with_for_host(self, for_host: bool) -> UnitFor {
918922
UnitFor {
919923
host: self.host || for_host,
920-
build_dep: self.build_dep,
924+
host_features: self.host_features,
921925
panic_setting: if for_host {
922926
PanicSetting::AlwaysUnwind
923927
} else {
@@ -926,15 +930,16 @@ impl UnitFor {
926930
}
927931
}
928932

929-
/// Returns a new copy updating it for a build dependency.
933+
/// Returns a new copy updating it whether or not it should use features
934+
/// for build dependencies and proc-macros.
930935
///
931936
/// This is part of the machinery responsible for handling feature
932937
/// decoupling for build dependencies in the new feature resolver.
933-
pub fn with_build_dep(mut self, build_dep: bool) -> UnitFor {
934-
if build_dep {
938+
pub fn with_host_features(mut self, host_features: bool) -> UnitFor {
939+
if host_features {
935940
assert!(self.host);
936941
}
937-
self.build_dep = self.build_dep || build_dep;
942+
self.host_features = self.host_features || host_features;
938943
self
939944
}
940945

@@ -944,8 +949,8 @@ impl UnitFor {
944949
self.host
945950
}
946951

947-
pub fn is_for_build_dep(&self) -> bool {
948-
self.build_dep
952+
pub fn is_for_host_features(&self) -> bool {
953+
self.host_features
949954
}
950955

951956
/// Returns how `panic` settings should be handled for this profile
@@ -958,43 +963,43 @@ impl UnitFor {
958963
static ALL: &[UnitFor] = &[
959964
UnitFor {
960965
host: false,
961-
build_dep: false,
966+
host_features: false,
962967
panic_setting: PanicSetting::ReadProfile,
963968
},
964969
UnitFor {
965970
host: true,
966-
build_dep: false,
971+
host_features: false,
967972
panic_setting: PanicSetting::AlwaysUnwind,
968973
},
969974
UnitFor {
970975
host: false,
971-
build_dep: false,
976+
host_features: false,
972977
panic_setting: PanicSetting::AlwaysUnwind,
973978
},
974979
UnitFor {
975980
host: false,
976-
build_dep: false,
981+
host_features: false,
977982
panic_setting: PanicSetting::Inherit,
978983
},
979-
// build_dep=true must always have host=true
984+
// host_features=true must always have host=true
980985
// `Inherit` is not used in build dependencies.
981986
UnitFor {
982987
host: true,
983-
build_dep: true,
988+
host_features: true,
984989
panic_setting: PanicSetting::ReadProfile,
985990
},
986991
UnitFor {
987992
host: true,
988-
build_dep: true,
993+
host_features: true,
989994
panic_setting: PanicSetting::AlwaysUnwind,
990995
},
991996
];
992997
ALL
993998
}
994999

9951000
pub(crate) fn map_to_features_for(&self) -> FeaturesFor {
996-
if self.is_for_build_dep() {
997-
FeaturesFor::BuildDep
1001+
if self.is_for_host_features() {
1002+
FeaturesFor::HostDep
9981003
} else {
9991004
FeaturesFor::NormalOrDev
10001005
}

0 commit comments

Comments
 (0)