Skip to content

Confusing error message on deref-coercion after partial move out #73268

Closed
@Aaron1011

Description

@Aaron1011

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

No one assigned

    Labels

    A-coercionsArea: implicit and explicit `expr as Type` coercionsA-diagnosticsArea: Messages for errors, warnings, and lintsC-enhancementCategory: An issue proposing an enhancement or a PR with one.D-confusingDiagnostics: Confusing error or lint that should be reworked.D-newcomer-roadblockDiagnostics: Confusing error or lint; hard to understand for new users.T-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