Skip to content

Diagnostics for two-phase borrows are confusing and unhelpful #77826

Closed
@Rik-de-Kort

Description

@Rik-de-Kort

When I have a struct with two methods on the impl, both borrowing self mutably, I cannot chain the functions, like s.second(s.first()): I get a borrow checker error. Instead, I have to assign s.first() to an auxiliary variable. Might be related to #21906 but could not find any other similar issues.

struct S{}

impl S{
    fn first(&mut self) -> bool{
        true
    }
    
    fn second(&mut self, b: bool) {
        if b { println!{"Hello, world!"}; }
    }
}

fn main() {
    let mut s = S{};
    s.second(s.first());
}

I expected to see this happen: a simple print of "hello world!"

Instead, this happened:

   Compiling playground v0.0.1 (/playground)
error[E0499]: cannot borrow `s` as mutable more than once at a time
  --> src/main.rs:15:14
   |
15 |     s.second(s.first())
   |     - ------ ^ second mutable borrow occurs here
   |     | |
   |     | first borrow later used by call
   |     first mutable borrow occurs here

error: aborting due to previous error

For more information about this error, try `rustc --explain E0499`.
error: could not compile `playground`

To learn more, run the command again with --verbose.

It works fine if we use an auxiliary variable, which looks quite ugly to my mind:

fn main() {
    let mut s = S{};
    let f = s.first();
    s.second(s.first());
}

Playground link

Metadata

Metadata

Assignees

No one assigned

    Labels

    D-confusingDiagnostics: Confusing error or lint that should be reworked.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.T-langRelevant to the language team

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions