Rust 1.20 caused pinning to become incorrect

I found another way to break Pin, using only the standard library and safe code, though it only works with unwinding enabled:

https://play.rust-lang.org/?gist=86b8a068bb072fba4aad47ddbf3e5ab8&version=nightly

…But you could make the case that it’s just a bug in the standard library.

Basically, VecDeque's Drop impl (which has may_dangle set) drops the two halves of its ring buffer separately:

            ptr::drop_in_place(front);
            ptr::drop_in_place(back);

If the drop of front panics, back never gets dropped, but the backing buffer still gets deallocated.

(This doesn’t work with structures or built-in arrays, because the compiler-generated drop glue will always try to drop all fields/elements, even if one drop call panics. And it doesn’t work for Vec because its Drop impl relies on the built-in [T] drop glue.)

6 Likes