MIRIStacked 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