Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Illegal aliasing of mutable references #8

Closed
RalfJung opened this issue Mar 18, 2020 · 6 comments
Closed

Illegal aliasing of mutable references #8

RalfJung opened this issue Mar 18, 2020 · 6 comments

Comments

@RalfJung
Copy link
Contributor

To make sure that there are no more issues like #3 in this crate, I decided to run its test suite in Miri. Unfortunately, that fails:

Miri backtrace
note: popped tracked tag for item [Unique for <277770> (call 232767)]
    --> src/ring_buffer/mod.rs:100:9
     |
100  |         (&mut self.data as *mut _ as *mut A).add(index.to_usize())
     |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ popped tracked tag for item [Unique for <277770> (call 232767)]
     |
note: inside call to `ring_buffer::RingBuffer::<i32>::mut_ptr` at src/ring_buffer/iter.rs:84:33
    --> src/ring_buffer/iter.rs:84:33
     |
84   |             Some(unsafe { &mut *self.buffer.mut_ptr(self.left_index.inc()) })
     |                                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
     = note: inside call to `<ring_buffer::iter::IterMut<i32, typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UTerm, typenum::bit::B1>, typenum::bit::B0>, typenum::bit::B0>, typenum::bit::B0>, typenum::bit::B0>, typenum::bit::B0>, typenum::bit::B0>> as std::iter::Iterator>::next` at /home/r/.rustup/toolchains/miri/lib/rustlib/src/rust/src/liballoc/vec.rs:2138:35
     = note: inside call to `std::vec::Vec::<&mut i32>::extend_desugared::<ring_buffer::iter::IterMut<i32, typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UTerm, typenum::bit::B1>, typenum::bit::B0>, typenum::bit::B0>, typenum::bit::B0>, typenum::bit::B0>, typenum::bit::B0>, typenum::bit::B0>>>` at /home/r/.rustup/toolchains/miri/lib/rustlib/src/rust/src/liballoc/vec.rs:2031:9
     = note: inside call to `<std::vec::Vec<&mut i32> as std::vec::SpecExtend<&mut i32, ring_buffer::iter::IterMut<i32, typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UTerm, typenum::bit::B1>, typenum::bit::B0>, typenum::bit::B0>, typenum::bit::B0>, typenum::bit::B0>, typenum::bit::B0>, typenum::bit::B0>>>>::spec_extend` at /home/r/.rustup/toolchains/miri/lib/rustlib/src/rust/src/liballoc/vec.rs:2026:9
     = note: inside call to `<std::vec::Vec<&mut i32> as std::vec::SpecExtend<&mut i32, ring_buffer::iter::IterMut<i32, typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UTerm, typenum::bit::B1>, typenum::bit::B0>, typenum::bit::B0>, typenum::bit::B0>, typenum::bit::B0>, typenum::bit::B0>, typenum::bit::B0>>>>::from_iter` at /home/r/.rustup/toolchains/miri/lib/rustlib/src/rust/src/liballoc/vec.rs:1926:9
     = note: inside call to `<std::vec::Vec<&mut i32> as std::iter::FromIterator<&mut i32>>::from_iter::<ring_buffer::iter::IterMut<i32, typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UTerm, typenum::bit::B1>, typenum::bit::B0>, typenum::bit::B0>, typenum::bit::B0>, typenum::bit::B0>, typenum::bit::B0>, typenum::bit::B0>>>` at /home/r/.rustup/toolchains/miri/lib/rustlib/src/rust/src/libcore/iter/traits/iterator.rs:1659:9
note: inside call to `<ring_buffer::iter::IterMut<i32, typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UTerm, typenum::bit::B1>, typenum::bit::B0>, typenum::bit::B0>, typenum::bit::B0>, typenum::bit::B0>, typenum::bit::B0>, typenum::bit::B0>> as std::iter::Iterator>::collect::<std::vec::Vec<&mut i32>>` at src/ring_buffer/mod.rs:1068:38
    --> src/ring_buffer/mod.rs:1068:38
     |
1068 |         let out_vec: Vec<&mut i32> = chunk.iter_mut().collect();
     |                                      ^^^^^^^^^^^^^^^^^^^^^^^^^^
note: inside call to `ring_buffer::test::mut_ref_iter` at src/ring_buffer/mod.rs:1066:5
    --> src/ring_buffer/mod.rs:1066:5
     |
1066 | /     fn mut_ref_iter() {
1067 | |         let mut chunk: RingBuffer<i32> = (0..64).collect();
1068 | |         let out_vec: Vec<&mut i32> = chunk.iter_mut().collect();
1069 | |         let mut should_vec_p: Vec<i32> = (0..64).collect();
1070 | |         let should_vec: Vec<&mut i32> = should_vec_p.iter_mut().collect();
1071 | |         assert_eq!(should_vec, out_vec);
1072 | |     }
     | |_____^
     = note: inside call to closure at /home/r/.rustup/toolchains/miri/lib/rustlib/src/rust/src/libcore/ops/function.rs:232:5
     = note: inside call to `<[closure@src/ring_buffer/mod.rs:1066:5: 1072:6] as std::ops::FnOnce<()>>::call_once - shim` at /home/r/.rustup/toolchains/miri/lib/rustlib/src/rust/src/libcore/ops/function.rs:232:5
     = note: inside call to `<fn() as std::ops::FnOnce<()>>::call_once - shim(fn())` at /home/r/.rustup/toolchains/miri/lib/rustlib/src/rust/src/libtest/lib.rs:518:5
     = note: inside call to `test::__rust_begin_short_backtrace::<fn()>` at /home/r/.rustup/toolchains/miri/lib/rustlib/src/rust/src/libtest/lib.rs:509:30
     = note: inside call to closure at /home/r/.rustup/toolchains/miri/lib/rustlib/src/rust/src/libcore/ops/function.rs:232:5
     = note: inside call to `<[closure@DefId(46:631 ~ test[7b6d]::run_test[0]::{{closure}}[2]) 0:fn()] as std::ops::FnOnce<()>>::call_once - shim(vtable)` at /home/r/.rustup/toolchains/miri/lib/rustlib/src/rust/src/liballoc/boxed.rs:1017:9
     = note: inside call to `<std::boxed::Box<dyn std::ops::FnOnce() + std::marker::Send> as std::ops::FnOnce<()>>::call_once` at /home/r/.rustup/toolchains/miri/lib/rustlib/src/rust/src/libstd/panic.rs:318:9
     = note: inside call to `<std::panic::AssertUnwindSafe<std::boxed::Box<dyn std::ops::FnOnce() + std::marker::Send>> as std::ops::FnOnce<()>>::call_once` at /home/r/.rustup/toolchains/miri/lib/rustlib/src/rust/src/libstd/panicking.rs:331:40
     = note: inside call to `std::panicking::r#try::do_call::<std::panic::AssertUnwindSafe<std::boxed::Box<dyn std::ops::FnOnce() + std::marker::Send>>, ()>` at /home/r/.rustup/toolchains/miri/lib/rustlib/src/rust/src/libstd/panicking.rs:274:15
     = note: inside call to `std::panicking::r#try::<(), std::panic::AssertUnwindSafe<std::boxed::Box<dyn std::ops::FnOnce() + std::marker::Send>>>` at /home/r/.rustup/toolchains/miri/lib/rustlib/src/rust/src/libstd/panic.rs:394:14
     = note: inside call to `std::panic::catch_unwind::<std::panic::AssertUnwindSafe<std::boxed::Box<dyn std::ops::FnOnce() + std::marker::Send>>, ()>` at /home/r/.rustup/toolchains/miri/lib/rustlib/src/rust/src/libtest/lib.rs:542:18
     = note: inside call to `test::run_test_in_process` at /home/r/.rustup/toolchains/miri/lib/rustlib/src/rust/src/libtest/lib.rs:451:39
     = note: inside call to closure at /home/r/.rustup/toolchains/miri/lib/rustlib/src/rust/src/libtest/lib.rs:476:13
     = note: inside call to `test::run_test::run_test_inner` at /home/r/.rustup/toolchains/miri/lib/rustlib/src/rust/src/libtest/lib.rs:506:28
     = note: inside call to `test::run_test` at /home/r/.rustup/toolchains/miri/lib/rustlib/src/rust/src/libtest/lib.rs:285:13
     = note: inside call to `test::run_tests::<[closure@DefId(46:230 ~ test[7b6d]::console[0]::run_tests_console[0]::{{closure}}[2]) 0:&mut test::console::ConsoleTestState, 1:&mut std::boxed::Box<dyn test::formatters::OutputFormatter>]>` at /home/r/.rustup/toolchains/miri/lib/rustlib/src/rust/src/libtest/console.rs:280:5
     = note: inside call to `test::run_tests_console` at /home/r/.rustup/toolchains/miri/lib/rustlib/src/rust/src/libtest/lib.rs:121:15
     = note: inside call to `test::test_main` at /home/r/.rustup/toolchains/miri/lib/rustlib/src/rust/src/libtest/lib.rs:140:5
     = note: inside call to `test::test_main_static`
     = note: inside call to `main` at /home/r/.rustup/toolchains/miri/lib/rustlib/src/rust/src/libstd/rt.rs:67:34
     = note: inside call to closure at /home/r/.rustup/toolchains/miri/lib/rustlib/src/rust/src/libstd/rt.rs:52:73
     = note: inside call to closure at /home/r/.rustup/toolchains/miri/lib/rustlib/src/rust/src/libstd/sys_common/backtrace.rs:130:5
     = note: inside call to `std::sys_common::backtrace::__rust_begin_short_backtrace::<[closure@DefId(1:6041 ~ std[e04c]::rt[0]::lang_start_internal[0]::{{closure}}[0]::{{closure}}[0]) 0:&dyn std::ops::Fn() -> i32 + std::marker::Sync + std::panic::RefUnwindSafe], i32>` at /home/r/.rustup/toolchains/miri/lib/rustlib/src/rust/src/libstd/rt.rs:52:13
     = note: inside call to closure at /home/r/.rustup/toolchains/miri/lib/rustlib/src/rust/src/libstd/panicking.rs:331:40
     = note: inside call to `std::panicking::r#try::do_call::<[closure@DefId(1:6040 ~ std[e04c]::rt[0]::lang_start_internal[0]::{{closure}}[0]) 0:&&dyn std::ops::Fn() -> i32 + std::marker::Sync + std::panic::RefUnwindSafe], i32>` at /home/r/.rustup/toolchains/miri/lib/rustlib/src/rust/src/libstd/panicking.rs:274:15
     = note: inside call to `std::panicking::r#try::<i32, [closure@DefId(1:6040 ~ std[e04c]::rt[0]::lang_start_internal[0]::{{closure}}[0]) 0:&&dyn std::ops::Fn() -> i32 + std::marker::Sync + std::panic::RefUnwindSafe]>` at /home/r/.rustup/toolchains/miri/lib/rustlib/src/rust/src/libstd/panic.rs:394:14
     = note: inside call to `std::panic::catch_unwind::<[closure@DefId(1:6040 ~ std[e04c]::rt[0]::lang_start_internal[0]::{{closure}}[0]) 0:&&dyn std::ops::Fn() -> i32 + std::marker::Sync + std::panic::RefUnwindSafe], i32>` at /home/r/.rustup/toolchains/miri/lib/rustlib/src/rust/src/libstd/rt.rs:51:25
     = note: inside call to `std::rt::lang_start_internal` at /home/r/.rustup/toolchains/miri/lib/rustlib/src/rust/src/libstd/rt.rs:67:5
     = note: inside call to `std::rt::lang_start::<()>`
     = note: this note originates in an attribute macro (in Nightly builds, run with -Z macro-backtrace for more info)

error: Miri evaluation error: trying to reborrow for SharedReadOnly, but parent tag <277770> does not have an appropriate item in the borrow stack
    --> /home/r/.rustup/toolchains/miri/lib/rustlib/src/rust/src/libcore/cmp.rs:1274:34
     |
1274 |             PartialEq::eq(*self, *other)
     |                                  ^^^^^^ trying to reborrow for SharedReadOnly, but parent tag <277770> does not have an appropriate item in the borrow stack
     |
     = note: inside call to `std::cmp::impls::<impl std::cmp::PartialEq for &mut i32>::eq` at /home/r/.rustup/toolchains/miri/lib/rustlib/src/rust/src/libcore/cmp.rs:1219:13
     = note: inside call to `std::cmp::impls::<impl std::cmp::PartialEq for &&mut i32>::eq` at /home/r/.rustup/toolchains/miri/lib/rustlib/src/rust/src/libcore/slice/mod.rs:5820:52
     = note: inside call to closure at /home/r/.rustup/toolchains/miri/lib/rustlib/src/rust/src/libcore/iter/traits/iterator.rs:2054:20
     = note: inside call to closure at /home/r/.rustup/toolchains/miri/lib/rustlib/src/rust/src/libcore/iter/traits/iterator.rs:1877:21
     = note: inside call to `<std::iter::Zip<std::slice::Iter<&mut i32>, std::slice::Iter<&mut i32>> as std::iter::Iterator>::try_fold::<(), [closure@DefId(2:4889 ~ core[4ac7]::iter[0]::traits[0]::iterator[0]::Iterator[0]::all[0]::check[0]::{{closure}}[0]) 0:[closure@DefId(2:7242 ~ core[4ac7]::slice[0]::{{impl}}[128]::equal[0]::{{closure}}[0])]], std::iter::LoopState<(), ()>>` at /home/r/.rustup/toolchains/miri/lib/rustlib/src/rust/src/libcore/iter/traits/iterator.rs:2057:9
     = note: inside call to `<std::iter::Zip<std::slice::Iter<&mut i32>, std::slice::Iter<&mut i32>> as std::iter::Iterator>::all::<[closure@DefId(2:7242 ~ core[4ac7]::slice[0]::{{impl}}[128]::equal[0]::{{closure}}[0])]>` at /home/r/.rustup/toolchains/miri/lib/rustlib/src/rust/src/libcore/slice/mod.rs:5820:9
     = note: inside call to `<[&mut i32] as core::slice::SlicePartialEq<&mut i32>>::equal` at /home/r/.rustup/toolchains/miri/lib/rustlib/src/rust/src/libcore/slice/mod.rs:5755:9
     = note: inside call to `core::slice::<impl std::cmp::PartialEq for [&mut i32]>::eq` at /home/r/.rustup/toolchains/miri/lib/rustlib/src/rust/src/liballoc/vec.rs:2278:50
note: inside call to `<std::vec::Vec<&mut i32> as std::cmp::PartialEq>::eq` at /home/r/.rustup/toolchains/miri/lib/rustlib/src/rust/src/libcore/macros/mod.rs:70:21
    --> src/ring_buffer/mod.rs:1071:9
     |
1071 |         assert_eq!(should_vec, out_vec);
     |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
note: inside call to `ring_buffer::test::mut_ref_iter` at src/ring_buffer/mod.rs:1066:5
    --> src/ring_buffer/mod.rs:1066:5
     |
1066 | /     fn mut_ref_iter() {
1067 | |         let mut chunk: RingBuffer<i32> = (0..64).collect();
1068 | |         let out_vec: Vec<&mut i32> = chunk.iter_mut().collect();
1069 | |         let mut should_vec_p: Vec<i32> = (0..64).collect();
1070 | |         let should_vec: Vec<&mut i32> = should_vec_p.iter_mut().collect();
1071 | |         assert_eq!(should_vec, out_vec);
1072 | |     }
     | |_____^
     = note: inside call to closure at /home/r/.rustup/toolchains/miri/lib/rustlib/src/rust/src/libcore/ops/function.rs:232:5
     = note: inside call to `<[closure@src/ring_buffer/mod.rs:1066:5: 1072:6] as std::ops::FnOnce<()>>::call_once - shim` at /home/r/.rustup/toolchains/miri/lib/rustlib/src/rust/src/libcore/ops/function.rs:232:5
     = note: inside call to `<fn() as std::ops::FnOnce<()>>::call_once - shim(fn())` at /home/r/.rustup/toolchains/miri/lib/rustlib/src/rust/src/libtest/lib.rs:518:5
     = note: inside call to `test::__rust_begin_short_backtrace::<fn()>` at /home/r/.rustup/toolchains/miri/lib/rustlib/src/rust/src/libtest/lib.rs:509:30
     = note: inside call to closure at /home/r/.rustup/toolchains/miri/lib/rustlib/src/rust/src/libcore/ops/function.rs:232:5
     = note: inside call to `<[closure@DefId(46:631 ~ test[7b6d]::run_test[0]::{{closure}}[2]) 0:fn()] as std::ops::FnOnce<()>>::call_once - shim(vtable)` at /home/r/.rustup/toolchains/miri/lib/rustlib/src/rust/src/liballoc/boxed.rs:1017:9
     = note: inside call to `<std::boxed::Box<dyn std::ops::FnOnce() + std::marker::Send> as std::ops::FnOnce<()>>::call_once` at /home/r/.rustup/toolchains/miri/lib/rustlib/src/rust/src/libstd/panic.rs:318:9
     = note: inside call to `<std::panic::AssertUnwindSafe<std::boxed::Box<dyn std::ops::FnOnce() + std::marker::Send>> as std::ops::FnOnce<()>>::call_once` at /home/r/.rustup/toolchains/miri/lib/rustlib/src/rust/src/libstd/panicking.rs:331:40
     = note: inside call to `std::panicking::r#try::do_call::<std::panic::AssertUnwindSafe<std::boxed::Box<dyn std::ops::FnOnce() + std::marker::Send>>, ()>` at /home/r/.rustup/toolchains/miri/lib/rustlib/src/rust/src/libstd/panicking.rs:274:15
     = note: inside call to `std::panicking::r#try::<(), std::panic::AssertUnwindSafe<std::boxed::Box<dyn std::ops::FnOnce() + std::marker::Send>>>` at /home/r/.rustup/toolchains/miri/lib/rustlib/src/rust/src/libstd/panic.rs:394:14
     = note: inside call to `std::panic::catch_unwind::<std::panic::AssertUnwindSafe<std::boxed::Box<dyn std::ops::FnOnce() + std::marker::Send>>, ()>` at /home/r/.rustup/toolchains/miri/lib/rustlib/src/rust/src/libtest/lib.rs:542:18
     = note: inside call to `test::run_test_in_process` at /home/r/.rustup/toolchains/miri/lib/rustlib/src/rust/src/libtest/lib.rs:451:39
     = note: inside call to closure at /home/r/.rustup/toolchains/miri/lib/rustlib/src/rust/src/libtest/lib.rs:476:13
     = note: inside call to `test::run_test::run_test_inner` at /home/r/.rustup/toolchains/miri/lib/rustlib/src/rust/src/libtest/lib.rs:506:28
     = note: inside call to `test::run_test` at /home/r/.rustup/toolchains/miri/lib/rustlib/src/rust/src/libtest/lib.rs:285:13
     = note: inside call to `test::run_tests::<[closure@DefId(46:230 ~ test[7b6d]::console[0]::run_tests_console[0]::{{closure}}[2]) 0:&mut test::console::ConsoleTestState, 1:&mut std::boxed::Box<dyn test::formatters::OutputFormatter>]>` at /home/r/.rustup/toolchains/miri/lib/rustlib/src/rust/src/libtest/console.rs:280:5
     = note: inside call to `test::run_tests_console` at /home/r/.rustup/toolchains/miri/lib/rustlib/src/rust/src/libtest/lib.rs:121:15
     = note: inside call to `test::test_main` at /home/r/.rustup/toolchains/miri/lib/rustlib/src/rust/src/libtest/lib.rs:140:5
     = note: inside call to `test::test_main_static`
     = note: inside call to `main` at /home/r/.rustup/toolchains/miri/lib/rustlib/src/rust/src/libstd/rt.rs:67:34
     = note: inside call to closure at /home/r/.rustup/toolchains/miri/lib/rustlib/src/rust/src/libstd/rt.rs:52:73
     = note: inside call to closure at /home/r/.rustup/toolchains/miri/lib/rustlib/src/rust/src/libstd/sys_common/backtrace.rs:130:5
     = note: inside call to `std::sys_common::backtrace::__rust_begin_short_backtrace::<[closure@DefId(1:6041 ~ std[e04c]::rt[0]::lang_start_internal[0]::{{closure}}[0]::{{closure}}[0]) 0:&dyn std::ops::Fn() -> i32 + std::marker::Sync + std::panic::RefUnwindSafe], i32>` at /home/r/.rustup/toolchains/miri/lib/rustlib/src/rust/src/libstd/rt.rs:52:13
     = note: inside call to closure at /home/r/.rustup/toolchains/miri/lib/rustlib/src/rust/src/libstd/panicking.rs:331:40
     = note: inside call to `std::panicking::r#try::do_call::<[closure@DefId(1:6040 ~ std[e04c]::rt[0]::lang_start_internal[0]::{{closure}}[0]) 0:&&dyn std::ops::Fn() -> i32 + std::marker::Sync + std::panic::RefUnwindSafe], i32>` at /home/r/.rustup/toolchains/miri/lib/rustlib/src/rust/src/libstd/panicking.rs:274:15
     = note: inside call to `std::panicking::r#try::<i32, [closure@DefId(1:6040 ~ std[e04c]::rt[0]::lang_start_internal[0]::{{closure}}[0]) 0:&&dyn std::ops::Fn() -> i32 + std::marker::Sync + std::panic::RefUnwindSafe]>` at /home/r/.rustup/toolchains/miri/lib/rustlib/src/rust/src/libstd/panic.rs:394:14
     = note: inside call to `std::panic::catch_unwind::<[closure@DefId(1:6040 ~ std[e04c]::rt[0]::lang_start_internal[0]::{{closure}}[0]) 0:&&dyn std::ops::Fn() -> i32 + std::marker::Sync + std::panic::RefUnwindSafe], i32>` at /home/r/.rustup/toolchains/miri/lib/rustlib/src/rust/src/libstd/rt.rs:51:25
     = note: inside call to `std::rt::lang_start_internal` at /home/r/.rustup/toolchains/miri/lib/rustlib/src/rust/src/libstd/rt.rs:67:5
     = note: inside call to `std::rt::lang_start::<()>`
     = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)

My interpretation of what happens is that the problem is here:

Some(unsafe { &mut *self.buffer.mut_ptr(self.left_index.inc()) })

This creates a fresh &mut RingBuffer that is passed to RingBuffer::mut_ptr. Any time a mutable reference is created it must be the unique pointer pointing to that memory -- all old aliases become invalid. We are still experimenting with the exact ruels for this; for further details, see this document.

The issue here is that this new mutably reference that got created here overaps with the mutable references that were handed out by the iterator previously. Thus those old references become invalid (their "lifetime ends"), but the caller still uses them later, leading to the error. This is a problem because Rust would like to perform optimizations based on the assumption that mutable references are truly unique -- code like this is incompatible with such optimizations.

Given that you are handling aliased pointers here (the buffer pointer and the ones returned by next overlap) and want to perform mutation, I think the only solution is to use raw pointers throughout. That way, the Rust compiler knows that nothing is unique, and does not do any optimizations. I think you can do that here by replacing the buffer field with a raw pointer to the MaybeUninit<N::SizedType> that lives inside the buffer. Then you never have to create a reference except for the ones returned by next, and those do not overlap because they all point to different elements. Does that make sense?

Also Cc rust-lang/unsafe-code-guidelines#133: this crate would benefit from mutable references being "less eager" in asserting uniqueness. Unfortunately, it is not clear if that is possible and what the trade-offs are.

@bodil
Copy link
Owner

bodil commented Mar 19, 2020

Oh wow, I've been unable to use miri with proptest for the longest time, I'm so happy it apparently works now.

@bodil
Copy link
Owner

bodil commented Mar 19, 2020

I spoke too soon. You've just run into a new failing test that runs before the proptest tests run. Miri still remains unable to cope with proptest. 😞

@RalfJung
Copy link
Contributor Author

I can look into what it takes to make proptest work. Miri is slow though, so fuzzing doesn't work very well.

@bodil bodil closed this as completed in 421287f Mar 19, 2020
@bodil
Copy link
Owner

bodil commented Mar 19, 2020

Proptest on miri isn't a huge priority for me, tbh, I'd rather get rid of proptest altogether and come up with a more stable solution. It's just a bit of a work in progress.

@bodil
Copy link
Owner

bodil commented Mar 19, 2020

Anyway, I fixed the issue, your suggestion was pretty much spot on. Only difference in the impl is that I went with just a straightforward *mut A instead of *mut MaybeUninit<BigBlobOfStuff>. Which has miri complaining about proptest again, instead of the actual code, and it's a good motivator to get proptest out so I can use miri to check the code regularly.

@RalfJung
Copy link
Contributor Author

Thanks!

It's also a good motivator for me to implement enough shims to get proptest to work. ;)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants