Skip to content

type mismatch in closure arguments without annotation with reference arguments #72658

@ogoffart

Description

@ogoffart

I tried something looking like this:
(but obviously the actual program was more complex)

struct X {
    do_something : Box<dyn Fn(&u32)>,
}

fn main() {
    let f = |_| { println!("something") };
    let _ = X { do_something: Box::new(f) };
}

And i got quite confused by the error:

error[E0631]: type mismatch in closure arguments
 --> src/main.rs:9:31
  |
8 |     let f = |_| { println!("something") };
  |             --- found signature of `fn(_) -> _`
9 |     let _ = X { do_something: Box::new(f) };
  |                               ^^^^^^^^^^^ expected signature of `for<'r> fn(&'r u32) -> _`
  |
  = note: required for the cast to the object type `dyn for<'r> std::ops::Fn(&'r u32)`

error[E0271]: type mismatch resolving `for<'r> <[closure@src/main.rs:8:13: 8:42] as std::ops::FnOnce<(&'r u32,)>>::Output == ()`
 --> src/main.rs:9:31
  |
9 |     let _ = X { do_something: Box::new(f) };
  |                               ^^^^^^^^^^^ expected bound lifetime parameter, found concrete lifetime
  |
  = note: required for the cast to the object type `dyn for<'r> std::ops::Fn(&'r u32)`

error: aborting due to 2 previous errors

I found ways to get that work: annotating the closure argument like so:

    let f = |_: &u32| { println!("something") };

Maybe the error message should suggest that.

But I would actually even expect this to work without annotations, since it works fine if the argument is not a reference. (ie: no errors if the type is Box<dyn Fn(u32)>)

Meta

rustc --version --verbose:

rustc 1.43.0 (4fb7144ed 2020-04-20)
binary: rustc
commit-hash: 4fb7144ed159f94491249e86d5bbd033b5d60550
commit-date: 2020-04-20
host: x86_64-unknown-linux-gnu
release: 1.43.0
LLVM version: 9.0

(also reproduced with nightly on rust playground)

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-closuresArea: Closures (`|…| { … }`)A-diagnosticsArea: Messages for errors, warnings, and lintsA-inferenceArea: Type inferenceC-bugCategory: This is a bug.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.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions