Skip to content

Commit 6154645

Browse files
committed
Rewrite new feature resolver to simplify DepKind handling.
Now that dev-dependencies are a global setting, only build-dependencies matter. This is maybe a little simpler to understand?
1 parent 134aeff commit 6154645

File tree

11 files changed

+187
-283
lines changed

11 files changed

+187
-283
lines changed

src/cargo/core/compiler/context/compilation_files.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,7 @@ impl<'a, 'cfg: 'a> CompilationFiles<'a, 'cfg> {
147147
/// Returns `None` if the unit should not use a metadata data hash (like
148148
/// rustdoc, or some dylibs).
149149
pub fn metadata(&self, unit: &Unit<'a>) -> Option<Metadata> {
150-
self.metas[unit].clone()
150+
self.metas[unit]
151151
}
152152

153153
/// Gets the short hash based only on the `PackageId`.
@@ -515,7 +515,7 @@ fn metadata_of<'a, 'cfg>(
515515
metadata_of(&dep.unit, cx, metas);
516516
}
517517
}
518-
metas[unit].clone()
518+
metas[unit]
519519
}
520520

521521
fn compute_metadata<'a, 'cfg>(

src/cargo/core/compiler/standard_lib.rs

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
//! Code for building the standard library.
22
33
use crate::core::compiler::{BuildContext, CompileKind, CompileMode, RustcTargetData, Unit};
4-
use crate::core::dependency::DepKind;
54
use crate::core::profiles::UnitFor;
65
use crate::core::resolver::features::ResolvedFeatures;
76
use crate::core::resolver::ResolveOpts;
@@ -149,11 +148,7 @@ pub fn generate_std_roots<'a>(
149148
unit_for,
150149
mode,
151150
);
152-
let features = std_features.activated_features(
153-
pkg.package_id(),
154-
DepKind::Normal,
155-
bcx.build_config.requested_kind,
156-
);
151+
let features = std_features.activated_features(pkg.package_id(), false);
157152
Ok(bcx.units.intern(
158153
pkg, lib, profile, kind, mode, features, /*is_std*/ true,
159154
))

src/cargo/core/compiler/unit_dependencies.rs

Lines changed: 42 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -178,7 +178,7 @@ fn deps_of_roots<'a, 'cfg>(roots: &[Unit<'a>], mut state: &mut State<'a, 'cfg>)
178178
} else if unit.target.is_custom_build() {
179179
// This normally doesn't happen, except `clean` aggressively
180180
// generates all units.
181-
UnitFor::new_build()
181+
UnitFor::new_build(false)
182182
} else if unit.target.for_host() {
183183
// Proc macro / plugin should never have panic set.
184184
UnitFor::new_compiler()
@@ -230,53 +230,48 @@ fn compute_deps<'a, 'cfg>(
230230
unit_for: UnitFor,
231231
) -> CargoResult<Vec<UnitDep<'a>>> {
232232
if unit.mode.is_run_custom_build() {
233-
return compute_deps_custom_build(unit, unit_for.dep_kind(), state);
233+
return compute_deps_custom_build(unit, unit_for, state);
234234
} else if unit.mode.is_doc() {
235235
// Note: this does not include doc test.
236236
return compute_deps_doc(unit, state);
237237
}
238238

239239
let bcx = state.bcx;
240240
let id = unit.pkg.package_id();
241-
let filtered_deps = state
242-
.resolve()
243-
.deps(id)
244-
.map(|(id, deps)| {
245-
assert!(!deps.is_empty());
246-
let filtered_deps = deps.iter().filter(|dep| {
247-
// If this target is a build command, then we only want build
248-
// dependencies, otherwise we want everything *other than* build
249-
// dependencies.
250-
if unit.target.is_custom_build() != dep.is_build() {
251-
return false;
252-
}
241+
let filtered_deps = state.resolve().deps(id).filter(|&(_id, deps)| {
242+
assert!(!deps.is_empty());
243+
deps.iter().any(|dep| {
244+
// If this target is a build command, then we only want build
245+
// dependencies, otherwise we want everything *other than* build
246+
// dependencies.
247+
if unit.target.is_custom_build() != dep.is_build() {
248+
return false;
249+
}
253250

254-
// If this dependency is **not** a transitive dependency, then it
255-
// only applies to test/example targets.
256-
if !dep.is_transitive()
257-
&& !unit.target.is_test()
258-
&& !unit.target.is_example()
259-
&& !unit.mode.is_any_test()
260-
{
261-
return false;
262-
}
251+
// If this dependency is **not** a transitive dependency, then it
252+
// only applies to test/example targets.
253+
if !dep.is_transitive()
254+
&& !unit.target.is_test()
255+
&& !unit.target.is_example()
256+
&& !unit.mode.is_any_test()
257+
{
258+
return false;
259+
}
263260

264-
// If this dependency is only available for certain platforms,
265-
// make sure we're only enabling it for that platform.
266-
if !bcx.target_data.dep_platform_activated(dep, unit.kind) {
267-
return false;
268-
}
261+
// If this dependency is only available for certain platforms,
262+
// make sure we're only enabling it for that platform.
263+
if !bcx.target_data.dep_platform_activated(dep, unit.kind) {
264+
return false;
265+
}
269266

270-
// If we've gotten past all that, then this dependency is
271-
// actually used!
272-
true
273-
});
274-
(id, filtered_deps.collect::<Vec<_>>())
267+
// If we've gotten past all that, then this dependency is
268+
// actually used!
269+
true
275270
})
276-
.filter(|(_id, deps)| !deps.is_empty());
271+
});
277272

278273
let mut ret = Vec::new();
279-
for (id, deps) in filtered_deps {
274+
for (id, _) in filtered_deps {
280275
let pkg = match state.get(id)? {
281276
Some(pkg) => pkg,
282277
None => continue,
@@ -286,23 +281,10 @@ fn compute_deps<'a, 'cfg>(
286281
None => continue,
287282
};
288283
let mode = check_or_build_mode(unit.mode, lib);
289-
let dep_kind = if unit.target.is_custom_build() {
290-
// Custom build scripts can *only* have build-dependencies.
291-
DepKind::Build
292-
} else if deps.iter().any(|dep| !dep.is_transitive()) {
293-
// A dependency can be listed in both [dependencies] and
294-
// [dev-dependencies], so this checks if any of the deps are
295-
// listed in dev-dependencies. Note that `filtered_deps` has
296-
// already removed dev-dependencies if it is not a
297-
// test/bench/example, so it is not necessary to check `unit`
298-
// here.
299-
DepKind::Development
300-
} else {
301-
DepKind::Normal
302-
};
303284
let dep_unit_for = unit_for
304285
.with_for_host(lib.for_host())
305-
.with_dep_kind(dep_kind);
286+
// If it is a custom build script, then it *only* has build dependencies.
287+
.with_build_dep(unit.target.is_custom_build());
306288

307289
if bcx.config.cli_unstable().dual_proc_macros && lib.proc_macro() && !unit.kind.is_host() {
308290
let unit_dep = new_unit_dep(state, unit, pkg, lib, dep_unit_for, unit.kind, mode)?;
@@ -330,7 +312,7 @@ fn compute_deps<'a, 'cfg>(
330312
if unit.target.is_custom_build() {
331313
return Ok(ret);
332314
}
333-
ret.extend(dep_build_script(unit, unit_for.dep_kind(), state)?);
315+
ret.extend(dep_build_script(unit, unit_for, state)?);
334316

335317
// If this target is a binary, test, example, etc, then it depends on
336318
// the library of the same package. The call to `resolve.deps` above
@@ -382,14 +364,9 @@ fn compute_deps<'a, 'cfg>(
382364
///
383365
/// The `unit` provided must represent an execution of a build script, and
384366
/// the returned set of units must all be run before `unit` is run.
385-
///
386-
/// `dep_kind` is the dependency kind of the package this build script is
387-
/// being built for. This ensures that the build script is built with the same
388-
/// features the package is built with (if the build script has cfg!()
389-
/// checks).
390367
fn compute_deps_custom_build<'a, 'cfg>(
391368
unit: &Unit<'a>,
392-
dep_kind: DepKind,
369+
unit_for: UnitFor,
393370
state: &mut State<'a, 'cfg>,
394371
) -> CargoResult<Vec<UnitDep<'a>>> {
395372
if let Some(links) = unit.pkg.manifest().links() {
@@ -400,7 +377,7 @@ fn compute_deps_custom_build<'a, 'cfg>(
400377
}
401378
// All dependencies of this unit should use profiles for custom
402379
// builds.
403-
let unit_for = UnitFor::new_build().with_dep_kind(dep_kind);
380+
let script_unit_for = UnitFor::new_build(unit_for.is_for_build_dep());
404381
// When not overridden, then the dependencies to run a build script are:
405382
//
406383
// 1. Compiling the build script itself.
@@ -415,7 +392,7 @@ fn compute_deps_custom_build<'a, 'cfg>(
415392
unit,
416393
unit.pkg,
417394
unit.target,
418-
unit_for,
395+
script_unit_for,
419396
// Build scripts always compiled for the host.
420397
CompileKind::Host,
421398
CompileMode::Build,
@@ -482,7 +459,7 @@ fn compute_deps_doc<'a, 'cfg>(
482459
}
483460

484461
// Be sure to build/run the build script for documented libraries.
485-
ret.extend(dep_build_script(unit, DepKind::Normal, state)?);
462+
ret.extend(dep_build_script(unit, UnitFor::new_normal(), state)?);
486463

487464
// If we document a binary/example, we need the library available.
488465
if unit.target.is_bin() || unit.target.is_example() {
@@ -524,7 +501,7 @@ fn maybe_lib<'a>(
524501
/// build script.
525502
fn dep_build_script<'a>(
526503
unit: &Unit<'a>,
527-
dep_kind: DepKind,
504+
unit_for: UnitFor,
528505
state: &State<'a, '_>,
529506
) -> CargoResult<Option<UnitDep<'a>>> {
530507
unit.pkg
@@ -538,7 +515,7 @@ fn dep_build_script<'a>(
538515
.bcx
539516
.profiles
540517
.get_profile_run_custom_build(&unit.profile);
541-
let script_unit_for = UnitFor::new_build().with_dep_kind(dep_kind);
518+
let script_unit_for = UnitFor::new_build(unit_for.is_for_build_dep());
542519
new_unit_dep_with_profile(
543520
state,
544521
unit,
@@ -609,7 +586,7 @@ fn new_unit_dep_with_profile<'a>(
609586
let public = state
610587
.resolve()
611588
.is_public_dep(parent.pkg.package_id(), pkg.package_id());
612-
let features = state.activated_features(pkg.package_id(), unit_for.dep_kind(), kind);
589+
let features = state.activated_features(pkg.package_id(), unit_for.is_for_build_dep());
613590
let unit = state
614591
.bcx
615592
.units
@@ -714,18 +691,13 @@ impl<'a, 'cfg> State<'a, 'cfg> {
714691
}
715692
}
716693

717-
fn activated_features(
718-
&self,
719-
pkg_id: PackageId,
720-
dep_kind: DepKind,
721-
compile_kind: CompileKind,
722-
) -> Vec<InternedString> {
694+
fn activated_features(&self, pkg_id: PackageId, for_build_dep: bool) -> Vec<InternedString> {
723695
let features = if self.is_std {
724696
self.std_features.unwrap()
725697
} else {
726698
self.usr_features
727699
};
728-
features.activated_features(pkg_id, dep_kind, compile_kind)
700+
features.activated_features(pkg_id, for_build_dep)
729701
}
730702

731703
fn get(&mut self, id: PackageId) -> CargoResult<Option<&'a Package>> {

src/cargo/core/dependency.rs

Lines changed: 0 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -92,23 +92,6 @@ pub enum DepKind {
9292
Build,
9393
}
9494

95-
impl DepKind {
96-
/// Convert a DepKind from a package to one of its dependencies.
97-
///
98-
/// The rules here determine how feature decoupling works. This works in
99-
/// conjunction with the new feature resolver.
100-
pub fn sticky_kind(&self, to: DepKind) -> DepKind {
101-
use DepKind::*;
102-
match (self, to) {
103-
(Normal, _) => to,
104-
(Build, _) => Build,
105-
(Development, Normal) => Development,
106-
(Development, Build) => Build,
107-
(Development, Development) => Development,
108-
}
109-
}
110-
}
111-
11295
fn parse_req_with_deprecated(
11396
name: InternedString,
11497
req: &str,

0 commit comments

Comments
 (0)