Search code examples
kotlingeneric-function

Kotlin generic function return type does not conform to declared nullability


fun <T: Any?> function(input: T): T = input
fun function2() {
    val n = function(1)!!
}

Since T is declared as nullable, I expected the output to be nullable as well, but Lint produces Unnecessary non-null assertion (!!) on a non-null receiver of type Int warning. Changing the output type signature to T? makes the warning go away.

Why does the output type not conform to the declaried nullability?


Solution

  • T: Any? does not mean "T is nullable". It constrains the type parameter T to be a subtype of Any?. Nullable types, as well as non-nullable types satisfy this constraint. In general, if B is a subtype of A, then A, B, A?, and B? are all subtypes of A?.

    When you do

    val n = function(1)
    

    The type parameter T is inferred to be Int, which is a non-nullable type that satisfies the constraint : Any?. The function is declared to return a T, so in this case it returns an Int. There are no problems here, and !! is unnecessary.

    Compare that to:

    val n = function<Int?>(1)
    

    where you explicitly say that T should be Int?, which is a nullable type (that also satisfy the constraint of : Any). In this case the function returns Int?, and !! can be added without a warning.