From ab90b2b901effc68a7cbef0db163559027762d0e Mon Sep 17 00:00:00 2001 From: Dmitry Petrov Date: Wed, 26 Sep 2018 12:05:09 +0300 Subject: [PATCH] Fix nullability propagation in inline class type mapping #KT-27096 See https://jetbrains.slack.com/archives/C06E082M6/p1537949572000100 --- .../codegen/box/inlineClasses/kt27096.kt | 23 ++ .../codegen/box/inlineClasses/kt27096_enum.kt | 31 +++ .../box/inlineClasses/kt27096_functional.kt | 26 ++ .../box/inlineClasses/kt27096_innerClass.kt | 42 +++ .../kt27096_nullablePrimitive.kt | 26 ++ .../kt27096_nullableReference.kt | 26 ++ .../box/inlineClasses/kt27096_primitive.kt | 32 +++ .../box/inlineClasses/kt27096_reference.kt | 32 +++ .../inlineClasses/nullableWrapperEquality.kt | 18 ++ .../inlineClasses/nullabilityInExpansion.kt | 40 +++ .../inlineClasses/nullabilityInExpansion.txt | 257 ++++++++++++++++++ ...ericInlineClassWithDefaultTypeParameter.kt | 8 +- ...ericInlineClassWithNotNullTypeParameter.kt | 8 +- .../codegen/BlackBoxCodegenTestGenerated.java | 45 +++ .../codegen/BytecodeListingTestGenerated.java | 5 + .../LightAnalysisModeTestGenerated.java | 45 +++ .../ir/IrBlackBoxCodegenTestGenerated.java | 45 +++ .../load/kotlin/typeSignatureMapping.kt | 59 +++- .../IrJsCodegenBoxTestGenerated.java | 45 +++ .../semantics/JsCodegenBoxTestGenerated.java | 45 +++ 20 files changed, 843 insertions(+), 15 deletions(-) create mode 100644 compiler/testData/codegen/box/inlineClasses/kt27096.kt create mode 100644 compiler/testData/codegen/box/inlineClasses/kt27096_enum.kt create mode 100644 compiler/testData/codegen/box/inlineClasses/kt27096_functional.kt create mode 100644 compiler/testData/codegen/box/inlineClasses/kt27096_innerClass.kt create mode 100644 compiler/testData/codegen/box/inlineClasses/kt27096_nullablePrimitive.kt create mode 100644 compiler/testData/codegen/box/inlineClasses/kt27096_nullableReference.kt create mode 100644 compiler/testData/codegen/box/inlineClasses/kt27096_primitive.kt create mode 100644 compiler/testData/codegen/box/inlineClasses/kt27096_reference.kt create mode 100644 compiler/testData/codegen/box/inlineClasses/nullableWrapperEquality.kt create mode 100644 compiler/testData/codegen/bytecodeListing/inlineClasses/nullabilityInExpansion.kt create mode 100644 compiler/testData/codegen/bytecodeListing/inlineClasses/nullabilityInExpansion.txt diff --git a/compiler/testData/codegen/box/inlineClasses/kt27096.kt b/compiler/testData/codegen/box/inlineClasses/kt27096.kt new file mode 100644 index 00000000000..a5bc4b904b7 --- /dev/null +++ b/compiler/testData/codegen/box/inlineClasses/kt27096.kt @@ -0,0 +1,23 @@ +// !LANGUAGE: +InlineClasses +// IGNORE_BACKEND: JVM_IR +// WITH_RUNTIME + +inline class Ucn(private val i: UInt) + +class PPInput(private val s: ByteArray) { + fun peek(n: UInt = 0u): Ucn? = + if (n >= s.size.toUInt()) + null + else + Ucn(s[n.toInt()].toUInt()) +} + +fun box(): String { + val ppInput = PPInput(byteArrayOf(0.toByte(), 0.toByte(), 0.toByte())) + + if (ppInput.peek(0u) == null) throw AssertionError() + if (ppInput.peek(100u) != null) throw AssertionError() + if (ppInput.peek(0u)!!.toString() != "Ucn(i=0)") throw AssertionError(ppInput.peek(0u)!!.toString()) + + return "OK" +} \ No newline at end of file diff --git a/compiler/testData/codegen/box/inlineClasses/kt27096_enum.kt b/compiler/testData/codegen/box/inlineClasses/kt27096_enum.kt new file mode 100644 index 00000000000..78b065d0db8 --- /dev/null +++ b/compiler/testData/codegen/box/inlineClasses/kt27096_enum.kt @@ -0,0 +1,31 @@ +// !LANGUAGE: +InlineClasses +// IGNORE_BACKEND: JVM_IR + +enum class En { N, A, B, C } + +inline class Z1(val x: En) +inline class Z2(val z: Z1) +inline class ZN(val z: Z1?) + +fun wrap1(x: En): Z1? = if (x.ordinal == 0) null else Z1(x) +fun wrap2(x: En): Z2? = if (x.ordinal == 0) null else Z2(Z1(x)) +fun wrapN(x: En): ZN? = if (x.ordinal == 0) null else ZN(Z1(x)) + +fun box(): String { + val n = En.N + val a = En.A + + if (wrap1(n) != null) throw AssertionError() + if (wrap1(a) == null) throw AssertionError() + if (wrap1(a)!!.x != a) throw AssertionError() + + if (wrap2(n) != null) throw AssertionError() + if (wrap2(a) == null) throw AssertionError() + if (wrap2(a)!!.z.x != a) throw AssertionError() + + if (wrapN(n) != null) throw AssertionError() + if (wrapN(a) == null) throw AssertionError() + if (wrapN(a)!!.z!!.x != a) throw AssertionError() + + return "OK" +} \ No newline at end of file diff --git a/compiler/testData/codegen/box/inlineClasses/kt27096_functional.kt b/compiler/testData/codegen/box/inlineClasses/kt27096_functional.kt new file mode 100644 index 00000000000..cbd66264ce5 --- /dev/null +++ b/compiler/testData/codegen/box/inlineClasses/kt27096_functional.kt @@ -0,0 +1,26 @@ +// !LANGUAGE: +InlineClasses +// IGNORE_BACKEND: JVM_IR + +inline class Z1(val x: () -> String) +inline class Z2(val z: Z1) +inline class ZN(val z: Z1?) + +fun wrap1(x: String): Z1? = if (x.length == 0) null else Z1({ x }) +fun wrap2(x: String): Z2? = if (x.length == 0) null else Z2(Z1({ x })) +fun wrapN(x: String): ZN? = if (x.length == 0) null else ZN(Z1({ x })) + +fun box(): String { + if (wrap1("") != null) throw AssertionError() + if (wrap1("a") == null) throw AssertionError() + if (wrap1("a")!!.x() != "a") throw AssertionError() + + if (wrap2("") != null) throw AssertionError() + if (wrap2("a") == null) throw AssertionError() + if (wrap2("a")!!.z.x() != "a") throw AssertionError() + + if (wrapN("") != null) throw AssertionError() + if (wrapN("a") == null) throw AssertionError() + if (wrapN("a")!!.z!!.x() != "a") throw AssertionError() + + return "OK" +} \ No newline at end of file diff --git a/compiler/testData/codegen/box/inlineClasses/kt27096_innerClass.kt b/compiler/testData/codegen/box/inlineClasses/kt27096_innerClass.kt new file mode 100644 index 00000000000..30f0fc5e60e --- /dev/null +++ b/compiler/testData/codegen/box/inlineClasses/kt27096_innerClass.kt @@ -0,0 +1,42 @@ +// !LANGUAGE: +InlineClasses +// IGNORE_BACKEND: JVM_IR + +class Outer(val x: X) { + inner class Inner(val y: Y) { + val hasNull = x == null || y == null + + fun outerX() = x + + override fun equals(other: Any?): Boolean = + other is Outer<*>.Inner<*> && + other.outerX() == x && + other.y == y + } +} + +inline class Z1(val x: Outer.Inner) +inline class Z2(val z: Z1) +inline class ZN(val z: Z1?) + +fun wrap1(xy : Outer.Inner): Z1? = if (xy.hasNull) null else Z1(xy) +fun wrap2(xy : Outer.Inner): Z2? = if (xy.hasNull) null else Z2(Z1(xy)) +fun wrapN(xy : Outer.Inner): ZN? = if (xy.hasNull) null else ZN(Z1(xy)) + +fun box(): String { + val n = Outer(null).Inner("a") + val a = Outer("a").Inner("a") + + if (wrap1(n) != null) throw AssertionError() + if (wrap1(a) == null) throw AssertionError() + if (wrap1(a)!!.x != a) throw AssertionError() + + if (wrap2(n) != null) throw AssertionError() + if (wrap2(a) == null) throw AssertionError() + if (wrap2(a)!!.z.x != a) throw AssertionError() + + if (wrapN(n) != null) throw AssertionError() + if (wrapN(a) == null) throw AssertionError() + if (wrapN(a)!!.z!!.x != a) throw AssertionError() + + return "OK" +} \ No newline at end of file diff --git a/compiler/testData/codegen/box/inlineClasses/kt27096_nullablePrimitive.kt b/compiler/testData/codegen/box/inlineClasses/kt27096_nullablePrimitive.kt new file mode 100644 index 00000000000..0cf5c528d6f --- /dev/null +++ b/compiler/testData/codegen/box/inlineClasses/kt27096_nullablePrimitive.kt @@ -0,0 +1,26 @@ +// !LANGUAGE: +InlineClasses +// IGNORE_BACKEND: JVM_IR + +inline class Z1(val x: Int?) +inline class Z2(val z: Z1) +inline class ZN(val z: Z1?) + +fun wrap1(n: Int): Z1? = if (n < 0) null else Z1(n) +fun wrap2(n: Int): Z2? = if (n < 0) null else Z2(Z1(n)) +fun wrapN(n: Int): ZN? = if (n < 0) null else ZN(Z1(n)) + +fun box(): String { + if (wrap1(-1) != null) throw AssertionError() + if (wrap1(42) == null) throw AssertionError() + if (wrap1(42)!!.x != 42) throw AssertionError() + + if (wrap2(-1) != null) throw AssertionError() + if (wrap2(42) == null) throw AssertionError() + if (wrap2(42)!!.z.x != 42) throw AssertionError() + + if (wrapN(-1) != null) throw AssertionError() + if (wrapN(42) == null) throw AssertionError() + if (wrapN(42)!!.z!!.x != 42) throw AssertionError() + + return "OK" +} \ No newline at end of file diff --git a/compiler/testData/codegen/box/inlineClasses/kt27096_nullableReference.kt b/compiler/testData/codegen/box/inlineClasses/kt27096_nullableReference.kt new file mode 100644 index 00000000000..5d025529b94 --- /dev/null +++ b/compiler/testData/codegen/box/inlineClasses/kt27096_nullableReference.kt @@ -0,0 +1,26 @@ +// !LANGUAGE: +InlineClasses +// IGNORE_BACKEND: JVM_IR + +inline class Z1(val x: String?) +inline class Z2(val z: Z1) +inline class ZN(val z: Z1?) + +fun wrap1(x: String): Z1? = if (x.length == 0) null else Z1(x) +fun wrap2(x: String): Z2? = if (x.length == 0) null else Z2(Z1(x)) +fun wrapN(x: String): ZN? = if (x.length == 0) null else ZN(Z1(x)) + +fun box(): String { + if (wrap1("") != null) throw AssertionError() + if (wrap1("a") == null) throw AssertionError() + if (wrap1("a")!!.x != "a") throw AssertionError() + + if (wrap2("") != null) throw AssertionError() + if (wrap2("a") == null) throw AssertionError() + if (wrap2("a")!!.z.x != "a") throw AssertionError() + + if (wrapN("") != null) throw AssertionError() + if (wrapN("a") == null) throw AssertionError() + if (wrapN("a")!!.z!!.x != "a") throw AssertionError() + + return "OK" +} \ No newline at end of file diff --git a/compiler/testData/codegen/box/inlineClasses/kt27096_primitive.kt b/compiler/testData/codegen/box/inlineClasses/kt27096_primitive.kt new file mode 100644 index 00000000000..8fb1a5430a3 --- /dev/null +++ b/compiler/testData/codegen/box/inlineClasses/kt27096_primitive.kt @@ -0,0 +1,32 @@ +// !LANGUAGE: +InlineClasses +// IGNORE_BACKEND: JVM_IR + +inline class Z1(val x: Int) +inline class Z2(val z: Z1) +inline class ZN(val z: Z1?) +inline class ZN2(val z: ZN) + +fun wrap1(n: Int): Z1? = if (n < 0) null else Z1(n) +fun wrap2(n: Int): Z2? = if (n < 0) null else Z2(Z1(n)) +fun wrapN(n: Int): ZN? = if (n < 0) null else ZN(Z1(n)) +fun wrapN2(n: Int): ZN2? = if (n < 0) null else ZN2(ZN(Z1(n))) + +fun box(): String { + if (wrap1(-1) != null) throw AssertionError() + if (wrap1(42) == null) throw AssertionError() + if (wrap1(42)!!.x != 42) throw AssertionError() + + if (wrap2(-1) != null) throw AssertionError() + if (wrap2(42) == null) throw AssertionError() + if (wrap2(42)!!.z.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 (wrapN2(-1) != null) throw AssertionError() + if (wrapN2(42) == null) throw AssertionError() + if (wrapN2(42)!!.z.z!!.x != 42) throw AssertionError() + + return "OK" +} \ No newline at end of file diff --git a/compiler/testData/codegen/box/inlineClasses/kt27096_reference.kt b/compiler/testData/codegen/box/inlineClasses/kt27096_reference.kt new file mode 100644 index 00000000000..fee44a61d47 --- /dev/null +++ b/compiler/testData/codegen/box/inlineClasses/kt27096_reference.kt @@ -0,0 +1,32 @@ +// !LANGUAGE: +InlineClasses +// IGNORE_BACKEND: JVM_IR + +inline class Z1(val x: String) +inline class Z2(val z: Z1) +inline class ZN(val z: Z1?) +inline class ZN2(val z: ZN) + +fun wrap1(x: String): Z1? = if (x.length == 0) null else Z1(x) +fun wrap2(x: String): Z2? = if (x.length == 0) null else Z2(Z1(x)) +fun wrapN(x: String): ZN? = if (x.length == 0) null else ZN(Z1(x)) +fun wrapN2(x: String): ZN2? = if (x.length == 0) null else ZN2(ZN(Z1(x))) + +fun box(): String { + if (wrap1("") != null) throw AssertionError() + if (wrap1("a") == null) throw AssertionError() + if (wrap1("a")!!.x != "a") throw AssertionError() + + if (wrap2("") != null) throw AssertionError() + if (wrap2("a") == null) throw AssertionError() + if (wrap2("a")!!.z.x != "a") throw AssertionError() + + if (wrapN("") != null) throw AssertionError() + if (wrapN("a") == null) throw AssertionError() + if (wrapN("a")!!.z!!.x != "a") throw AssertionError() + + if (wrapN2("") != null) throw AssertionError() + if (wrapN2("a") == null) throw AssertionError() + if (wrapN2("a")!!.z.z!!.x != "a") throw AssertionError() + + return "OK" +} \ No newline at end of file diff --git a/compiler/testData/codegen/box/inlineClasses/nullableWrapperEquality.kt b/compiler/testData/codegen/box/inlineClasses/nullableWrapperEquality.kt new file mode 100644 index 00000000000..f74d94334c2 --- /dev/null +++ b/compiler/testData/codegen/box/inlineClasses/nullableWrapperEquality.kt @@ -0,0 +1,18 @@ +// !LANGUAGE: +InlineClasses +// IGNORE_BACKEND: JVM_IR + +inline class Z1(val x: String) +inline class ZN(val z: Z1?) +inline class ZN2(val z: ZN) + +fun zap(b: Boolean): ZN2? = if (b) null else ZN2(ZN(null)) + +fun eq(a: Any?, b: Any?) = a == b + +fun box(): String { + val x = zap(true) + val y = zap(false) + if (eq(x, y)) throw AssertionError() + + return "OK" +} \ No newline at end of file diff --git a/compiler/testData/codegen/bytecodeListing/inlineClasses/nullabilityInExpansion.kt b/compiler/testData/codegen/bytecodeListing/inlineClasses/nullabilityInExpansion.kt new file mode 100644 index 00000000000..0b8676305fe --- /dev/null +++ b/compiler/testData/codegen/bytecodeListing/inlineClasses/nullabilityInExpansion.kt @@ -0,0 +1,40 @@ +// !LANGUAGE: +InlineClasses + +inline class Z1(val x: Int) +inline class Z2(val z: Z1) +inline class ZN(val z: Z1?) +inline class ZN2(val z: ZN) + +inline class S1(val x: String) +inline class S2(val z: S1) +inline class SN(val z: S1?) +inline class SN2(val z: SN) + +inline class Q1(val x: Int?) +inline class Q2(val z: Q1) +inline class QN(val z: Q1?) + +inline class W1(val x: String?) +inline class W2(val z: W1) +inline class WN(val z: W1?) + +fun zwrap1(n: Int): Z1? = if (n < 0) null else Z1(n) +fun zwrap2(n: Int): Z2? = if (n < 0) null else Z2(Z1(n)) +fun zwrapN(n: Int): ZN? = if (n < 0) null else ZN(Z1(n)) +fun zwrapN2(n: Int): ZN2? = if (n < 0) null else ZN2(ZN(Z1(n))) +fun zwrapNbox(n: Int): ZN2 = ZN2(ZN(Z1(n))) + +fun swrap1(x: String): S1? = if (x.length == 0) null else S1(x) +fun swrap2(x: String): S2? = if (x.length == 0) null else S2(S1(x)) +fun swrapN(x: String): SN? = if (x.length == 0) null else SN(S1(x)) +fun swrapN2(x: String): SN2? = if (x.length == 0) null else SN2(SN(S1(x))) +fun swrapNbox(x: String): SN2 = SN2(SN(S1(x))) + +fun qwrap1(n: Int): Q1? = if (n < 0) null else Q1(n) +fun qwrap2(n: Int): Q2? = if (n < 0) null else Q2(Q1(n)) +fun qwrapN(n: Int): QN? = if (n < 0) null else QN(Q1(n)) + +fun wwrap1(x: String): W1? = if (x.length == 0) null else W1(x) +fun wwrap2(x: String): W2? = if (x.length == 0) null else W2(W1(x)) +fun wwrapN(x: String): WN? = if (x.length == 0) null else WN(W1(x)) + diff --git a/compiler/testData/codegen/bytecodeListing/inlineClasses/nullabilityInExpansion.txt b/compiler/testData/codegen/bytecodeListing/inlineClasses/nullabilityInExpansion.txt new file mode 100644 index 00000000000..53f5648390a --- /dev/null +++ b/compiler/testData/codegen/bytecodeListing/inlineClasses/nullabilityInExpansion.txt @@ -0,0 +1,257 @@ +@kotlin.Metadata +public final class NullabilityInExpansionKt { + public final static @org.jetbrains.annotations.Nullable method qwrap1(p0: int): Q1 + public final static @org.jetbrains.annotations.Nullable method qwrap2(p0: int): Q2 + public final static @org.jetbrains.annotations.Nullable method qwrapN(p0: int): QN + public final static @org.jetbrains.annotations.Nullable method swrap1(@org.jetbrains.annotations.NotNull p0: java.lang.String): java.lang.String + public final static @org.jetbrains.annotations.Nullable method swrap2(@org.jetbrains.annotations.NotNull p0: java.lang.String): java.lang.String + public final static @org.jetbrains.annotations.Nullable method swrapN(@org.jetbrains.annotations.NotNull p0: java.lang.String): SN + public final static @org.jetbrains.annotations.Nullable method swrapN2(@org.jetbrains.annotations.NotNull p0: java.lang.String): SN2 + public final static @org.jetbrains.annotations.NotNull method swrapNbox(@org.jetbrains.annotations.NotNull p0: java.lang.String): java.lang.String + public final static @org.jetbrains.annotations.Nullable method wwrap1(@org.jetbrains.annotations.NotNull p0: java.lang.String): W1 + public final static @org.jetbrains.annotations.Nullable method wwrap2(@org.jetbrains.annotations.NotNull p0: java.lang.String): W2 + public final static @org.jetbrains.annotations.Nullable method wwrapN(@org.jetbrains.annotations.NotNull p0: java.lang.String): WN + public final static @org.jetbrains.annotations.Nullable method zwrap1(p0: int): Z1 + public final static @org.jetbrains.annotations.Nullable method zwrap2(p0: int): Z2 + public final static @org.jetbrains.annotations.Nullable method zwrapN(p0: int): ZN + public final static @org.jetbrains.annotations.Nullable method zwrapN2(p0: int): ZN2 + public final static @org.jetbrains.annotations.NotNull method zwrapNbox(p0: int): Z1 +} + +@kotlin.Metadata +public final class Q1 { + private final @org.jetbrains.annotations.Nullable field x: java.lang.Integer + private synthetic method (@org.jetbrains.annotations.Nullable p0: java.lang.Integer): void + public synthetic final static @org.jetbrains.annotations.NotNull method box-impl(@org.jetbrains.annotations.Nullable p0: java.lang.Integer): Q1 + public static @org.jetbrains.annotations.NotNull method constructor-impl(@org.jetbrains.annotations.Nullable p0: java.lang.Integer): java.lang.Integer + public method equals(p0: java.lang.Object): boolean + public static method equals-impl(p0: java.lang.Integer, @org.jetbrains.annotations.Nullable p1: java.lang.Object): boolean + public final static method equals-impl0(@org.jetbrains.annotations.Nullable p0: java.lang.Integer, @org.jetbrains.annotations.Nullable p1: java.lang.Integer): boolean + public final @org.jetbrains.annotations.Nullable method getX(): java.lang.Integer + public method hashCode(): int + public static method hashCode-impl(p0: java.lang.Integer): int + public method toString(): java.lang.String + public static @org.jetbrains.annotations.NotNull method toString-impl(p0: java.lang.Integer): java.lang.String + public synthetic final @org.jetbrains.annotations.Nullable method unbox-impl(): java.lang.Integer +} + +@kotlin.Metadata +public final class Q2 { + private final @org.jetbrains.annotations.NotNull field z: java.lang.Integer + private synthetic method (@org.jetbrains.annotations.NotNull p0: java.lang.Integer): void + public synthetic final static @org.jetbrains.annotations.NotNull method box-impl(@org.jetbrains.annotations.NotNull p0: java.lang.Integer): Q2 + public static @org.jetbrains.annotations.NotNull method constructor-impl(@org.jetbrains.annotations.NotNull p0: java.lang.Integer): java.lang.Integer + public method equals(p0: java.lang.Object): boolean + public static method equals-impl(p0: java.lang.Integer, @org.jetbrains.annotations.Nullable p1: java.lang.Object): boolean + public final static method equals-impl0(@org.jetbrains.annotations.NotNull p0: java.lang.Integer, @org.jetbrains.annotations.NotNull p1: java.lang.Integer): boolean + public final @org.jetbrains.annotations.NotNull method getZ(): java.lang.Integer + public method hashCode(): int + public static method hashCode-impl(p0: java.lang.Integer): int + public method toString(): java.lang.String + public static @org.jetbrains.annotations.NotNull method toString-impl(p0: java.lang.Integer): java.lang.String + public synthetic final @org.jetbrains.annotations.NotNull method unbox-impl(): java.lang.Integer +} + +@kotlin.Metadata +public final class QN { + private final @org.jetbrains.annotations.Nullable field z: Q1 + private synthetic method (@org.jetbrains.annotations.Nullable p0: Q1): void + public synthetic final static @org.jetbrains.annotations.NotNull method box-impl(@org.jetbrains.annotations.Nullable p0: Q1): QN + public static @org.jetbrains.annotations.NotNull method constructor-impl(@org.jetbrains.annotations.Nullable p0: Q1): Q1 + public method equals(p0: java.lang.Object): boolean + public static method equals-impl(p0: Q1, @org.jetbrains.annotations.Nullable p1: java.lang.Object): boolean + public final static method equals-impl0(@org.jetbrains.annotations.Nullable p0: Q1, @org.jetbrains.annotations.Nullable p1: Q1): boolean + public final @org.jetbrains.annotations.Nullable method getZ(): Q1 + public method hashCode(): int + public static method hashCode-impl(p0: Q1): int + public method toString(): java.lang.String + public static @org.jetbrains.annotations.NotNull method toString-impl(p0: Q1): java.lang.String + public synthetic final @org.jetbrains.annotations.Nullable method unbox-impl(): Q1 +} + +@kotlin.Metadata +public final class S1 { + private final @org.jetbrains.annotations.NotNull field x: java.lang.String + private synthetic method (@org.jetbrains.annotations.NotNull p0: java.lang.String): void + public synthetic final static @org.jetbrains.annotations.NotNull method box-impl(@org.jetbrains.annotations.NotNull p0: java.lang.String): S1 + public static @org.jetbrains.annotations.NotNull method constructor-impl(@org.jetbrains.annotations.NotNull p0: java.lang.String): java.lang.String + public method equals(p0: java.lang.Object): boolean + public static method equals-impl(p0: java.lang.String, @org.jetbrains.annotations.Nullable p1: java.lang.Object): boolean + public final static method equals-impl0(@org.jetbrains.annotations.NotNull p0: java.lang.String, @org.jetbrains.annotations.NotNull p1: java.lang.String): boolean + public final @org.jetbrains.annotations.NotNull method getX(): java.lang.String + public method hashCode(): int + public static method hashCode-impl(p0: java.lang.String): int + public method toString(): java.lang.String + public static @org.jetbrains.annotations.NotNull method toString-impl(p0: java.lang.String): java.lang.String + public synthetic final @org.jetbrains.annotations.NotNull method unbox-impl(): java.lang.String +} + +@kotlin.Metadata +public final class S2 { + private final @org.jetbrains.annotations.NotNull field z: java.lang.String + private synthetic method (@org.jetbrains.annotations.NotNull p0: java.lang.String): void + public synthetic final static @org.jetbrains.annotations.NotNull method box-impl(@org.jetbrains.annotations.NotNull p0: java.lang.String): S2 + public static @org.jetbrains.annotations.NotNull method constructor-impl(@org.jetbrains.annotations.NotNull p0: java.lang.String): java.lang.String + public method equals(p0: java.lang.Object): boolean + public static method equals-impl(p0: java.lang.String, @org.jetbrains.annotations.Nullable p1: java.lang.Object): boolean + public final static method equals-impl0(@org.jetbrains.annotations.NotNull p0: java.lang.String, @org.jetbrains.annotations.NotNull p1: java.lang.String): boolean + public final @org.jetbrains.annotations.NotNull method getZ(): java.lang.String + public method hashCode(): int + public static method hashCode-impl(p0: java.lang.String): int + public method toString(): java.lang.String + public static @org.jetbrains.annotations.NotNull method toString-impl(p0: java.lang.String): java.lang.String + public synthetic final @org.jetbrains.annotations.NotNull method unbox-impl(): java.lang.String +} + +@kotlin.Metadata +public final class SN { + private final @org.jetbrains.annotations.Nullable field z: java.lang.String + private synthetic method (@org.jetbrains.annotations.Nullable p0: java.lang.String): void + public synthetic final static @org.jetbrains.annotations.NotNull method box-impl(@org.jetbrains.annotations.Nullable p0: java.lang.String): SN + public static @org.jetbrains.annotations.NotNull method constructor-impl(@org.jetbrains.annotations.Nullable p0: java.lang.String): java.lang.String + public method equals(p0: java.lang.Object): boolean + public static method equals-impl(p0: java.lang.String, @org.jetbrains.annotations.Nullable p1: java.lang.Object): boolean + public final static method equals-impl0(@org.jetbrains.annotations.Nullable p0: java.lang.String, @org.jetbrains.annotations.Nullable p1: java.lang.String): boolean + public final @org.jetbrains.annotations.Nullable method getZ(): java.lang.String + public method hashCode(): int + public static method hashCode-impl(p0: java.lang.String): int + public method toString(): java.lang.String + public static @org.jetbrains.annotations.NotNull method toString-impl(p0: java.lang.String): java.lang.String + public synthetic final @org.jetbrains.annotations.Nullable method unbox-impl(): java.lang.String +} + +@kotlin.Metadata +public final class SN2 { + private final @org.jetbrains.annotations.NotNull field z: java.lang.String + private synthetic method (@org.jetbrains.annotations.NotNull p0: java.lang.String): void + public synthetic final static @org.jetbrains.annotations.NotNull method box-impl(@org.jetbrains.annotations.NotNull p0: java.lang.String): SN2 + public static @org.jetbrains.annotations.NotNull method constructor-impl(@org.jetbrains.annotations.NotNull p0: java.lang.String): java.lang.String + public method equals(p0: java.lang.Object): boolean + public static method equals-impl(p0: java.lang.String, @org.jetbrains.annotations.Nullable p1: java.lang.Object): boolean + public final static method equals-impl0(@org.jetbrains.annotations.NotNull p0: java.lang.String, @org.jetbrains.annotations.NotNull p1: java.lang.String): boolean + public final @org.jetbrains.annotations.NotNull method getZ(): java.lang.String + public method hashCode(): int + public static method hashCode-impl(p0: java.lang.String): int + public method toString(): java.lang.String + public static @org.jetbrains.annotations.NotNull method toString-impl(p0: java.lang.String): java.lang.String + public synthetic final @org.jetbrains.annotations.NotNull method unbox-impl(): java.lang.String +} + +@kotlin.Metadata +public final class W1 { + private final @org.jetbrains.annotations.Nullable field x: java.lang.String + private synthetic method (@org.jetbrains.annotations.Nullable p0: java.lang.String): void + public synthetic final static @org.jetbrains.annotations.NotNull method box-impl(@org.jetbrains.annotations.Nullable p0: java.lang.String): W1 + public static @org.jetbrains.annotations.NotNull method constructor-impl(@org.jetbrains.annotations.Nullable p0: java.lang.String): java.lang.String + public method equals(p0: java.lang.Object): boolean + public static method equals-impl(p0: java.lang.String, @org.jetbrains.annotations.Nullable p1: java.lang.Object): boolean + public final static method equals-impl0(@org.jetbrains.annotations.Nullable p0: java.lang.String, @org.jetbrains.annotations.Nullable p1: java.lang.String): boolean + public final @org.jetbrains.annotations.Nullable method getX(): java.lang.String + public method hashCode(): int + public static method hashCode-impl(p0: java.lang.String): int + public method toString(): java.lang.String + public static @org.jetbrains.annotations.NotNull method toString-impl(p0: java.lang.String): java.lang.String + public synthetic final @org.jetbrains.annotations.Nullable method unbox-impl(): java.lang.String +} + +@kotlin.Metadata +public final class W2 { + private final @org.jetbrains.annotations.NotNull field z: java.lang.String + private synthetic method (@org.jetbrains.annotations.NotNull p0: java.lang.String): void + public synthetic final static @org.jetbrains.annotations.NotNull method box-impl(@org.jetbrains.annotations.NotNull p0: java.lang.String): W2 + public static @org.jetbrains.annotations.NotNull method constructor-impl(@org.jetbrains.annotations.NotNull p0: java.lang.String): java.lang.String + public method equals(p0: java.lang.Object): boolean + public static method equals-impl(p0: java.lang.String, @org.jetbrains.annotations.Nullable p1: java.lang.Object): boolean + public final static method equals-impl0(@org.jetbrains.annotations.NotNull p0: java.lang.String, @org.jetbrains.annotations.NotNull p1: java.lang.String): boolean + public final @org.jetbrains.annotations.NotNull method getZ(): java.lang.String + public method hashCode(): int + public static method hashCode-impl(p0: java.lang.String): int + public method toString(): java.lang.String + public static @org.jetbrains.annotations.NotNull method toString-impl(p0: java.lang.String): java.lang.String + public synthetic final @org.jetbrains.annotations.NotNull method unbox-impl(): java.lang.String +} + +@kotlin.Metadata +public final class WN { + private final @org.jetbrains.annotations.Nullable field z: W1 + private synthetic method (@org.jetbrains.annotations.Nullable p0: W1): void + public synthetic final static @org.jetbrains.annotations.NotNull method box-impl(@org.jetbrains.annotations.Nullable p0: W1): WN + public static @org.jetbrains.annotations.NotNull method constructor-impl(@org.jetbrains.annotations.Nullable p0: W1): W1 + public method equals(p0: java.lang.Object): boolean + public static method equals-impl(p0: W1, @org.jetbrains.annotations.Nullable p1: java.lang.Object): boolean + public final static method equals-impl0(@org.jetbrains.annotations.Nullable p0: W1, @org.jetbrains.annotations.Nullable p1: W1): boolean + public final @org.jetbrains.annotations.Nullable method getZ(): W1 + public method hashCode(): int + public static method hashCode-impl(p0: W1): int + public method toString(): java.lang.String + public static @org.jetbrains.annotations.NotNull method toString-impl(p0: W1): java.lang.String + public synthetic final @org.jetbrains.annotations.Nullable method unbox-impl(): W1 +} + +@kotlin.Metadata +public final class Z1 { + private final field x: int + private synthetic method (p0: int): void + public synthetic final static @org.jetbrains.annotations.NotNull method box-impl(p0: int): Z1 + public static method constructor-impl(p0: int): int + public method equals(p0: java.lang.Object): boolean + public static method equals-impl(p0: int, @org.jetbrains.annotations.Nullable p1: java.lang.Object): boolean + public final static method equals-impl0(p0: int, p1: int): boolean + public final method getX(): int + public method hashCode(): int + public static method hashCode-impl(p0: int): int + public method toString(): java.lang.String + public static @org.jetbrains.annotations.NotNull method toString-impl(p0: int): java.lang.String + public synthetic final method unbox-impl(): int +} + +@kotlin.Metadata +public final class Z2 { + private final field z: int + private synthetic method (p0: int): void + public synthetic final static @org.jetbrains.annotations.NotNull method box-impl(p0: int): Z2 + public static method constructor-impl(p0: int): int + public method equals(p0: java.lang.Object): boolean + public static method equals-impl(p0: int, @org.jetbrains.annotations.Nullable p1: java.lang.Object): boolean + public final static method equals-impl0(p0: int, p1: int): boolean + public final method getZ(): int + public method hashCode(): int + public static method hashCode-impl(p0: int): int + public method toString(): java.lang.String + public static @org.jetbrains.annotations.NotNull method toString-impl(p0: int): java.lang.String + public synthetic final method unbox-impl(): int +} + +@kotlin.Metadata +public final class ZN { + private final @org.jetbrains.annotations.Nullable field z: Z1 + private synthetic method (@org.jetbrains.annotations.Nullable p0: Z1): void + public synthetic final static @org.jetbrains.annotations.NotNull method box-impl(@org.jetbrains.annotations.Nullable p0: Z1): ZN + public static @org.jetbrains.annotations.NotNull method constructor-impl(@org.jetbrains.annotations.Nullable p0: Z1): Z1 + public method equals(p0: java.lang.Object): boolean + public static method equals-impl(p0: Z1, @org.jetbrains.annotations.Nullable p1: java.lang.Object): boolean + public final static method equals-impl0(@org.jetbrains.annotations.Nullable p0: Z1, @org.jetbrains.annotations.Nullable p1: Z1): boolean + public final @org.jetbrains.annotations.Nullable method getZ(): Z1 + public method hashCode(): int + public static method hashCode-impl(p0: Z1): int + public method toString(): java.lang.String + public static @org.jetbrains.annotations.NotNull method toString-impl(p0: Z1): java.lang.String + public synthetic final @org.jetbrains.annotations.Nullable method unbox-impl(): Z1 +} + +@kotlin.Metadata +public final class ZN2 { + private final @org.jetbrains.annotations.NotNull field z: Z1 + private synthetic method (@org.jetbrains.annotations.NotNull p0: Z1): void + public synthetic final static @org.jetbrains.annotations.NotNull method box-impl(@org.jetbrains.annotations.NotNull p0: Z1): ZN2 + public static @org.jetbrains.annotations.NotNull method constructor-impl(@org.jetbrains.annotations.NotNull p0: Z1): Z1 + public method equals(p0: java.lang.Object): boolean + public static method equals-impl(p0: Z1, @org.jetbrains.annotations.Nullable p1: java.lang.Object): boolean + public final static method equals-impl0(@org.jetbrains.annotations.NotNull p0: Z1, @org.jetbrains.annotations.NotNull p1: Z1): boolean + public final @org.jetbrains.annotations.NotNull method getZ(): Z1 + public method hashCode(): int + public static method hashCode-impl(p0: Z1): int + public method toString(): java.lang.String + public static @org.jetbrains.annotations.NotNull method toString-impl(p0: Z1): java.lang.String + public synthetic final @org.jetbrains.annotations.NotNull method unbox-impl(): Z1 +} diff --git a/compiler/testData/writeSignature/inlineClasses/genericInlineClassWithDefaultTypeParameter.kt b/compiler/testData/writeSignature/inlineClasses/genericInlineClassWithDefaultTypeParameter.kt index d4ad56c262b..95519d2fa1b 100644 --- a/compiler/testData/writeSignature/inlineClasses/genericInlineClassWithDefaultTypeParameter.kt +++ b/compiler/testData/writeSignature/inlineClasses/genericInlineClassWithDefaultTypeParameter.kt @@ -16,19 +16,19 @@ object Test { } // method: Test::withNotNullPrimitive-jBNXRxo -// jvm signature: (Ljava/lang/Object;)V +// jvm signature: (I)V // generic signature: null // method: Test::withAdditionalGenericParameter-HGK7qdE -// jvm signature: (LInv;Ljava/lang/Object;)V -// generic signature: (LInv;Ljava/lang/Object;)V +// jvm signature: (LInv;Ljava/lang/String;)V +// generic signature: (LInv;Ljava/lang/String;)V // method: Test::asNullable-wrrn6tY // jvm signature: (LDefault;)V // generic signature: (LDefault;)V // method: Test::asNullableTypeArgument-jBNXRxo -// jvm signature: (Ljava/lang/Object;)V +// jvm signature: (Ljava/lang/Integer;)V // generic signature: null // method: Test::asNullableAndNullableTypeArgument-wrrn6tY diff --git a/compiler/testData/writeSignature/inlineClasses/genericInlineClassWithNotNullTypeParameter.kt b/compiler/testData/writeSignature/inlineClasses/genericInlineClassWithNotNullTypeParameter.kt index 0c15ceb4d73..ee96f370f88 100644 --- a/compiler/testData/writeSignature/inlineClasses/genericInlineClassWithNotNullTypeParameter.kt +++ b/compiler/testData/writeSignature/inlineClasses/genericInlineClassWithNotNullTypeParameter.kt @@ -15,15 +15,15 @@ object Test { } // method: Test::withNotNullPrimitive-inxE8tU -// jvm signature: (Ljava/lang/Object;)V +// jvm signature: (I)V // generic signature: null // method: Test::asNullable-UczwCtY -// jvm signature: (Ljava/lang/Object;)V -// generic signature: null +// jvm signature: (LNonNull;)V +// generic signature: (LNonNull;)V // method: Test::withNotNullForNullableValue-3nNnbBk -// jvm signature: (Ljava/lang/Object;)V +// jvm signature: (Ljava/lang/Integer;)V // generic signature: null // method: Test::asNullableForNullableValue-wXDnar0 diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java index 880ea6afe8f..473b35c19ad 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java @@ -11819,6 +11819,46 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { runTest("compiler/testData/codegen/box/inlineClasses/kt26103_original.kt"); } + @TestMetadata("kt27096.kt") + public void testKt27096() throws Exception { + runTest("compiler/testData/codegen/box/inlineClasses/kt27096.kt"); + } + + @TestMetadata("kt27096_enum.kt") + public void testKt27096_enum() throws Exception { + runTest("compiler/testData/codegen/box/inlineClasses/kt27096_enum.kt"); + } + + @TestMetadata("kt27096_functional.kt") + public void testKt27096_functional() throws Exception { + runTest("compiler/testData/codegen/box/inlineClasses/kt27096_functional.kt"); + } + + @TestMetadata("kt27096_innerClass.kt") + public void testKt27096_innerClass() throws Exception { + runTest("compiler/testData/codegen/box/inlineClasses/kt27096_innerClass.kt"); + } + + @TestMetadata("kt27096_nullablePrimitive.kt") + public void testKt27096_nullablePrimitive() throws Exception { + runTest("compiler/testData/codegen/box/inlineClasses/kt27096_nullablePrimitive.kt"); + } + + @TestMetadata("kt27096_nullableReference.kt") + public void testKt27096_nullableReference() throws Exception { + runTest("compiler/testData/codegen/box/inlineClasses/kt27096_nullableReference.kt"); + } + + @TestMetadata("kt27096_primitive.kt") + public void testKt27096_primitive() throws Exception { + runTest("compiler/testData/codegen/box/inlineClasses/kt27096_primitive.kt"); + } + + @TestMetadata("kt27096_reference.kt") + public void testKt27096_reference() throws Exception { + runTest("compiler/testData/codegen/box/inlineClasses/kt27096_reference.kt"); + } + @TestMetadata("kt27140.kt") public void testKt27140() throws Exception { runTest("compiler/testData/codegen/box/inlineClasses/kt27140.kt"); @@ -11834,6 +11874,11 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { runTest("compiler/testData/codegen/box/inlineClasses/nullableEqeqNonNull.kt"); } + @TestMetadata("nullableWrapperEquality.kt") + public void testNullableWrapperEquality() throws Exception { + runTest("compiler/testData/codegen/box/inlineClasses/nullableWrapperEquality.kt"); + } + @TestMetadata("overridingFunCallingPrivateFun.kt") public void testOverridingFunCallingPrivateFun() throws Exception { runTest("compiler/testData/codegen/box/inlineClasses/overridingFunCallingPrivateFun.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/BytecodeListingTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/BytecodeListingTestGenerated.java index b7ee51a36ce..defe1acdcce 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/BytecodeListingTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/BytecodeListingTestGenerated.java @@ -339,6 +339,11 @@ public class BytecodeListingTestGenerated extends AbstractBytecodeListingTest { runTest("compiler/testData/codegen/bytecodeListing/inlineClasses/noBridgesForErasedInlineClass.kt"); } + @TestMetadata("nullabilityInExpansion.kt") + public void testNullabilityInExpansion() throws Exception { + runTest("compiler/testData/codegen/bytecodeListing/inlineClasses/nullabilityInExpansion.kt"); + } + @TestMetadata("primaryValsWithDifferentVisibilities.kt") public void testPrimaryValsWithDifferentVisibilities() throws Exception { runTest("compiler/testData/codegen/bytecodeListing/inlineClasses/primaryValsWithDifferentVisibilities.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java index 94f2f913546..3ff2cf774fc 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java @@ -11819,6 +11819,46 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes runTest("compiler/testData/codegen/box/inlineClasses/kt26103_original.kt"); } + @TestMetadata("kt27096.kt") + public void testKt27096() throws Exception { + runTest("compiler/testData/codegen/box/inlineClasses/kt27096.kt"); + } + + @TestMetadata("kt27096_enum.kt") + public void testKt27096_enum() throws Exception { + runTest("compiler/testData/codegen/box/inlineClasses/kt27096_enum.kt"); + } + + @TestMetadata("kt27096_functional.kt") + public void testKt27096_functional() throws Exception { + runTest("compiler/testData/codegen/box/inlineClasses/kt27096_functional.kt"); + } + + @TestMetadata("kt27096_innerClass.kt") + public void testKt27096_innerClass() throws Exception { + runTest("compiler/testData/codegen/box/inlineClasses/kt27096_innerClass.kt"); + } + + @TestMetadata("kt27096_nullablePrimitive.kt") + public void testKt27096_nullablePrimitive() throws Exception { + runTest("compiler/testData/codegen/box/inlineClasses/kt27096_nullablePrimitive.kt"); + } + + @TestMetadata("kt27096_nullableReference.kt") + public void testKt27096_nullableReference() throws Exception { + runTest("compiler/testData/codegen/box/inlineClasses/kt27096_nullableReference.kt"); + } + + @TestMetadata("kt27096_primitive.kt") + public void testKt27096_primitive() throws Exception { + runTest("compiler/testData/codegen/box/inlineClasses/kt27096_primitive.kt"); + } + + @TestMetadata("kt27096_reference.kt") + public void testKt27096_reference() throws Exception { + runTest("compiler/testData/codegen/box/inlineClasses/kt27096_reference.kt"); + } + @TestMetadata("kt27140.kt") public void testKt27140() throws Exception { runTest("compiler/testData/codegen/box/inlineClasses/kt27140.kt"); @@ -11834,6 +11874,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes runTest("compiler/testData/codegen/box/inlineClasses/nullableEqeqNonNull.kt"); } + @TestMetadata("nullableWrapperEquality.kt") + public void testNullableWrapperEquality() throws Exception { + runTest("compiler/testData/codegen/box/inlineClasses/nullableWrapperEquality.kt"); + } + @TestMetadata("overridingFunCallingPrivateFun.kt") public void testOverridingFunCallingPrivateFun() throws Exception { runTest("compiler/testData/codegen/box/inlineClasses/overridingFunCallingPrivateFun.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java index 20a018e0c42..b606f59101e 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java @@ -11824,6 +11824,46 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes runTest("compiler/testData/codegen/box/inlineClasses/kt26103_original.kt"); } + @TestMetadata("kt27096.kt") + public void testKt27096() throws Exception { + runTest("compiler/testData/codegen/box/inlineClasses/kt27096.kt"); + } + + @TestMetadata("kt27096_enum.kt") + public void testKt27096_enum() throws Exception { + runTest("compiler/testData/codegen/box/inlineClasses/kt27096_enum.kt"); + } + + @TestMetadata("kt27096_functional.kt") + public void testKt27096_functional() throws Exception { + runTest("compiler/testData/codegen/box/inlineClasses/kt27096_functional.kt"); + } + + @TestMetadata("kt27096_innerClass.kt") + public void testKt27096_innerClass() throws Exception { + runTest("compiler/testData/codegen/box/inlineClasses/kt27096_innerClass.kt"); + } + + @TestMetadata("kt27096_nullablePrimitive.kt") + public void testKt27096_nullablePrimitive() throws Exception { + runTest("compiler/testData/codegen/box/inlineClasses/kt27096_nullablePrimitive.kt"); + } + + @TestMetadata("kt27096_nullableReference.kt") + public void testKt27096_nullableReference() throws Exception { + runTest("compiler/testData/codegen/box/inlineClasses/kt27096_nullableReference.kt"); + } + + @TestMetadata("kt27096_primitive.kt") + public void testKt27096_primitive() throws Exception { + runTest("compiler/testData/codegen/box/inlineClasses/kt27096_primitive.kt"); + } + + @TestMetadata("kt27096_reference.kt") + public void testKt27096_reference() throws Exception { + runTest("compiler/testData/codegen/box/inlineClasses/kt27096_reference.kt"); + } + @TestMetadata("kt27140.kt") public void testKt27140() throws Exception { runTest("compiler/testData/codegen/box/inlineClasses/kt27140.kt"); @@ -11839,6 +11879,11 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes runTest("compiler/testData/codegen/box/inlineClasses/nullableEqeqNonNull.kt"); } + @TestMetadata("nullableWrapperEquality.kt") + public void testNullableWrapperEquality() throws Exception { + runTest("compiler/testData/codegen/box/inlineClasses/nullableWrapperEquality.kt"); + } + @TestMetadata("overridingFunCallingPrivateFun.kt") public void testOverridingFunCallingPrivateFun() throws Exception { runTest("compiler/testData/codegen/box/inlineClasses/overridingFunCallingPrivateFun.kt"); diff --git a/core/descriptors.jvm/src/org/jetbrains/kotlin/load/kotlin/typeSignatureMapping.kt b/core/descriptors.jvm/src/org/jetbrains/kotlin/load/kotlin/typeSignatureMapping.kt index 8035e2cef3f..337f5cf3094 100644 --- a/core/descriptors.jvm/src/org/jetbrains/kotlin/load/kotlin/typeSignatureMapping.kt +++ b/core/descriptors.jvm/src/org/jetbrains/kotlin/load/kotlin/typeSignatureMapping.kt @@ -12,11 +12,14 @@ import org.jetbrains.kotlin.load.java.typeEnhancement.hasEnhancedNullability import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.SpecialNames -import org.jetbrains.kotlin.resolve.* +import org.jetbrains.kotlin.resolve.DescriptorUtils import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameUnsafe import org.jetbrains.kotlin.resolve.jvm.JvmClassName import org.jetbrains.kotlin.resolve.jvm.JvmPrimitiveType +import org.jetbrains.kotlin.resolve.substitutedUnderlyingType +import org.jetbrains.kotlin.resolve.unsubstitutedUnderlyingType import org.jetbrains.kotlin.types.* +import org.jetbrains.kotlin.types.typeUtil.makeNullable import org.jetbrains.kotlin.types.typeUtil.replaceArgumentsWithStarProjections import org.jetbrains.kotlin.utils.DO_NOTHING_3 @@ -127,14 +130,13 @@ fun mapType( descriptor is ClassDescriptor -> { // NB if inline class is recursive, it's ok to map it as wrapped - if (descriptor.isInline && !mode.needInlineClassWrapping && !kotlinType.isRecursiveInlineClassType()) { - val typeForMapping = computeUnderlyingType(kotlinType) - if (typeForMapping != null) { - val newMode = if (typeForMapping.isInlineClassType()) mode else mode.wrapInlineClassesMode() + if (descriptor.isInline && !mode.needInlineClassWrapping) { + val expandedType = computeExpandedTypeForInlineClass(kotlinType) + if (expandedType != null) { return mapType( - typeForMapping, + expandedType, factory, - newMode, + mode.wrapInlineClassesMode(), typeMappingConfiguration, descriptorTypeWriter, writeGenericType, @@ -251,6 +253,49 @@ internal fun computeUnderlyingType(inlineClassType: KotlinType): KotlinType? { inlineClassType.substitutedUnderlyingType() } +internal fun computeExpandedTypeForInlineClass(inlineClassType: KotlinType): KotlinType? = + computeExpandedTypeInner(inlineClassType, hashSetOf()) + +internal fun computeExpandedTypeInner(kotlinType: KotlinType, visitedClassifiers: HashSet): KotlinType? { + val classifier = kotlinType.constructor.declarationDescriptor + ?: throw AssertionError("Type with a declaration expected: $kotlinType") + if (!visitedClassifiers.add(classifier)) return null + + return when { + classifier is TypeParameterDescriptor -> + computeExpandedTypeInner(getRepresentativeUpperBound(classifier), visitedClassifiers) + ?.let { expandedUpperBound -> + if (expandedUpperBound.isNullable() || !kotlinType.isMarkedNullable) + expandedUpperBound + else + expandedUpperBound.makeNullable() + } + + classifier is ClassDescriptor && classifier.isInline -> { + val inlineClassBoxType = kotlinType + + val underlyingType = kotlinType.substitutedUnderlyingType() ?: return null + val expandedUnderlyingType = computeExpandedTypeInner(underlyingType, visitedClassifiers) ?: return null + when { + !kotlinType.isMarkedNullable -> expandedUnderlyingType + + // Here inline class type is nullable. Apply nullability to the expandedUnderlyingType. + + // Nullable types become inline class boxes + expandedUnderlyingType.isNullable() -> inlineClassBoxType + + // Primitives become inline class boxes + KotlinBuiltIns.isPrimitiveType(expandedUnderlyingType) -> inlineClassBoxType + + // Non-null reference types become nullable reference types + else -> expandedUnderlyingType.makeNullable() + } + } + + else -> kotlinType + } +} + internal fun shouldUseUnderlyingType(inlineClassType: KotlinType): Boolean { val underlyingType = inlineClassType.unsubstitutedUnderlyingType() ?: return false diff --git a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/IrJsCodegenBoxTestGenerated.java b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/IrJsCodegenBoxTestGenerated.java index d66a45ac677..f2528550a8e 100644 --- a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/IrJsCodegenBoxTestGenerated.java +++ b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/IrJsCodegenBoxTestGenerated.java @@ -10359,6 +10359,46 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest { runTest("compiler/testData/codegen/box/inlineClasses/kt26103_original.kt"); } + @TestMetadata("kt27096.kt") + public void testKt27096() throws Exception { + runTest("compiler/testData/codegen/box/inlineClasses/kt27096.kt"); + } + + @TestMetadata("kt27096_enum.kt") + public void testKt27096_enum() throws Exception { + runTest("compiler/testData/codegen/box/inlineClasses/kt27096_enum.kt"); + } + + @TestMetadata("kt27096_functional.kt") + public void testKt27096_functional() throws Exception { + runTest("compiler/testData/codegen/box/inlineClasses/kt27096_functional.kt"); + } + + @TestMetadata("kt27096_innerClass.kt") + public void testKt27096_innerClass() throws Exception { + runTest("compiler/testData/codegen/box/inlineClasses/kt27096_innerClass.kt"); + } + + @TestMetadata("kt27096_nullablePrimitive.kt") + public void testKt27096_nullablePrimitive() throws Exception { + runTest("compiler/testData/codegen/box/inlineClasses/kt27096_nullablePrimitive.kt"); + } + + @TestMetadata("kt27096_nullableReference.kt") + public void testKt27096_nullableReference() throws Exception { + runTest("compiler/testData/codegen/box/inlineClasses/kt27096_nullableReference.kt"); + } + + @TestMetadata("kt27096_primitive.kt") + public void testKt27096_primitive() throws Exception { + runTest("compiler/testData/codegen/box/inlineClasses/kt27096_primitive.kt"); + } + + @TestMetadata("kt27096_reference.kt") + public void testKt27096_reference() throws Exception { + runTest("compiler/testData/codegen/box/inlineClasses/kt27096_reference.kt"); + } + @TestMetadata("kt27140.kt") public void testKt27140() throws Exception { runTest("compiler/testData/codegen/box/inlineClasses/kt27140.kt"); @@ -10374,6 +10414,11 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest { runTest("compiler/testData/codegen/box/inlineClasses/nullableEqeqNonNull.kt"); } + @TestMetadata("nullableWrapperEquality.kt") + public void testNullableWrapperEquality() throws Exception { + runTest("compiler/testData/codegen/box/inlineClasses/nullableWrapperEquality.kt"); + } + @TestMetadata("overridingFunCallingPrivateFun.kt") public void testOverridingFunCallingPrivateFun() throws Exception { runTest("compiler/testData/codegen/box/inlineClasses/overridingFunCallingPrivateFun.kt"); diff --git a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java index 8d2286ed113..1727fb03fb1 100644 --- a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java +++ b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java @@ -11404,6 +11404,46 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest { runTest("compiler/testData/codegen/box/inlineClasses/kt26103_original.kt"); } + @TestMetadata("kt27096.kt") + public void testKt27096() throws Exception { + runTest("compiler/testData/codegen/box/inlineClasses/kt27096.kt"); + } + + @TestMetadata("kt27096_enum.kt") + public void testKt27096_enum() throws Exception { + runTest("compiler/testData/codegen/box/inlineClasses/kt27096_enum.kt"); + } + + @TestMetadata("kt27096_functional.kt") + public void testKt27096_functional() throws Exception { + runTest("compiler/testData/codegen/box/inlineClasses/kt27096_functional.kt"); + } + + @TestMetadata("kt27096_innerClass.kt") + public void testKt27096_innerClass() throws Exception { + runTest("compiler/testData/codegen/box/inlineClasses/kt27096_innerClass.kt"); + } + + @TestMetadata("kt27096_nullablePrimitive.kt") + public void testKt27096_nullablePrimitive() throws Exception { + runTest("compiler/testData/codegen/box/inlineClasses/kt27096_nullablePrimitive.kt"); + } + + @TestMetadata("kt27096_nullableReference.kt") + public void testKt27096_nullableReference() throws Exception { + runTest("compiler/testData/codegen/box/inlineClasses/kt27096_nullableReference.kt"); + } + + @TestMetadata("kt27096_primitive.kt") + public void testKt27096_primitive() throws Exception { + runTest("compiler/testData/codegen/box/inlineClasses/kt27096_primitive.kt"); + } + + @TestMetadata("kt27096_reference.kt") + public void testKt27096_reference() throws Exception { + runTest("compiler/testData/codegen/box/inlineClasses/kt27096_reference.kt"); + } + @TestMetadata("kt27140.kt") public void testKt27140() throws Exception { runTest("compiler/testData/codegen/box/inlineClasses/kt27140.kt"); @@ -11419,6 +11459,11 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest { runTest("compiler/testData/codegen/box/inlineClasses/nullableEqeqNonNull.kt"); } + @TestMetadata("nullableWrapperEquality.kt") + public void testNullableWrapperEquality() throws Exception { + runTest("compiler/testData/codegen/box/inlineClasses/nullableWrapperEquality.kt"); + } + @TestMetadata("overridingFunCallingPrivateFun.kt") public void testOverridingFunCallingPrivateFun() throws Exception { runTest("compiler/testData/codegen/box/inlineClasses/overridingFunCallingPrivateFun.kt");