Skip to content

Stacked Borrows vs inner pointers into "stable-deref" types #194

Closed
@Aaron1011

Description

@Aaron1011

When running Miri on owning-ref, I ran into an error with this (minimized) snippet (playground):

fn main() {
    let val: Box<u8> = Box::new(25);
    let ptr: *const u8 = &*val;
    
    let _moved_val = val;
    let _my_val: u8 = unsafe { *ptr };
}

which errors with:

error[E0080]: Miri evaluation error: trying to reborrow for SharedReadOnly, but parent tag <1359> does not have an appropriate item in the borrow stack
   --> /root/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/src/liballoc/alloc.rs:219:28
    |
219 |     let size = size_of_val(&*ptr);
    |                            ^^^^^ Miri evaluation error: trying to reborrow for SharedReadOnly, but parent tag <1359> does not have an appropriate item in the borrow stack
    |

In this snippet, we're creating a raw pointer into a Box, moving the Box, then dereferencing the raw pointer. The owning-ref crate (and more generally, anything relying on stable_deref_trait) relies on this working. In fact, this is the entire reason for the existence of stable_deref_trait.

The error message is a little confusing. However, I believe that the read from ptr causes the Unique item on the stack to be disabled (since the Unique is above the SharedReadOnly that grants access).

Does it make sense to consider this kind of behavior UB, given that stable_deref_trait and owning-ref (and probably other crates as well) rely on it?

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-aliasing-modelTopic: Related to the aliasing model (e.g. Stacked/Tree Borrows)C-open-questionCategory: An open question that we should revisit

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions