mirror of
https://github.com/rust-lang/cargo.git
synced 2025-09-25 11:14:46 +00:00
Refactor artifact deps in FeatureResolver::deps
This moves the closure used for computing artifact dependency information out into a separate function. The large line lengths were causing rustfmt to fail to format the entire parent closure. Also, the rightwards drift was getting quite extreme. This also simplifies the code a little by avoiding all the transpose stuff and needing the separate match at the end.
This commit is contained in:
parent
6cba807e2c
commit
e637d7c5c7
@ -802,6 +802,63 @@ impl<'a, 'gctx> FeatureResolver<'a, 'gctx> {
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the `FeaturesFor` needed for this dependency.
|
||||
///
|
||||
/// This includes the `FeaturesFor` for artifact dependencies, which
|
||||
/// might specify multiple targets.
|
||||
fn artifact_features_for(
|
||||
this: &mut FeatureResolver<'_, '_>,
|
||||
pkg_id: PackageId,
|
||||
dep: &Dependency,
|
||||
lib_fk: FeaturesFor,
|
||||
) -> CargoResult<Vec<FeaturesFor>> {
|
||||
let Some(artifact) = dep.artifact() else {
|
||||
return Ok(vec![lib_fk]);
|
||||
};
|
||||
let mut result = Vec::new();
|
||||
let host_triple = this.target_data.rustc.host;
|
||||
// Not all targets may be queried before resolution since artifact
|
||||
// dependencies and per-pkg-targets are not immediately known.
|
||||
let mut activate_target = |target| {
|
||||
let name = dep.name_in_toml();
|
||||
this.target_data
|
||||
.merge_compile_kind(CompileKind::Target(target))
|
||||
.with_context(|| {
|
||||
format!(
|
||||
"failed to determine target information for target `{target}`.\n \
|
||||
Artifact dependency `{name}` in package `{pkg_id}` requires building \
|
||||
for `{target}`",
|
||||
target = target.rustc_target()
|
||||
)
|
||||
})
|
||||
};
|
||||
|
||||
if let Some(target) = artifact.target() {
|
||||
match target {
|
||||
ArtifactTarget::Force(target) => {
|
||||
activate_target(target)?;
|
||||
result.push(FeaturesFor::ArtifactDep(target))
|
||||
}
|
||||
// FIXME: this needs to interact with the `default-target`
|
||||
// and `forced-target` values of the dependency
|
||||
ArtifactTarget::BuildDependencyAssumeTarget => {
|
||||
for kind in this.requested_targets {
|
||||
let target = match kind {
|
||||
CompileKind::Host => CompileTarget::new(&host_triple).unwrap(),
|
||||
CompileKind::Target(target) => *target,
|
||||
};
|
||||
activate_target(target)?;
|
||||
result.push(FeaturesFor::ArtifactDep(target));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if artifact.is_lib() || artifact.target().is_none() {
|
||||
result.push(lib_fk);
|
||||
}
|
||||
Ok(result)
|
||||
}
|
||||
|
||||
self.resolve
|
||||
.deps(pkg_id)
|
||||
.map(|(dep_id, deps)| {
|
||||
@ -850,79 +907,15 @@ impl<'a, 'gctx> FeatureResolver<'a, 'gctx> {
|
||||
// for various targets which are either specified in the manifest
|
||||
// or on the cargo command-line.
|
||||
let lib_fk = if fk == FeaturesFor::default() {
|
||||
(self.track_for_host && (dep.is_build() || self.has_proc_macro_lib(dep_id)))
|
||||
.then(|| FeaturesFor::HostDep)
|
||||
.unwrap_or_default()
|
||||
(self.track_for_host
|
||||
&& (dep.is_build() || self.has_proc_macro_lib(dep_id)))
|
||||
.then(|| FeaturesFor::HostDep)
|
||||
.unwrap_or_default()
|
||||
} else {
|
||||
fk
|
||||
};
|
||||
|
||||
// `artifact_target_keys` are produced to fulfil the needs of artifacts that have a target specification.
|
||||
let artifact_target_keys = dep
|
||||
.artifact()
|
||||
.map(|artifact| {
|
||||
let host_triple = self.target_data.rustc.host;
|
||||
// not all targets may be queried before resolution since artifact dependencies
|
||||
// and per-pkg-targets are not immediately known.
|
||||
let mut activate_target = |target| {
|
||||
let name = dep.name_in_toml();
|
||||
self.target_data
|
||||
.merge_compile_kind(CompileKind::Target(target))
|
||||
.with_context(|| format!("failed to determine target information for target `{target}`.\n \
|
||||
Artifact dependency `{name}` in package `{pkg_id}` requires building for `{target}`", target = target.rustc_target()))
|
||||
};
|
||||
CargoResult::Ok((
|
||||
artifact.is_lib(),
|
||||
artifact
|
||||
.target()
|
||||
.map(|target| {
|
||||
CargoResult::Ok(match target {
|
||||
ArtifactTarget::Force(target) => {
|
||||
activate_target(target)?;
|
||||
vec![FeaturesFor::ArtifactDep(target)]
|
||||
}
|
||||
// FIXME: this needs to interact with the `default-target` and `forced-target` values
|
||||
// of the dependency
|
||||
ArtifactTarget::BuildDependencyAssumeTarget => self
|
||||
.requested_targets
|
||||
.iter()
|
||||
.map(|kind| match kind {
|
||||
CompileKind::Host => {
|
||||
CompileTarget::new(&host_triple)
|
||||
.unwrap()
|
||||
}
|
||||
CompileKind::Target(target) => *target,
|
||||
})
|
||||
.map(|target| {
|
||||
activate_target(target)?;
|
||||
Ok(FeaturesFor::ArtifactDep(target))
|
||||
})
|
||||
.collect::<CargoResult<_>>()?,
|
||||
})
|
||||
})
|
||||
.transpose()?,
|
||||
))
|
||||
})
|
||||
.transpose()?;
|
||||
|
||||
let dep_fks = match artifact_target_keys {
|
||||
// The artifact is also a library and does specify custom
|
||||
// targets.
|
||||
// The library's feature key needs to be used alongside
|
||||
// the keys artifact targets.
|
||||
Some((is_lib, Some(mut dep_fks))) if is_lib => {
|
||||
dep_fks.push(lib_fk);
|
||||
dep_fks
|
||||
}
|
||||
// The artifact is not a library, but does specify
|
||||
// custom targets.
|
||||
// Use only these targets feature keys.
|
||||
Some((_, Some(dep_fks))) => dep_fks,
|
||||
// There is no artifact in the current dependency
|
||||
// or there is no target specified on the artifact.
|
||||
// Use the standard feature key without any alteration.
|
||||
Some((_, None)) | None => vec![lib_fk],
|
||||
};
|
||||
let dep_fks = artifact_features_for(self, pkg_id, dep, lib_fk)?;
|
||||
Ok(dep_fks.into_iter().map(move |dep_fk| (dep, dep_fk)))
|
||||
})
|
||||
.flatten_ok()
|
||||
|
Loading…
x
Reference in New Issue
Block a user