Closed SerVB closed 4 years ago
The type has to be non nullable, because Nothing
is not a subtype of Nothing?
, but the opposite is true. Can you change that ?
Nothing
is not a subtype ofNothing?
Nothing
is a subtype of Nothing?
. Like T
is a subtype of T?
.
So if I change it to Nothing
here, map.firstOrNull { type isSubtypeOf it }
won't give NothingSchemaProvider
for Nothing?
so my code won't work.
The type has to be non nullable
Are you sure? On the screenshots from https://github.com/papsign/Ktor-OpenAPI-Generator/issues/26#issuecomment-605528988, I see there are many nullable keys in the map...
The map you see is the cache of the types that have already been built. Subtype and Supertype are quite confusing indeed. It is indeed correct to use the non nullable type, all current builders are configured like this. All nullable types are subtypes to their non nullable counterpart but not the opposite, so:
map.firstOrNull { type isSubtypeOf it }
type
is the type being matched, it
is one of the registered handler types.
Nothing? isSubtypeOf Nothing == true
Nothing isSubtypeOf Nothing? == false
If you try to match Nothing
to a handler with a registered type of Nothing?
it will fail and fallback to the next non nullable type.
Subtype and Supertype are quite confusing indeed.
I strongly agree but I believe here that I am not mistaken.
There is what running shows:
import kotlin.reflect.full.createType
import kotlin.reflect.full.isSubtypeOf
import kotlin.reflect.full.withNullability
object NothingWrapper {
private val nothing: Nothing get() = TODO("Nothing can't be ever assigned or returned")
val typeOfNothing = this::nothing.returnType
}
fun main() {
val nonNullableAny = Any::class.createType(nullable = false)
val nullableAny = Any::class.createType(nullable = true)
println(nonNullableAny) // kotlin.Any
println(nullableAny) // kotlin.Any?
println(nullableAny.isSubtypeOf(nonNullableAny)) // false
println(nonNullableAny.isSubtypeOf(nullableAny)) // true
val nonNullableNothing = NothingWrapper.typeOfNothing
val nullableNothing = nonNullableNothing.withNullability(true)
println(nonNullableNothing) // kotlin.Nothing
println(nullableNothing) // kotlin.Nothing?
println(nullableNothing.isSubtypeOf(nonNullableNothing)) // false
println(nonNullableNothing.isSubtypeOf(nullableNothing)) // true
}
So
Nothing? isSubtypeOf Nothing == false
Nothing isSubtypeOf Nothing? == true
Yeah, i just tested it myself. This nomenclature is so confusing. You are indeed right. It was a stroke of luck that the system worked when i tested it... I should have registered all types as nullable, i'm doing the appropriate changes.
The changes have been made, turns out only the Enum handler was wrong, which of course i used to create the nothing type... Thank you.
Follow up of #26.
Thank you, but you variant puts
java.lang.Void
in the map so mykotlin.Nothing?
isn't its subtype. I've made some changes and they work for me. Could you accept them to the main repo?