agerasev/ringbuf

bug: `is_full()` panics with empty struct/enum objects

deermichel opened this issue · 2 comments

Tracked down some interesting behavior:

Using is_full on a producer or consumer that is backed by a "primitive" buffer like u8 works as expected:

let (prod, cons) = ringbuf::HeapRb::<u8>::new(256).split();
if prod.is_full() {
    // works
}

However with buffers of objects like zero-size structs/enums, is_full panics:

struct Message {}

let (prod, cons) = ringbuf::HeapRb::<Message>::new(256).split();
if prod.is_full() {
    // panics
}

Stack backtrace:

thread 'main' panicked at /Users/deermichel/.cargo/registry/src/index.crates.io-6f17d22bba15001f/ringbuf-0.4.4/src/traits/utils.rs:22:42:
attempt to multiply with overflow
stack backtrace:
   0:        0x10b720313 - std::backtrace_rs::backtrace::libunwind::trace::hb4c5e3692fb6a0e3
                               at /rustc/eeb90cda1969383f56a2637cbd3037bdf598841c/library/std/src/../../backtrace/src/backtrace/libunwind.rs:116:5
   1:        0x10b720313 - std::backtrace_rs::backtrace::trace_unsynchronized::hd4d640b18da86d0c
                               at /rustc/eeb90cda1969383f56a2637cbd3037bdf598841c/library/std/src/../../backtrace/src/backtrace/mod.rs:66:5
   2:        0x10b720313 - std::sys::backtrace::_print_fmt::h527f8414b59f1169
                               at /rustc/eeb90cda1969383f56a2637cbd3037bdf598841c/library/std/src/sys/backtrace.rs:65:5
...

Probably that's expected with zero-size items and counts as a user error. As soon as you add a field to the struct or enum, the panic disappears - but maybe there's a nicer way to catch this, so nobody needs to repeat debugging this petty bug :)

Very interesting...

This is caused by the fact that Vec<T>::capacity() is undefined for ZST:

... if you store zero-sized types inside a Vec, it will not allocate space for them. Note that in this case the Vec might not report a capacity of 0.

I've made a fix in 9cf82af.

Thanks for your report!

that was quick, thanks! now I learned something new as well :)