Skip to content

E0596 explanation points to return type, not the argument type of called function #119985

@danjl1100

Description

@danjl1100

Code

struct MyVec<T>(T);

impl<T> MyVec<T> {
    fn replace_with<U>(&self, mut f: impl FnMut() -> U) -> MyVec<U> {
        // reports correct error E0596,
        // but with odd explanation in the rustc output:   -------- ""change this to return `FnMut` instead of `Fn`""
        self.map(|_| f())
    }
    fn map<U>(&self, _: impl Fn(&T) -> U) -> MyVec<U> {
        todo!()
    }
}

Current output

error[E0596]: cannot borrow `f` as mutable, as it is a captured variable in a `Fn` closure
 --> src/lib.rs:7:22
  |
4 |     fn replace_with<U>(&self, mut f: impl FnMut() -> U) -> MyVec<U> {
  |        ------------                                        -------- change this to return `FnMut` instead of `Fn`
...
7 |         self.map(|_| f())
  |                  --- ^ cannot borrow as mutable
  |                  |
  |                  in this closure

For more information about this error, try `rustc --explain E0596`.

Desired output

error[E0596]: cannot borrow `f` as mutable, as it is a captured variable in a `Fn` closure
 --> src/lib.rs:7:22
  |
7 |         self.map(|_| f())
  |         -------- --- ^ cannot borrow as mutable
  |         |        |
  |         |        in this closure
  |         expects `Fn` instead of `FnMut`
8 |     }
9 |     fn map<U>(&self, _: impl Fn(&T) -> U) -> MyVec<U> {
  |                         ---------------- change this to accept `FnMut` instead of `Fn`

For more information about this error, try `rustc --explain E0596`.

Rationale and extra context

Affected playground, with correct error but misleading explanation.

Removing impl block and self parameters shows the correct/expected diagnostic explanation,
demonstrated in this playground

Other cases

No response

Rust Version

Duplicated on playground with both "Stable 1.75.0", and on playground selecting nightly:

Build using the Nightly version: 1.77.0-nightly
(2024-01-13 d78329b92e8d141d1950)

Anything else?

Overall, not a huge issue - the actual error indication is correct.
The small oddity is where it points to the function return type as the location of the Fn. This took me a bit to identify the mismatched Fn/FnMut 🙂

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
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions