Skip to content

Mutable slices as function parameters allow aliasing mutable references #40288

Closed
@abonander

Description

@abonander

This currently affects all 3 release channels.

If you have a mutable slice of references as an input to a function, it allows borrows to escape and cause aliasing. The following example compiles and prints "3", but it shouldn't compile at all (Playground):

fn save_ref<'a>(refr: &'a i32, to: &mut [&'a i32]) {
    for val in &mut *to {
        *val = refr;
    }
}

fn main() {
    let ref init = 0i32;
    let ref mut refr = 1i32;

    let mut out = [init];
    
    save_ref(&*refr, &mut out);
    
    // This shouldn't be allowed as `refr` is borrowed
    *refr = 3;
    
    // Prints 3?!
    println!("{:?}", out[0]);
}

This appears to be tied to slices as the non-slice equivalent fails to compile as expected (Playground):

fn save_ref<'a>(refr: &'a i32, to: &mut &'a i32) {
    *to = refr;
}

fn main() {
    let ref mut refr = 1i32;
    let mut out = &0i32;
    
    save_ref(&*refr, &mut out);
    
    // ERROR: cannot assign to `*refr` because it is borrowed
    *refr = 3;

    println!("{:?}", out);
}

cc seanmonstar/httparse#34

Metadata

Metadata

Assignees

Labels

I-unsoundIssue: A soundness hole (worst kind of bug), see: https://en.wikipedia.org/wiki/SoundnessP-highHigh priorityT-compilerRelevant to the compiler team, which will review and decide on the PR/issue.

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions