Closed
Description
This is actually an unsoundness in AST borrowck: AST borrowck doesn't check things that are matched on for conflicting borrows unless there are actually pattern bindings, e.g. this compiles:
enum Xyz {
A,
B,
}
fn main() {
let mut e = Xyz::A;
let f = &mut e;
match e {
Xyz::A => println!("a"),
Xyz::B => println!("b"),
};
*f = Xyz::B;
}
That is unsound because of e.g. data races. For example, this code compiles and runs, and semi-reliably segfaults:
#![feature(test)]
use std::{thread, time};
extern crate crossbeam;
extern crate test;
enum Xyz<'a> {
A(&'a usize),
B(usize),
}
fn main() {
let mut e = Xyz::A(&0);
crossbeam::scope(|scope| {
scope.spawn(|| {
let now = time::Instant::now();
let ten_millis = time::Duration::from_millis(50);
while now.elapsed() < ten_millis {
for _ in 0..1000000 {
e = Xyz::A(&0);
test::black_box(()); // compiler barrier
e = Xyz::B(0xaaaaaaaa);
}
}
});
let ten_millis = time::Duration::from_millis(10);
thread::sleep(ten_millis);
match e {
Xyz::A(&0) => println!("a"),
_ => println!("b"),
};
});
}