Skip to content

Duplicated implementation is not general enough error on function pointers #97997

Closed
@madsmtm

Description

@madsmtm

Given the following code (playground link):

trait Foo {
    const ASSOC: bool = true;
}
impl<T> Foo for fn(T) {}

fn foo(_x: i32) {}

fn impls_foo<T: Foo>(_x: T) {}

fn main() {
    // Works, but if the below code is present, it is shown as failed
    impls_foo(foo as fn(i32));

    // Fails as expected, see https://github.com/rust-lang/rust/issues/56105
    <fn(&u8) as Foo>::ASSOC;
}

The current (nightly ec55c61 2022-06-10, regressed in the past week) output is:

   Compiling playground v0.0.1 (/playground)
error: implementation of `Foo` is not general enough
  --> src/main.rs:12:5
   |
12 |     impls_foo(foo as fn(i32));
   |     ^^^^^^^^^^^^^^^^^^^^^^^^^ implementation of `Foo` is not general enough
   |
   = note: `Foo` would have to be implemented for the type `for<'r> fn(&'r u8)`
   = note: ...but `Foo` is actually implemented for the type `fn(&'0 u8)`, for some specific lifetime `'0`

error: implementation of `Foo` is not general enough
  --> src/main.rs:15:5
   |
15 |     <fn(&u8) as Foo>::ASSOC;
   |     ^^^^^^^^^^^^^^^^^^^^^^^ implementation of `Foo` is not general enough
   |
   = note: `Foo` would have to be implemented for the type `for<'r> fn(&'r u8)`
   = note: ...but `Foo` is actually implemented for the type `fn(&'0 u8)`, for some specific lifetime `'0`

error: could not compile `playground` due to 2 previous errors

Ideally the output should look like:

   Compiling playground v0.0.1 (/playground)
error: implementation of `Foo` is not general enough
  --> src/main.rs:15:5
   |
15 |     <fn(&u8) as Foo>::ASSOC;
   |     ^^^^^^^^^^^^^^^^^^^^^^^ implementation of `Foo` is not general enough
   |
   = note: `Foo` would have to be implemented for the type `for<'r> fn(&'r u8)`
   = note: ...but `Foo` is actually implemented for the type `fn(&'0 u8)`, for some specific lifetime `'0`

error: could not compile `playground` due to previous error

The desired result can be achieved by swapping the order of the two statements <fn(&u8) as Foo>::ASSOC; and impls_foo(foo as fn(i32));.

Metadata

Metadata

Labels

A-diagnosticsArea: Messages for errors, warnings, and lintsT-compilerRelevant to the compiler team, which will review and decide on the PR/issue.

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions