Skip to content

Commit fc13634

Browse files
committed
Auto merge of #13917 - weihanglo:resolve, r=epage
refactor: misc refactors for `ops::resolve` ### What does this PR try to resolve? This is a preparation for another `-Zpatch-files` experiment, so that the future PR can move things around easier without too many conflicts. ### How should we test and review this PR? Generally they shouldn't affect anything existing behavior. a6230e3 might be a bit dubious, though I believe preloading workspace members is kinda idempotent and registering patches/lockfile never cares about it. ### Additional information
2 parents 0ea330d + 327649b commit fc13634

File tree

2 files changed

+56
-42
lines changed

2 files changed

+56
-42
lines changed

src/cargo/core/resolver/resolve.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -205,7 +205,7 @@ impl Resolve {
205205
self.graph.path_to_top(pkg)
206206
}
207207

208-
pub fn register_used_patches(&mut self, patches: &[Summary]) {
208+
pub fn register_used_patches<'a>(&mut self, patches: impl Iterator<Item = &'a Summary>) {
209209
for summary in patches {
210210
if !self.graph.contains(&summary.package_id()) {
211211
self.unused_patches.push(summary.package_id())

src/cargo/ops/resolve.rs

+55-41
Original file line numberDiff line numberDiff line change
@@ -64,9 +64,14 @@ use crate::core::resolver::{
6464
self, HasDevUnits, Resolve, ResolveOpts, ResolveVersion, VersionOrdering, VersionPreferences,
6565
};
6666
use crate::core::summary::Summary;
67-
use crate::core::{
68-
GitReference, PackageId, PackageIdSpec, PackageIdSpecQuery, PackageSet, SourceId, Workspace,
69-
};
67+
use crate::core::Dependency;
68+
use crate::core::GitReference;
69+
use crate::core::PackageId;
70+
use crate::core::PackageIdSpec;
71+
use crate::core::PackageIdSpecQuery;
72+
use crate::core::PackageSet;
73+
use crate::core::SourceId;
74+
use crate::core::Workspace;
7075
use crate::ops;
7176
use crate::sources::PathSource;
7277
use crate::util::cache_lock::CacheLockMode;
@@ -76,6 +81,9 @@ use anyhow::Context as _;
7681
use std::collections::{HashMap, HashSet};
7782
use tracing::{debug, trace};
7883

84+
/// Filter for keep using Package ID from previous lockfile.
85+
type Keep<'a> = &'a dyn Fn(&PackageId) -> bool;
86+
7987
/// Result for `resolve_ws_with_opts`.
8088
pub struct WorkspaceResolve<'gctx> {
8189
/// Packages to be downloaded.
@@ -312,7 +320,7 @@ pub fn resolve_with_previous<'gctx>(
312320
cli_features: &CliFeatures,
313321
has_dev_units: HasDevUnits,
314322
previous: Option<&Resolve>,
315-
keep_previous: Option<&dyn Fn(&PackageId) -> bool>,
323+
keep_previous: Option<Keep<'_>>,
316324
specs: &[PackageIdSpec],
317325
register_patches: bool,
318326
) -> CargoResult<Resolve> {
@@ -322,6 +330,16 @@ pub fn resolve_with_previous<'gctx>(
322330
.gctx()
323331
.acquire_package_cache_lock(CacheLockMode::DownloadExclusive)?;
324332

333+
// Some packages are already loaded when setting up a workspace. This
334+
// makes it so anything that was already loaded will not be loaded again.
335+
// Without this there were cases where members would be parsed multiple times
336+
ws.preload(registry);
337+
338+
// In case any members were not already loaded or the Workspace is_ephemeral.
339+
for member in ws.members() {
340+
registry.add_sources(Some(member.package_id().source_id()))?;
341+
}
342+
325343
// Try to keep all from previous resolve if no instruction given.
326344
let keep_previous = keep_previous.unwrap_or(&|_| true);
327345

@@ -372,16 +390,6 @@ pub fn resolve_with_previous<'gctx>(
372390
registry.lock_patches();
373391
}
374392

375-
// Some packages are already loaded when setting up a workspace. This
376-
// makes it so anything that was already loaded will not be loaded again.
377-
// Without this there were cases where members would be parsed multiple times
378-
ws.preload(registry);
379-
380-
// In case any members were not already loaded or the Workspace is_ephemeral.
381-
for member in ws.members() {
382-
registry.add_sources(Some(member.package_id().source_id()))?;
383-
}
384-
385393
let summaries: Vec<(Summary, ResolveOpts)> = ws
386394
.members_with_features(specs, cli_features)?
387395
.into_iter()
@@ -397,26 +405,8 @@ pub fn resolve_with_previous<'gctx>(
397405
})
398406
.collect();
399407

400-
let root_replace = ws.root_replace();
401-
402-
let replace = match previous {
403-
Some(r) => root_replace
404-
.iter()
405-
.map(|(spec, dep)| {
406-
for (&key, &val) in r.replacements().iter() {
407-
if spec.matches(key) && dep.matches_id(val) && keep(&val) {
408-
let mut dep = dep.clone();
409-
dep.lock_to(val);
410-
return (spec.clone(), dep);
411-
}
412-
}
413-
(spec.clone(), dep.clone())
414-
})
415-
.collect::<Vec<_>>(),
416-
None => root_replace.to_vec(),
417-
};
408+
let replace = lock_replacements(ws, previous, &keep);
418409

419-
ws.preload(registry);
420410
let mut resolved = resolver::resolve(
421411
&summaries,
422412
&replace,
@@ -425,12 +415,9 @@ pub fn resolve_with_previous<'gctx>(
425415
ResolveVersion::with_rust_version(ws.rust_version()),
426416
Some(ws.gctx()),
427417
)?;
428-
let patches: Vec<_> = registry
429-
.patches()
430-
.values()
431-
.flat_map(|v| v.iter().cloned())
432-
.collect();
433-
resolved.register_used_patches(&patches[..]);
418+
419+
let patches = registry.patches().values().flat_map(|v| v.iter());
420+
resolved.register_used_patches(patches);
434421

435422
if register_patches && !resolved.unused_patches().is_empty() {
436423
emit_warnings_of_unused_patches(ws, &resolved, registry)?;
@@ -508,7 +495,7 @@ fn register_previous_locks(
508495
ws: &Workspace<'_>,
509496
registry: &mut PackageRegistry<'_>,
510497
resolve: &Resolve,
511-
keep: &dyn Fn(&PackageId) -> bool,
498+
keep: Keep<'_>,
512499
dev_deps: bool,
513500
) {
514501
let path_pkg = |id: SourceId| {
@@ -805,7 +792,7 @@ fn register_patch_entries(
805792
ws: &Workspace<'_>,
806793
previous: Option<&Resolve>,
807794
version_prefs: &mut VersionPreferences,
808-
keep_previous: &dyn Fn(&PackageId) -> bool,
795+
keep_previous: Keep<'_>,
809796
) -> CargoResult<HashSet<PackageId>> {
810797
let mut avoid_patch_ids = HashSet::new();
811798
for (url, patches) in ws.root_patch()?.iter() {
@@ -910,3 +897,30 @@ fn register_patch_entries(
910897

911898
Ok(avoid_patch_ids)
912899
}
900+
901+
/// Locks each `[replace]` entry to a specific Package ID
902+
/// if the lockfile contains any correspoding previous replacement.
903+
fn lock_replacements(
904+
ws: &Workspace<'_>,
905+
previous: Option<&Resolve>,
906+
keep: Keep<'_>,
907+
) -> Vec<(PackageIdSpec, Dependency)> {
908+
let root_replace = ws.root_replace();
909+
let replace = match previous {
910+
Some(r) => root_replace
911+
.iter()
912+
.map(|(spec, dep)| {
913+
for (&key, &val) in r.replacements().iter() {
914+
if spec.matches(key) && dep.matches_id(val) && keep(&val) {
915+
let mut dep = dep.clone();
916+
dep.lock_to(val);
917+
return (spec.clone(), dep);
918+
}
919+
}
920+
(spec.clone(), dep.clone())
921+
})
922+
.collect::<Vec<_>>(),
923+
None => root_replace.to_vec(),
924+
};
925+
replace
926+
}

0 commit comments

Comments
 (0)