Skip to content

What about: aliasing requirements for nested references? #532

Open
@oxalica

Description

@oxalica

Ref:

This is already a fact under {Stacked,Tree}Borrow, though I think it's unfortunate to forbids optimizations on structs containing reference fields. Specifically, optimizing out duplicated-read through double-reference after a function call and caching an (known to be unchanged) pointer indirection are not possible.

fn main() {
    let mut s = 0u8;
    let borrow = &raw mut s;
    unsafe {
        let const_borrow: *const *mut u8 = &raw const borrow;
        let x: &&u8 = &*const_borrow.cast::<&u8>();

        // This can be in another innocent fn, but inline to avoid `static mut`.
        {
            let y1 = **x;
            *borrow = 1; // modify, maybe through some user-provided fn.
            let y2 = **x;
            assert!(y1 != y2);
        }

        // An alternative with caching. But compiler is not allowed to
        // transform the code above into this.
        {
            let y: &u8 = *x;
            let y1 = *y;
            *borrow = 2; // modify
            let y2 = *y; // <- Undefined Behavior
            assert!(y1 != y2);
        }
    }
}

Here we can notice that even through x and *x is both unchanged and u8: Freeze, **x can change via a foreign pointer with write permission. Thus caching one level of indirection *x is not possible because it would be Disabled by that foreign write.

Could we do better on this? For this example, maybe we could leave protectors on the access trace of a Frozen reference argument (when without interior mutability, or course)?

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-aliasing-modelTopic: Related to the aliasing model (e.g. Stacked/Tree Borrows)

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions