-
Notifications
You must be signed in to change notification settings - Fork 12.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
NLL (two-phase-borrows) regression: image
crate
#48357
Comments
I'd like to work on this. |
There actually seems to be two distinct issues at play here. One is #48495 - The main cause of the This snippet compiles with ast-borrowck, but not with NLL (playground): #![feature(nll)]
enum SimpleFoo {
Ref(u8)
}
fn bar(mut foo: SimpleFoo) {
match foo {
SimpleFoo::Ref(ref mut inner) | SimpleFoo::Ref(ref mut inner) => {
println!("Inner: {:?}", inner);
},
}
}
fn main() {
bar(SimpleFoo::Ref(5));
} NLL seems to be treating the two 'ref mut's as distinct borrows, even though only one of them will ever be used. |
I believe the issue has to do with how Any solution needs to ensure that snippets like this one continue to not compile: #![feature(nll)]
fn bar(a: u8) {
let mut first = 5;
let mut second = 6;
let temp;
match a {
10 => {
temp = &mut first;
},
20 => {
temp = &mut second;
}
_ => panic!()
}
println!("Variables: {:?} {:?}", first, second);
*temp = 7;
}
fn main() {} I think the best approach would be to change how the |
A related regression: #![feature(nll)]
fn bar(a: usize) {
let mut first = 5;
let temp;
match a {
10 => {
temp = &mut first;
},
20 => {
temp = &mut first;
}
_ => panic!()
}
println!("Temp: {:?}", temp);
}
fn main() {
bar(10)
} The general theme seems to be that the depth-first search performed by region inference seems to be interacting badly with multiple borrows of the same place. In general, region inference is doing the right thing- even though only branch will ever be taken, borrow checking needs to act as though both are taken, so that things like my previous snippet correctly fail to compile. However, we run into problems when the same place is borrowed in multiple blocks that eventually flow to the same target. What we really care about is ensuring that the place remains borrowed - which branch the borrow occurs on isn't important. |
One more minimization: #![feature(nll)]
fn bar(a: bool) {
let mut first = 5;
let temp;
if a {
temp = &mut first;
} else {
temp = &mut first;
}
*temp = 20;
}
fn main() {
bar(true)
} |
I believe @nikomatsakis was correct - this seems to be a duplicate of #48070, as removing |
This should in theory be fixed now -- certainly the minimizations by @Aaron1011 have been fixed. |
Confirmed that |
rustc 1.25.0-nightly (27a046e 2018-02-18), https://github.com/PistonDevelopers/image, output with an unrelated warning removed.
cargo +nightly build
: OKcargo +nightly rustc -- -Znll
: OKcargo +nightly rustc -- -Znll -Ztwo-phase-borrows
cargo +nightly rustc -- -Zborrowck=mir -Ztwo-phase-borrows
The text was updated successfully, but these errors were encountered: