You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
A perry-runtime change broke the link of five perry-ext-* crates and no per-PR gate could have caught it (#7650 → fixed in #7655). It would have surfaced at the next tag, days later.
The gap
cargo-test scopes a per-PR run to the changed crates' reverse-dependency closure (scripts/ci_test_scope.py); the full workspace runs on tags and nightly only. perry-ext-* sits outside the closure of a GC change to perry-runtime, so nothing built it.
But the ext crates are structurally more fragile than the closure suggests, not less: they link a feature-stripped runtime through perry-ffi's runtime-link, built with -Wl,-dead_strip. Any new reference edge inside perry-runtime can keep a chain alive that the stripper had been removing, and the failure is a link error, not a test failure:
Undefined symbols for architecture arm64:
"_js_blob_new", "_js_fetch_with_options", "_js_fetch_notify_signal_aborted"
In #7650 the edge was one added call — pin_object → arena::classify_heap_space — in code that had previously done a raw flag write.
Proposal
Add a cheap per-PR arm that links (not runs) the ext crates whenever crates/perry-runtime/** or crates/perry-stdlib/** changes:
Those five are the ones that actually failed; a wider set is better if it is affordable. Measured cost on a dev Mac from a warm target dir: ~5 minutes for all five together, and it needs no runtime behaviour, no fixture and no host pinning — it is a linker check.
Alternatively, teach ci_test_scope.py that perry-runtime/perry-stdlib changes pull in perry-ext-* regardless of the declared dependency graph, since the real coupling here is the link, not the crate graph.
A
perry-runtimechange broke the link of fiveperry-ext-*crates and no per-PR gate could have caught it (#7650 → fixed in #7655). It would have surfaced at the next tag, days later.The gap
cargo-testscopes a per-PR run to the changed crates' reverse-dependency closure (scripts/ci_test_scope.py); the full workspace runs on tags and nightly only.perry-ext-*sits outside the closure of a GC change toperry-runtime, so nothing built it.But the ext crates are structurally more fragile than the closure suggests, not less: they link a feature-stripped runtime through
perry-ffi'sruntime-link, built with-Wl,-dead_strip. Any new reference edge insideperry-runtimecan keep a chain alive that the stripper had been removing, and the failure is a link error, not a test failure:In #7650 the edge was one added call —
pin_object→arena::classify_heap_space— in code that had previously done a raw flag write.Proposal
Add a cheap per-PR arm that links (not runs) the ext crates whenever
crates/perry-runtime/**orcrates/perry-stdlib/**changes:Those five are the ones that actually failed; a wider set is better if it is affordable. Measured cost on a dev Mac from a warm target dir: ~5 minutes for all five together, and it needs no runtime behaviour, no fixture and no host pinning — it is a linker check.
Alternatively, teach
ci_test_scope.pythatperry-runtime/perry-stdlibchanges pull inperry-ext-*regardless of the declared dependency graph, since the real coupling here is the link, not the crate graph.Two things to get right
Context: #7650, #7655; the ext staticlib feature-stripping is also behind #7522 and #6847.