]> git.lizzy.rs Git - rust.git/commitdiff
Rollup merge of #89162 - petrochenkov:ivmap, r=davidtwco
authorthe8472 <the8472@users.noreply.github.com>
Wed, 22 Sep 2021 17:03:25 +0000 (19:03 +0200)
committerGitHub <noreply@github.com>
Wed, 22 Sep 2021 17:03:25 +0000 (19:03 +0200)
rustc_index: Add some map-like APIs to `IndexVec`

`IndexVec` is often used as a map, but its map APIs are lacking.
This PR adds a couple of useful methods.

compiler/rustc_ast_lowering/src/item.rs
compiler/rustc_ast_lowering/src/lib.rs
compiler/rustc_index/src/bit_set.rs
compiler/rustc_index/src/vec.rs

index 25e6fed68b566fcf5192cd88d81ea488d9a7fa5e..9f879494d7374ff574afb02f34f18597744cb89b 100644 (file)
@@ -474,9 +474,10 @@ fn lower_use_tree(
                         res
                     } else {
                         // Associate an HirId to both ids even if there is no resolution.
-                        self.node_id_to_hir_id.ensure_contains_elem(new_node_id, || None);
-                        debug_assert!(self.node_id_to_hir_id[new_node_id].is_none());
-                        self.node_id_to_hir_id[new_node_id] = Some(hir::HirId::make_owner(new_id));
+                        let _old = self
+                            .node_id_to_hir_id
+                            .insert(new_node_id, hir::HirId::make_owner(new_id));
+                        debug_assert!(_old.is_none());
                         continue;
                     };
                     let ident = *ident;
index 5ec060f654090b5297dbafac9ae91fe14617acf7..3c75089a760f32fb9cc74c78391d8b32cc7fabac 100644 (file)
@@ -469,11 +469,8 @@ fn with_hir_id_owner(
         let def_id = self.resolver.local_def_id(owner);
 
         // Always allocate the first `HirId` for the owner itself.
-        self.node_id_to_hir_id.ensure_contains_elem(owner, || None);
-        if let Some(_lowered) = self.node_id_to_hir_id[owner] {
-            panic!("with_hir_id_owner must not be called multiple times on owner {:?}", def_id);
-        }
-        self.node_id_to_hir_id[owner] = Some(hir::HirId::make_owner(def_id));
+        let _old = self.node_id_to_hir_id.insert(owner, hir::HirId::make_owner(def_id));
+        debug_assert_eq!(_old, None);
 
         let current_owner = std::mem::replace(&mut self.current_hir_id_owner, def_id);
         let current_local_counter =
@@ -484,8 +481,8 @@ fn with_hir_id_owner(
         self.current_hir_id_owner = current_owner;
         self.item_local_id_counter = current_local_counter;
 
-        self.owners.ensure_contains_elem(def_id, || None);
-        self.owners[def_id] = Some(item);
+        let _old = self.owners.insert(def_id, item);
+        debug_assert!(_old.is_none());
 
         def_id
     }
@@ -499,18 +496,13 @@ fn with_hir_id_owner(
     fn lower_node_id(&mut self, ast_node_id: NodeId) -> hir::HirId {
         assert_ne!(ast_node_id, DUMMY_NODE_ID);
 
-        self.node_id_to_hir_id.ensure_contains_elem(ast_node_id, || None);
-        if let Some(existing_hir_id) = self.node_id_to_hir_id[ast_node_id] {
-            existing_hir_id
-        } else {
+        *self.node_id_to_hir_id.get_or_insert_with(ast_node_id, || {
             // Generate a new `HirId`.
             let owner = self.current_hir_id_owner;
             let local_id = self.item_local_id_counter;
             self.item_local_id_counter.increment_by(1);
-            let hir_id = hir::HirId { owner, local_id };
-            self.node_id_to_hir_id[ast_node_id] = Some(hir_id);
-            hir_id
-        }
+            hir::HirId { owner, local_id }
+        })
     }
 
     fn next_id(&mut self) -> hir::HirId {
index aeb3f9970ab9e6a0cda3cb926d1dc54117c30818..5b1add4cfc6117c65baf25e3da754f4699c237a8 100644 (file)
@@ -1072,13 +1072,9 @@ pub fn new(num_columns: usize) -> Self {
     }
 
     fn ensure_row(&mut self, row: R) -> &mut HybridBitSet<C> {
-        // Instantiate any missing rows up to and including row `row` with an
-        // empty HybridBitSet.
-        self.rows.ensure_contains_elem(row, || None);
-
+        // Instantiate any missing rows up to and including row `row` with an empty HybridBitSet.
         // Then replace row `row` with a full HybridBitSet if necessary.
-        let num_columns = self.num_columns;
-        self.rows[row].get_or_insert_with(|| HybridBitSet::new_empty(num_columns))
+        self.rows.get_or_insert_with(row, || HybridBitSet::new_empty(self.num_columns))
     }
 
     /// Sets the cell at `(row, column)` to true. Put another way, insert
index 246fa28d986e5b59c52a613a5d1ef14235cfd595..8535a7c866d96bb255a9565cf4195b1c46161778 100644 (file)
@@ -720,6 +720,21 @@ pub fn resize_to_elem(&mut self, elem: I, fill_value: impl FnMut() -> T) {
     }
 }
 
+/// `IndexVec` is often used as a map, so it provides some map-like APIs.
+impl<I: Idx, T> IndexVec<I, Option<T>> {
+    #[inline]
+    pub fn insert(&mut self, index: I, value: T) -> Option<T> {
+        self.ensure_contains_elem(index, || None);
+        self[index].replace(value)
+    }
+
+    #[inline]
+    pub fn get_or_insert_with(&mut self, index: I, value: impl FnOnce() -> T) -> &mut T {
+        self.ensure_contains_elem(index, || None);
+        self[index].get_or_insert_with(value)
+    }
+}
+
 impl<I: Idx, T: Clone> IndexVec<I, T> {
     #[inline]
     pub fn resize(&mut self, new_len: usize, value: T) {