Skip to content

Commit

Permalink
fix: panic in Storage::get (#2657)
Browse files Browse the repository at this point in the history
* fix: don't panic on invalid id in Storage::get

* formatting

* removed double matches

* more match removal

* fix formatting

* add fix to Storage::label_for_invalid_id
  • Loading branch information
SparkyPotato authored May 14, 2022
1 parent 284ed46 commit 75b881e
Showing 1 changed file with 17 additions and 14 deletions.
31 changes: 17 additions & 14 deletions wgpu-core/src/hub.rs
Original file line number Diff line number Diff line change
Expand Up @@ -149,22 +149,24 @@ impl<T, I: id::TypedId> ops::IndexMut<id::Valid<I>> for Storage<T, I> {
impl<T, I: id::TypedId> Storage<T, I> {
pub(crate) fn contains(&self, id: I) -> bool {
let (index, epoch, _) = id.unzip();
match self.map[index as usize] {
Element::Vacant => false,
Element::Occupied(_, storage_epoch) | Element::Error(storage_epoch, ..) => {
epoch == storage_epoch
match self.map.get(index as usize) {
Some(&Element::Vacant) => false,
Some(&Element::Occupied(_, storage_epoch) | &Element::Error(storage_epoch, _)) => {
storage_epoch == epoch
}
None => false,
}
}

/// Get a reference to an item behind a potentially invalid ID.
/// Panics if there is an epoch mismatch, or the entry is empty.
pub(crate) fn get(&self, id: I) -> Result<&T, InvalidId> {
let (index, epoch, _) = id.unzip();
let (result, storage_epoch) = match self.map[index as usize] {
Element::Occupied(ref v, epoch) => (Ok(v), epoch),
Element::Vacant => panic!("{}[{}] does not exist", self.kind, index),
Element::Error(epoch, ..) => (Err(InvalidId), epoch),
let (result, storage_epoch) = match self.map.get(index as usize) {
Some(&Element::Occupied(ref v, epoch)) => (Ok(v), epoch),
Some(&Element::Vacant) => panic!("{}[{}] does not exist", self.kind, index),
Some(&Element::Error(epoch, ..)) => (Err(InvalidId), epoch),
None => return Err(InvalidId),
};
assert_eq!(
epoch, storage_epoch,
Expand All @@ -178,10 +180,11 @@ impl<T, I: id::TypedId> Storage<T, I> {
/// Panics if there is an epoch mismatch, or the entry is empty.
pub(crate) fn get_mut(&mut self, id: I) -> Result<&mut T, InvalidId> {
let (index, epoch, _) = id.unzip();
let (result, storage_epoch) = match self.map[index as usize] {
Element::Occupied(ref mut v, epoch) => (Ok(v), epoch),
Element::Vacant => panic!("{}[{}] does not exist", self.kind, index),
Element::Error(epoch, ..) => (Err(InvalidId), epoch),
let (result, storage_epoch) = match self.map.get_mut(index as usize) {
Some(&mut Element::Occupied(ref mut v, epoch)) => (Ok(v), epoch),
Some(&mut Element::Vacant) => panic!("{}[{}] does not exist", self.kind, index),
Some(&mut Element::Error(epoch, ..)) => (Err(InvalidId), epoch),
None => return Err(InvalidId),
};
assert_eq!(
epoch, storage_epoch,
Expand All @@ -193,8 +196,8 @@ impl<T, I: id::TypedId> Storage<T, I> {

pub(crate) fn label_for_invalid_id(&self, id: I) -> &str {
let (index, _, _) = id.unzip();
match self.map[index as usize] {
Element::Error(_, ref label) => label,
match self.map.get(index as usize) {
Some(&Element::Error(_, ref label)) => label,
_ => "",
}
}
Expand Down

0 comments on commit 75b881e

Please sign in to comment.