Skip to content

"this closure does not fulfill the lifetime requirements" could be more helpful #102877

Open

Description

@mejrs

Given the following code: https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=5ac285a480fc6ac1d4eb482768a4cec7

fn foo(_: &mut impl FnMut(&str)) {}

fn main() {
    let mut fun = |_arg| {};
    foo(&mut fun);
}

The current output is:

Compiling playground v0.0.1 (/playground)
error[[E0308]](https://doc.rust-lang.org/stable/error-index.html#E0308): mismatched types
 --> src/main.rs:5:5
  |
5 |     foo(&mut fun);
  |     ^^^^^^^^^^^^^ one type is more general than the other
  |
  = note: expected trait `for<'r> FnMut<(&'r str,)>`
             found trait `FnMut<(&str,)>`
note: this closure does not fulfill the lifetime requirements
 --> src/main.rs:4:19
  |
4 |     let mut fun = |_arg| {};
  |                   ^^^^^^
note: the lifetime requirement is introduced here
 --> src/main.rs:1:21
  |
1 | fn foo(_: &mut impl FnMut(&str)) {}
  |                     ^^^^^^^^^^^

error: implementation of `FnOnce` is not general enough
 --> src/main.rs:5:5
  |
5 |     foo(&mut fun);
  |     ^^^^^^^^^^^^^ implementation of `FnOnce` is not general enough
  |
  = note: closure with signature `fn(&'2 str)` must implement `FnOnce<(&'1 str,)>`, for any lifetime `'1`...
  = note: ...but it actually implements `FnOnce<(&'2 str,)>`, for some specific lifetime `'2`

For more information about this error, try `rustc --explain E0308`.
error: could not compile `playground` due to 2 previous errors

Ideally it should suggest naming the closure argument type:

let mut fun = |_arg: &str| {};
                   ++++++

Or it could say something else? I'm not sure what would make more sense, but this error isn't great.

Activity

  1. added
    A-diagnosticsArea: Messages for errors, warnings, and lints
    T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.
    on Oct 10, 2022
  2. kadiwa4 commented on Mar 1, 2024

    @kadiwa4
    Contributor

    [Outdated] Since #105888, rustc provides you with a working suggestion:

    Outdated output (2024-03-01)
    error[E0308]: mismatched types
     --> src/main.rs:5:5
      |
    5 |     foo(&mut fun);
      |     ^^^^^^^^^^^^^ one type is more general than the other
      |
      = note: expected trait `for<'a> FnMut(&'a str)`
                 found trait `FnMut(&str)`
    note: this closure does not fulfill the lifetime requirements
     --> src/main.rs:4:19
      |
    4 |     let mut fun = |_arg| {};
      |                   ^^^^^^
    note: the lifetime requirement is introduced here
     --> src/main.rs:1:21
      |
    1 | fn foo(_: &mut impl FnMut(&str)) {}
      |                     ^^^^^^^^^^^
    help: consider specifying the type of the closure parameters
      |
    4 |     let mut fun = |_arg: &_| {};
      |                   ~~~~~~~~~~
    
    error: implementation of `FnOnce` is not general enough
     --> src/main.rs:5:5
      |
    5 |     foo(&mut fun);
      |     ^^^^^^^^^^^^^ implementation of `FnOnce` is not general enough
      |
      = note: closure with signature `fn(&'2 str)` must implement `FnOnce<(&'1 str,)>`, for any lifetime `'1`...
      = note: ...but it actually implements `FnOnce<(&'2 str,)>`, for some specific lifetime `'2`
    
    For more information about this error, try `rustc --explain E0308`.
    error: could not compile `playground` (bin "playground") due to 2 previous errors
    

    Test is in tests/ui/lifetimes/issue-79187.

    Update: The suggestion was removed again in #119849.
    Updated, not so helpful output (2024-09-06):

    error: implementation of `FnMut` is not general enough
     --> src/main.rs:5:5
      |
    5 |     foo(&mut fun);
      |     ^^^^^^^^^^^^^ implementation of `FnMut` is not general enough
      |
      = note: closure with signature `fn(&'2 str)` must implement `FnMut<(&'1 str,)>`, for any lifetime `'1`...
      = note: ...but it actually implements `FnMut<(&'2 str,)>`, for some specific lifetime `'2`
    
    error: implementation of `FnOnce` is not general enough
     --> src/main.rs:5:5
      |
    5 |     foo(&mut fun);
      |     ^^^^^^^^^^^^^ implementation of `FnOnce` is not general enough
      |
      = note: closure with signature `fn(&'2 str)` must implement `FnOnce<(&'1 str,)>`, for any lifetime `'1`...
      = note: ...but it actually implements `FnOnce<(&'2 str,)>`, for some specific lifetime `'2`
    
    error: could not compile `playground` (bin "playground") due to 2 previous errors
    
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

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

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions