Miri gives a UB because of stacked borrows
Closed this issue · 1 comments
oblique commented
I run Miri on your crate and it gave an UB on push_access
function. I don't have a clear understanding on stacked borrows yet, so I don't know how it can be fixed.
This is the output:
% cargo +nightly miri test
Compiling ringbuf v0.2.7 (/home/oblique/git/ringbuf)
Finished test [unoptimized + debuginfo] target(s) in 0.09s
Running unittests src/lib.rs (target/miri/x86_64-unknown-linux-gnu/debug/deps/ringbuf-e44ea49f80c6b586)
running 39 tests
test tests::access::discard ... error: Undefined Behavior: trying to reborrow <220885> for SharedReadWrite permission at alloc84260[0x0], but that tag does not exist in the borrow stack for this location
--> src/producer.rs:99:19
|
99 | let n = f(slices.0, slices.1);
| ^^^^^^^^
| |
| trying to reborrow <220885> for SharedReadWrite permission at alloc84260[0x0], but that tag does not exist in the borrow stack for this location
| this error occurs as part of a reborrow at alloc84260[0x0..0xa]
|
= help: this indicates a potential bug in the program: it performed an invalid operation, but the rules it violated are still experimental
= help: see https://github.com/rust-lang/unsafe-code-guidelines/blob/master/wip/stacked-borrows.md for further information
= note: inside `producer::Producer::<i8>::push_access::<[closure@src/producer.rs:152:30: 159:14]>` at src/producer.rs:99:19
note: inside `producer::Producer::<i8>::push` at src/producer.rs:152:13
--> src/producer.rs:152:13
|
152 | / self.push_access(|slice, _| {
153 | | if !slice.is_empty() {
154 | | mem::swap(slice.get_unchecked_mut(0), &mut elem_mu);
155 | | 1
... |
158 | | }
159 | | })
| |______________^
note: inside `tests::access::discard` at src/tests/access.rs:245:9
--> src/tests/access.rs:245:9
|
245 | prod.push(i).unwrap();
| ^^^^^^^^^^^^
note: inside closure at src/tests/access.rs:237:1
--> src/tests/access.rs:237:1
|
236 | #[test]
| ------- in this procedural macro expansion
237 | / fn discard() {
238 | | // Initialize ringbuffer, prod and cons
239 | | let rb = RingBuffer::<i8>::new(10);
240 | | let (mut prod, mut cons) = rb.split();
... |
279 | | assert_eq!(cons.pop(), Some(0));
280 | | }
| |_^
= note: this error originates in the attribute macro `test` (in Nightly builds, run with -Z macro-backtrace for more info)
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
error: aborting due to previous error
error: test failed, to rerun pass '--lib'
oblique commented
I managed to fix the issue and opened a PR.