rust-lang / rust

Empowering everyone to build reliable and efficient software.
https://www.rust-lang.org
Other
97.91k stars 12.67k forks source link

fn pointer coercion fails for method on type with lifetime #32003

Open typoon opened 8 years ago

typoon commented 8 years ago

The following code does not infer the type of the method correctly:

/*
<anon>:12:31: 12:45 error: mismatched types:
 expected `fn(MyStruct<'_>)`,
    found `fn(MyStruct<'_>) {MyStruct<'a>::func}`
(expected concrete lifetime,
    found bound lifetime parameter ) [E0308]
<anon>:12     let fails: fn(MyStruct) = MyStruct::func; // ERROR: mismatched types
                                        ^~~~~~~~~~~~~~
<anon>:12:31: 12:45 help: see the detailed explanation for E0308
*/
struct MyStruct<'a> {
    y: &'a u32,
}

impl<'a> MyStruct<'a> {
    pub fn func(self) {}
}

fn wrapper<'a>(x: MyStruct<'a>) { x.func() }

fn main() {
    let fails: fn(MyStruct) = MyStruct::func; // ERROR: mismatched types
    let works: fn(MyStruct) = wrapper;
}

As one can see in the error message (found fn(MyStruct<'_>) {MyStruct<'a>::func}), it seems that the compiler is getting confused when inferring the type of the expression.

If the lifetime from MyStruct is removed, the code compiles fine.

PS: Thanks to huon for simplifying the example demonstrating the issue

arielb1 commented 8 years ago

The issue is early vs. late-bound lifetimes.

steveklabnik commented 4 years ago

Triage: no change

Dylan-DPC commented 1 year ago

Current error output:

error[[E0308]](https://doc.rust-lang.org/stable/error_codes/E0308.html): mismatched types
  --> src/main.rs:12:31
   |
12 |     let fails: fn(MyStruct) = MyStruct::func; // ERROR: mismatched types
   |                               ^^^^^^^^^^^^^^ one type is more general than the other
   |
   = note: expected fn pointer `for<'a> fn(MyStruct<'a>)`
                 found fn item `fn(MyStruct<'_>) {MyStruct::<'_>::func}`