Skip to content

Misleading diagnostic when type inference for Box<dyn FnOnce()> fails #85567

Open
@lukas-code

Description

@lukas-code

Given the following code: (playground link)

use std::marker::PhantomData;

struct Receiver<T> {
    _phantom: PhantomData<T>,
}

impl<T> Receiver<T> {
    fn new() -> Self {
        Self {
            _phantom: PhantomData,
        }
    }

    fn get(&self) -> T {
        unimplemented!()
    }
}

fn main() {
    let receiver: Receiver<Box<_>> = Receiver::new();
    let function = receiver.get();
    function();
    let _: Receiver<Box<dyn FnOnce()>> = receiver;
}

The current output is:

   Compiling playground v0.0.1 (/playground)
error[E0277]: expected a `Fn<()>` closure, found `dyn FnOnce()`
  --> src/main.rs:22:5
   |
22 |     function();
   |     ^^^^^^^^^^ expected an `Fn<()>` closure, found `dyn FnOnce()`
   |
   = help: the trait `Fn<()>` is not implemented for `dyn FnOnce()`
   = note: wrap the `dyn FnOnce()` in a closure with no arguments: `|| { /* code */ }`
   = note: required because of the requirements on the impl of `Fn<()>` for `Box<dyn FnOnce()>`

error: aborting due to previous error

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

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

Ideally the output should look like:

   Compiling playground v0.0.1 (/playground)
error[E0282]: type annotations needed for `Receiver<Box<_>>`
  --> src/main.rs:20:19
   |
20 |     let receiver: Receiver<Box<_>> = Receiver::new();
   |         --------  ^^^^^^^^^^^^^^^^ cannot infer type
   |         |
   |         consider giving `receiver` the explicit type `Receiver<Box<_>>`, with the type parameters specified

error: aborting due to previous error

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

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

Removing the last line in main or removing the type annotation of receiver will give this output.

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