From 74a1f918f2cc8972afe0b64859a518b859de1104 Mon Sep 17 00:00:00 2001 From: Jake Lishman Date: Thu, 5 Sep 2024 11:24:17 +0100 Subject: [PATCH] Fix `Interner::with_capacity` for default keys The new method did not account for allocating the default key, causing code that then tried to use it to panic. --- crates/circuit/src/interner.rs | 33 ++++++++++++++++++++++++++------- 1 file changed, 26 insertions(+), 7 deletions(-) diff --git a/crates/circuit/src/interner.rs b/crates/circuit/src/interner.rs index a8ac269b1a18..a72efb037afb 100644 --- a/crates/circuit/src/interner.rs +++ b/crates/circuit/src/interner.rs @@ -105,9 +105,7 @@ where /// `Interner::get_default` to reliably work correctly without a hash lookup (though ideally /// we'd just use specialisation to do that). pub fn new() -> Self { - let mut set = IndexSet::with_capacity_and_hasher(1, Default::default()); - set.insert(Default::default()); - Self(set) + Self::with_capacity(1) } /// Retrieve the key corresponding to the default store, without any hash or equality lookup. @@ -126,11 +124,14 @@ where } } + /// Create an interner with enough space to hold `capacity` entries. + /// + /// Note that the default item of the interner is always allocated and given a key immediately, + /// which will use one slot of the capacity. pub fn with_capacity(capacity: usize) -> Self { - Self(IndexSet::with_capacity_and_hasher( - capacity, - ::ahash::RandomState::new(), - )) + let mut set = IndexSet::with_capacity_and_hasher(capacity, ::ahash::RandomState::new()); + set.insert(Default::default()); + Self(set) } } @@ -196,3 +197,21 @@ where } } } + +#[cfg(test)] +mod test { + use super::*; + + #[test] + fn default_key_exists() { + let mut interner = Interner::<[u32]>::new(); + assert_eq!(interner.get_default(), interner.get_default()); + assert_eq!(interner.get(interner.get_default()), &[]); + assert_eq!(interner.insert_owned(Vec::new()), interner.get_default()); + assert_eq!(interner.insert(&[]), interner.get_default()); + + let capacity = Interner::::with_capacity(4); + assert_eq!(capacity.get_default(), capacity.get_default()); + assert_eq!(capacity.get(capacity.get_default()), ""); + } +}