Rollup merge of #115999 - matthewjasper:closure-capture-let-guards, r=b-naber
Capture scrutinee of if let guards correctly Previously we were always capturing by value. cc #51114
This commit is contained in:
commit
e6f4b35d9f
5 changed files with 164 additions and 4 deletions
|
@ -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…
Add table
Add a link
Reference in a new issue