Skip to content

Example in instantiating_binders.md does not compile #2397

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

Open
smanilov opened this issue May 20, 2025 · 4 comments
Open

Example in instantiating_binders.md does not compile #2397

smanilov opened this issue May 20, 2025 · 4 comments
Assignees

Comments

@smanilov
Copy link
Contributor

smanilov commented May 20, 2025

I'm not sure it's supposed to compile, but this example:

fn foo<'a>(a: &'a u32) -> &'a u32 {
    a
}
fn bar<T>(a: fn(&u32) -> T) -> T {
    a(&10)
}

fn main() {
    let higher_ranked_fn_ptr = foo as for<'a> fn(&'a u32) -> &'a u32;
    let references_bound_vars = bar(higher_ranked_fn_ptr);
}

Gives me the following diagnostic:

error[E0308]: mismatched types
  --> src/main.rs:10:37
   |
10 |     let references_bound_vars = bar(higher_ranked_fn_ptr);
   |                                 --- ^^^^^^^^^^^^^^^^^^^^ one type is more general than the other
   |                                 |
   |                                 arguments to this function are incorrect
   |
   = note: expected fn pointer `for<'a> fn(&'a _) -> _`
              found fn pointer `for<'a> fn(&'a _) -> &'a u32`
note: function defined here
  --> src/main.rs:4:4
   |
4  | fn bar<T>(a: fn(&u32) -> T) -> T {
   |    ^^^    ----------------

For more information about this error, try `rustc --explain E0308`.
error: could not compile `foo` (bin "foo") due to 1 previous error

Is the example supposed to compile? I don't grok the type system quite enough to answer this myself, sorry.

Page is here: https://rustc-dev-guide.rust-lang.org/ty_module/instantiating_binders.html

@smanilov
Copy link
Contributor Author

I was poking at this and made a small modification: using a function item instead of a function pointer:

fn foo<'a>(a: &'a u32) -> &'a u32 {
    a
}
fn bar<T>(a: impl Fn(&u32) -> T) -> T {
    a(&10)
}

fn main() {
    // let higher_ranked_fn_ptr = foo as for<'a> fn(&'a u32) -> &'a u32;
    let _ = bar(&foo);
}

I now get an even stranger error:

error[E0308]: mismatched types
  --> src/main.rs:10:13
   |
10 |     let _ = bar(&foo);
   |             ^^^^^^^^^ one type is more general than the other
   |
   = note: expected reference `&_`
              found reference `&_`
note: the lifetime requirement is introduced here
  --> src/main.rs:4:31
   |
4  | fn bar<T>(a: impl Fn(&u32) -> T) -> T {
   |                               ^

For more information about this error, try `rustc --explain E0308`.
error: could not compile `foo` (bin "foo") due to 1 previous error

Specifically, the note is very confusing:

   = note: expected reference `&_`
              found reference `&_`

But I am adding this comment, as it might help narrow down the issue. (If the example is indeed intended to compile. I saw no indications that it's not.)

@BoxyUwU BoxyUwU self-assigned this May 20, 2025
@BoxyUwU
Copy link
Member

BoxyUwU commented May 20, 2025

This example isn't supposed to compile 👍 I'll edit the surrounding text to make that a little more clear. thank you for letting me know it's confusing

@smanilov
Copy link
Contributor Author

Thanks! Could you please link the PR to this one, before I close this one?

@BoxyUwU
Copy link
Member

BoxyUwU commented May 20, 2025

When a PR fixes this issue it'll automatically close the issue so don't worry about closing this

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants