Skip to content

Commit 03d94f4

Browse files
committed
feat(resolve): Direct people to working around less optimal MSRV-resolver results
In discussing #14414, the general problem of the resolver picking a version older than a package needs for its MSRV (or lack of one) because of the MSRV of other packages came up. This tries to patch over that problem by telling users that a dependency might be able to be newer than the resolver selected. The message is fairly generic and might be misread to be about any MSRV update which an MSRV `fallback` strategy allows, which would make the count off. The reason it is so generic is we don't know with precision why it was held back - Direct dependents may have a non-semver upper bound on the version as we aren't trying to unify the version requirements across direct dependents at this time - A dependency could have removed a feature without making a breaking change - This seems like it should instead be an error but thats a conversation for another day - ~~The user enabled `-Zminimal-versions`~~ - This is now detected and the message skipped Note: separate from this, we may also print the status suffix for this case if the package was not selected for update (e.g. passing `--workspace`).
1 parent 7aa43fa commit 03d94f4

File tree

3 files changed

+50
-7
lines changed

3 files changed

+50
-7
lines changed

src/cargo/ops/cargo_update.rs

+48-7
Original file line numberDiff line numberDiff line change
@@ -519,6 +519,7 @@ fn print_lockfile_generation(
519519
annotate_required_rust_version(ws, resolve, &mut changes);
520520

521521
status_locking(ws, num_pkgs)?;
522+
let mut changed_stats = UpdateStats::default();
522523
for change in changes.values() {
523524
if change.is_member.unwrap_or(false) {
524525
continue;
@@ -538,8 +539,9 @@ fn print_lockfile_generation(
538539
vec![]
539540
};
540541

541-
let required_rust_version = report_required_rust_version(resolve, change, None);
542-
let latest = report_latest(&possibilities, change, None);
542+
let required_rust_version =
543+
report_required_rust_version(resolve, change, Some(&mut changed_stats));
544+
let latest = report_latest(&possibilities, change, Some(&mut changed_stats));
543545
let note = required_rust_version.or(latest);
544546

545547
if let Some(note) = note {
@@ -559,6 +561,22 @@ fn print_lockfile_generation(
559561
}
560562
}
561563

564+
let compat_ver_compat_msrv = changed_stats.compat_ver_compat_msrv;
565+
if 0 < compat_ver_compat_msrv
566+
&& !ws.gctx().cli_unstable().direct_minimal_versions
567+
&& !ws.gctx().cli_unstable().minimal_versions
568+
{
569+
if compat_ver_compat_msrv == 1 {
570+
ws.gctx().shell().note(format!(
571+
"{compat_ver_compat_msrv} package may have a higher, compatible versions. To update it, run `cargo update <name> --precise <version>"
572+
))?;
573+
} else {
574+
ws.gctx().shell().note(format!(
575+
"{compat_ver_compat_msrv} packages may have higher, compatible versions. To update them, run `cargo update <name> --precise <version>"
576+
))?;
577+
}
578+
}
579+
562580
Ok(())
563581
}
564582

@@ -580,6 +598,7 @@ fn print_lockfile_sync(
580598
annotate_required_rust_version(ws, resolve, &mut changes);
581599

582600
status_locking(ws, num_pkgs)?;
601+
let mut changed_stats = UpdateStats::default();
583602
for change in changes.values() {
584603
if change.is_member.unwrap_or(false) {
585604
continue;
@@ -601,8 +620,9 @@ fn print_lockfile_sync(
601620
vec![]
602621
};
603622

604-
let required_rust_version = report_required_rust_version(resolve, change, None);
605-
let latest = report_latest(&possibilities, change, None);
623+
let required_rust_version =
624+
report_required_rust_version(resolve, change, Some(&mut changed_stats));
625+
let latest = report_latest(&possibilities, change, Some(&mut changed_stats));
606626
let note = required_rust_version.or(latest).unwrap_or_default();
607627

608628
ws.gctx().shell().status_with_color(
@@ -615,6 +635,16 @@ fn print_lockfile_sync(
615635
}
616636
}
617637

638+
let compat_ver_compat_msrv = changed_stats.compat_ver_compat_msrv;
639+
if 0 < compat_ver_compat_msrv
640+
&& !ws.gctx().cli_unstable().direct_minimal_versions
641+
&& !ws.gctx().cli_unstable().minimal_versions
642+
{
643+
ws.gctx().shell().note(format!(
644+
"{compat_ver_compat_msrv} were updated but higher versions may be available by manually updating with `cargo update <name> --precise <version>"
645+
))?;
646+
}
647+
618648
Ok(())
619649
}
620650

@@ -636,6 +666,7 @@ fn print_lockfile_updates(
636666
status_locking(ws, num_pkgs)?;
637667
}
638668
let mut unchanged_behind = 0;
669+
let mut changed_stats = UpdateStats::default();
639670
for change in changes.values() {
640671
let possibilities = if let Some(query) = change.alternatives_query() {
641672
loop {
@@ -654,8 +685,9 @@ fn print_lockfile_updates(
654685
PackageChangeKind::Added
655686
| PackageChangeKind::Upgraded
656687
| PackageChangeKind::Downgraded => {
657-
let required_rust_version = report_required_rust_version(resolve, change, None);
658-
let latest = report_latest(&possibilities, change, None);
688+
let required_rust_version =
689+
report_required_rust_version(resolve, change, Some(&mut changed_stats));
690+
let latest = report_latest(&possibilities, change, Some(&mut changed_stats));
659691
let note = required_rust_version.or(latest).unwrap_or_default();
660692

661693
ws.gctx().shell().status_with_color(
@@ -694,6 +726,15 @@ fn print_lockfile_updates(
694726
}
695727
}
696728

729+
let compat_ver_compat_msrv = changed_stats.compat_ver_compat_msrv;
730+
if 0 < compat_ver_compat_msrv
731+
&& !ws.gctx().cli_unstable().direct_minimal_versions
732+
&& !ws.gctx().cli_unstable().minimal_versions
733+
{
734+
ws.gctx().shell().note(format!(
735+
"{compat_ver_compat_msrv} were updated but higher versions may be available by manually updating with `cargo update <name> --precise <version>"
736+
))?;
737+
}
697738
if ws.gctx().shell().verbosity() == Verbosity::Verbose {
698739
ws.gctx().shell().note(
699740
"to see how you depend on a package, run `cargo tree --invert --package <dep>@<ver>`",
@@ -886,7 +927,7 @@ fn report_latest(
886927
}
887928
}
888929

889-
#[derive(Default)]
930+
#[derive(Copy, Clone, Default, Debug)]
890931
struct UpdateStats {
891932
required_rust_version: usize,
892933
compat_ver_compat_msrv: usize,

tests/testsuite/rust_version.rs

+1
Original file line numberDiff line numberDiff line change
@@ -1214,6 +1214,7 @@ fn report_rust_versions() {
12141214
[ADDING] dep-only-unset-compatible v1.55.0 (available: v1.75.0)
12151215
[ADDING] dep-only-unset-incompatible v1.2345.0 (requires Rust 1.2345.0)
12161216
[ADDING] dep-shared-incompatible v1.75.0 (requires Rust 1.75.0)
1217+
[NOTE] 2 packages may have higher, compatible versions. To update them, run `cargo update <name> --precise <version>
12171218
12181219
"#]])
12191220
.run();

tests/testsuite/workspaces.rs

+1
Original file line numberDiff line numberDiff line change
@@ -698,6 +698,7 @@ fn share_dependencies() {
698698
[UPDATING] `dummy-registry` index
699699
[LOCKING] 1 package to latest compatible version
700700
[ADDING] dep1 v0.1.3 (available: v0.1.8)
701+
[NOTE] 1 package may have a higher, compatible versions. To update it, run `cargo update <name> --precise <version>
701702
[DOWNLOADING] crates ...
702703
[DOWNLOADED] dep1 v0.1.3 (registry `dummy-registry`)
703704
[CHECKING] dep1 v0.1.3

0 commit comments

Comments
 (0)