Skip to content

Rust fails to coerce to a fn pointer when passing an array as an argument to a generic function. #136420

@theemathas

Description

@theemathas
Contributor

I tried this code:

fn foo() {}
fn bar() {}

fn main() {
    let _a = if true { foo } else { bar };
    let _b = vec![foo, bar];
    let _c = [foo, bar];
    d(if true { foo } else { bar });
    e(vec![foo, bar]);
    f([foo, bar]);
}

fn d<T>(_: T) {}
fn e<T>(_: Vec<T>) {}
fn f<T>(_: [T; 2]) {}

I expected the six lines to either all compile or all error. Instead, only the f([foo, bar]) line fails, with the following error:

error[E0308]: mismatched types
  --> src/main.rs:10:7
   |
10 |     f([foo, bar]);
   |     - ^^^^^^^^^^ expected `[fn() {foo}; 2]`, found `[fn(); 2]`
   |     |
   |     arguments to this function are incorrect
   |
   = note: expected array `[fn() {foo}; 2]`
              found array `[fn(); 2]`
note: function defined here
  --> src/main.rs:15:4
   |
15 | fn f<T>(_: [T; 2]) {}
   |    ^    ---------

For more information about this error, try `rustc --explain E0308`.

For some reason, it's failing to coerce the function items into function pointers, but only when an array is being passed to a generic function.

Discovered by @xero-lib

Meta

Issue reproducible on the playground with stable rust 1.84.1, and nightly rust 1.86.0-nightly (2025-02-01 8239a37f9c0951a037cf)

@rustbot labels +A-inference +A-coercions

Activity

added
needs-triageThis issue may need triage. Remove it if it has been sufficiently triaged.
A-coercionsArea: implicit and explicit `expr as Type` coercions
on Feb 2, 2025
added
T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.
T-typesRelevant to the types team, which will review and decide on the PR/issue.
needs-triageThis issue may need triage. Remove it if it has been sufficiently triaged.
and removed
needs-triageThis issue may need triage. Remove it if it has been sufficiently triaged.
on Feb 4, 2025
removed
needs-triageThis issue may need triage. Remove it if it has been sufficiently triaged.
on Mar 1, 2025
adwinwhite

adwinwhite commented on Apr 14, 2025

@adwinwhite
Contributor

The cause is that f's type parameter is resolved during the coercion of the first element, rather than based on the final type of the array. Refer to fcx.coerce in CoerceMany::coerce_inner.

adwinwhite

adwinwhite commented on Apr 25, 2025

@adwinwhite
Contributor

@rustbot claim

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

A-coercionsArea: implicit and explicit `expr as Type` coercionsA-inferenceArea: Type inferenceC-bugCategory: This is a bug.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.T-typesRelevant to the types team, which will review and decide on the PR/issue.

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

    Development

    Participants

    @theemathas@jieyouxu@rustbot@Noratrieb@adwinwhite

    Issue actions

      Rust fails to coerce to a fn pointer when passing an array as an argument to a generic function. · Issue #136420 · rust-lang/rust