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 {
|
return when {
|
||||||
typeConstructor.isTypeParameter() -> {
|
typeConstructor.isTypeParameter() -> {
|
||||||
val typeParameter = typeConstructor.asTypeParameter()
|
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)
|
sw?.writeTypeVariable(typeParameter.getName(), asmType)
|
||||||
asmType
|
asmType
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,13 +6,13 @@ OPTIONAL_JVM_INLINE_ANNOTATION
|
|||||||
value class Z1<T: Int>(val x: T)
|
value class Z1<T: Int>(val x: T)
|
||||||
|
|
||||||
OPTIONAL_JVM_INLINE_ANNOTATION
|
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
|
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
|
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 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))
|
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(-1) != null) throw AssertionError()
|
||||||
if (wrap2(42) == 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(-1) != null) throw AssertionError()
|
||||||
if (wrapN(42) == 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(-1) != null) throw AssertionError()
|
||||||
if (wrapN2(42) == 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"
|
return "OK"
|
||||||
}
|
}
|
||||||
+1
-1
@@ -9,7 +9,7 @@ OPTIONAL_JVM_INLINE_ANNOTATION
|
|||||||
value class ZN<T: Z1<String>?>(val z: T)
|
value class ZN<T: Z1<String>?>(val z: T)
|
||||||
|
|
||||||
OPTIONAL_JVM_INLINE_ANNOTATION
|
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))
|
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()
|
val typeParameter = classifier.getTypeParameterClassifier()
|
||||||
|
|
||||||
return when {
|
return when {
|
||||||
typeParameter != null ->
|
typeParameter != null -> {
|
||||||
computeExpandedTypeInner(typeParameter.getRepresentativeUpperBound(), visitedClassifiers)
|
val upperBound = typeParameter.getRepresentativeUpperBound()
|
||||||
|
computeExpandedTypeInner(upperBound, visitedClassifiers)
|
||||||
?.let { expandedUpperBound ->
|
?.let { expandedUpperBound ->
|
||||||
if (expandedUpperBound.isNullableType() || !kotlinType.isMarkedNullable())
|
when {
|
||||||
expandedUpperBound
|
expandedUpperBound is SimpleTypeMarker && expandedUpperBound.isPrimitiveType() &&
|
||||||
else
|
kotlinType.isNullableType() && upperBound.typeConstructor().isInlineClass() -> upperBound.makeNullable()
|
||||||
expandedUpperBound.makeNullable()
|
expandedUpperBound.isNullableType() || !kotlinType.isMarkedNullable() -> expandedUpperBound
|
||||||
|
else -> expandedUpperBound.makeNullable()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
classifier.isInlineClass() -> {
|
classifier.isInlineClass() -> {
|
||||||
// kotlinType is the boxed inline class type
|
// kotlinType is the boxed inline class type
|
||||||
|
|||||||
Reference in New Issue
Block a user