Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why can't Kotlin super type parameters be inferred from constructor?

In Kotlin if we have a class w/constructor:

open class Wrapper<T>(val value: T)

We can call the constructor without specifying the type parameter:

val wrapped = Wrapper("value")

Specifying the type parameter (e.g. Wrapper<String>("value")) is redundant, and IntelliJ will tell you so.

However, if the constructor call is an extends clause, the type parameter is mandatory. E.g.

class StringWrapper : Wrapper<String>("value") // compiles
class StringWrapper : Wrapper("value") // does not compile

Why can't the type parameter be inferred in this seemingly very similar case?

like image 328
Erik Vesteraas Avatar asked Sep 16 '19 12:09

Erik Vesteraas


1 Answers

The type parameter certainly could be inferred in this case, but there is no code in place in the compiler for doing that yet. JetBrains team member Stanislav Erokhin commented on this here in 2017.

[...] for now compiler force users declare type arguments for parent class explicitly.

Let's experiment a bit. The check in question in the compiler source code is here

if (currentArguments.size != currentParameters.size) {
    c.trace.report(
        WRONG_NUMBER_OF_TYPE_ARGUMENTS.on(
            qualifierPart.typeArguments ?: qualifierPart.expression,
            currentParameters.size, classifierDescriptorChain[index]
        )
    )
    return null
}

What if we remove that check? Turns out we get rid of

error: one type argument expected for class Wrapper<T>

but we don't get much further; instead we get

error: type arguments should be specified for an outer class 'Wrapper'. Use full class name to specify them

Making it work will require much bigger changes...

So, in short, it is theoretically possible, but not yet implemented.

like image 136
Enselic Avatar answered Nov 09 '22 16:11

Enselic