Stale `paint_children` / hoisted children cause `hit_inner` panic after `remove_and_drop_node`
- Dominant language
- Rust
- Stars
- 4.1k
- Forks
- 203
- Avg merge
- 8h 58m
- Merged PRs (30d)
- 112
Description
# Stale `paint_children` / hoisted children cause `hit_inner` panic after `remove_and_drop_node`
## Problem
`DocumentMutator::remove_and_drop_node` updates `parent.children` (line 516: `retain`), but does not clean up the derived `paint_children` list or `stacking_context` hoisted children lists. These are only rebuilt during the next `resolve()` pass.
If a hit test runs between `remove_and_drop_node` and the next `resolve()`, `Node::hit_inner` iterates these stale lists and calls `self.with(stale_id)`, which does `tree().get(id).unwrap()` and panics.
## Affected call sites
Three places in `hit_inner` (`node.rs`):
| Line | List | Path |
|------|------|------|
| 1271 | `paint_children` | child traversal |
| 1260 | `pos_z_hoisted_children` | positive z-index hoisted children |
| 1283 | `neg_z_hoisted_children` | negative z-index hoisted children |
## Reproduction
Tests in `tests/blitz-tests/tests/hit_test_after_remove_node.rs`:
1. Build a DOM with child elements (with/without z-index)
2. `pump()` to build `paint_children` and hoisted children lists
3. `remove_and_drop_node` on a child (without pumping)
4. `hit()` in the area where the removed child used to be
5. Panic at `self.tree().get(id).unwrap()`
## Root cause
`paint_children` and hoisted children are **derived data** built during `resolve()`. `remove_and_drop_node` updates the DOM tree (`children` / `parent`) but not these derived lists. Between removal and the next `resolve()`, the lists contain stale NodeIds pointing to dropped nodes.
Contributor guide
Research direction
Start with DocumentMutator::remove_and_drop_node and the three stale-list paths in node.rs::hit_inner. Run tests/blitz-tests/tests/hit_test_after_remove_node.rs and reproduce removal followed by hit() without pump(). Done means the affected hit tests no longer panic after removing children, including children with and without z-index.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- frontend, web-dev
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Quiet
- Clarity
- Clearly specified
- Newbie friendliness
- 72/100