Vec1 does not uphold its non-empty guarantee in its Vec1::drain API. Here's an example:
use std::mem;
use vec1::vec1;
fn main() {
let mut xs1 = vec1![0i32, 1, 2, 3];
println!("xs1 = {:?}", xs1.as_slice());
let rtail = xs1.drain(..3).expect("range is not a strict subset");
mem::forget(rtail);
println!("xs1 = {:?}", xs1.as_slice());
}
This examples prints:
xs1 = [0, 1, 2, 3]
xs1 = []
The API is still sound, because vec1 does not use unsafe code and Vec1 APIs will panic if a Vec1 is empty. 👍🏽 This is a niche situation and I think it's reasonable to accept this behavior as is for the vec1 crate! For what it's worth though, I believe this can be avoided by taking advantage of the non-empty guarantee and swapping items when the drain range is a prefix. See the SwapDrainSegment implementation in the mitsein crate for an example (and the Vec::drain documentation).
Vec1does not uphold its non-empty guarantee in itsVec1::drainAPI. Here's an example:This examples prints:
The API is still sound, because
vec1does not useunsafecode andVec1APIs will panic if aVec1is empty. 👍🏽 This is a niche situation and I think it's reasonable to accept this behavior as is for thevec1crate! For what it's worth though, I believe this can be avoided by taking advantage of the non-empty guarantee and swapping items when the drain range is a prefix. See theSwapDrainSegmentimplementation in themitseincrate for an example (and theVec::draindocumentation).