Skip to content

Trait bound not satisfied should specify "fn item" vs "fn ptr" kind #99875

Closed
@CAD97

Description

@CAD97

Given the following code: [playground]

struct Argument;
struct Return;

fn function(_: Argument) -> Return { todo!() }

trait Trait {}
impl Trait for fn(Argument) -> Return {}

fn takes(_: impl Trait) {}

fn main() {
    takes(function);
    takes(|_: Argument| -> Return { todo!() });
}

The current output is:

error[E0277]: the trait bound `fn(Argument) -> Return {function}: Trait` is not satisfied
  --> src/main.rs:12:11
   |
12 |     takes(function);
   |     ----- ^^^^^^^^ the trait `Trait` is not implemented for `fn(Argument) -> Return {function}`
   |     |
   |     required by a bound introduced by this call
   |
   = help: the trait `Trait` is implemented for `fn(Argument) -> Return`
note: required by a bound in `takes`
  --> src/main.rs:9:18
   |
9  | fn takes(_: impl Trait) {}
   |                  ^^^^^ required by this bound in `takes`

error[E0277]: the trait bound `[closure@src/main.rs:13:11: 13:34]: Trait` is not satisfied
  --> src/main.rs:13:5
   |
13 |     takes(|_: Argument| -> Return { todo!() });
   |     ^^^^^ the trait `Trait` is not implemented for `[closure@src/main.rs:13:11: 13:34]`
   |
   = help: the trait `Trait` is implemented for `fn(Argument) -> Return`
note: required by a bound in `takes`
  --> src/main.rs:9:18
   |
9  | fn takes(_: impl Trait) {}
   |                  ^^^^^ required by this bound in `takes`

Compare E0308 mismatched types: [playground]

error[E0308]: mismatched types
  --> src/main.rs:12:21
   |
12 |     let _: fn(()) = function;
   |            ------   ^^^^^^^^ expected `()`, found struct `Argument`
   |            |
   |            expected due to this
   |
   = note: expected fn pointer `fn(())`
                 found fn item `fn(Argument) -> Return {function}`

error[E0308]: mismatched types
  --> src/main.rs:13:21
   |
13 |     let _: fn(()) = |_: Argument| -> Return { todo!() };
   |            ------   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `()`, found struct `Argument`
   |            |
   |            expected due to this
   |
   = note: expected fn pointer `fn(())`
                 found closure `[closure@src/main.rs:13:21: 13:44]`

Ideally the output (of the reported example) should look like:

error[[E0277]](https://doc.rust-lang.org/nightly/error-index.html#E0277): the trait bound `fn(Argument) -> Return {function}: Trait` is not satisfied
  --> src/main.rs:12:11
   |
12 |     takes(function);
   |     ----- ^^^^^^^^ the trait `Trait` is not implemented for fn item `fn(Argument) -> Return {function}`
   |     |
   |     required by a bound introduced by this call
   |
   = help: the trait `Trait` is implemented for fn pointer `fn(Argument) -> Return`
note: required by a bound in `takes`
  --> src/main.rs:9:18
   |
9  | fn takes(_: impl Trait) {}
   |                  ^^^^^ required by this bound in `takes`

error[[E0277]](https://doc.rust-lang.org/nightly/error-index.html#E0277): the trait bound `[closure@src/main.rs:13:11: 13:34]: Trait` is not satisfied
  --> src/main.rs:13:5
   |
13 |     takes(|_: Argument| -> Return { todo!() });
   |     ^^^^^ the trait `Trait` is not implemented for closure `[closure@src/main.rs:13:11: 13:34]`
   |
   = help: the trait `Trait` is implemented for fn pointer `fn(Argument) -> Return`
note: required by a bound in `takes`
  --> src/main.rs:9:18
   |
9  | fn takes(_: impl Trait) {}
   |                  ^^^^^ required by this bound in `takes`

Metadata

Metadata

Assignees

Labels

A-diagnosticsArea: Messages for errors, warnings, and lintsE-easyCall for participation: Easy difficulty. Experience needed to fix: Not much. Good first issue.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