rust-dirstate: panic if the DirstateMap counters go below 0 stable
authorRaphaël Gomès <rgomes@octobus.net>
Tue, 05 Apr 2022 10:55:28 +0200
branchstable
changeset 49001 2593873cda0f
parent 49000 dd6b67d5c256
child 49002 fbc02ccc207e
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
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);