diff --git a/changelog.d/8917-census-carrier-pin.md b/changelog.d/8917-census-carrier-pin.md new file mode 100644 index 0000000000..a3bd74ab34 --- /dev/null +++ b/changelog.d/8917-census-carrier-pin.md @@ -0,0 +1,7 @@ +Restored the literal `if descriptor.old_carrier || descriptor.cache_carrier` two-armed expression in `scan_shape_table_rekey_mut`. + +#8899 lifted that condition into a `let is_carrier = …` binding for its memo key. The change was semantically inert, but `scripts/shape_descriptor_census.py` deliberately pins the *whole* two-armed expression — so that a sabotage which widens the gate or swaps the arms has to be red — and the refactor stopped matching that pin. `lint` has been red on `main` since #8899 landed. + +It also silently disarmed the census's own self-test: that test sabotages this exact literal via `str.replace(old, new, 1)`, which does nothing when the string is absent, so the "un-gated into an unconditional table root" case was being replaced into nothing and proving nothing. + +The condition is now written out at the decision site, with a comment saying why it must stay literal; `is_carrier` remains and still keys the memo. diff --git a/crates/perry-runtime/src/object/shapes.rs b/crates/perry-runtime/src/object/shapes.rs index 3506f13a23..007424891a 100644 --- a/crates/perry-runtime/src/object/shapes.rs +++ b/crates/perry-runtime/src/object/shapes.rs @@ -1771,7 +1771,13 @@ pub(crate) fn scan_shape_table_rekey_mut(visitor: &mut crate::gc::RuntimeRootVis continue; } let probe_addr = addr; - let moved = if is_carrier { + // Written out rather than reusing `is_carrier` on purpose: the + // census gate (`scripts/shape_descriptor_census.py`) pins this exact + // two-armed expression so that a sabotage which widens the gate or + // swaps the arms is red, and its own self-test sabotages this very + // literal. `is_carrier` above is the same predicate, and is what + // keys the memo. + let moved = if descriptor.old_carrier || descriptor.cache_carrier { visitor.visit_usize_slot(&mut addr) } else { visitor.visit_metadata_usize_slot(&mut addr)