Skip to content

Commit 720a186

Browse files
build(anvil): regen from latest anvil-multiple-regions (miri libtest + careful guard)
Pull latest cargo-anvil (fc9160a) and regenerate. Key upstream fixes: - anvil-miri now runs via libtest (cargo miri test --all-features --tests) instead of cargo miri nextest run. Under miri, nextest's process-per-test model multiplies the (expensive) per-process interpreter startup; libtest runs all tests of a binary in one miri process. This was the main PR wall-time regression vs the repo's existing extended-analysis miri job (which already used cargo miri test): ~80min -> expected ~42min on Windows. - anvil-careful now tracks the careful-sysroot build identity (nightly rustc -vV + cargo-careful version) in target/anvil/careful-sysroot.id and runs cargo clean when it changes, fixing the stale-sysroot E0463/metadata errors (cargo can't see the in-place sysroot rebuild behind the stable cache path). Also adds the anvil-managed [lints] region to the new crate plurality (removing its manual [lints] workspace=true to avoid a duplicate-key error). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent caee29c commit 720a186

4 files changed

Lines changed: 102 additions & 34 deletions

File tree

.anvil.lock

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
version = 1
22
tool = "anvil"
33
tool_version = "0.1.0"
4-
catalog_checksum = "sha256:dc69d6bd4f8e89cad6086d5d3abcf06e8e537724ea43c88a1456d57f98fb03a0"
4+
catalog_checksum = "sha256:e21fde4692a7e449af76ee33b59e69cb19faec381998858e1d66824f0aa4b808"
55

66
[[file]]
77
path = ".github/actions/anvil-impact/action.yml"
@@ -61,7 +61,7 @@ checksum = "sha256:a45359b92a6d851fc39bfa1c03aeb489b544ae37a1cea390dbbf860b2def8
6161

6262
[[file]]
6363
path = "justfiles/anvil/checks.just"
64-
checksum = "sha256:8fa7a3f9b9e8e397e303d6073bc6b704cac93e5c09bff43aa23ae345b6423b6b"
64+
checksum = "sha256:7b08dd242aeb1e887c9793febe463f0a6c4efcb6ade50d96a0c318aff6b9a9e2"
6565

6666
[[file]]
6767
path = "justfiles/anvil/groups.just"
@@ -77,7 +77,7 @@ checksum = "sha256:dceac9a2a9172dbb1d397f2fd2a214359bd3d128cfbabd84107488bcecc34
7777

7878
[[file]]
7979
path = "justfiles/anvil/tools.just"
80-
checksum = "sha256:56c9ad456cfa8dedf53f12a973aa8484f049b2e3a992521e1e4ab30b4501ce76"
80+
checksum = "sha256:d5aa37cad32dc2bf6b56836b08d0f7fa668494b30c85f49741967a0978b7aed2"
8181

8282
[[file]]
8383
path = "justfiles/anvil/versions.just"
@@ -233,6 +233,11 @@ host = "crates/ohno_macros/Cargo.toml"
233233
id = "anvil-lints"
234234
checksum = "sha256:2dd7c0f21339fd17092b8dedfe924aa86732c3520baab84f914c2d8f4103ac40"
235235

236+
[[region]]
237+
host = "crates/plurality/Cargo.toml"
238+
id = "anvil-lints"
239+
checksum = "sha256:2dd7c0f21339fd17092b8dedfe924aa86732c3520baab84f914c2d8f4103ac40"
240+
236241
[[region]]
237242
host = "crates/recoverable/Cargo.toml"
238243
id = "anvil-lints"

crates/plurality/Cargo.toml

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -55,9 +55,6 @@ sharded-slab = { workspace = true }
5555
slab = { workspace = true, features = ["std"] }
5656
slotmap = { workspace = true, features = ["std"] }
5757

58-
[lints]
59-
workspace = true
60-
6158
[[bench]]
6259
name = "criterion_alloc"
6360
harness = false
@@ -73,3 +70,8 @@ harness = false
7370
[[bench]]
7471
name = "pool_comparison"
7572
harness = false
73+
74+
# >>> anvil-managed: anvil-lints
75+
[lints]
76+
workspace = true
77+
# <<< anvil-managed: anvil-lints

justfiles/anvil/checks.just

Lines changed: 81 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -941,17 +941,32 @@ anvil-mutants-diff: anvil-mutants-diff-validate-prereqs
941941
anvil-miri: anvil-miri-validate-prereqs
942942
$ErrorActionPreference = 'Stop'
943943
if ($env:ANVIL_INCLUDE_AFFECTED -eq '--skip') { exit 0 }
944-
# `--no-tests=pass`: miri-only exception. Tests that touch the
945-
# filesystem, spawn subprocesses, or use other miri-incompatible
946-
# APIs commonly carry `#[cfg_attr(miri, ignore)]` (this is the
947-
# canonical opt-out for build-tooling / CLI crates). A crate
948-
# whose test set ends up entirely-skipped under miri legitimately
949-
# produces zero runnable tests; nextest's default exit-4 ("no
950-
# tests to run") would fail the recipe in that case. We treat
951-
# empty test runs as success for miri only. Other nextest-using
952-
# recipes (llvm-cov) keep exit-4 as a failure because zero tests
953-
# there almost always indicates a config mistake.
954-
& cargo '+{{ rust_nightly }}' miri nextest run --no-tests=pass @(if ($env:ANVIL_INCLUDE_AFFECTED) { -split $env:ANVIL_INCLUDE_AFFECTED } else { '--workspace' })
944+
# Run miri via libtest (`cargo miri test`), NOT `cargo miri nextest
945+
# run`. nextest uses a process-per-test model; under miri every
946+
# process pays the full cost of re-interpreting std initialization,
947+
# so process-per-test roughly DOUBLES miri wall-time on a large suite
948+
# (the dominant cost on the PR critical path). libtest runs all tests
949+
# of a binary in a single process, matching how upstream runs miri.
950+
#
951+
# `--tests` selects the same target set nextest ran -- lib unit tests,
952+
# bin unit tests, and integration tests -- while excluding doctests
953+
# (miri cannot run them) and benches/examples. We use `--tests` rather
954+
# than `--lib --tests` because `--lib` errors with "no library targets
955+
# found" on a bin-only affected package under impact scoping; `--tests`
956+
# already covers lib unit tests and tolerates libless packages. We do
957+
# NOT use `--all-targets`: it would add `--benches` (criterion benches
958+
# have `harness = false` and run a full measurement loop -- ruinously
959+
# slow under miri) and `--examples` (runs each example's `main`, often
960+
# miri-incompatible I/O), without adding doctest coverage.
961+
#
962+
# `--all-features` exercises feature-gated code so UB hidden behind an
963+
# optional feature is caught, matching how upstream runs miri.
964+
#
965+
# libtest exits 0 when a binary has zero runnable tests (e.g. a crate
966+
# whose tests are all `#[cfg_attr(miri, ignore)]` -- the canonical
967+
# opt-out for build-tooling / CLI crates), so the old nextest
968+
# `--no-tests=pass` workaround is no longer needed.
969+
& cargo '+{{ rust_nightly }}' miri test --all-features --tests @(if ($env:ANVIL_INCLUDE_AFFECTED) { -split $env:ANVIL_INCLUDE_AFFECTED } else { '--workspace' })
955970
if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE }
956971

957972
# Stricter miri profiles. Each runs miri over the full workspace
@@ -973,7 +988,7 @@ anvil-miri-tree-borrows: anvil-miri-tree-borrows-validate-prereqs
973988
$pkg = @(if ($env:ANVIL_INCLUDE_AFFECTED) { -split $env:ANVIL_INCLUDE_AFFECTED } else { '--workspace' })
974989
$env:MIRIFLAGS = "-Zmiri-tree-borrows $($env:MIRIFLAGS)".Trim()
975990
$env:RUSTFLAGS = "--cfg miri_tree_borrows $($env:RUSTFLAGS)".Trim()
976-
& cargo '+{{ rust_nightly }}' miri nextest run --no-tests=pass @pkg
991+
& cargo '+{{ rust_nightly }}' miri test --all-features --tests @pkg
977992
if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE }
978993

979994
[script("pwsh")]
@@ -983,7 +998,7 @@ anvil-miri-strict-provenance: anvil-miri-strict-provenance-validate-prereqs
983998
$pkg = @(if ($env:ANVIL_INCLUDE_AFFECTED) { -split $env:ANVIL_INCLUDE_AFFECTED } else { '--workspace' })
984999
$env:MIRIFLAGS = "-Zmiri-strict-provenance $($env:MIRIFLAGS)".Trim()
9851000
$env:RUSTFLAGS = "--cfg miri_strict_provenance $($env:RUSTFLAGS)".Trim()
986-
& cargo '+{{ rust_nightly }}' miri nextest run --no-tests=pass @pkg
1001+
& cargo '+{{ rust_nightly }}' miri test --all-features --tests @pkg
9871002
if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE }
9881003

9891004
# Race coverage rotates the miri-many-seeds window daily by
@@ -1003,14 +1018,57 @@ anvil-miri-race-coverage: anvil-miri-race-coverage-validate-prereqs
10031018
$env:MIRIFLAGS = "-Zmiri-many-seeds=$low..$high $($env:MIRIFLAGS)".Trim()
10041019
$env:RUSTFLAGS = "--cfg miri_race_coverage $($env:RUSTFLAGS)".Trim()
10051020
Write-Host "anvil-miri-race-coverage: seed window $low..$high (day $day)"
1006-
& cargo '+{{ rust_nightly }}' miri nextest run --no-tests=pass @pkg
1021+
& cargo '+{{ rust_nightly }}' miri test --all-features --tests @pkg
10071022
if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE }
10081023

10091024
[script("pwsh")]
10101025
anvil-careful: anvil-careful-validate-prereqs
10111026
$ErrorActionPreference = 'Stop'
10121027
if ($env:ANVIL_INCLUDE_AFFECTED -eq '--skip') { exit 0 }
1013-
& cargo '+{{ rust_nightly }}' careful test @(if ($env:ANVIL_INCLUDE_AFFECTED) { -split $env:ANVIL_INCLUDE_AFFECTED } else { '--workspace' }) --all-features --locked
1028+
$pkg = @(if ($env:ANVIL_INCLUDE_AFFECTED) { -split $env:ANVIL_INCLUDE_AFFECTED } else { '--workspace' })
1029+
# Guard against cargo-careful's stale-sysroot hazard. cargo-careful
1030+
# builds a custom std ("careful sysroot": debug-assertions + extra UB
1031+
# checks) into a STABLE cache path -- ProjectDirs(de.ralfj.cargo-careful),
1032+
# NOT keyed by rustc version -- and runs the workspace build with
1033+
# `--sysroot <that stable path>`. cargo's fingerprint hashes the
1034+
# RUSTFLAGS string (the stable sysroot *path*) but not the sysroot's
1035+
# *contents*. So when the pinned nightly (or the careful tool, which sets
1036+
# the std-build flags) changes, cargo-careful rebuilds that std in place
1037+
# while cargo still considers the workspace artifacts up to date -- they
1038+
# then link against a now-replaced std and fail with metadata /
1039+
# "found crate compiled by an incompatible version of rustc" errors.
1040+
#
1041+
# cargo can't see this, so we track the careful build identity ourselves
1042+
# (the nightly rustc -- commit hash et al. -- plus the careful tool
1043+
# version) and `cargo clean` when it changes, forcing the workspace to be
1044+
# rebuilt against the freshly-built std. The marker lives under target/,
1045+
# so it is wiped by the clean and travels with any target/ cache.
1046+
$rustcVV = (& rustc '+{{ rust_nightly }}' -vV | Out-String)
1047+
if ($LASTEXITCODE -ne 0) { Write-Error 'anvil-careful: could not query nightly rustc version'; exit 1 }
1048+
$idSource = $rustcVV.Trim() + "`ncargo-careful {{ cargo_careful_version }}"
1049+
$sha = [System.Security.Cryptography.SHA256]::Create()
1050+
$idHash = ([System.BitConverter]::ToString($sha.ComputeHash([System.Text.Encoding]::UTF8.GetBytes($idSource)))).Replace('-', '').ToLower()
1051+
# Human-readable identity for log output: the first `rustc -vV` line
1052+
# (e.g. "rustc 1.98.0-nightly (<hash> <date>)") plus the careful version.
1053+
$idLabel = "$(($rustcVV -split "`n")[0].Trim()) + cargo-careful {{ cargo_careful_version }}"
1054+
$marker = Join-Path 'target' 'anvil/careful-sysroot.id'
1055+
$prev = if (Test-Path -LiteralPath $marker) { (Get-Content -LiteralPath $marker -Raw).Trim() } else { $null }
1056+
if ($null -ne $prev -and $prev -ne $idHash) {
1057+
Write-Host 'anvil-careful: careful sysroot identity changed since the last run -- running `cargo clean` so the'
1058+
Write-Host ' workspace is rebuilt against the freshly-built careful std (cargo cannot detect the in-place'
1059+
Write-Host ' sysroot rebuild on its own, so stale artifacts would otherwise fail with an'
1060+
Write-Host ' "incompatible version of rustc" / metadata mismatch).'
1061+
Write-Host " reason : the pinned nightly toolchain and/or the cargo-careful version changed"
1062+
Write-Host " now : $idLabel"
1063+
Write-Host " identity: $($prev.Substring(0, [Math]::Min(12, $prev.Length)))... -> $($idHash.Substring(0, 12))..."
1064+
cargo clean
1065+
if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE }
1066+
}
1067+
# Persist the current identity (also seeds the marker on first run, when
1068+
# there is nothing to clean). Written after the clean so it survives it.
1069+
New-Item -ItemType Directory -Force -Path (Split-Path $marker) | Out-Null
1070+
Set-Content -LiteralPath $marker -Value $idHash
1071+
& cargo '+{{ rust_nightly }}' careful test @pkg --all-features --locked
10141072
if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE }
10151073

10161074
# Affected tier. `loom` is a permutation-based concurrency model
@@ -1343,32 +1401,32 @@ anvil-examples-validate-prereqs: anvil-tool-rustc-validate-prereqs
13431401
# --- pr-runtime-analysis members ---
13441402

13451403
[group("anvil-setup")]
1346-
anvil-miri-setup installer="install": anvil-component-nightly-miri-install anvil-component-nightly-rust-src-install (anvil-tool-cargo-nextest-install installer)
1404+
anvil-miri-setup installer="install": anvil-component-nightly-miri-install anvil-component-nightly-rust-src-install
13471405

13481406
[group("anvil-setup")]
1349-
anvil-miri-validate-prereqs: anvil-component-nightly-miri-validate-prereqs anvil-component-nightly-rust-src-validate-prereqs anvil-tool-cargo-nextest-validate-prereqs
1407+
anvil-miri-validate-prereqs: anvil-component-nightly-miri-validate-prereqs anvil-component-nightly-rust-src-validate-prereqs
13501408

13511409
# The three nightly-miri profiles share the same toolchain prereqs
13521410
# as anvil-miri; they only differ in the MIRIFLAGS / RUSTFLAGS the
13531411
# recipe sets. Separate setup recipes keep the per-check fan-out
13541412
# regular (groups.just can iterate without special-casing).
13551413
[group("anvil-setup")]
1356-
anvil-miri-tree-borrows-setup installer="install": anvil-component-nightly-miri-install anvil-component-nightly-rust-src-install (anvil-tool-cargo-nextest-install installer)
1414+
anvil-miri-tree-borrows-setup installer="install": anvil-component-nightly-miri-install anvil-component-nightly-rust-src-install
13571415

13581416
[group("anvil-setup")]
1359-
anvil-miri-tree-borrows-validate-prereqs: anvil-component-nightly-miri-validate-prereqs anvil-component-nightly-rust-src-validate-prereqs anvil-tool-cargo-nextest-validate-prereqs
1417+
anvil-miri-tree-borrows-validate-prereqs: anvil-component-nightly-miri-validate-prereqs anvil-component-nightly-rust-src-validate-prereqs
13601418

13611419
[group("anvil-setup")]
1362-
anvil-miri-strict-provenance-setup installer="install": anvil-component-nightly-miri-install anvil-component-nightly-rust-src-install (anvil-tool-cargo-nextest-install installer)
1420+
anvil-miri-strict-provenance-setup installer="install": anvil-component-nightly-miri-install anvil-component-nightly-rust-src-install
13631421

13641422
[group("anvil-setup")]
1365-
anvil-miri-strict-provenance-validate-prereqs: anvil-component-nightly-miri-validate-prereqs anvil-component-nightly-rust-src-validate-prereqs anvil-tool-cargo-nextest-validate-prereqs
1423+
anvil-miri-strict-provenance-validate-prereqs: anvil-component-nightly-miri-validate-prereqs anvil-component-nightly-rust-src-validate-prereqs
13661424

13671425
[group("anvil-setup")]
1368-
anvil-miri-race-coverage-setup installer="install": anvil-component-nightly-miri-install anvil-component-nightly-rust-src-install (anvil-tool-cargo-nextest-install installer)
1426+
anvil-miri-race-coverage-setup installer="install": anvil-component-nightly-miri-install anvil-component-nightly-rust-src-install
13691427

13701428
[group("anvil-setup")]
1371-
anvil-miri-race-coverage-validate-prereqs: anvil-component-nightly-miri-validate-prereqs anvil-component-nightly-rust-src-validate-prereqs anvil-tool-cargo-nextest-validate-prereqs
1429+
anvil-miri-race-coverage-validate-prereqs: anvil-component-nightly-miri-validate-prereqs anvil-component-nightly-rust-src-validate-prereqs
13721430

13731431
[group("anvil-setup")]
13741432
anvil-careful-setup installer="install": anvil-component-nightly-rust-src-install (anvil-tool-cargo-careful-install installer)

justfiles/anvil/tools.just

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -96,8 +96,8 @@ anvil-system-deps-check:
9696
# hunspell-sys build script can LOAD libclang.dll at runtime (the
9797
# loader ignores LIBCLANG_PATH). Catch the present-but-undiscoverable
9898
# case here instead of letting the build fail with STATUS_DLL_NOT_FOUND.
99-
$pathDirs = ($env:PATH -split ';') | Where-Object { $_ } | ForEach-Object { $_.TrimEnd('\') }
100-
if ($pathDirs -notcontains $libclangDir.TrimEnd('\')) {
99+
$pathDirs = ($env:PATH -split ';') | ForEach-Object { $_.Trim().TrimEnd('\') } | Where-Object { $_ }
100+
if ($pathDirs -notcontains $libclangDir.Trim().TrimEnd('\')) {
101101
$missing += [pscustomobject]@{
102102
name = 'libclang (present but not on PATH)'
103103
why = "libclang.dll exists at '$libclangDir' but that directory is not on PATH; the hunspell-sys build script cannot load it (STATUS_DLL_NOT_FOUND)"
@@ -332,7 +332,7 @@ _install-component toolchain component:
332332
$sysroot = $sysroot.Trim()
333333
$present = switch ($component) {
334334
'rust-src' { Test-Path (Join-Path $sysroot 'lib/rustlib/src/rust/library') }
335-
'llvm-tools' { @(Get-ChildItem (Join-Path $sysroot 'lib/rustlib') -Recurse -Filter 'llvm-profdata*' -ErrorAction SilentlyContinue).Count -gt 0 }
335+
'llvm-tools' { @(Get-ChildItem -Path (Join-Path $sysroot 'lib/rustlib/*/bin/llvm-profdata*') -ErrorAction SilentlyContinue).Count -gt 0 }
336336
default { $false }
337337
}
338338
}
@@ -400,8 +400,11 @@ _check-component toolchain component:
400400
# rust-src lands the standard-library sources under the sysroot.
401401
'rust-src' { Test-Path (Join-Path $sysroot 'lib/rustlib/src/rust/library') }
402402
# llvm-tools ships llvm-profdata/llvm-cov under the per-target
403-
# bin directory.
404-
'llvm-tools' { @(Get-ChildItem (Join-Path $sysroot 'lib/rustlib') -Recurse -Filter 'llvm-profdata*' -ErrorAction SilentlyContinue).Count -gt 0 }
403+
# bin directory. Probe with a shallow glob over
404+
# lib/rustlib/<target>/bin rather than a recursive scan of the
405+
# whole rustlib tree (which also holds rust-src's std sources),
406+
# keeping validate-prereqs fast on large sysroots.
407+
'llvm-tools' { @(Get-ChildItem -Path (Join-Path $sysroot 'lib/rustlib/*/bin/llvm-profdata*') -ErrorAction SilentlyContinue).Count -gt 0 }
405408
default { $false }
406409
}
407410
}

0 commit comments

Comments
 (0)