Skip to content

Improve error message when attempting to move out of Deref target #141878

Open
@CorrM

Description

@CorrM

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:

  1. Explain the Deref involvement when applicable
  2. Suggest direct field access as the primary solution when possible
  3. Provide cloning as a secondary option
  4. 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:

  1. Misleading suggestion: It suggests cloning as the primary solution, which may be unnecessary
  2. Missing context: It doesn't explain that the field access is going through Deref
  3. No alternative solutions: It doesn't mention that accessing the field directly might be possible
  4. Unclear root cause: Users may not understand why they're getting a "dereference" error when they own the value

Benefits

This improvement would:

  1. Reduce confusion for developers encountering this error
  2. Promote better practices by suggesting direct field access over unnecessary cloning
  3. Improve learning by explaining the underlying mechanism
  4. 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

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-diagnosticsArea: Messages for errors, warnings, and lintsT-compilerRelevant to the compiler team, which will review and decide on the PR/issue.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions