Skip to content

Possibly confusing error message when deref/deref_mut are used. #58843

@real-felix

Description

@real-felix

Beginners can be confused when deref and deref_mut are called implicitely:

In this given code:

struct Foo { a: Vec<i32>, b: Vec<i32>, } fn add(foo: std::sync::Mutex<Foo>) { let f = foo.lock().unwrap(); for i in &mut f.a { for j in &f.b { *i += *j; } } }

The error message is not the clearest:

error[E0502]: cannot borrow `f` as immutable because it is also borrowed as mutable --> src/lib.rs:10:19 | 9 | for i in &mut f.a { | -------- | | | | | mutable borrow occurs here | mutable borrow used here, in later iteration of loop 10 | for j in &f.b { | ^ immutable borrow occurs here 

The users could not understand that the borrows are done by deref and deref_mut, since the calls are implicit. They could think that, for an unknown reason, the borrow checker does not understand that the fields are disjoint.

I think that it would be an improvement if the compiler added that the implicit call to deref/deref_mut is responsible of the borrowing:

error[E0502]: cannot borrow `f` as immutable because it is also borrowed as mutable --> src/lib.rs:10:19 | 9 | for i in &mut f.a { | -------- | | | | | mutable borrow occurs here due to a call to `Deref::deref` | mutable borrow used here, in later iteration of loop 10 | for j in &f.b { | ^ immutable borrow occurs here due to a call to `DerefMut::deref_mut` 

This could be even better if the compiler gave the solution:

You can call `DerefMut::deref_mut` before borrowing the fields: --> src/lib.rs:8:1 7 | let mut f = foo.lock().unwrap(); | let f = DerefMut::deref_mut(&mut f); ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-diagnosticsArea: Messages for errors, warnings, and lintsC-enhancementCategory: An issue proposing an enhancement or a PR with one.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