Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve diagnostics like "incompatible types: expected fn item, found a different fn item" #102608

Closed
jruderman opened this issue Oct 3, 2022 · 5 comments · Fixed by #105552
Closed
Assignees
Labels
A-diagnostics Area: Messages for errors, warnings, and lints D-newcomer-roadblock Diagnostics: Confusing error or lint; hard to understand for new users. E-mentor Call for participation: This issue has a mentor. Use #t-compiler/help on Zulip for discussion. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@jruderman
Copy link
Contributor

jruderman commented Oct 3, 2022

Given the following code (playground):

fn double(n: u32) -> u32 { 
    n * 2
}

fn triple(n: u32) -> u32 {
    n * 3
}

fn f(n: u32) -> u32 {
    let g = if n % 2 == 0 {
        &double
    } else {
        &triple
    };

    g(n)
}

fn main() {
    assert_eq!(f(7), 21);
    assert_eq!(f(8), 16);
}

The current output is:

error[E0308]: `if` and `else` have incompatible types
  --> src/main.rs:13:9
   |
10 |       let g = if n % 2 == 0 {
   |  _____________-
11 | |         &double
   | |         ------- expected because of this
12 | |     } else {
13 | |         &triple
   | |         ^^^^^^^ expected fn item, found a different fn item
14 | |     };
   | |_____- `if` and `else` have incompatible types
   |
   = note: expected reference `&fn(u32) -> u32 {double}`
              found reference `&fn(u32) -> u32 {triple}`

I would like this error to explain why these are incompatible despite having the same signature (or link to an explanation).

I would also like it to suggest an alternative, perhaps one of these:

  • Change &double to &(double as fn(u32) -> u32)
  • Change &double to double
@jruderman jruderman added A-diagnostics Area: Messages for errors, warnings, and lints T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Oct 3, 2022
@estebank estebank added the D-newcomer-roadblock Diagnostics: Confusing error or lint; hard to understand for new users. label Oct 3, 2022
@estebank
Copy link
Contributor

estebank commented Oct 3, 2022

We should in every E0308 explain that different functions have distinct types, and how to cast them to a fn pointer.

(I thought we were doing that already. :-/ )

@estebank estebank added the E-mentor Call for participation: This issue has a mentor. Use #t-compiler/help on Zulip for discussion. label Oct 3, 2022
@compiler-errors
Copy link
Member

@estebank we don't do it in this case because these are references to fndef and not just fndef types themselves. We can probably add logic to deeply compare if types are "equal modulo function item types", but it might be kinda complicated.

@estebank
Copy link
Contributor

estebank commented Oct 3, 2022

@compiler-errors that makes sense. We might get away with only supporting the simple case of reference to fn like in the OP. For more complex cases we might get over our heads to provide a structured suggestion (but we might want to just check if there are diverging fns and only provide a note for those cases as a hint that might or might not get the user unstuck).

@mattjperez
Copy link
Contributor

@rustbot claim

@mattjperez
Copy link
Contributor

mattjperez commented Dec 11, 2022

I've added a help note when there are type mismatched and both expected and found are function items, linking to https://doc.rust-lang.org/reference/types/function-item.html.

I'm still working on how to add the alternative suggestions to the output

Change &double to &(double as fn(u32) -> u32)
Change &double to double

But i think adding these to the example in the rust reference page linked above would be helpful either way.

Dylan-DPC added a commit to Dylan-DPC/rust that referenced this issue Jan 25, 2023
…note, r=compiler-errors

Add help message about function pointers

rust-lang#102608
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-diagnostics Area: Messages for errors, warnings, and lints D-newcomer-roadblock Diagnostics: Confusing error or lint; hard to understand for new users. E-mentor Call for participation: This issue has a mentor. Use #t-compiler/help on Zulip for discussion. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants