Implementing Deref in PrimaryMap turns out to be error-prone, so remove it.

One of the big advantages of PrimaryMap is that it protects against
using the wrong indices via a distinct index type. A Deref trait that
returns a plain slice would accept other indices. Add a comment
explaining this.
This commit is contained in:
Dan Gohman
2018-08-28 20:51:15 -07:00
parent c836a96e30
commit 67b7a8594a

View File

@@ -1,6 +1,6 @@
//! Densely numbered entity references as mapping keys. //! Densely numbered entity references as mapping keys.
use std::marker::PhantomData; use std::marker::PhantomData;
use std::ops::{Deref, DerefMut, Index, IndexMut}; use std::ops::{Index, IndexMut};
use std::slice; use std::slice;
use std::vec::Vec; use std::vec::Vec;
use {EntityRef, Iter, IterMut, Keys}; use {EntityRef, Iter, IterMut, Keys};
@@ -14,6 +14,11 @@ use {EntityRef, Iter, IterMut, Keys};
/// ///
/// There should only be a single `PrimaryMap` instance for a given `EntityRef` type, otherwise /// There should only be a single `PrimaryMap` instance for a given `EntityRef` type, otherwise
/// conflicting references will be created. Using unknown keys for indexing will cause a panic. /// conflicting references will be created. Using unknown keys for indexing will cause a panic.
///
/// Note that `PrimaryMap` doesn't implement `Deref` or `DerefMut`, which would allow
/// `&PrimaryMap<K, V>` to convert to `&[V]`. One of the main advantages of `PrimaryMap` is
/// that it only allows indexing with the distinct `EntityRef` key type, so converting to a
/// plain slice would make it easier to use incorrectly.
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct PrimaryMap<K, V> pub struct PrimaryMap<K, V>
where where
@@ -145,26 +150,6 @@ where
} }
} }
impl<K, V> Deref for PrimaryMap<K, V>
where
K: EntityRef,
{
type Target = [V];
fn deref(&self) -> &Self::Target {
&self.elems
}
}
impl<K, V> DerefMut for PrimaryMap<K, V>
where
K: EntityRef,
{
fn deref_mut(&mut self) -> &mut [V] {
&mut self.elems
}
}
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::*; use super::*;
@@ -341,13 +326,4 @@ mod tests {
} }
} }
} }
#[test]
fn deref() {
let mut m = PrimaryMap::<E, isize>::new();
let _: &[isize] = m.as_ref();
let _: &mut [isize] = m.as_mut();
let _: &[isize] = &m;
let _: &mut [isize] = &mut m;
}
} }