From 794a376b20bdf8aaad3ef3b4708dc9c34a8c071e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ralph=20K=C3=BCpper?= Date: Sun, 2 Aug 2026 22:29:48 +0200 Subject: [PATCH] fix(gc): silence the two product-build warnings from #7250's barrier arming --- .../7278-barrier-arming-product-warnings.md | 19 ++++++++++++ .../perry-runtime/src/builtins/arithmetic.rs | 4 +++ crates/perry-runtime/src/gc/barrier_arming.rs | 5 ++++ crates/perry-runtime/src/gc/mod.rs | 6 +++- .../gc/tests/copying/pointer_publish_7154.rs | 29 +++++++++---------- crates/perry-runtime/src/gc/tests/oldgen.rs | 5 +++- 6 files changed, 51 insertions(+), 17 deletions(-) create mode 100644 changelog.d/7278-barrier-arming-product-warnings.md diff --git a/changelog.d/7278-barrier-arming-product-warnings.md b/changelog.d/7278-barrier-arming-product-warnings.md new file mode 100644 index 0000000000..2abb88a94d --- /dev/null +++ b/changelog.d/7278-barrier-arming-product-warnings.md @@ -0,0 +1,19 @@ +`Warnings (product)` has failed on every PR opened since #7250 landed. Two denied +warnings in the lazy-barrier-arming code: + +- `gc/mod.rs` re-exported `barrier_arming::*` as `pub(crate)`, but every item in + that module is `pub(super)` — narrower — so the glob re-exported nothing and + rustc said so. A plain `use` is what the in-module callers actually need. +- `remembered_reconstruct_census`'s only non-test caller is `telemetry.rs`'s + cycle-JSON emitter, which is itself `allow(dead_code)` without the + `diagnostics` feature, so a product build saw the function as unused. Now + carries the same `cfg_attr` as the three sibling sites in `telemetry.rs`. + +Neither was caught before merge because `main`'s last `Tests` run predates #7250, +so no run on `main` had ever compiled this code with `-D warnings`. + +Three further pre-existing denied warnings were blocking the same job family and +are fixed here too: a redundant `unsafe` wrapper in `pointer_publish_7154.rs` +(#7179), a dead initializer in `oldgen.rs` re-derived by its own loop (#7147), +and `reset_typeof_string_cache_for_test` (#7226), which has no callers anywhere +in the workspace. diff --git a/crates/perry-runtime/src/builtins/arithmetic.rs b/crates/perry-runtime/src/builtins/arithmetic.rs index cda3970325..56299f89ea 100644 --- a/crates/perry-runtime/src/builtins/arithmetic.rs +++ b/crates/perry-runtime/src/builtins/arithmetic.rs @@ -591,6 +591,10 @@ pub fn scan_typeof_string_roots_mut(visitor: &mut crate::gc::RuntimeRootVisitor< /// arenas between tests while thread-locals persist, so a cache entry from a /// previous test names memory the new arena does not own. #[cfg(test)] +// #7277: no callers anywhere in the workspace. Kept rather than deleted because +// it is the only handle on this cache's reset path, but it is dead today — if +// nothing adopts it, delete it rather than letting it rot behind this attribute. +#[allow(dead_code)] pub(crate) fn reset_typeof_string_cache_for_test() { for cache in [ &TYPEOF_UNDEFINED, diff --git a/crates/perry-runtime/src/gc/barrier_arming.rs b/crates/perry-runtime/src/gc/barrier_arming.rs index 8904f28c2e..16dda2f84d 100644 --- a/crates/perry-runtime/src/gc/barrier_arming.rs +++ b/crates/perry-runtime/src/gc/barrier_arming.rs @@ -115,6 +115,11 @@ thread_local! { static TEST_ARMED_OVERRIDE: Cell> = const { Cell::new(None) }; } +// #7277: the only non-test caller is `telemetry.rs`'s cycle-JSON emitter, +// which is itself `allow(dead_code)` without the `diagnostics` feature — so a +// product build (`cargo check -p perry --bins`, `-D warnings`) sees this as +// unused. Same `cfg_attr` the three sibling sites in `telemetry.rs` use. +#[cfg_attr(not(feature = "diagnostics"), allow(dead_code))] pub(super) fn remembered_reconstruct_census() -> RememberedReconstructCensus { RECONSTRUCT_CENSUS.with(Cell::get) } diff --git a/crates/perry-runtime/src/gc/mod.rs b/crates/perry-runtime/src/gc/mod.rs index 17b9f68c4d..8bc22cba0f 100644 --- a/crates/perry-runtime/src/gc/mod.rs +++ b/crates/perry-runtime/src/gc/mod.rs @@ -67,7 +67,11 @@ pub(crate) use trace::*; mod barrier; pub use barrier::*; mod barrier_arming; -pub(crate) use barrier_arming::*; +// #7277: every item in `barrier_arming` is `pub(super)` (i.e. `pub(in gc)`), +// which is narrower than `pub(crate)` — so the glob re-exported nothing and +// rustc warned. A plain `use` brings them into `gc`'s namespace, which is all +// the in-module callers (`telemetry.rs`, `cycle.rs`) actually need. +use barrier_arming::*; mod copying; use copying::*; // The copied-minor pointer classifier is consumed by the weak-holder registry diff --git a/crates/perry-runtime/src/gc/tests/copying/pointer_publish_7154.rs b/crates/perry-runtime/src/gc/tests/copying/pointer_publish_7154.rs index ca8511ee9f..6fdd5f7a57 100644 --- a/crates/perry-runtime/src/gc/tests/copying/pointer_publish_7154.rs +++ b/crates/perry-runtime/src/gc/tests/copying/pointer_publish_7154.rs @@ -228,23 +228,22 @@ fn test_weakmap_overwrite_value_is_traced_7154() { /// map's entries array the same way `js_weakmap_get` does. fn weak_entry_addr_for(map: f64, key: f64) -> usize { let map_ptr = (map.to_bits() & POINTER_MASK) as *mut crate::ObjectHeader; - unsafe { - let entries = crate::object::js_object_get_field(map_ptr, 0); - let entries_ptr = (entries.bits() & POINTER_MASK) as *mut crate::array::ArrayHeader; - let len = crate::array::js_array_length(entries_ptr) as usize; - for i in 0..len { - let entry_val = crate::array::js_array_get(entries_ptr, i as u32); - let entry = (entry_val.bits() & POINTER_MASK) as *mut crate::ObjectHeader; - if entry.is_null() { - continue; - } - let stored_key = crate::object::js_object_get_field(entry, 0); - if stored_key.bits() == key.to_bits() { - return entry as usize; - } + // #7277: the calls below are safe fns; the wrapper was redundant. + let entries = crate::object::js_object_get_field(map_ptr, 0); + let entries_ptr = (entries.bits() & POINTER_MASK) as *mut crate::array::ArrayHeader; + let len = crate::array::js_array_length(entries_ptr) as usize; + for i in 0..len { + let entry_val = crate::array::js_array_get(entries_ptr, i as u32); + let entry = (entry_val.bits() & POINTER_MASK) as *mut crate::ObjectHeader; + if entry.is_null() { + continue; + } + let stored_key = crate::object::js_object_get_field(entry, 0); + if stored_key.bits() == key.to_bits() { + return entry as usize; } - 0 } + 0 } /// A freshly allocated closure's capture slots must read as a non-pointer diff --git a/crates/perry-runtime/src/gc/tests/oldgen.rs b/crates/perry-runtime/src/gc/tests/oldgen.rs index 5a96b33d85..f7ac390794 100644 --- a/crates/perry-runtime/src/gc/tests/oldgen.rs +++ b/crates/perry-runtime/src/gc/tests/oldgen.rs @@ -1185,7 +1185,10 @@ fn test_minor_preserves_old_to_young_edge_across_minors() { // Re-derived from the parent's slot after every minor (see the loop), so // both are `mut`: a relocating minor moves the child. let mut child = crate::arena::arena_alloc_gc(40, 8, GC_TYPE_OBJECT) as usize; - let mut child_header = unsafe { header_from_user_ptr(child as *const u8) }; + // #7277: no initializer — the loop below re-derives this from the parent's + // slot after every minor (a relocating minor moves the child), so the + // initial value was never read. + let mut child_header; assert!(crate::arena::pointer_in_nursery(child)); unsafe { *fields = ptr_bits(child);