1

I have 3 function types:

type ThreadedFunction = fn(&mut Thread, Object) -> FunctionResult;
type UniversalFunction = fn(&mut Thread, Unused) -> FunctionResult;
type Function = fn(&mut Thread, &Method) -> FunctionResult;
static_assertions::assert_eq_size!(primitives::Unused, &Method);
static_assertions::assert_eq_size!(primitives::Unused, Object);

The universal functions ignore the second parameter, so I'd like to be able to use them in the two other contexts. The sizes of Object, Unused and &Method are the same.

I would like to be able to do something like:

pub fn unused(thread: &mut Thread, _: Unused) -> FunctionResult {
    NormalReturn
}

pub fn somewhere() -> ThreadedFunction {
    unused as ThreadedFunction
}

This is unsafe:

error[E0605]: non-primitive cast: `for<'r> fn(&'r mut interpreter::Thread, interpreter::primitives::Unused) -> interpreter::FunctionResult {unused}` as `for<'r> fn(&'r mut interpreter::Thread, object::Object) -> interpreter::FunctionResult`
  --> src/interpreter.rs:25:13
   |
25 |             unused as ThreadedFunction
   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^ invalid cast

Wrapping the cast in unsafe {} doesn't help.

This could be impossible, but it would be very convenient to be able to do as it would save a bunch of code duplication.

Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
Dave Mason
  • 669
  • 6
  • 15

1 Answers1

7

No, you cannot perform this cast because the function references have different types. All of the parameter types and return types must be the same for two functions to have the same type.

Instead, you can return a closure that doesn't capture any environment. Because of that, it can be automatically converted into a function:

fn somewhere() -> ThreadedFunction {
    |a, b| unused(a, Unused)
}

That is equivalent to this wrapper function:

fn unused_adapted(thread: &mut Thread, _: Object) -> FunctionResult {
    unused(thread, Unused)
}

fn somewhere() -> ThreadedFunction {
    unused_adapted
}

See also:

Timmmm
  • 88,195
  • 71
  • 364
  • 509
Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366