Open
Description
Code
#[derive(Debug, Clone)]
pub struct Inner {
pub name: String,
pub data: Vec<String>,
}
#[derive(Debug, Clone)]
pub struct Outer {
inner: Inner,
pub extra: i32,
}
impl std::ops::Deref for Outer {
type Target = Inner;
fn deref(&self) -> &Self::Target {
&self.inner
}
}
impl From<Outer> for String {
fn from(value: Outer) -> String {
// This tries to move through Deref, causing the error
value.name // Error occurs here
}
}
Current output
When a struct implements Deref
and you try to move a field that's accessed through the deref target, the error message focuses on cloning rather than explaining the deref issue:
error[E0507]: cannot move out of dereference of `Outer`
--> src/lib.rs:20:9
|
20 | value.name
| ^^^^^^^^^^ move occurs because value has type `String`, which does not implement the `Copy` trait
|
help: consider cloning the value if the performance cost is acceptable
|
20 | value.name.clone()
| ++++++++
Desired output
The error message should be enhanced to:
- Explain the
Deref
involvement when applicable - Suggest direct field access as the primary solution when possible
- Provide cloning as a secondary option
- Make it clear why the move is failing
error[E0507]: cannot move out of dereference of `Outer`
--> src/lib.rs:20:9
|
20 | value.name
| ^^^^^^^^^^ move occurs because `name` is accessed through `Deref` to `Inner`
|
note: `Outer` implements `Deref<Target = Inner>`, so `value.name` is equivalent to `(*value).name`
help: access the field directly from the owned struct instead of through `Deref`
|
20 | value.inner.name
| ++++++
help: or consider cloning the value if the performance cost is acceptable
|
20 | value.name.clone()
| ++++++++
Rationale and extra context
Summary
The current error message for attempting to move out of a dereferenced value can be misleading, especially when the type implements Deref
. The compiler suggests cloning as the primary solution, but often the real issue is that the user is accidentally accessing fields through Deref
instead of accessing the owned fields directly.
Problem
The current error message has several issues:
- Misleading suggestion: It suggests cloning as the primary solution, which may be unnecessary
- Missing context: It doesn't explain that the field access is going through
Deref
- No alternative solutions: It doesn't mention that accessing the field directly might be possible
- Unclear root cause: Users may not understand why they're getting a "dereference" error when they own the value
Benefits
This improvement would:
- Reduce confusion for developers encountering this error
- Promote better practices by suggesting direct field access over unnecessary cloning
- Improve learning by explaining the underlying mechanism
- Save performance by avoiding unnecessary clones when direct access is possible
Rust Version
rustc 1.87.0 (17067e9ac 2025-05-09)
binary: rustc
commit-hash: 17067e9ac6d7ecb70e50f92c1944e545188d2359
commit-date: 2025-05-09
host: x86_64-pc-windows-msvc
release: 1.87.0
LLVM version: 20.1.1