In the code below the example_1
function compiles, whereas example_2
fails to compile.
In principle the compiler could infer that the value of f
is no longer used elsewhere, since f
is set to None
similar to example_1
. Can someone explain why compiling example_2
fails nevertheless with an E0507
?
enum Foo {
Bar,
Baz
}
pub fn example_1() {
let mut f: Option<Foo> = Some(Foo::Bar);
loop {
match (1, &f) {
(_, Some(_)) => {
let g = f.unwrap();
f = None
},
(_, None) => println!("None"),
}
if true { break }
}
}
pub fn example_2() {
let mut f: Option<Foo> = Some(Foo::Bar);
loop {
match (1, &f) {
(_, Some(fr)) => {
// error[E0507]: cannot move out of `*fr` which is behind a shared reference
let g = *fr;
f = None
},
(_, None) => println!("None"),
}
if true { break }
}
}
Errors:
Compiling playground v0.0.1 (/playground)
warning: unused variable: `g`
--> src/lib.rs:14:21
|
14 | let g = f.unwrap();
| ^ help: if this is intentional, prefix it with an underscore: `_g`
|
= note: `#[warn(unused_variables)]` on by default
warning: unused variable: `g`
--> src/lib.rs:36:21
|
36 | let g = *fr;
| ^ help: if this is intentional, prefix it with an underscore: `_g`
error[E0507]: cannot move out of `*fr` which is behind a shared reference
--> src/lib.rs:36:25
|
36 | let g = *fr;
| ^^^ move occurs because `*fr` has type `Foo`, which does not implement the `Copy` trait
|
note: if `Foo` implemented `Clone`, you could clone the value
--> src/lib.rs:1:1
|
1 | enum Foo {
| ^^^^^^^^ consider implementing `Clone` for this type
...
36 | let g = *fr;
| --- you could clone this value
help: consider removing the dereference here
|
36 - let g = *fr;
36 + let g = fr;
|
For more information about this error, try `rustc --explain E0507`.
warning: `playground` (lib) generated 2 warnings
error: could not compile `playground` (lib) due to 1 previous error; 2 warnings emitted