-
Notifications
You must be signed in to change notification settings - Fork 397
Closed
Description
Consider the following code:
use std::ptr::drop_in_place;
struct Thing(i32);
static mut STATIC: Thing = Thing(1);
fn works() {
unsafe {
drop_in_place((&raw const STATIC).cast_mut());
}
}
fn fails() {
let x = Thing(2);
unsafe {
drop_in_place((&raw const x).cast_mut());
}
}
fn main() {
works();
fails();
}
I expected works()
and fails()
to either both be UB, or both be defined behavior. However, Miri reports UB only for the fails()
function.
Miri error
error: Undefined Behavior: trying to retag from <298> for Unique permission at alloc155[0x0], but that tag only grants SharedReadOnly permission for this location
--> /playground/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/ptr/mod.rs:804:1
|
804 | pub unsafe fn drop_in_place<T: PointeeSized>(to_drop: *mut T) {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this error occurs as part of retag at alloc155[0x0..0x4]
|
= 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: <298> was created by a SharedReadOnly retag at offsets [0x0..0x4]
--> src/main.rs:16:23
|
16 | drop_in_place((&raw const x).cast_mut());
| ^^^^^^^^^^^^^^
= note: BACKTRACE (of the first span):
= note: inside `std::ptr::drop_in_place::<Thing> - shim(None)` at /playground/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/ptr/mod.rs:804:1: 804:62
note: inside `fails`
--> src/main.rs:16:9
|
16 | drop_in_place((&raw const x).cast_mut());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
note: inside `main`
--> src/main.rs:22:5
|
22 | fails();
| ^^^^^^^
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
Adding a Drop
implementation that mutates the value does not change this behavior.
impl Drop for Thing {
fn drop(&mut self) {
self.0 = 3;
}
}
Changing the original code to use static
instead of static mut
results in Miri detecting UB.
Miri error with `static`
error: Undefined Behavior: writing to alloc1 which is read-only
--> /playground/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/ptr/mod.rs:804:1
|
804 | pub unsafe fn drop_in_place<T: PointeeSized>(to_drop: *mut T) {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Undefined Behavior occurred here
|
= help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
= help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
= note: BACKTRACE:
= note: inside `std::ptr::drop_in_place::<Thing> - shim(None)` at /playground/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/ptr/mod.rs:804:1: 804:62
note: inside `works`
--> src/main.rs:9:9
|
9 | drop_in_place((&raw const STATIC).cast_mut());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
note: inside `main`
--> src/main.rs:21:5
|
21 | works();
| ^^^^^^^
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
Discovered while experimenting with rust-lang/rust#146187.
Reproduced the problem on the playground with version 1.91.0-nightly (2025-09-09 7ad23f43a225546c0951)
.
Metadata
Metadata
Assignees
Labels
No labels