ferrilab/bitvec

Splice panics for simple example

Opened this issue · 1 comments

I would expect the following code to run without problems. But in debug mode, it panics.

let mut bv = bitvec![0, 1, 0, 0, 1];
	drop(bv.splice(
		2 .. 2,
		(0usize .. 2).flat_map(|index| {
			let array = BitArray::<_, Lsb0>::from(index);
			array.into_iter().take(2)
		}),
	));
---- vec::tests::iter::splice stdout ----
thread 'vec::tests::iter::splice' panicked at src/vec/iter.rs:685:13:
assertion `left == right` failed
  left: FullSpan
 right: EmptyInput
stack backtrace:
   0: rust_begin_unwind
             at /rustc/eeb90cda1969383f56a2637cbd3037bdf598841c/library/std/src/panicking.rs:665:5
   1: core::panicking::panic_fmt
             at /rustc/eeb90cda1969383f56a2637cbd3037bdf598841c/library/core/src/panicking.rs:74:14
   2: core::panicking::assert_failed_inner
             at /rustc/eeb90cda1969383f56a2637cbd3037bdf598841c/library/core/src/panicking.rs:410:17
   3: core::panicking::assert_failed
             at /rustc/eeb90cda1969383f56a2637cbd3037bdf598841c/library/core/src/panicking.rs:365:5
   4: <bitvec::vec::iter::Splice<T,O,I> as core::ops::drop::Drop>::drop
             at ./src/vec/iter.rs:685:4
   5: core::ptr::drop_in_place<bitvec::vec::iter::Splice<usize,bitvec::order::Lsb0,core::iter::adapters::flatten::FlatMap<core::ops::range::Range<usize>,core::iter::adapters::take::Take<bitvec::array::iter::IntoIter<usize,bitvec::order::Lsb0>>,bitvec::vec::tests::iter::splice::{{closure}}>>>
             at /rustc/eeb90cda1969383f56a2637cbd3037bdf598841c/library/core/src/ptr/mod.rs:542:1
   6: core::mem::drop
             at /rustc/eeb90cda1969383f56a2637cbd3037bdf598841c/library/core/src/mem/mod.rs:938:24
   7: bitvec::vec::tests::iter::splice
             at ./src/vec/tests/iter.rs:43:2
   8: bitvec::vec::tests::iter::splice::{{closure}}
             at ./src/vec/tests/iter.rs:24:12
   9: core::ops::function::FnOnce::call_once
             at /rustc/eeb90cda1969383f56a2637cbd3037bdf598841c/library/core/src/ops/function.rs:250:5
  10: core::ops::function::FnOnce::call_once
             at /rustc/eeb90cda1969383f56a2637cbd3037bdf598841c/library/core/src/ops/function.rs:250:5
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.

It seems like the assertion is simply wrong. Looking at the source code of fill, if the given iterator matches exactly the length of the filled region, then it returns FullSpan rather than EmptyInput.

I guess the idea was to ensure that really all bits are getting overwritten by the splice iterator. To ensure that, it should be enough to ensure that fill returns FullSpan and that the iterator is empty. If I understand the assertion in the next line correctly, it ensures that the iterator is empty. So simply changing the first assertion should do the trick.