making a temporary tuple for pattern matching tries to move borrowed content
5d6b69b
Opened by Jack O'Connor at
This works, even though it looks like it's moving out of shared pointers, because of the ref keyword:
fn works(foo_opt1: &Option<Foo>, foo_opt2: &Option<Foo>) {
if let Some(ref foo1) = *foo_opt1 {
if let Some(ref foo2) = *foo_opt2 {
println!("this works")
}
}
}
However this very similar code does not work:
fn doesnt_work(foo_opt1: &Option<Foo>, foo_opt2: &Option<Foo>) {
if let (Some(ref foo1), Some(ref foo2)) = (*foo_opt1, *foo_opt2) {
println!("this does not compile!");
}
}
We get this error:
|
13 | if let (Some(ref foo1), Some(ref foo2)) = (*foo_opt1, *foo_opt2) {
| ^^^^^^^^^ cannot move out of borrowed content
It looks like the temporary tuple created on the right is a moving operation that can't be "undone" by the ref keyword. Could the compiler be smarter about this, or would that be unsound somehow?
This is expected.
*foo_opt1produces a place, which can then be matched on like in your first code. But the second code evaluates this place into the value, which is not allowed. The compiler still emits the same diagnostic, but I think it could be smarter here and emit a nicer error.nora at 2023-07-01 13:13:11