fitzgen / bumpalo

A fast bump allocation arena for Rust
https://docs.rs/bumpalo
Apache License 2.0
1.35k stars 110 forks source link

Miri Stacked Borrows violation after replacing `std::boxed::Box` with `bumpalo::boxed::Box` #187

Closed lukechu10 closed 1 year ago

lukechu10 commented 1 year ago

The following code doesn't run with miri's Stacked Borrows:

use bumpalo::Bump;
use bumpalo::boxed::Box as BumpBox;

fn main() {
    let bump = Bump::new();
    let mut vec = Vec::new();

    let boxed = BumpBox::new_in(1, &bump);
    let raw = BumpBox::into_raw(boxed);
    dbg!(raw);
    vec.push(raw);

    let mut_ref = unsafe { &mut *raw };
    dbg!(mut_ref);

    for raw in vec {
        let _ = unsafe { BumpBox::from_raw(raw) };
    }
}

But if all instances of BumpBox are replaced with the Box from std, miri no longer complains.

Error:

``` error: Undefined Behavior: trying to retag from <5216> for Unique permission at alloc2489[0x1bc], but that tag does not exist in the borrow stack for this location --> src\main.rs:13:28 | 13 | let mut_ref = unsafe { &mut *raw }; | ^^^^^^^^^ | | | trying to retag from <5216> for Unique permission at alloc2489[0x1bc], but that tag does not exist in the borrow stack for this location | this error occurs as part of retag at alloc2489[0x1bc..0x1c0] | = 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: <5216> was created by a SharedReadWrite retag at offsets [0x1bc..0x1c0] --> src\main.rs:9:15 | 9 | let raw = BumpBox::into_raw(boxed); | ^^^^^^^^^^^^^^^^^^^^^^^^ help: <5216> was later invalidated at offsets [0x1bc..0x1c0] by a Unique retag --> src\main.rs:9:15 | 9 | let raw = BumpBox::into_raw(boxed); | ^^^^^^^^^^^^^^^^^^^^^^^^ = note: BACKTRACE: = note: inside `main` at src\main.rs:13:28 = note: inside `>::call_once - shim(fn())` at C:\Users\_\.rustup\toolchains\nightly-x86_64-pc-windows-msvc\lib\rustlib\src\rust\library\core\src\ops\function.rs:510:5 = note: inside `std::sys_common::backtrace::__rust_begin_short_backtrace::` at C:\Users\_\.rustup\toolchains\nightly-x86_64-pc-windows-msvc\lib\rustlib\src\rust\library\std\src\sys_common\backtrace.rs:121:18 = note: inside closure at C:\Users\_\.rustup\toolchains\nightly-x86_64-pc-windows-msvc\lib\rustlib\src\rust\library\std\src\rt.rs:166:18 = note: inside `std::ops::function::impls:: for &dyn std::ops::Fn() -> i32 + std::marker::Sync + std::panic::RefUnwindSafe>::call_once` at C:\Users\_\.rustup\toolchains\nightly-x86_64-pc-windows-msvc\lib\rustlib\src\rust\library\core\src\ops\function.rs:609:13 = note: inside `std::panicking::r#try::do_call::<&dyn std::ops::Fn() -> i32 + std::marker::Sync + std::panic::RefUnwindSafe, i32>` at C:\Users\_\.rustup\toolchains\nightly-x86_64-pc-windows-msvc\lib\rustlib\src\rust\library\std\src\panicking.rs:483:40 = note: inside `std::panicking::r#try:: i32 + std::marker::Sync + std::panic::RefUnwindSafe>` at C:\Users\_\.rustup\toolchains\nightly-x86_64-pc-windows-msvc\lib\rustlib\src\rust\library\std\src\panicking.rs:447:19 = note: inside `std::panic::catch_unwind::<&dyn std::ops::Fn() -> i32 + std::marker::Sync + std::panic::RefUnwindSafe, i32>` at C:\Users\_\.rustup\toolchains\nightly-x86_64-pc-windows-msvc\lib\rustlib\src\rust\library\std\src\panic.rs:137:14 = note: inside closure at C:\Users\_\.rustup\toolchains\nightly-x86_64-pc-windows-msvc\lib\rustlib\src\rust\library\std\src\rt.rs:148:48 = note: inside `std::panicking::r#try::do_call::<[closure@std::rt::lang_start_internal::{closure#2}], isize>` at C:\Users\_\.rustup\toolchains\nightly-x86_64-pc-windows-msvc\lib\rustlib\src\rust\library\std\src\panicking.rs:483:40 = note: inside `std::panicking::r#try::` at C:\Users\_\.rustup\toolchains\nightly-x86_64-pc-windows-msvc\lib\rustlib\src\rust\library\std\src\panicking.rs:447:19 = note: inside `std::panic::catch_unwind::<[closure@std::rt::lang_start_internal::{closure#2}], isize>` at C:\Users\_\.rustup\toolchains\nightly-x86_64-pc-windows-msvc\lib\rustlib\src\rust\library\std\src\panic.rs:137:14 = note: inside `std::rt::lang_start_internal` at C:\Users\_\.rustup\toolchains\nightly-x86_64-pc-windows-msvc\lib\rustlib\src\rust\library\std\src\rt.rs:148:20 = note: inside `std::rt::lang_start::<()>` at C:\Users\_\.rustup\toolchains\nightly-x86_64-pc-windows-msvc\lib\rustlib\src\rust\library\std\src\rt.rs:165:17 error: aborting due to previous error ```

I am not sure if this is a false-positive from miri or a regression from bumpalo but the error is there with the following versions of bumpalo and miri:

There was no error with previous versions of miri and same code.

This also errors when using the allocator api on nightly.

Possibly related to https://github.com/rust-lang/miri/issues/2104