Overriding function in sub interface with implementation returning "Nothing" changes return type to "Nothing"


If I define the following two interfaces:

interface Parent {
    fun value(): List<String>

interface Child : Parent {
    override fun value() = throw IllegalStateException()

And then try to implement interface Child:

object ChildImplementation : Child {
    override fun value() = listOf("A value")

The compiler compains: Return type of ‘value’ is not a subtype of the return type of the overridden member ‘public open fun value(): Nothing defined in …Child’

Is this the expected behavior? I would assume that overriding a function does not allow you to change its return type (except when you change it to a covariant type).

Nothing is the subtype of all Kotlin types, so this is in fact a covariant override.

Ah, I see. I had not found that information.

Unfortunately now I have to use a longer notation for the same thing. If I put the throw in a function, I could write:

fun somethingSpecial() = throw IllegalStateException()

interface Child : Parent {
    override fun value() = somethingSpecial()

But now I have to write the following. The function only has to be written once, so that is not a problem, but I would prefer not having to repeat the type of the list elements:

fun <T> somethingSpecial() : List<T> = throw IllegalStateException()

interface Child : Parent {
    override fun value() = somethingSpecial<String>()

Is there any way I could use something short without changing the return type, and without implementors of the interface having to implement the function?

This problem is covered by the issue https://youtrack.jetbrains.com/issue/KT-11684

Good to see that it already has been reported. I voted for it, and I am now postponing all development until Kotlin 2.0 :wink:

Why not explicitly define the return type. That should not cause a problem either and is far less clunky.

It is part of a DSL, and the return type is noise at that point. Here is an example that will hopefully clarify the need a bit:

class Component(private val provided: Provided) {
    interface Provided : SubComponent.Provided {
        override fun someService(): SomeService = providedByMe()
        fun anotherService(): AnotherService
    fun subComponentCreator() =
        SubComponent(object : Provided by provided {
            override fun someService() = getAnInstanceOfSomeServiceFromSomewhere()

If somebody wants to use Component, then they no longer have to implement someService():

Component(object : Component.Provided {
     override fun anotherService() = ...
     // Function overrides for functions of "SubComponent.Provided"
     // not overridden by "Component.Provided".

So in Component.Provided the only information I want to communicate is that an instance of SomeService will be provided by Component. At that point it serves no purpose to communicate the return type again. I also do not want the return type changed to a covariant type, because I intend to override the function later and want to return an instance of the original type then.