Make capacity() methods not rely on Array::CAPACITY (#83)

* Make capacity() methods not rely on Array::CAPACITY

Because Array isn't an unsafe trait, unsafe code cannot depend on the
length of a slice produced by Array::as_slice to be at least as long as
Array::CAPACITY. This means that unsafe code also cannot depend on
capacity() methods that return Array::CAPACITY. Returning the result of
a slice len() call ensures that if nothing else, with a sound
implementation of Array, capacity() methods will return a valid length
for a sub-slice of the backing array.

* Add comments explaining choice against using Array::CAPACITY
This commit is contained in:
Benjamin Scherer
2020-07-15 21:02:26 -06:00
committed by GitHub
parent 99598c1cda
commit 478a8a0124
2 changed files with 6 additions and 2 deletions
+4 -1
View File
@@ -194,7 +194,10 @@ impl<A: Array> ArrayVec<A> {
#[inline(always)]
#[must_use]
pub fn capacity(&self) -> usize {
A::CAPACITY
// Note: This shouldn't use A::CAPACITY, because unsafe code can't rely on
// any Array invariants. This ensures that at the very least, the returned
// value is a valid length for a subslice of the backing array.
self.data.as_slice().len()
}
/// Truncates the `ArrayVec` down to length 0.
+2 -1
View File
@@ -212,7 +212,8 @@ impl<A: Array> TinyVec<A> {
#[must_use]
pub fn capacity(&self) -> usize {
match self {
TinyVec::Inline(_) => A::CAPACITY,
// Note: this shouldn't use A::CAPACITY. See ArrayVec::capacity().
TinyVec::Inline(v) => v.capacity(),
TinyVec::Heap(v) => v.capacity(),
}
}