Skip to content

Confusing diagnostic when using closures #81511

Open
@StyMaar

Description

@StyMaar

When trying to compile this code (Rust stable 1.49.0)

fn my_function(callback: impl FnMut(&str) + Send + 'static){}

fn main(){
    let closure_consumer = |data| {};
    my_function(closure_consumer);
}

I expected it to compile fine,

Instead, we get this funny nonsensical error :

  |
  |     my_function(closure_consumer);
  |     ^^^^^^^^^^^ one type is more general than the other
  |
  = note: expected type `FnOnce<(&str,)>`
             found type `FnOnce<(&str,)>`

The code compiles fine if we add a type annotation to the closure (notice the |data: &str|)

fn my_function(callback: impl FnMut(&str) + Send + 'static){}

fn main(){
    let closure_consumer = |data: &str| {};
    my_function(closure_consumer);
}

This may be a type inference bug (because closure are supposed to work even without type annotations) but it's also (and most importantly IMHO) a diagnostic bug, because the error gives me zero information about what is going on.

When compiling with the latest nightly (1.51.0-nightly (2021-01-28 c0b64d9)), we have a more detailed error, but it doesn't make a better job at explaining what we are supposed to do to make this code run :

  |
6 |     my_function(closure_consumer);
  |     ^^^^^^^^^^^ lifetime mismatch
  |
  = note: expected type `FnOnce<(&str,)>`
             found type `FnOnce<(&str,)>`
note: this closure does not fulfill the lifetime requirements
 --> src/main.rs:5:28
  |
5 |     let closure_consumer = |data| {};
  |                            ^^^^^^^^^
note: the lifetime requirement is introduced here
 --> src/main.rs:2:31
  |
2 | fn my_function(callback: impl FnMut(&str) + Send + 'static){}

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-closuresArea: Closures (`|…| { … }`)A-diagnosticsArea: Messages for errors, warnings, and lintsA-lifetimesArea: Lifetimes / regionsC-bugCategory: This is a bug.D-newcomer-roadblockDiagnostics: Confusing error or lint; hard to understand for new users.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