Closed
Description
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);
}