Skip to content

Poor error for manual implementations of function traits #39259

@jdm

Description

@jdm
Contributor
#![feature(fn_traits)]

struct S;

impl Fn(u32) -> u32 for S {
    fn call(&self) -> u32 {
        5
    }
}

fn main() {
}

This yields:

error[E0229]: associated type bindings are not allowed here
 --> foo2.rs:5:17
  |
5 | impl Fn(u32) -> u32 for S {
  |                 ^^^ associate type not allowed here

error: aborting due to previous error

Which is extremely confusing and non-actionable.

Activity

added
A-diagnosticsArea: Messages for errors, warnings, and lints
on Jan 23, 2017
jdm

jdm commented on Jan 23, 2017

@jdm
ContributorAuthor
durka

durka commented on Jan 23, 2017

@durka
Contributor

It is sort of actionable if you know that Fn(u32) -> u32 really means Fn<(u32,), Output=u32>. Let's put that expansion in a note on the error message I guess?

added
T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.
on Mar 9, 2017
BGR360

BGR360 commented on Dec 29, 2021

@BGR360
Contributor

This code now produces two confusing errors:

#![feature(fn_traits)]
#![feature(unboxed_closures)]

struct S;

impl Fn(u32) -> u32 for S {
    fn call(&self) -> u32 {
        5
    }
}

fn main() {}
error[E0229]: associated type bindings are not allowed here
 --> src/main.rs:6:17
  |
6 | impl Fn(u32) -> u32 for S {
  |                 ^^^ associated type not allowed here

error[E0277]: expected a `FnMut<(u32,)>` closure, found `S`
  --> src/main.rs:6:6
   |
6  | impl Fn(u32) -> u32 for S {
   |      ^^^^^^^^^^^^^^ expected an `FnMut<(u32,)>` closure, found `S`
   |
   = help: the trait `FnMut<(u32,)>` is not implemented for `S`
note: required by a bound in `Fn`

In the first one, the erroneous span has moved inside of the parentheses, so I feel it's no longer as correct as it used to be, and no more helpful.

And the second one just seems... incorrect? Idk, I'm not intimately familiar with this nightly feature.

@rustbot label +D-confusing +D-terse +requires-nightly +D-incorrect

added
D-confusingDiagnostics: Confusing error or lint that should be reworked.
D-incorrectDiagnostics: A diagnostic that is giving misleading or incorrect information.
D-terseDiagnostics: An error or lint that doesn't give enough information about the problem at hand.
requires-nightlyThis issue requires a nightly compiler in some way.
on Dec 29, 2021
estebank

estebank commented on Jan 8, 2023

@estebank
Contributor

Current output:

error[E0229]: associated type bindings are not allowed here
 --> src/main.rs:8:17
  |
8 | impl Fn(u32) -> u32 for S {
  |                 ^^^ associated type not allowed here
Ezrashaw

Ezrashaw commented on Jan 9, 2023

@Ezrashaw
Contributor

My understanding of this issue is that the impl Fn(u32) -> u32 is expanded to impl Fn<(u32, ), Output = u32> where Output is not allowed and must be moved elsewhere.

Two issues currently seem to exist:

  1. That the expansion (Fn(u32) -> u32 -> Fn<(u32, ), Output = u32>) for fn_traits is not shown. This can be addressed by adding a note to the error message.
  2. That E0229 doesn't suggest a moving the associated type, this needs a proper suggestion and should be discussed more.

I'll work on 1. 2 seems out of scope of this issue.

@rustbot claim

estebank

estebank commented on Jan 9, 2023

@estebank
Contributor

@Ezrashaw if you're able to detect that you've got Fn trait syntax in the Trait part of the imp item, you should be able to print the type directly (to get the desugared version) and mention in passing "include type Output = u32 in the impl body instead" or something like that.

Ezrashaw

Ezrashaw commented on Jan 9, 2023

@Ezrashaw
Contributor

@estebank Isn't that suggestion generic to all "assoc type not allowed here" error?

estebank

estebank commented on Jan 10, 2023

@estebank
Contributor

Come to think of it, It would be.

Ezrashaw

Ezrashaw commented on Jan 11, 2023

@Ezrashaw
Contributor

Hmm, @estebank I think I've run into a problem: I cannot print the type. The error occurs is emitted from rustc_hir_analysis and so ype checking hasn't been done yet.

estebank

estebank commented on Jan 11, 2023

@estebank
Contributor

Because this is a nightly feature, I would side step the issue by not mentioning the type for now and only mention the "represent the closure with the regular trait syntax instead and move the output type to the body this way", but it should be easy to come up with a mechanism to translate from one syntax to the other (if it doesn't exist already!), while not having to rely on ty::*, only on the AST and resolve.

added a commit that references this issue on Mar 10, 2023
7699462
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

A-diagnosticsArea: Messages for errors, warnings, and lintsC-enhancementCategory: An issue proposing an enhancement or a PR with one.D-confusingDiagnostics: Confusing error or lint that should be reworked.D-incorrectDiagnostics: A diagnostic that is giving misleading or incorrect information.D-terseDiagnostics: An error or lint that doesn't give enough information about the problem at hand.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.requires-nightlyThis issue requires a nightly compiler in some way.

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

    Development

    Participants

    @jdm@steveklabnik@durka@estebank@Mark-Simulacrum

    Issue actions

      Poor error for manual implementations of function traits · Issue #39259 · rust-lang/rust