Skip to content

Allow coercing non-capturing closures to function pointers #1555

Closed
@archshift

Description

@archshift

In C++, you are able to pass a non-capturing lambda as a function pointer, as, for example, a function argument:

void foo(void (*foobar)(void)) {
    // impl
}
void bar() {
    foo([]() { /* do something */ });
}

It would be incredibly convenient for rust to be able to do the same:

fn foo(foobar: fn()) {
    // impl
}
fn bar() {
    foo(|| { /* do something */ });
}

A use case would be a static (const) array of function pointers, where dynamic dispatch is not necessary.
Example in current rust (this is a compilable example):

extern {
  static mut b: u32;
  static n: usize;
}

const a: [&'static Fn(); 4] = [
  &|| unsafe { b = 4 },
  &|| unsafe { b = 2 },
  &|| unsafe { b = 3 },
  &|| unsafe { b = 1 },
];

pub fn main() {
  if n < 4 {
    a[n]();
  }
}

This obviously relies upon dynamic dispatch to a level that rust is unable to optimize away. Ideally it would be possible to use a table of fn()s instead of &'static Fn() and rust would be able to coerce the closures into function pointers because nothing needs to be captured.

Another, possibly more widely-applicable scenario is simply being able to pass a closure into a C function that takes a callback.

See previous discussion at rust-lang/rust#32449.

Metadata

Metadata

Assignees

No one assigned

    Labels

    T-langRelevant to the language team, which will review and decide on the RFC.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions