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

Extremely confusing error around function pointers with inferred arguments #76353

Open
jyn514 opened this issue Sep 5, 2020 · 6 comments
Open
Labels
A-diagnostics Area: Messages for errors, warnings, and lints A-inference Area: Type inference A-type-system Area: Type system D-confusing Diagnostics: Confusing error or lint that should be reworked. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@jyn514
Copy link
Member

jyn514 commented Sep 5, 2020

Consider the following code (playground):

struct S<'a>(&'a str);

fn f(inner: fn(&str, &S)) {
}

#[allow(unreachable_code)]
fn main() {
    let inner: fn(_, _) = unimplemented!();
    f(inner);
}

Rustc gives an error:

error[E0308]: mismatched types
 --> src/main.rs:9:7
  |
9 |     f(inner);
  |       ^^^^^ one type is more general than the other
  |
  = note: expected fn pointer `for<'r, 's, 't0> fn(&'r str, &'s S<'t0>)`
             found fn pointer `fn(&str, &S<'_>)`

Here is the fixed code (playground):

    let inner: fn(&str, &S<'_>) = unimplemented!();
    f(inner);

In particular, the only thing that changed was fn(_, _) -> fn(&str, &S<'_>). But this is exactly the type that was printed in the diagnostic originally! What changed?

I don't understand why this error was emitted, but it would at least be nice to suggest the transformation that makes the code work.

Reduced from rust-lang/crater#542.

@jyn514 jyn514 added A-type-system Area: Type system A-diagnostics Area: Messages for errors, warnings, and lints A-inference Area: Type inference D-confusing Diagnostics: Confusing error or lint that should be reworked. labels Sep 5, 2020
@jyn514 jyn514 changed the title Extremely confusing error around function pointers Extremely confusing error around function pointers with inferred arguments Sep 5, 2020
@estebank estebank added the T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. label Sep 5, 2020
@Aaron1011
Copy link
Member

Aaron1011 commented Sep 7, 2020

This looks like the function-pointer version of #41078 - we don't convert a 'normal' region inference variable into a higher-ranked region. See #41078 (comment) for more details

@camsteffen
Copy link
Contributor

Is this the same issue? The error fails to make any mention of lifetime 'a.

struct Bar<'a>(&'a str);

impl<'a> Bar<'a> {
    fn hello(&self, name: &'a str) {
        println!("Hello {}!", name);
    }
    
    fn say(&self, f: fn(&Self, &str), name: &str) {
        f(self, name)
    }
    
}

fn main() {
    Bar("").say(Bar::hello, "World");
}

Error:

error[E0308]: mismatched types
  --> src/main.rs:15:17
   |
15 |     Bar("").say(Bar::hello, "World");
   |                 ^^^^^^^^^^ one type is more general than the other
   |
   = note: expected fn pointer `for<'r, 's> fn(&'r Bar<'_>, &'s str)`
              found fn pointer `for<'r> fn(&'r Bar<'_>, &str)`

@jyn514
Copy link
Member Author

jyn514 commented Nov 16, 2020

@camjackson no, that one's because you explicitly restricted name: &'a str to one specific lifetime: https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=428e0b2ea360140631ca300668635f97

https://doc.rust-lang.org/nomicon/hrtb.html

@camsteffen
Copy link
Contributor

I know, but the compiler error is misleading.

@jyn514
Copy link
Member Author

jyn514 commented Nov 16, 2020

Ok, can you open a separate issue for that then? This issue is about when the error isn't necessary at all, the compiler just isn't smart enough to infer the higher-ranked type.

@estebank
Copy link
Contributor

estebank commented Jan 8, 2023

Current output

error[E0308]: mismatched types
 --> src/main.rs:9:7
  |
9 |     f(inner);
  |     - ^^^^^ one type is more general than the other
  |     |
  |     arguments to this function are incorrect
  |
  = note: expected fn pointer `for<'a, 'b, 'c> fn(&'a str, &'b S<'c>)`
             found fn pointer `fn(_, _)`
note: function defined here
 --> src/main.rs:3:4
  |
3 | fn f(inner: fn(&str, &S)) {
  |    ^ -------------------
help: consider removing the ``
  |
9 |     f(inner);
  |
error[E0308]: mismatched types
  --> src/main.rs:17:17
   |
17 |     Bar("").say(Bar::hello, "World");
   |             --- ^^^^^^^^^^ one type is more general than the other
   |             |
   |             arguments to this function are incorrect
   |
   = note: expected fn pointer `for<'a, 'b> fn(&'a Bar<'_>, &'b str)`
                 found fn item `for<'a> fn(&'a Bar<'_>, &str) {Bar::<'_>::hello}`
note: associated function defined here
  --> src/main.rs:10:8
   |
10 |     fn say(&self, f: fn(&Self, &str), name: &str) {
   |        ^^^        ------------------

JohnTitor pushed a commit to JohnTitor/rust that referenced this issue Jan 8, 2023
…r-errors

Do not emit wrong E0308 suggestion for closure mismatch

Found in rust-lang#76353.
JohnTitor pushed a commit to JohnTitor/rust that referenced this issue Jan 8, 2023
…r-errors

Do not emit wrong E0308 suggestion for closure mismatch

Found in rust-lang#76353.
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 A-inference Area: Type inference A-type-system Area: Type system D-confusing Diagnostics: Confusing error or lint that should be reworked. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

No branches or pull requests

4 participants