I haven't worked on Rust for some time, I got a issue raised with a crate, and would like an opinion, see
It looks without great study to be probably OK.
The iterator consumes so the only other access is drop. The drop on the Iterator (not shown in issue) appears to take care of clearing out content.
I can see a potential soundness issue but nothing like the issue opener described.
The issue I can see is that the drop implementation of the IntoIterShortVec type does first consume all items in a loop and then sets the internal length to 0 so they aren't dropped again by destructor of the the ShortVec inside. But if one of the items' destructors panics, I think the inner ShortVec would still get dropped normally during unwinding and hence you could get some double-free.
IMO, BasicVec::get() is "technically unsound", since the documented safety condition is not enough to ensure UB free for the use of ptr::read(), quote from the documentation:
Ownership of the Returned Value
readcreates a bitwise copy ofT, regardless of whetherTisCopy. IfTis notCopy, using both the returned value and the value at*srccan violate memory safety.
at least, there should be something like this statement in the safety documentation:
/// # Safety
/// [...]
/// `BasicVec::get(ix)` can only be called at most once for each valid `ix`
but as the type BasicVec is private, it's not a big deal, we only need to check the use of BasicVec::get() within the same module.
from a quick glance, I think the IntoIterShortVec type indeed has a double drop problem, because . you should at least wrap it in a IntoIterShortVec<T> contains a ShortVec<T>, which also implements DropManuallyDrop.
EDIT:
whoops, I missed the line of setting the internal length to 0, but still, there's a possibility of double drop in the case of panic, as pointed out by @steffahn
Thanks. I do have a memory of fixing issues related to panics in destructors when working on the supported crate ( pstd ). Hopefully the supported crate does not have such issues.
It does not have Drop so will leak memory if not manually emptied.
That is correct, set_alloc has to be called to free the memory. I think I designed it this way to minimise memory usage, that is it avoids having to store a reference to the Tuning (Allocator) in every ShortVec instance. I was trying quite hard to minimise memory usage in this BTreeMap.
Of course it would be simplest to use a plain Vec, but that has extra overhead.