Skip to content

Commit bfe4128

Browse files
authored
Refactor artifact deps in FeatureResolver::deps (#15492)
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.
2 parents 6cba807 + e637d7c commit bfe4128

File tree

1 file changed

+62
-69
lines changed

1 file changed

+62
-69
lines changed

src/cargo/core/resolver/features.rs

Lines changed: 62 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -802,6 +802,63 @@ impl<'a, 'gctx> FeatureResolver<'a, 'gctx> {
802802
}
803803
}
804804

805+
/// Returns the `FeaturesFor` needed for this dependency.
806+
///
807+
/// This includes the `FeaturesFor` for artifact dependencies, which
808+
/// might specify multiple targets.
809+
fn artifact_features_for(
810+
this: &mut FeatureResolver<'_, '_>,
811+
pkg_id: PackageId,
812+
dep: &Dependency,
813+
lib_fk: FeaturesFor,
814+
) -> CargoResult<Vec<FeaturesFor>> {
815+
let Some(artifact) = dep.artifact() else {
816+
return Ok(vec![lib_fk]);
817+
};
818+
let mut result = Vec::new();
819+
let host_triple = this.target_data.rustc.host;
820+
// Not all targets may be queried before resolution since artifact
821+
// dependencies and per-pkg-targets are not immediately known.
822+
let mut activate_target = |target| {
823+
let name = dep.name_in_toml();
824+
this.target_data
825+
.merge_compile_kind(CompileKind::Target(target))
826+
.with_context(|| {
827+
format!(
828+
"failed to determine target information for target `{target}`.\n \
829+
Artifact dependency `{name}` in package `{pkg_id}` requires building \
830+
for `{target}`",
831+
target = target.rustc_target()
832+
)
833+
})
834+
};
835+
836+
if let Some(target) = artifact.target() {
837+
match target {
838+
ArtifactTarget::Force(target) => {
839+
activate_target(target)?;
840+
result.push(FeaturesFor::ArtifactDep(target))
841+
}
842+
// FIXME: this needs to interact with the `default-target`
843+
// and `forced-target` values of the dependency
844+
ArtifactTarget::BuildDependencyAssumeTarget => {
845+
for kind in this.requested_targets {
846+
let target = match kind {
847+
CompileKind::Host => CompileTarget::new(&host_triple).unwrap(),
848+
CompileKind::Target(target) => *target,
849+
};
850+
activate_target(target)?;
851+
result.push(FeaturesFor::ArtifactDep(target));
852+
}
853+
}
854+
}
855+
}
856+
if artifact.is_lib() || artifact.target().is_none() {
857+
result.push(lib_fk);
858+
}
859+
Ok(result)
860+
}
861+
805862
self.resolve
806863
.deps(pkg_id)
807864
.map(|(dep_id, deps)| {
@@ -850,79 +907,15 @@ impl<'a, 'gctx> FeatureResolver<'a, 'gctx> {
850907
// for various targets which are either specified in the manifest
851908
// or on the cargo command-line.
852909
let lib_fk = if fk == FeaturesFor::default() {
853-
(self.track_for_host && (dep.is_build() || self.has_proc_macro_lib(dep_id)))
854-
.then(|| FeaturesFor::HostDep)
855-
.unwrap_or_default()
910+
(self.track_for_host
911+
&& (dep.is_build() || self.has_proc_macro_lib(dep_id)))
912+
.then(|| FeaturesFor::HostDep)
913+
.unwrap_or_default()
856914
} else {
857915
fk
858916
};
859917

860-
// `artifact_target_keys` are produced to fulfil the needs of artifacts that have a target specification.
861-
let artifact_target_keys = dep
862-
.artifact()
863-
.map(|artifact| {
864-
let host_triple = self.target_data.rustc.host;
865-
// not all targets may be queried before resolution since artifact dependencies
866-
// and per-pkg-targets are not immediately known.
867-
let mut activate_target = |target| {
868-
let name = dep.name_in_toml();
869-
self.target_data
870-
.merge_compile_kind(CompileKind::Target(target))
871-
.with_context(|| format!("failed to determine target information for target `{target}`.\n \
872-
Artifact dependency `{name}` in package `{pkg_id}` requires building for `{target}`", target = target.rustc_target()))
873-
};
874-
CargoResult::Ok((
875-
artifact.is_lib(),
876-
artifact
877-
.target()
878-
.map(|target| {
879-
CargoResult::Ok(match target {
880-
ArtifactTarget::Force(target) => {
881-
activate_target(target)?;
882-
vec![FeaturesFor::ArtifactDep(target)]
883-
}
884-
// FIXME: this needs to interact with the `default-target` and `forced-target` values
885-
// of the dependency
886-
ArtifactTarget::BuildDependencyAssumeTarget => self
887-
.requested_targets
888-
.iter()
889-
.map(|kind| match kind {
890-
CompileKind::Host => {
891-
CompileTarget::new(&host_triple)
892-
.unwrap()
893-
}
894-
CompileKind::Target(target) => *target,
895-
})
896-
.map(|target| {
897-
activate_target(target)?;
898-
Ok(FeaturesFor::ArtifactDep(target))
899-
})
900-
.collect::<CargoResult<_>>()?,
901-
})
902-
})
903-
.transpose()?,
904-
))
905-
})
906-
.transpose()?;
907-
908-
let dep_fks = match artifact_target_keys {
909-
// The artifact is also a library and does specify custom
910-
// targets.
911-
// The library's feature key needs to be used alongside
912-
// the keys artifact targets.
913-
Some((is_lib, Some(mut dep_fks))) if is_lib => {
914-
dep_fks.push(lib_fk);
915-
dep_fks
916-
}
917-
// The artifact is not a library, but does specify
918-
// custom targets.
919-
// Use only these targets feature keys.
920-
Some((_, Some(dep_fks))) => dep_fks,
921-
// There is no artifact in the current dependency
922-
// or there is no target specified on the artifact.
923-
// Use the standard feature key without any alteration.
924-
Some((_, None)) | None => vec![lib_fk],
925-
};
918+
let dep_fks = artifact_features_for(self, pkg_id, dep, lib_fk)?;
926919
Ok(dep_fks.into_iter().map(move |dep_fk| (dep, dep_fk)))
927920
})
928921
.flatten_ok()

0 commit comments

Comments
 (0)