Error when casting a function is not informative

e8a565e
Opened by Josh Matthews at 2023-05-26 11:06:54
fn heap_size(_: &usize) -> usize {
    0
}

const f: *const fn(*const usize) -> usize = (&heap_size as *const fn(&usize) -> usize) as *const fn(*const usize) -> usize;

fn main() {
}

yields

<anon>:5:46: 5:86 error: casting `&fn(&usize) -> usize {heap_size}` as `*const fn(&usize) -> usize` is invalid
<anon>:5 const f: *const fn(*const usize) -> usize = (&heap_size as *const fn(&usize) -> usize) as *const fn(*const usize) -> usize;
                                                      ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
error: aborting due to previous error

This error tells me nothing about why it's invalid, and there's no extended explanation.

  1. This is because no cast rule is legal.

    Ariel Ben-Yehuda at 2015-10-11 07:29:25

  2. Still an unhelpful diagnostic that should be better.

    Demi Marie Obenour at 2015-10-11 08:24:03

  3. I don't really think it would be improved by "expected &-pointer, found *-pointer" (the issue is that an fn item does not necessarily have the same representation as an fn pointer, which makes the &T -> *const T coercion not take place).

    Ariel Ben-Yehuda at 2015-10-11 11:05:44

  4. It may be desirable then to include an error for this particular case indicating that there is no valid version of the cast.

    Andrew Lilley Brinker at 2015-10-11 12:06:07

  5. It'd also be nice if there was some treatment of "functions are function items until you explicitly cast them to function pointer types" in the docs.

    Aidan Hobson Sayers at 2016-07-06 00:02:55

  6. @aidanhs: Hmm... that's a good point. I don't know that the distinction is made in the current version of the book. Is this something that would be worthwhile to include in the new version? cc: @steveklabnik

    Andrew Lilley Brinker at 2016-07-06 00:05:52

  7. For anyone who stumbles across this issue and wants to actually know how to cast functions (particularly extern ones), see #20178 for a hint until the docs/error message is updated.

    Aidan Hobson Sayers at 2016-07-06 00:12:19

  8. Triage: the error message is fundamentally the same here, just with the new format:

    error[E0606]: casting `&for<'r> fn(&'r usize) -> usize {heap_size}` as `*const for<'r> fn(&'r usize) -> usize` is invalid
     --> src/main.rs:5:45
      |
    5 | const f: *const fn(*const usize) -> usize = (&heap_size as *const fn(&usize) -> usize) as *const fn(*const usize) -> usize;
      |                                             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    
    

    Steve Klabnik at 2019-09-16 13:15:12