Map nullable type parameter with nullable inline class upper bound
which, in turn, has primitive or nullable underlying type to inline class. #KT-32162
This commit is contained in:
@@ -82,7 +82,12 @@ object AbstractTypeMapper {
|
||||
return when {
|
||||
typeConstructor.isTypeParameter() -> {
|
||||
val typeParameter = typeConstructor.asTypeParameter()
|
||||
val asmType = mapType(context, typeParameter.representativeUpperBound(), mode, null)
|
||||
val upperBound = typeParameter.representativeUpperBound()
|
||||
val newType = if (upperBound.typeConstructor().isInlineClass() && type.isNullableType())
|
||||
upperBound.makeNullable()
|
||||
else upperBound
|
||||
|
||||
val asmType = mapType(context, newType, mode, null)
|
||||
sw?.writeTypeVariable(typeParameter.getName(), asmType)
|
||||
asmType
|
||||
}
|
||||
|
||||
@@ -6,13 +6,13 @@ OPTIONAL_JVM_INLINE_ANNOTATION
|
||||
value class Z1<T: Int>(val x: T)
|
||||
|
||||
OPTIONAL_JVM_INLINE_ANNOTATION
|
||||
value class Z2<T: Z1<Int>>(val z: T)
|
||||
value class Z2<T: Z1<Int>>(val z1: T)
|
||||
|
||||
OPTIONAL_JVM_INLINE_ANNOTATION
|
||||
value class ZN<T: Z1<Int>>(val z: T?)
|
||||
value class ZN<TN: Z1<Int>>(val z1: TN?)
|
||||
|
||||
OPTIONAL_JVM_INLINE_ANNOTATION
|
||||
value class ZN2<T: ZN<Z1<Int>>>(val z: T)
|
||||
value class ZN2<T: ZN<Z1<Int>>>(val zn: T)
|
||||
|
||||
fun wrap1(n: Int): Z1<Int>? = if (n < 0) null else Z1(n)
|
||||
fun wrap2(n: Int): Z2<Z1<Int>>? = if (n < 0) null else Z2(Z1(n))
|
||||
@@ -26,15 +26,15 @@ fun box(): String {
|
||||
|
||||
if (wrap2(-1) != null) throw AssertionError()
|
||||
if (wrap2(42) == null) throw AssertionError()
|
||||
if (wrap2(42)!!.z.x != 42) throw AssertionError()
|
||||
if (wrap2(42)!!.z1.x != 42) throw AssertionError()
|
||||
|
||||
if (wrapN(-1) != null) throw AssertionError()
|
||||
if (wrapN(42) == null) throw AssertionError()
|
||||
if (wrapN(42)!!.z!!.x != 42) throw AssertionError()
|
||||
if (wrapN(42)!!.z1!!.x != 42) throw AssertionError()
|
||||
|
||||
if (wrapN2(-1) != null) throw AssertionError()
|
||||
if (wrapN2(42) == null) throw AssertionError()
|
||||
if (wrapN2(42)!!.z.z!!.x != 42) throw AssertionError()
|
||||
if (wrapN2(42)!!.zn.z1!!.x != 42) throw AssertionError()
|
||||
|
||||
return "OK"
|
||||
}
|
||||
+1
-1
@@ -9,7 +9,7 @@ OPTIONAL_JVM_INLINE_ANNOTATION
|
||||
value class ZN<T: Z1<String>?>(val z: T)
|
||||
|
||||
OPTIONAL_JVM_INLINE_ANNOTATION
|
||||
value class ZN2<T: ZN<Z1<String>?>>(val z: T)
|
||||
value class ZN2<TN: ZN<Z1<String>?>>(val z: TN)
|
||||
|
||||
fun zap(b: Boolean): ZN2<ZN<Z1<String>?>>? = if (b) null else ZN2(ZN(null))
|
||||
|
||||
|
||||
@@ -21,14 +21,18 @@ private fun TypeSystemCommonBackendContext.computeExpandedTypeInner(
|
||||
val typeParameter = classifier.getTypeParameterClassifier()
|
||||
|
||||
return when {
|
||||
typeParameter != null ->
|
||||
computeExpandedTypeInner(typeParameter.getRepresentativeUpperBound(), visitedClassifiers)
|
||||
typeParameter != null -> {
|
||||
val upperBound = typeParameter.getRepresentativeUpperBound()
|
||||
computeExpandedTypeInner(upperBound, visitedClassifiers)
|
||||
?.let { expandedUpperBound ->
|
||||
if (expandedUpperBound.isNullableType() || !kotlinType.isMarkedNullable())
|
||||
expandedUpperBound
|
||||
else
|
||||
expandedUpperBound.makeNullable()
|
||||
when {
|
||||
expandedUpperBound is SimpleTypeMarker && expandedUpperBound.isPrimitiveType() &&
|
||||
kotlinType.isNullableType() && upperBound.typeConstructor().isInlineClass() -> upperBound.makeNullable()
|
||||
expandedUpperBound.isNullableType() || !kotlinType.isMarkedNullable() -> expandedUpperBound
|
||||
else -> expandedUpperBound.makeNullable()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
classifier.isInlineClass() -> {
|
||||
// kotlinType is the boxed inline class type
|
||||
|
||||
Reference in New Issue
Block a user