Closed
Description
When running the following Rust code:
fn my_fn(event: &Event<'_>) {}
struct Event<'a>(&'a ());
fn main() {
const ptr: &fn(&Event<'_>) = &my_fn as _;
}
The cast using as _
should succeed, or the compiler should give a clearer reason for rejection if it is truly invalid. Since the types are compatible under HRLB, i guess this coercion should ideally be allowed.
The issue arises from using a reference before the function pointer. (It works when removed)
However, the compiler currently emits the following error:
error[E0605]: non-primitive cast: `&for<'a, 'b> fn(&'a Event<'b>) {my_fn}` as `&for<'a, 'b> fn(&'a Event<'b>)`
--> src/main.rs:8:43
|
8 | const ptr: &fn(&Event<'_>) = &my_fn as _;
| ^^^^^^^^^^^^^^^ an `as` expression can only be used to convert between primitive types or to coerce to a specific trait object
This happens on stable, beta, and nightly Rust.
Workaround:
fn my_fn(event: &Event<'_>) {}
struct Event<'a>(&'a ());
const fn force<F: Fn(&Event<'_>)>(x: F) -> F {
x
}
fn main() {
const ptr: &fn(&Event<'_>) = &force(|event| { my_fn(event) });
}
Thanks to @_madfrog on Discord for the help
Activity
zachs18 commentedon Apr 30, 2025
Note that unary prefix
&
binds tigher thanas
casting, so&foo as bar
is(&foo) as bar
, not&(foo as bar)
. Changing&my_fn as _
in the OP to&(my_fn as _)
makes it compile.Swiiz commentedon Apr 30, 2025
Maybe the compiler diagnostic could be improved to explain this.
xizheyin commentedon May 8, 2025
@rustbot claim
Perhaps note pointing only to
&my_fn
instead of&my_fn as _
would be clearer.Rollup merge of rust-lang#140787 - xizheyin:issue-140491, r=nnethercote
Unrolled build for #140787