Skip to content

Coercing higher ranked associated functions into a function pointer requires wrapping in a closure #140663

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
parrottq opened this issue May 5, 2025 · 1 comment
Labels
A-coercions Area: implicit and explicit `expr as Type` coercions A-higher-ranked Area: Higher-ranked things (e.g., lifetimes, types, trait bounds aka HRTBs) C-bug Category: This is a bug. needs-triage This issue may need triage. Remove it if it has been sufficiently triaged.

Comments

@parrottq
Copy link

parrottq commented May 5, 2025

Playground

struct A<'a>(&'a ());

impl<'a> A<'a> {
    fn associated(a: &'a (), b: &()) {}
}

fn main() {
    let works_not: for<'a> fn(&'a (), &()) = A::associated; // Error
    let works_not: for<'a, 'b> fn(&'a (), &'b ()) = A::associated; // Error
    let works: for<'a> fn(&'a (), &()) = |a, b| A::associated(a, b); // Ok
    let works: for<'a, 'b> fn(&'a (), &'b ()) = |a, b| A::associated(a, b); // Ok

    // Free standing functions work fine
    fn fun<'a>(a: &'a (), b: &()) {}
    let works: for<'a> fn(&'a (), &()) = fun; // Ok
}

I expected the associated function to be coercible into a function pointer directly or for a diagnostic to tell me to wrap the function in a closure to fix the error.

Instead, I got a confusing compiler error which lead me to think that the for<'_> was wrong, which doesn't seem to be the case.

error[E0308]: mismatched types
   --> crates/wavestore_service_report/src/lib.rs:195:45
    |
195 |     let no_works: for<'a> fn(&'a (), &()) = A::associated; // Error
    |                   -----------------------   ^^^^^^^^^^^^^ one type is more general than the other
    |                   |
    |                   expected due to this
    |
    = note: expected fn pointer `for<'a, 'b> fn(&'a (), &'b ())`
                  found fn item `for<'a> fn(&(), &'a ()) {A::<'_>::associated}`

Meta

rustc --version --verbose:

rustc 1.85.1 (4eb161250 2025-03-15)
binary: rustc
commit-hash: 4eb161250e340c8f48f66e2b929ef4a5bed7c181
commit-date: 2025-03-15
host: x86_64-unknown-linux-gnu
release: 1.85.1
LLVM version: 19.1.7
@parrottq parrottq added the C-bug Category: This is a bug. label May 5, 2025
@rustbot rustbot added the needs-triage This issue may need triage. Remove it if it has been sufficiently triaged. label May 5, 2025
@compiler-errors
Copy link
Member

This is not a bug, but an observable reality of the difference between early- and late-bound lifetimes. In the impl impl<'a> A<'a>, 'a is "early-bound", and thus it cannot be treated like a late-bound/higher-ranked lifetime.

@lolbinarycat lolbinarycat added A-coercions Area: implicit and explicit `expr as Type` coercions A-higher-ranked Area: Higher-ranked things (e.g., lifetimes, types, trait bounds aka HRTBs) labels May 6, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-coercions Area: implicit and explicit `expr as Type` coercions A-higher-ranked Area: Higher-ranked things (e.g., lifetimes, types, trait bounds aka HRTBs) C-bug Category: This is a bug. needs-triage This issue may need triage. Remove it if it has been sufficiently triaged.
Projects
None yet
Development

No branches or pull requests

4 participants