From e46a0dd2c2b2dd4e566d111dbf153eb1ec67e1a6 Mon Sep 17 00:00:00 2001 From: Ryan Gibb Date: Mon, 21 Sep 2026 17:59:38 +0100 Subject: [PATCH] eval/cargo: resolve for the toolchain cargo falls back to, and a goal that shows it --- eval/cargo/goals.txt | 1 + eval/cargo/run_goal.py | 30 +++++++++++++++++------------- eval/cargo/verify.py | 9 ++++++++- 3 files changed, 26 insertions(+), 14 deletions(-) diff --git a/eval/cargo/goals.txt b/eval/cargo/goals.txt index 67730b1..0f5ee8d 100644 --- a/eval/cargo/goals.txt +++ b/eval/cargo/goals.txt @@ -26,3 +26,4 @@ reqwest wasm-bindgen diesel actix-web +rustradio-ui diff --git a/eval/cargo/run_goal.py b/eval/cargo/run_goal.py index 8023ef0..184fd71 100644 --- a/eval/cargo/run_goal.py +++ b/eval/cargo/run_goal.py @@ -59,6 +59,13 @@ def index_line(name, version): return None +def installed_rustc(): + """What cargo falls back to when no member declares rust-version.""" + out = subprocess.run(["rustc", "--version"], capture_output=True, + text=True).stdout + return out.split()[1] + + def run_pac(crate, rustv=None): cmd = [PAC, "cargo", INDEX, crate] if rustv: @@ -264,19 +271,16 @@ def main(): root_entry = index_line(root_name, root_version) rustv = root_entry.get("rust_version") if root_entry else None - # Pass 2 (only when the root crate itself declares an MSRV): real - # cargo's resolver v3 reads that field straight off the manifest it - # is resolving and applies the MSRV-preferring sort unconditionally - # -- there is no cargo flag that targets a toolchain other than the - # one named in rust-version, so pac's --rust-version is only a - # correct stand-in for "the toolchain cargo resolves for" when set - # to exactly this value. Left unset (rustv is None), pac's - # preference is off, matching a root with no declared rust-version, - # where cargo has nothing to prefer by either. - if rustv: - pac_res = run_pac(args.crate, rustv=rustv) - else: - pac_res = probe + # Pass 2: the toolchain cargo resolves for. Resolver v3 reads + # rust-version off the manifest, and when no workspace member + # declares one it falls back to the rustc it finds installed + # (ops/resolve.rs, `if rust_versions.is_empty()`). Leaving pac's + # preference off in that case would hand the two sides different + # settings and show up as a divergence that is the harness's, so + # the fallback is reproduced here rather than assumed away. + if rustv is None: + rustv = installed_rustc() + pac_res = run_pac(args.crate, rustv=rustv) try: cargo_res = run_cargo(root_name, root_version, diff --git a/eval/cargo/verify.py b/eval/cargo/verify.py index 785e834..f2b7f8b 100755 --- a/eval/cargo/verify.py +++ b/eval/cargo/verify.py @@ -80,7 +80,14 @@ def main(): root_name, root_version = probe["root"] entry = run_goal.index_line(root_name, root_version) rustv = entry.get("rust_version") if entry else None - pac = run_goal.run_pac(args.crate, rustv=rustv) if rustv else probe + # The same fallback run_goal.py reproduces: with no member declaring a + # rust-version, resolver v3 ranks against the installed rustc rather + # than against nothing, so the lock being verified has to be the one + # pac writes for that toolchain. Verified red-then-green on + # rustradio-ui, whose rustradio dependency moves under it. + if rustv is None: + rustv = run_goal.installed_rustc() + pac = run_goal.run_pac(args.crate, rustv=rustv) if not pac["ok"]: print("%-24s PAC FAILED (msrv pass)" % args.crate) return 1 -- knotmirror 0.0.1