Fix `Interner::with_capacity` for default keys (#13092)

The new method did not account for allocating the default key, causing
code that then tried to use it to panic.
This commit is contained in:
Jake Lishman 2024-09-05 12:51:06 +01:00 committed by GitHub
parent 52733ae09f
commit 86c63eb3d7
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
1 changed files with 26 additions and 7 deletions

View File

@ -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::<str>::with_capacity(4);
assert_eq!(capacity.get_default(), capacity.get_default());
assert_eq!(capacity.get(capacity.get_default()), "");
}
}