Closed
Description
E0507 E0009 should be mutually exclusive
E0009
cannot bind by-move and by-ref in the same pattern
E0507
cannot move out of borrowed content
Example
fn main() {
Holder {
copy_type: 0,
almost_copy: AlmostCopy(42),
never_copy: "Hello world".to_string(),
}.func()
}
#[derive(Debug)]
struct AlmostCopy(usize);
#[derive(Debug)]
struct Holder {
copy_type: usize,
almost_copy: AlmostCopy,
never_copy: String,
}
impl Holder {
fn func(&self) {
let &Holder {
copy_type,
almost_copy,
ref never_copy,
} = self;
println!(
"{}: {:?} -- {:?}",
copy_type,
almost_copy,
never_copy,
);
}
}
Output
Compiling playground v0.0.1 (/playground)
error[E0009]: cannot bind by-move and by-ref in the same pattern
--> src/main.rs:24:13
|
24 | almost_copy,
| ^^^^^^^^^^^ by-move pattern here
25 | ref never_copy,
| -------------- both by-ref and by-move used
error[E0507]: cannot move out of `self.almost_copy` which is behind a shared reference
--> src/main.rs:26:13
|
24 | almost_copy,
| -----------
| |
| data moved here
| move occurs because `almost_copy` has type `AlmostCopy`, which does not implement the `Copy` trait
25 | ref never_copy,
26 | } = self;
| ^^^^
help: consider removing the `&`
|
22 | let Holder {
23 | copy_type,
24 | almost_copy,
25 | ref never_copy,
26 | } = self;
|
error: aborting due to 2 previous errors
Some errors have detailed explanations: E0009, E0507.
For more information about an error, try `rustc --explain E0009`.
error: Could not compile `playground`.
To learn more, run the command again with --verbose.
Reasoning
A situation where both trigger, E0507
is a much more clear indication of something wrong in the code. In this example, the intention is that AlmostCopy
implements Copy
, and will subsequently trigger neither error. The presence of E0009
is misleading when it doesn't include any mention of Copy
without the click-through.