Capture scrutinee of if let guards correctly
Previously we were always capturing by value.
This commit is contained in:
parent
62d9034a0d
commit
d4ffb3b08a
@ -664,10 +664,12 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> {
|
|||||||
);
|
);
|
||||||
self.walk_pat(discr_place, arm.pat, arm.guard.is_some());
|
self.walk_pat(discr_place, arm.pat, arm.guard.is_some());
|
||||||
|
|
||||||
if let Some(hir::Guard::If(e)) = arm.guard {
|
match arm.guard {
|
||||||
self.consume_expr(e)
|
Some(hir::Guard::If(ref e)) => self.consume_expr(e),
|
||||||
} else if let Some(hir::Guard::IfLet(ref l)) = arm.guard {
|
Some(hir::Guard::IfLet(ref l)) => {
|
||||||
self.consume_expr(l.init)
|
self.walk_local(l.init, l.pat, None, |t| t.borrow_expr(l.init, ty::ImmBorrow))
|
||||||
|
}
|
||||||
|
None => {}
|
||||||
}
|
}
|
||||||
|
|
||||||
self.consume_expr(arm.body);
|
self.consume_expr(arm.body);
|
||||||
|
@ -0,0 +1,33 @@
|
|||||||
|
error[E0505]: cannot move out of `value` because it is borrowed
|
||||||
|
--> $DIR/if-let-guards-errors.rs:16:13
|
||||||
|
|
|
||||||
|
LL | let f = |x: &E| {
|
||||||
|
| ------- borrow of `value` occurs here
|
||||||
|
LL | match &x {
|
||||||
|
LL | E::Number(_) if let E::Number(ref mut n) = *value => { }
|
||||||
|
| ------ borrow occurs due to use in closure
|
||||||
|
...
|
||||||
|
LL | let x = value;
|
||||||
|
| ^^^^^ move out of `value` occurs here
|
||||||
|
LL |
|
||||||
|
LL | drop(f);
|
||||||
|
| - borrow later used here
|
||||||
|
|
||||||
|
error[E0382]: use of moved value: `value`
|
||||||
|
--> $DIR/if-let-guards-errors.rs:28:13
|
||||||
|
|
|
||||||
|
LL | fn if_let_move(value: Box<E>) {
|
||||||
|
| ----- move occurs because `value` has type `Box<E>`, which does not implement the `Copy` trait
|
||||||
|
LL | let f = |x: &E| {
|
||||||
|
| ------- value moved into closure here
|
||||||
|
LL | match &x {
|
||||||
|
LL | E::Number(_) if let E::String(s) = *value => { }
|
||||||
|
| ------ variable moved due to use in closure
|
||||||
|
...
|
||||||
|
LL | let x = value;
|
||||||
|
| ^^^^^ value used here after move
|
||||||
|
|
||||||
|
error: aborting due to 2 previous errors
|
||||||
|
|
||||||
|
Some errors have detailed explanations: E0382, E0505.
|
||||||
|
For more information about an error, try `rustc --explain E0382`.
|
@ -0,0 +1,33 @@
|
|||||||
|
error[E0505]: cannot move out of `value` because it is borrowed
|
||||||
|
--> $DIR/if-let-guards-errors.rs:16:13
|
||||||
|
|
|
||||||
|
LL | let f = |x: &E| {
|
||||||
|
| ------- borrow of `*value` occurs here
|
||||||
|
LL | match &x {
|
||||||
|
LL | E::Number(_) if let E::Number(ref mut n) = *value => { }
|
||||||
|
| ------ borrow occurs due to use in closure
|
||||||
|
...
|
||||||
|
LL | let x = value;
|
||||||
|
| ^^^^^ move out of `value` occurs here
|
||||||
|
LL |
|
||||||
|
LL | drop(f);
|
||||||
|
| - borrow later used here
|
||||||
|
|
||||||
|
error[E0382]: use of moved value: `value`
|
||||||
|
--> $DIR/if-let-guards-errors.rs:28:13
|
||||||
|
|
|
||||||
|
LL | fn if_let_move(value: Box<E>) {
|
||||||
|
| ----- move occurs because `value` has type `Box<E>`, which does not implement the `Copy` trait
|
||||||
|
LL | let f = |x: &E| {
|
||||||
|
| ------- value moved into closure here
|
||||||
|
LL | match &x {
|
||||||
|
LL | E::Number(_) if let E::String(s) = *value => { }
|
||||||
|
| ------ variable moved due to use in closure
|
||||||
|
...
|
||||||
|
LL | let x = value;
|
||||||
|
| ^^^^^ value used here after move
|
||||||
|
|
||||||
|
error: aborting due to 2 previous errors
|
||||||
|
|
||||||
|
Some errors have detailed explanations: E0382, E0505.
|
||||||
|
For more information about an error, try `rustc --explain E0382`.
|
@ -0,0 +1,37 @@
|
|||||||
|
// Check the if let guards don't force capture by value
|
||||||
|
// revisions: e2018 e2021
|
||||||
|
//[e2018] edition:2018
|
||||||
|
//[e2021] edition:2021
|
||||||
|
|
||||||
|
#![feature(if_let_guard)]
|
||||||
|
#![allow(irrefutable_let_patterns)]
|
||||||
|
|
||||||
|
fn if_let_ref_mut(mut value: Box<E>) {
|
||||||
|
let f = |x: &E| {
|
||||||
|
match &x {
|
||||||
|
E::Number(_) if let E::Number(ref mut n) = *value => { }
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
let x = value;
|
||||||
|
//~^ ERROR cannot move out of `value` because it is borrowed
|
||||||
|
drop(f);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn if_let_move(value: Box<E>) {
|
||||||
|
let f = |x: &E| {
|
||||||
|
match &x {
|
||||||
|
E::Number(_) if let E::String(s) = *value => { }
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
let x = value;
|
||||||
|
//~^ ERROR use of moved value: `value`
|
||||||
|
}
|
||||||
|
|
||||||
|
enum E {
|
||||||
|
String(String),
|
||||||
|
Number(i32),
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {}
|
@ -0,0 +1,55 @@
|
|||||||
|
// Check the if let guards don't force capture by value
|
||||||
|
// revisions: e2018 e2021
|
||||||
|
// check-pass
|
||||||
|
//[e2018] edition:2018
|
||||||
|
//[e2021] edition:2021
|
||||||
|
|
||||||
|
#![feature(if_let_guard)]
|
||||||
|
#![allow(irrefutable_let_patterns)]
|
||||||
|
|
||||||
|
fn if_let_underscore(value: Box<E>) {
|
||||||
|
|x: &E| {
|
||||||
|
match &x {
|
||||||
|
E::Number(_) if let _ = *value => { }
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
let x = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn if_let_copy(value: Box<E>) {
|
||||||
|
|x: &E| {
|
||||||
|
match &x {
|
||||||
|
E::Number(_) if let E::Number(n) = *value => { }
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
let x = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn if_let_ref(value: Box<E>) {
|
||||||
|
|x: &E| {
|
||||||
|
match &x {
|
||||||
|
E::Number(_) if let E::Number(ref n) = *value => { }
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
let x = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn if_let_ref_mut(mut value: Box<E>) {
|
||||||
|
|x: &E| {
|
||||||
|
match &x {
|
||||||
|
E::Number(_) if let E::Number(ref mut n) = *value => { }
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
let x = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
enum E {
|
||||||
|
String(String),
|
||||||
|
Number(i32),
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {}
|
Loading…
x
Reference in New Issue
Block a user