Closed
Description
The following code:
use std::ops::Deref;
struct NotCopy {
inner: bool
}
struct Foo {
first: NotCopy,
second: NotCopy
}
impl Deref for Foo {
type Target = NotCopy;
fn deref(&self) -> &NotCopy {
&self.second
}
}
fn use_it(val: Foo) {
let inner = val.first;
//val.second;
val.inner;
}
gives the following error message:
error[E0382]: borrow of moved value: `val`
--> src/lib.rs:22:5
|
20 | let inner = val.first;
| --------- value moved here
21 | //val.second;
22 | val.inner;
| ^^^ value borrowed here after partial move
|
= note: move occurs because `val.first` has type `NotCopy`, which does not implement the `Copy` trait
This error occurs because val.inner
performs a deref-coercion to access the field inner
on NotCopy
. However, this is not mentioned in the error message - we instead refer to val being 'borrowed' by what appears to be a normal field access.
If val.second
is uncommented, and val.inner
commented out, the code compiles successfully. This may be very confusing to users who don't realize that only one field involves a deref-coercion, as it looks like either access should be allowed.
When a move error occurs, we should explicitly mention any deref-coercions that occur, and explain why they prevent the code from compiling.
Metadata
Metadata
Assignees
Labels
Area: implicit and explicit `expr as Type` coercionsArea: Messages for errors, warnings, and lintsCategory: An issue proposing an enhancement or a PR with one.Diagnostics: Confusing error or lint that should be reworked.Diagnostics: Confusing error or lint; hard to understand for new users.Relevant to the compiler team, which will review and decide on the PR/issue.