MIRI の Stacked Borrows モデルは相性が悪いクレートが多い。
有名なクレート arraydeque (配列による両端キューを提供) もその一つである。
以下は Stacked Borrows でのみ UB になる (Tree Borrows では問題ない)。
fn main() {
use arraydeque::ArrayDeque;
drop(ArrayDeque::<i32, 3>::new().drain(..));
}
error: Undefined Behavior: not granting access to tag <313> because that would remove [SharedReadOnly for <337>] which is strongly protected
--> C:\Users\nossi\.cargo\registry\src\index.crates.io-1949cf8c6b5b557f\arraydeque-0.5.1\src\lib.rs:2391:37
|
2391 | let source_deque = unsafe { &mut *self.deque };
| ^^^^^^^^^^^^^^^^ Undefined Behavior occurred here
|
= help: this indicates a potential bug in the program: it performed an invalid operation, but the Stacked Borrows 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
help: <313> was created by a SharedReadWrite retag at offsets [0x0..0x20]
--> src\main.rs:3:10
|
3 | drop(ArrayDeque::<i32, 3>::new().drain(..));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
help: <337> is this argument
--> src\main.rs:3:5
|
3 | drop(ArrayDeque::<i32, 3>::new().drain(..));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
= note: BACKTRACE (of the first span):
= note: inside `<arraydeque::Drain<'_, i32, 3, arraydeque::Saturating> as std::ops::Drop>::drop` at C:\Users\nossi\.cargo\registry\src\index.crates.io-1949cf8c6b5b557f\arraydeque-0.5.1\src\lib.rs:2391:37: 2391:53
= note: inside `std::ptr::drop_in_place::<arraydeque::Drain<'_, i32, 3, arraydeque::Saturating>> - shim(Some(arraydeque::Drain<'_, i32, 3, arraydeque::Saturating>))` at C:\Users\nossi\.rustup\toolchains\nightly-x86_64-pc-windows-msvc\lib\rustlib\src\rust\library\core\src\ptr\mod.rs:804:1: 804:62
= note: inside `std::mem::drop::<arraydeque::Drain<'_, i32, 3, arraydeque::Saturating>>` at C:\Users\nossi\.rustup\toolchains\nightly-x86_64-pc-windows-msvc\lib\rustlib\src\rust\library\core\src\mem\mod.rs:961:24: 961:25
note: inside `main`
--> src\main.rs:3:5
|
3 | drop(ArrayDeque::<i32, 3>::new().drain(..));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace