# HG changeset patch # User Raphaël Gomès # Date 1649148928 -7200 # Node ID 2593873cda0f41fdf8e905b49a5a763d9a67788f # Parent dd6b67d5c2569e99a15f7a47f1d060a09b3b330e rust-dirstate: panic if the DirstateMap counters go below 0 When modifying the API I hit some... interesting errors (trying to allocate 178GB of RAM, for example) because I failed to keep the counters correctly updated. This counter underflow is likely to happen when code is changed around and can have up to eat-your-dirstate level of consequences, which is not nice. The very small runtime cost of checking these counters should really not be an issue and will help us uncover bugs when/if they do appear in the future. Differential Revision: https://phab.mercurial-scm.org/D12430 diff -r dd6b67d5c256 -r 2593873cda0f rust/hg-core/src/dirstate_tree/dirstate_map.rs --- a/rust/hg-core/src/dirstate_tree/dirstate_map.rs Tue Apr 05 10:55:28 2022 +0200 +++ b/rust/hg-core/src/dirstate_tree/dirstate_map.rs Tue Apr 05 10:55:28 2022 +0200 @@ -831,10 +831,20 @@ )? { dropped = d; if dropped.had_entry { - node.descendants_with_entry_count -= 1; + node.descendants_with_entry_count = node + .descendants_with_entry_count + .checked_sub(1) + .expect( + "descendants_with_entry_count should be >= 0", + ); } if dropped.was_tracked { - node.tracked_descendants_count -= 1; + node.tracked_descendants_count = node + .tracked_descendants_count + .checked_sub(1) + .expect( + "tracked_descendants_count should be >= 0", + ); } // Directory caches must be invalidated when removing a @@ -889,10 +899,16 @@ filename, )? { if dropped.had_entry { - map.nodes_with_entry_count -= 1 + map.nodes_with_entry_count = map + .nodes_with_entry_count + .checked_sub(1) + .expect("nodes_with_entry_count should be >= 0"); } if dropped.had_copy_source { - map.nodes_with_copy_source_count -= 1 + map.nodes_with_copy_source_count = map + .nodes_with_copy_source_count + .checked_sub(1) + .expect("nodes_with_copy_source_count should be >= 0"); } } else { debug_assert!(!was_tracked);