By skipping the call to `copy` with a zero length. This makes it closer
to `push`. This speeds up rustc (which uses `SmallVec` extensively) by
2% on one benchmark.
Also clarify the panic condition.
Fix all problems encounted with Miri -Ztag-raw-pointers
I poked at this crate with `-Zmiri-tag-raw-pointers` before, and I was unable to fix what I found (I just added a test case that ruled out one of my wrong ideas https://github.com/servo/rust-smallvec/pull/271). I tried again just now and I guess I just understand better this time.
This PR fixes 3 separate pointer invalidation problems, which are detected by running `MIRIFLAGS=-Zmiri-tag-raw-pointers cargo miri test`.
Depending on how you squint, 2 or 3 of these are https://github.com/rust-lang/unsafe-code-guidelines/issues/133. The last one is _probably_ still present even with late invalidation, because `set_len` does a write through a `&mut`.
It's unclear to me if any of these things that Miri complains about are potentially a miscompilation in rustc due to the use of LLVM `noalias`. But perhaps given how subtle this codebase is overall, it would be best to run the tools on their pickiest settings, even if there are a few things more like a false positive than a real problem.
Miri does not check all of Stacked Borrows (the prototype aliasing model
for Rust) without -Zmiri-tag-raw-pointers. This enables the check in CI,
and makes a few adjustments to fix places where pointers were
invalidated by construction or use of a mutable reference.
Add support for arbitrary
This PR adds optional support for [Arbitrary](https://github.com/rust-fuzz/arbitrary/), which is helpful in fuzz testing. The implementation is nearly identical to Arbitrary's existing Vec implementation.
Test for drains that shift the tail, when inline
Previously, the test suite only had one trip through the tail-shifting
code in Drain::drop, and that is in the heap state.
In the current implementation, a tail-shifting drain while in the inline
state produces potentially dangerous aliasing which is currently
accepted by default Miri and rejected with -Ztrack-raw-pointers.
Adding this test case ensures that if this ever becomes an actual
problem it will be easy to find.
Previously, the test suite only had one trip through the tail-shifting
code in Drain::drop, and that is in the heap state.
In the current implementation, a tail-shifting drain while in the inline
state produces potentially dangerous aliasing which is currently
accepted by default Miri and rejected with -Ztrack-raw-pointers.
Adding this test case ensures that if this ever becomes an actual
problem it will be easy to find.
Version 1.6.0
Release notes:
* The `union` feature is now compatible with stable Rust 1.49 (#248, #247).
* Fixed warnings when compiling with Rust 1.51 nightly (#242, #246).
Release notes:
* The `union` feature is now compatible with stable Rust 1.49 (#248).
* Fixed warnings when compiling with Rust 1.51 nightly (#242, #246).
Wrap with ManuallyDrop so that the union feature works on 1.50
Per https://github.com/servo/rust-smallvec/issues/247#issuecomment-752794872
The unrelated diff was produced by rustfmt, which my editor runs automatically. I'm a bit surprised, usually when this produces a diff it's a big one. Do you want me to revert those lines?
Silence warnings about deprecated LayoutErr
This is renamed to LayoutError in Rust 1.51 and later, but we need to continue using the old name to support older versions of Rust.
Remove `min_const_generics` feature
Depends on https://github.com/rust-lang/rust/pull/79135.
If #240 is already under development and will be available before the 1.50 release, then feel free to close this PR. Otherwise, the feature removal will benefit upstream projects in the meanwhile.
Remove extraneous branch from push
`push` does two branches on the "smallness" of the `smallvec`: one before the reserve check and one after. LLVM doesn't seem to optimize the second branch away for the (very common) non-growing case. In addition, in the growing branch we know the memory will be on the heap, so no need to branch here.
On my machine, this improves `bench_push` from approx 300ns to 263ns (+/- 5 on both).
Version 1.5.0
Change log:
* Add the `append` method (#237).
* Add support for more array sizes between 17 and 31 (#234).
* Don't panic on deserialization errors (#238).
Change log:
* Add the `append` method (#237).
* Add support for more array sizes between 17 and 31 (#234).
* Don't panic on deserialization errors (#238).
Return allocation error in deserialize instead of panicking
There's no way to catch allocation errors since out of memory errors
cause an abort. Fail gracefully by returning the error instead of
panicking.
I happened upon this error when deserializing untrusted data with bincode. Bincode provides a byte limit bound but for sequences it's not possible to enforce this through serde since collection types like smallvec handle their own allocation.