Bug 1613006 - Update smallvec. r=heycam

Differential Revision: https://phabricator.services.mozilla.com/D61513

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Emilio Cobos Álvarez 2020-02-06 23:33:31 +00:00
parent e3a676c7fc
commit 11e346a675
6 changed files with 175 additions and 82 deletions

32
Cargo.lock generated
View File

@ -205,7 +205,7 @@ dependencies = [
"cranelift-wasm",
"env_logger",
"log",
"smallvec 1.0.0",
"smallvec 1.2.0",
]
[[package]]
@ -715,7 +715,7 @@ dependencies = [
"cranelift-codegen-shared",
"cranelift-entity 0.56.0",
"log",
"smallvec 1.0.0",
"smallvec 1.2.0",
"target-lexicon 0.10.0",
"thiserror",
]
@ -751,7 +751,7 @@ source = "git+https://github.com/bytecodealliance/cranelift?rev=eb20fcab349ce20a
dependencies = [
"cranelift-codegen",
"log",
"smallvec 1.0.0",
"smallvec 1.2.0",
"target-lexicon 0.10.0",
]
@ -844,7 +844,7 @@ dependencies = [
"phf",
"proc-macro2",
"quote",
"smallvec 1.0.0",
"smallvec 1.2.0",
"syn",
]
@ -1217,7 +1217,7 @@ name = "fallible"
version = "0.0.1"
dependencies = [
"hashglobe",
"smallvec 1.0.0",
"smallvec 1.2.0",
]
[[package]]
@ -1408,7 +1408,7 @@ dependencies = [
"parking_lot",
"selectors",
"servo_arc",
"smallvec 1.0.0",
"smallvec 1.2.0",
"style",
"style_traits",
"to_shmem",
@ -2221,7 +2221,7 @@ dependencies = [
"selectors",
"servo_arc",
"smallbitvec",
"smallvec 1.0.0",
"smallvec 1.2.0",
"thin-slice",
"void",
]
@ -2601,7 +2601,7 @@ dependencies = [
"neqo-qpack",
"neqo-transport",
"num-traits",
"smallvec 1.0.0",
"smallvec 1.2.0",
]
[[package]]
@ -2625,7 +2625,7 @@ dependencies = [
"neqo-common",
"neqo-crypto",
"rand",
"smallvec 1.0.0",
"smallvec 1.2.0",
]
[[package]]
@ -3620,7 +3620,7 @@ dependencies = [
"phf_codegen",
"precomputed-hash",
"servo_arc",
"smallvec 1.0.0",
"smallvec 1.2.0",
"thin-slice",
"to_shmem",
"to_shmem_derive",
@ -3817,9 +3817,9 @@ dependencies = [
[[package]]
name = "smallvec"
version = "1.0.0"
version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4ecf3b85f68e8abaa7555aa5abdb1153079387e60b718283d732f03897fcfc86"
checksum = "5c2fb2ec9bcd216a5b0d0ccf31ab17b5ed1d627960edff65bbe95d3ce221cefc"
[[package]]
name = "socket2"
@ -3941,7 +3941,7 @@ dependencies = [
"serde",
"servo_arc",
"smallbitvec",
"smallvec 1.0.0",
"smallvec 1.2.0",
"static_prefs",
"style_derive",
"style_traits",
@ -4002,7 +4002,7 @@ dependencies = [
"num-traits",
"selectors",
"size_of_test",
"smallvec 1.0.0",
"smallvec 1.2.0",
"style",
"style_traits",
"to_shmem",
@ -4184,7 +4184,7 @@ dependencies = [
"cssparser",
"servo_arc",
"smallbitvec",
"smallvec 1.0.0",
"smallvec 1.2.0",
"thin-slice",
]
@ -4730,7 +4730,7 @@ dependencies = [
"peek-poke 0.2.0 (git+https://github.com/kvark/peek-poke?rev=969bd7fe2be1a83f87916dc8b388c63cfd457075)",
"rendy-descriptor",
"rendy-memory",
"smallvec 1.0.0",
"smallvec 1.2.0",
"vec_map",
]

View File

@ -1 +1 @@
{"files":{"Cargo.toml":"a0b3c2e96922c85896116d470c1e5cd67a1c8165c0f8f78d3e719d3c74c6e4d7","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"0b28172679e0009b655da42797c03fd163a3379d5cfa67ba1f1655e974a2a1a9","README.md":"38eef4ebde6fe6effa12a2dbca3bd69d6446b2935f19a329ac4926f1cb2e5013","benches/bench.rs":"9dca7122a3dcb2c099e49807e4d3b8f01d9220e2b3db0a54e9901ee74392866f","lib.rs":"0bf36124f10391d44b6afa228fb77dfadb7376da8108c0dc064d01b1adbe7fad","scripts/run_miri.sh":"cd645dfecf19cc77141ecaf698e58a3a743ad69aca5e5d25c8e5d3911e031322","specialization.rs":"46433586203399251cba496d67b88d34e1be3c2b591986b77463513da1c66471"},"package":"4ecf3b85f68e8abaa7555aa5abdb1153079387e60b718283d732f03897fcfc86"}
{"files":{"Cargo.toml":"82c58cfe1208040b0772a4eb0fc59c2f84c75dd28115f2847a6edc91a340b7f4","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"0b28172679e0009b655da42797c03fd163a3379d5cfa67ba1f1655e974a2a1a9","README.md":"a01127c37308457e8d396b176fb790846be0978c173be3f13260b62efcef011b","benches/bench.rs":"9dca7122a3dcb2c099e49807e4d3b8f01d9220e2b3db0a54e9901ee74392866f","lib.rs":"6b128fc5aa50b5dd775d45252e277c13546f1de2ebee340c6c8ff48627678244","scripts/run_miri.sh":"2e83d153efc16cbc3c41589e306faa0624c8b9a0feecea3baae6e34f4563ac42","specialization.rs":"46433586203399251cba496d67b88d34e1be3c2b591986b77463513da1c66471"},"package":"5c2fb2ec9bcd216a5b0d0ccf31ab17b5ed1d627960edff65bbe95d3ce221cefc"}

View File

@ -13,10 +13,10 @@
[package]
edition = "2018"
name = "smallvec"
version = "1.0.0"
version = "1.2.0"
authors = ["Simon Sapin <simon.sapin@exyr.org>"]
description = "'Small vector' optimization: store up to a small number of items on the stack"
documentation = "https://doc.servo.org/smallvec/"
documentation = "https://docs.rs/smallvec/"
readme = "README.md"
keywords = ["small", "vec", "vector", "stack", "no_std"]
categories = ["data-structures"]

View File

@ -6,3 +6,21 @@ rust-smallvec
[Release notes](https://github.com/servo/rust-smallvec/releases)
"Small vector" optimization for Rust: store up to a small number of items on the stack
## Example
```rust
use smallvec::{SmallVec, smallvec};
// This SmallVec can hold up to 4 items on the stack:
let mut v: SmallVec<[i32; 4]> = smallvec![1, 2, 3, 4];
// It will automatically move its contents to the heap if
// contains more than four items:
v.push(5);
// SmallVec points to a slice, so you can use normal slice
// indexing and other methods to access its contents:
v[0] = v[1] + v[2];
v.sort();
```

View File

@ -14,9 +14,6 @@
//! `write` feature implements the `std::io::Write` trait for vectors of `u8`.
//! When this feature is enabled, `smallvec` depends on `std`.
//!
//! To depend on `smallvec` without `libstd`, use `default-features = false` in the `smallvec`
//! section of Cargo.toml to disable its `"std"` feature.
//!
//! ## `union` feature
//!
//! When the `union` feature is enabled `smallvec` will track its state (inline or spilled)
@ -34,13 +31,14 @@
#![cfg_attr(feature = "may_dangle", feature(dropck_eyepatch))]
#![deny(missing_docs)]
#[macro_use]
extern crate alloc;
#[doc(hidden)]
pub extern crate alloc;
#[cfg(any(test, feature = "write"))]
extern crate std;
use alloc::vec::Vec;
use alloc::boxed::Box;
use alloc::{vec, vec::Vec};
use core::borrow::{Borrow, BorrowMut};
use core::cmp;
use core::fmt;
@ -118,7 +116,7 @@ macro_rules! smallvec {
$(vec.push($x);)*
vec
} else {
$crate::SmallVec::from_vec(vec![$($x,)*])
$crate::SmallVec::from_vec($crate::alloc::vec![$($x,)*])
}
});
}
@ -256,7 +254,7 @@ impl<'a, T: 'a + Array> Drop for Drain<'a, T> {
#[cfg(feature = "union")]
union SmallVecData<A: Array> {
inline: MaybeUninit<A>,
heap: (NonNull<A::Item>, usize),
heap: (*mut A::Item, usize),
}
#[cfg(feature = "union")]
@ -279,24 +277,22 @@ impl<A: Array> SmallVecData<A> {
}
#[inline]
unsafe fn heap(&self) -> (*mut A::Item, usize) {
(self.heap.0.as_ptr(), self.heap.1)
self.heap
}
#[inline]
unsafe fn heap_mut(&mut self) -> (*mut A::Item, &mut usize) {
(self.heap.0.as_ptr(), &mut self.heap.1)
unsafe fn heap_mut(&mut self) -> &mut (*mut A::Item, usize) {
&mut self.heap
}
#[inline]
fn from_heap(ptr: *mut A::Item, len: usize) -> SmallVecData<A> {
SmallVecData {
heap: (NonNull::new(ptr).unwrap(), len),
}
SmallVecData { heap: (ptr, len) }
}
}
#[cfg(not(feature = "union"))]
enum SmallVecData<A: Array> {
Inline(MaybeUninit<A>),
Heap((NonNull<A::Item>, usize)),
Heap((*mut A::Item, usize)),
}
#[cfg(not(feature = "union"))]
@ -329,20 +325,20 @@ impl<A: Array> SmallVecData<A> {
#[inline]
unsafe fn heap(&self) -> (*mut A::Item, usize) {
match self {
SmallVecData::Heap(data) => (data.0.as_ptr(), data.1),
SmallVecData::Heap(data) => *data,
_ => debug_unreachable!(),
}
}
#[inline]
unsafe fn heap_mut(&mut self) -> (*mut A::Item, &mut usize) {
unsafe fn heap_mut(&mut self) -> &mut (*mut A::Item, usize) {
match self {
SmallVecData::Heap(data) => (data.0.as_ptr(), &mut data.1),
SmallVecData::Heap(data) => data,
_ => debug_unreachable!(),
}
}
#[inline]
fn from_heap(ptr: *mut A::Item, len: usize) -> SmallVecData<A> {
SmallVecData::Heap((NonNull::new(ptr).unwrap(), len))
SmallVecData::Heap((ptr, len))
}
}
@ -569,7 +565,7 @@ impl<A: Array> SmallVec<A> {
fn triple_mut(&mut self) -> (*mut A::Item, &mut usize, usize) {
unsafe {
if self.spilled() {
let (ptr, len_ptr) = self.data.heap_mut();
let &mut (ptr, ref mut len_ptr) = self.data.heap_mut();
(ptr, len_ptr, self.capacity)
} else {
(self.data.inline_mut(), &mut self.capacity, A::size())
@ -641,7 +637,7 @@ impl<A: Array> SmallVec<A> {
}
let (ptr, len_ptr, _) = self.triple_mut();
*len_ptr = len + 1;
ptr::write(ptr.offset(len as isize), value);
ptr::write(ptr.add(len), value);
}
}
@ -655,7 +651,7 @@ impl<A: Array> SmallVec<A> {
}
let last_index = *len_ptr - 1;
*len_ptr = last_index;
Some(ptr::read(ptr.offset(last_index as isize)))
Some(ptr::read(ptr.add(last_index)))
}
}
@ -761,7 +757,7 @@ impl<A: Array> SmallVec<A> {
while len < *len_ptr {
let last_index = *len_ptr - 1;
*len_ptr = last_index;
ptr::drop_in_place(ptr.offset(last_index as isize));
ptr::drop_in_place(ptr.add(last_index));
}
}
}
@ -809,9 +805,9 @@ impl<A: Array> SmallVec<A> {
let len = *len_ptr;
assert!(index < len);
*len_ptr = len - 1;
ptr = ptr.offset(index as isize);
ptr = ptr.add(index);
let item = ptr::read(ptr);
ptr::copy(ptr.offset(1), ptr, len - index - 1);
ptr::copy(ptr.add(1), ptr, len - index - 1);
item
}
}
@ -827,8 +823,8 @@ impl<A: Array> SmallVec<A> {
let len = *len_ptr;
assert!(index <= len);
*len_ptr = len + 1;
ptr = ptr.offset(index as isize);
ptr::copy(ptr, ptr.offset(1), len - index);
ptr = ptr.add(index);
ptr::copy(ptr, ptr.add(1), len - index);
ptr::write(ptr, element);
}
}
@ -849,23 +845,23 @@ impl<A: Array> SmallVec<A> {
unsafe {
let old_len = self.len();
assert!(index <= old_len);
let mut ptr = self.as_mut_ptr().offset(index as isize);
let mut ptr = self.as_mut_ptr().add(index);
// Move the trailing elements.
ptr::copy(ptr, ptr.offset(lower_size_bound as isize), old_len - index);
ptr::copy(ptr, ptr.add(lower_size_bound), old_len - index);
// In case the iterator panics, don't double-drop the items we just copied above.
self.set_len(index);
let mut num_added = 0;
for element in iter {
let mut cur = ptr.offset(num_added as isize);
let mut cur = ptr.add(num_added);
if num_added >= lower_size_bound {
// Iterator provided more elements than the hint. Move trailing items again.
self.reserve(1);
ptr = self.as_mut_ptr().offset(index as isize);
cur = ptr.offset(num_added as isize);
ptr::copy(cur, cur.offset(1), old_len - index);
ptr = self.as_mut_ptr().add(index);
cur = ptr.add(num_added);
ptr::copy(cur, cur.add(1), old_len - index);
}
ptr::write(cur, element);
num_added += 1;
@ -873,8 +869,8 @@ impl<A: Array> SmallVec<A> {
if num_added < lower_size_bound {
// Iterator provided fewer elements than the hint
ptr::copy(
ptr.offset(lower_size_bound as isize),
ptr.offset(num_added as isize),
ptr.add(lower_size_bound),
ptr.add(num_added),
old_len - index,
);
}
@ -898,6 +894,14 @@ impl<A: Array> SmallVec<A> {
}
}
/// Converts a `SmallVec` into a `Box<[T]>` without reallocating if the `SmallVec` has already spilled
/// onto the heap.
///
/// Note that this will drop any excess capacity.
pub fn into_boxed_slice(self) -> Box<[A::Item]> {
self.into_vec().into_boxed_slice()
}
/// Convert the SmallVec into an `A` if possible. Otherwise return `Err(Self)`.
///
/// This method returns `Err(Self)` if the SmallVec is too short (and the `A` contains uninitialized elements),
@ -957,11 +961,11 @@ impl<A: Array> SmallVec<A> {
unsafe {
for r in 1..len {
let p_r = ptr.offset(r as isize);
let p_wm1 = ptr.offset((w - 1) as isize);
let p_r = ptr.add(r);
let p_wm1 = ptr.add(w - 1);
if !same_bucket(&mut *p_r, &mut *p_wm1) {
if r != w {
let p_w = p_wm1.offset(1);
let p_w = p_wm1.add(1);
mem::swap(&mut *p_r, &mut *p_w);
}
w += 1;
@ -1039,8 +1043,8 @@ impl<A: Array> SmallVec<A> {
/// // writing into the old `SmallVec`'s inline storage on the
/// // stack.
/// assert!(spilled);
/// for i in 0..len as isize {
/// ptr::write(p.offset(i), 4 + i);
/// for i in 0..len {
/// ptr::write(p.add(i), 4 + i);
/// }
///
/// // Put everything back together into a SmallVec with a different
@ -1103,8 +1107,8 @@ where
unsafe {
let slice_ptr = slice.as_ptr();
let ptr = self.as_mut_ptr().offset(index as isize);
ptr::copy(ptr, ptr.offset(slice.len() as isize), len - index);
let ptr = self.as_mut_ptr().add(index);
ptr::copy(ptr, ptr.add(slice.len()), len - index);
ptr::copy_nonoverlapping(slice_ptr, ptr, slice.len());
self.set_len(len + slice.len());
}
@ -1156,8 +1160,8 @@ where
let (ptr, len_ptr, _) = v.triple_mut();
let mut local_len = SetLenOnDrop::new(len_ptr);
for i in 0..n as isize {
::core::ptr::write(ptr.offset(i), elem.clone());
for i in 0..n {
::core::ptr::write(ptr.add(i), elem.clone());
local_len.increment_len(1);
}
}
@ -1318,7 +1322,7 @@ where
#[cfg(not(feature = "specialization"))]
#[inline]
fn from(slice: &'a [A::Item]) -> SmallVec<A> {
slice.into_iter().cloned().collect()
slice.iter().cloned().collect()
}
#[cfg(feature = "specialization")]
@ -1384,7 +1388,7 @@ impl<A: Array> Extend<A::Item> for SmallVec<A> {
let mut len = SetLenOnDrop::new(len_ptr);
while len.get() < cap {
if let Some(out) = iter.next() {
ptr::write(ptr.offset(len.get() as isize), out);
ptr::write(ptr.add(len.get()), out);
len.increment_len(1);
} else {
return;
@ -1463,10 +1467,6 @@ where
fn eq(&self, other: &SmallVec<B>) -> bool {
self[..] == other[..]
}
#[inline]
fn ne(&self, other: &SmallVec<B>) -> bool {
self[..] != other[..]
}
}
impl<A: Array> Eq for SmallVec<A> where A::Item: Eq {}
@ -1513,6 +1513,24 @@ pub struct IntoIter<A: Array> {
end: usize,
}
impl<A: Array> fmt::Debug for IntoIter<A>
where
A::Item: fmt::Debug,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_tuple("IntoIter").field(&self.as_slice()).finish()
}
}
impl<A: Array + Clone> Clone for IntoIter<A>
where
A::Item: Clone,
{
fn clone(&self) -> IntoIter<A> {
SmallVec::from(self.as_slice()).into_iter()
}
}
impl<A: Array> Drop for IntoIter<A> {
fn drop(&mut self) {
for _ in self {}
@ -1528,9 +1546,9 @@ impl<A: Array> Iterator for IntoIter<A> {
None
} else {
unsafe {
let current = self.current as isize;
let current = self.current;
self.current += 1;
Some(ptr::read(self.data.as_ptr().offset(current)))
Some(ptr::read(self.data.as_ptr().add(current)))
}
}
}
@ -1550,7 +1568,7 @@ impl<A: Array> DoubleEndedIterator for IntoIter<A> {
} else {
unsafe {
self.end -= 1;
Some(ptr::read(self.data.as_ptr().offset(self.end as isize)))
Some(ptr::read(self.data.as_ptr().add(self.end)))
}
}
}
@ -1559,6 +1577,20 @@ impl<A: Array> DoubleEndedIterator for IntoIter<A> {
impl<A: Array> ExactSizeIterator for IntoIter<A> {}
impl<A: Array> FusedIterator for IntoIter<A> {}
impl<A: Array> IntoIter<A> {
/// Returns the remaining items of this iterator as a slice.
pub fn as_slice(&self) -> &[A::Item] {
let len = self.end - self.current;
unsafe { core::slice::from_raw_parts(self.data.as_ptr().add(self.current), len) }
}
/// Returns the remaining items of this iterator as a mutable slice.
pub fn as_mut_slice(&mut self) -> &mut [A::Item] {
let len = self.end - self.current;
unsafe { core::slice::from_raw_parts_mut(self.data.as_mut_ptr().add(self.current), len) }
}
}
impl<A: Array> IntoIterator for SmallVec<A> {
type IntoIter = IntoIter<A>;
type Item = A::Item;
@ -1613,7 +1645,7 @@ impl<'a> SetLenOnDrop<'a> {
fn new(len: &'a mut usize) -> Self {
SetLenOnDrop {
local_len: *len,
len: len,
len,
}
}
@ -1649,7 +1681,7 @@ macro_rules! impl_array(
impl_array!(
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 20, 24, 32, 36, 0x40, 0x60, 0x80,
0x100, 0x200, 0x400, 0x600, 0x800, 0x1000, 0x2000, 0x4000, 0x6000, 0x8000, 0x10000, 0x20000,
0x40000, 0x60000, 0x80000, 0x100000
0x40000, 0x60000, 0x80000, 0x10_0000
);
#[cfg(test)]
@ -1661,7 +1693,7 @@ mod tests {
use alloc::borrow::ToOwned;
use alloc::boxed::Box;
use alloc::rc::Rc;
use alloc::vec::Vec;
use alloc::{vec, vec::Vec};
#[test]
pub fn test_zero() {
@ -1976,7 +2008,6 @@ mod tests {
);
}
#[cfg(all(feature = "std", not(miri)))] // Miri currently does not support unwinding
#[test]
// https://github.com/servo/rust-smallvec/issues/96
fn test_insert_many_panic() {
@ -2109,7 +2140,6 @@ mod tests {
assert!(c > b);
}
#[cfg(feature = "std")]
#[test]
fn test_hash() {
use std::collections::hash_map::DefaultHasher;
@ -2231,6 +2261,51 @@ mod tests {
assert_eq!(vec.into_iter().len(), 1);
}
#[test]
fn test_into_iter_as_slice() {
let vec = SmallVec::<[u32; 2]>::from(&[1, 2, 3][..]);
let mut iter = vec.clone().into_iter();
assert_eq!(iter.as_slice(), &[1, 2, 3]);
assert_eq!(iter.as_mut_slice(), &[1, 2, 3]);
iter.next();
assert_eq!(iter.as_slice(), &[2, 3]);
assert_eq!(iter.as_mut_slice(), &[2, 3]);
iter.next_back();
assert_eq!(iter.as_slice(), &[2]);
assert_eq!(iter.as_mut_slice(), &[2]);
}
#[test]
fn test_into_iter_clone() {
// Test that the cloned iterator yields identical elements and that it owns its own copy
// (i.e. no use after move errors).
let mut iter = SmallVec::<[u8; 2]>::from_iter(0..3).into_iter();
let mut clone_iter = iter.clone();
while let Some(x) = iter.next() {
assert_eq!(x, clone_iter.next().unwrap());
}
assert_eq!(clone_iter.next(), None);
}
#[test]
fn test_into_iter_clone_partially_consumed_iterator() {
// Test that the cloned iterator only contains the remaining elements of the original iterator.
let mut iter = SmallVec::<[u8; 2]>::from_iter(0..3).into_iter().skip(1);
let mut clone_iter = iter.clone();
while let Some(x) = iter.next() {
assert_eq!(x, clone_iter.next().unwrap());
}
assert_eq!(clone_iter.next(), None);
}
#[test]
fn test_into_iter_clone_empty_smallvec() {
let mut iter = SmallVec::<[u8; 2]>::new().into_iter();
let mut clone_iter = iter.clone();
assert_eq!(iter.next(), None);
assert_eq!(clone_iter.next(), None);
}
#[test]
fn shrink_to_fit_unspill() {
let mut vec = SmallVec::<[u8; 2]>::from_iter(0..3);
@ -2359,10 +2434,10 @@ mod tests {
assert_eq!(v[..], [1, 0][..]);
}
#[cfg(feature = "std")]
#[cfg(feature = "write")]
#[test]
fn test_write() {
use io::Write;
use std::io::Write;
let data = [1, 2, 3, 4, 5];

View File

@ -16,6 +16,6 @@ rustup default "$MIRI_NIGHTLY"
rustup component add miri
cargo miri setup
cargo miri test --verbose -- -- -Zunstable-options --exclude-should-panic
cargo miri test --verbose --features union -- -- -Zunstable-options --exclude-should-panic
cargo miri test --verbose --all-features -- -- -Zunstable-options --exclude-should-panic
cargo miri test --verbose -- -Zmiri-ignore-leaks
cargo miri test --verbose --features union -- -Zmiri-ignore-leaks
cargo miri test --verbose --all-features -- -Zmiri-ignore-leaks