Skip to content

Borrow checker unsoundness with unions #45157

@petrochenkov

Description

@petrochenkov
#![allow(unused)]

#[derive(Clone, Copy, Default)]
struct S {
    a: u8,
    b: u8,
}
#[derive(Clone, Copy, Default)]
struct Z {
    c: u8,
    d: u8,
}

union U {
    s: S,
    z: Z,
}

fn main() { unsafe {
    let mut u = U { s: Default::default() };
    
    let mref = &mut u.s.a;
    let err = &u.z.c; // This line compiles, but it certainly shouldn't ...
    drop(mref); // ... (at least if `mref` is used after `err`)
}}

"Cousins" of borrowed union sub-fields (and their further children) are not marked as borrowed.
The same bug should happen with move checking as well, but I haven't made an example yet.

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-borrow-checkerArea: The borrow checkerC-bugCategory: This is a bug.I-unsoundIssue: A soundness hole (worst kind of bug), see: https://en.wikipedia.org/wiki/SoundnessT-compilerRelevant to the compiler team, which will review and decide on the PR/issue.T-langRelevant to the language team, which will review and decide on the PR/issue.fixed-by-NLLBugs fixed, but only when NLL is enabled.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions