When implementing an interface in Kotlin with an inline
function:
interface Foo {
fun qux(fn: () -> Unit)
}
open class Bar : Foo {
final override inline fun qux(fn: () -> Unit){TODO()}
}
the IDE (and possibly the compiler) complains with this message:
Override by an inline function
To suppress this message, I have to use the @Suppress("OVERRIDE_BY_INLINE")
annotation. What is wrong?
What I am already aware:
- For a normal inline function, kotlinc will inline all usages of the inline function, but it will still compile the non-inline version of the function so that it can be called from Java (and possibly for backward compatibility or whatever reason).
- It is impossible to inline a virtual method. Inline simply means "copy all the code into the caller", but for invoking an abstract/interface method, the implementation is determined at runtime based on the actual class of the object involved, so it is not possible to know which implementation to copy into the function.
However, this isn't the case when invoking a final function. In the example above, when I invoke bar.qux()
, the compiler can ensure that only this particular implementation will be used, and can safely inlined. It is irrelevant with whether it overrides the Foo.qux
method -- calling foo.qux
will use the non-inline version mentioned in point 1, and calling bar.qux
can inline safely.
Is this warning there only to make sure developers are aware of this? Or are there side effects?
final
? – Exclaveoverride
isopen
by default, and you needfinal
forinline
. – Sweepstakesopen
modifier onBar
. It wasopen
in my own code. – SweepstakesBar.qux
can be made to work forfoo.qux
. – Cower