You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
binding-less matches on borrowed data are incorrectly allowed #45045
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:
enumXyz{A,B,}fnmain(){letmut 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};externcrate crossbeam;externcrate test;enumXyz<'a>{A(&'ausize),B(usize),}fnmain(){letmut 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 _ in0..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"),};});}
@pnkfelix points out that two-phase borrows may be the cause. This example gets an error:
#![feature(nll)]enumXyz{A,B,}fnmain(){letmut e = Xyz::A;let f = &mut e;let g = f;match e {Xyz::A => println!("a"),Xyz::B => println!("b"),};*g = Xyz::B;}
this gets the following output:
error[E0503]: cannot use `e` because it was mutably borrowed
--> src/main.rs:13:9
|
10 | let f = &mut e;
| ------ borrow of `e` occurs here
...
13 | Xyz::A => println!("a"),
| ^^^^^^ use of borrowed `e`
Activity
bstrie commentedon Oct 10, 2017
Does this imply that this is another bug on the pile of things fixed by MIR borrowck?
arielb1 commentedon Oct 11, 2017
Yeah.
nikomatsakis commentedon Jan 4, 2018
This still compiles with MIR borrowck, so I guess more work is needed.
nikomatsakis commentedon Jan 11, 2018
Is this same problem as #27282 ?
nikomatsakis commentedon Jan 11, 2018
It seems like the problem is that the
discriminantstatement is not considered an access. Here is the relevant portion of the MIR:nikomatsakis commentedon Jan 11, 2018
@pnkfelix points out that two-phase borrows may be the cause. This example gets an error:
this gets the following output:
nikomatsakis commentedon Jan 11, 2018
Copying @arielb1's segfaulting example and enabling nll mode also gives an error playpen
arielb1 commentedon Jan 13, 2018
@nikomatsakis
That's indeed what I expect under 2-phase borrows.
Add NLL test for rust-lang#45045
Rollup merge of rust-lang#47456 - chrisvittal:nll-tests, r=nikomatsakis
Rollup merge of rust-lang#47456 - chrisvittal:nll-tests, r=nikomatsakis