Skip to content

Confusing compiler error with auto-deref on a type without DerefMut to call a function requiring &mut self #57839

Closed

Description

This seems to be slightly related to #28419 but maybe not the same as the error is a different? Feel free to close if it actually is the same.

use std::ops;

struct Foo(Bar);

struct Bar;

impl ops::Deref for Foo {
    type Target = Bar;
    fn deref(&self) -> &Bar {
        &self.0
    }
}

impl Bar {
    fn do_stuff(&mut self) {}
}

fn main() {
    let mut f = Foo(Bar);
    f.do_stuff();
}

This currently gives the following error

error[E0596]: cannot borrow data in a `&` reference as mutable
  --> src/main.rs:20:5
   |
20 |     f.do_stuff();
   |     ^ cannot borrow as mutable

error: aborting due to previous error

There are multiple problems with that error message:
a) A DerefMut impl would be needed but that's not what it writes
b) It's unclear where the & reference in that line comes from (auto-deref!)
c) f itself can actually be borrowed mutable, but the error suggests that it can't and that this is the problem

Maybe there's some opportunity for generally improving error messages when auto-deref is involved, and somehow making that clear in the error message. E.g. by putting another paragraph there saying when calling do_stuff() on type Foo caused by auto-deref or similar, or maybe similar to how borrow errors are shown ("which was borrowed mutable $here") by marking in a separate message that auto-deref has happened here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Assignees

No one assigned

    Labels

    A-diagnosticsArea: Messages for errors, warnings, and lints

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions