Richard Gomez
12/01/2021, 9:53 PMcompiles method compiles without issue, but if I save the expression to a variable instead of returning it, it complains about a type mismatch.Richard Gomez
12/01/2021, 9:56 PMResponse, but it needs to be RestResponse because that allows you to set status code, headers, etc.
// Both of these work
@GET
fun compiles2(): Response {
return if (dto != null) dto
else ErrResponse("baz")
}
@GET
fun compiles3(): Response {
val response = if (dto != null) dto
else ErrResponse("baz")
return response
}Casey Brooks
12/01/2021, 10:05 PMcompiles() method, the compiler knows the return type of the function, and so it can check whether the generic RestResponse returns the specific type of the function, and indeed it does. There is no type inference in here, just simple type-checking.
In fails(), the compiler must first infer the type of the response variable, and since the RestResponse is (I'm assuming) a Java class, it tries to reconcile the Java generic variance with Kotlin, and determines it to have out variance. But the fails() function itself does not have that variance, which is why it won't compile. Adding a type-hint might help the compiler infer the type correctly (val response: RestResponse<Response> = ...)Richard Gomez
12/01/2021, 10:06 PMRichard Gomez
12/01/2021, 10:08 PMInThat's a good guess, and what I was initially thinking, but I don't think it's specific to Java. The error persists even when I use a Kotlin 'mock' of RestResponse., the compiler must first infer the type of thefails()variable, and since theresponseis (I'm assuming) a Java class, it tries to reconcile the Java generic variance with Kotlin, and determines it to haveRestResponsevariance.out
data class RestResponse<T>(val status: Int, val entity: T) {
companion object {
fun <T> ok(entity: T): RestResponse<T> = RestResponse(200, entity)
fun <T> status(status: Int, entity: T): RestResponse<T> = RestResponse(status, entity)
}
}
(Adding an explicit type hint does work though)ilya.gorbunov
12/02/2021, 5:28 AMRestResponse<Ok> and RestResponse<Error> and assign them to RestResponse<Response> even though Ok and Error are subtypes of Responseilya.gorbunov
12/02/2021, 5:30 AMRestResponse<Response>, it can infer types of RestResponse.ok and RestResponse.status invocations as
ok<Response>(...) and status<Response>(...), so the result will be assignable to RestResponse<Response>.ilya.gorbunov
12/02/2021, 5:39 AMRestResponse<out Response>ilya.gorbunov
12/02/2021, 5:41 AMRichard Gomez
12/05/2021, 10:36 PM