Inferred type is () -> Unit but KFunction<TypeVariable(U)> was expected

We’re getting errors like:

  +loop_main.kt:158:54: error: type mismatch: inferred type is () -> Unit but KFunction<TypeVariable(U)> was expected
  +      moduleRegistry.exportFunc(name, "Z_printZ_vv", spectest_print);
  +                                                     ^
  +loop_main.kt:159:58: error: type mismatch: inferred type is (Int) -> Unit but KFunction<TypeVariable(U)> was expected
  +      moduleRegistry.exportFunc(name, "Z_print_i32Z_vi", spectest_print_i32);
  +                                                         ^
  +loop_main.kt:160:58: error: type mismatch: inferred type is (Float) -> Unit but KFunction<TypeVariable(U)> was expected
  +      moduleRegistry.exportFunc(name, "Z_print_f32Z_vf", spectest_print_f32);
  +                                                         ^
  +loop_main.kt:161:63: error: type mismatch: inferred type is (Int, Float) -> Unit but KFunction<TypeVariable(U)> was expected
  +      moduleRegistry.exportFunc(name, "Z_print_i32_f32Z_vif", spectest_print_i32_f32);
  +                                                              ^
  +loop_main.kt:162:58: error: type mismatch: inferred type is (Double) -> Unit but KFunction<TypeVariable(U)> was expected
  +      moduleRegistry.exportFunc(name, "Z_print_f64Z_vd", spectest_print_f64);
  +                                                         ^
  +loop_main.kt:163:63: error: type mismatch: inferred type is (Double, Double) -> Unit but KFunction<TypeVariable(U)> was expected
  +      moduleRegistry.exportFunc(name, "Z_print_f64_f64Z_vdd", spectest_print_f64_f64);

where the functions are of the form:

  var spectest_print = fun() {
    print("spectest.print()\n");
  }

and we don’t know how to make sense of any of this.

Think of () -> Unit as an interface type with one invoke method and nothing else. Now think of KFunction<R> as a interface with lots of properties and methods to get information like the name, parameter names, visibility, etc, and even a call method to actually run it (docs) . Since () -> Unit doesn’t have any of that metadata, it can’t really be used in place where that metadata is expected.

Here’s some more info on methods references (KFunction<R>): Reflection

Here’s some code that compiles:

import kotlin.reflect.*

var spectest_print = fun() {
    print("spectest.print()\n");
}

fun <T> doSomething(input: KFunction<T>) {
    println(input) 
} 

fun main() {
    //doSomething(spectest_print) // broken
    doSomething(spectest_print::invoke) //compiles
} 

I don’t know if this is enough. Not sure what the export func uses from the KFunction<R>. It may be that you need to do something more like

import kotlin.reflect.*

fun namedFunction() {
    print("spectest.print()\n");
}

var spectest_print = ::namedFunction

fun <T> doSomething(input: KFunction<T>) {
    println(input) 
} 

fun main() {
    doSomething(spectest_print)
} 

Hopefully those two example get you unstuck.

we made the code take Any instead of KFunction and it worked. 🤷🏻