[ty] Reuse exception checkpoints when a new place is read (#29750)

## Summary

Cold CLI checks of Home Assistant’s KNX integration took 14% less time,
and checks of its Reolink integration took 4.5% less time. Each row
averages 12 paired runs of `ty check
homeassistant/components/<integration>` with the project’s dependencies
installed. Both integrations emitted the same diagnostics before and
after.

| Integration | Before | After |
| --- | ---: | ---: |
| KNX | 389.5 ms | 334.9 ms |
| Reolink | 396.0 ms | 378.1 ms |

The KNX decoder has a long sequence of branches inside a `try` block.
Reading a name like `GroupValueRead` for the first time used to trigger
another snapshot of the bindings visible to the exception handler.
Restoring an earlier snapshot already gives that name the same undefined
state. We now leave the checkpoint’s binding revision alone on that
first read and advance it when the place gets a definition.

In isolation, a cold CLI check importing the original
`xknx.APCI.from_knx` body went from 84.5 ms to 36.4 ms (57%). For
`reolink_aio.Host.map_channel_json_response`, it went from 41.9 ms to
32.4 ms (23%).
This commit is contained in:
Charlie Marsh authored and GitHub committed 2026-10-26 21:48:18 -07:00
1 parent 18c5d27c41
commit 8aeb8e2ebc
1 file changed
+2 -1
+2 -1
View File
@@ -2193,7 +2193,8 @@ impl<'db> UseDefMapBuilder<'db> {
}
pub(super) fn add_place(&mut self, place: ScopedPlaceId) {
self.checkpoint_state.record_binding_change();
// Earlier snapshots restore new places as undefined. The first definition
// changes the bindings visible to an exception handler.
match place {
ScopedPlaceId::Symbol(symbol) => {
let new_place = self.symbol_states.push(PendingPlaceState::new(