diff --git a/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/BasicExpressionTypingVisitor.java b/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/BasicExpressionTypingVisitor.java index b6cdd225a5e..235cef21896 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/BasicExpressionTypingVisitor.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/BasicExpressionTypingVisitor.java @@ -65,6 +65,7 @@ import org.jetbrains.kotlin.util.slicedMap.WritableSlice; import java.util.Collection; import java.util.Collections; +import java.util.Iterator; import java.util.List; import static org.jetbrains.kotlin.descriptors.ReceiverParameterDescriptor.NO_RECEIVER_PARAMETER; @@ -581,7 +582,11 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor { } private static boolean isAllowedInClassLiteral(@NotNull JetType type) { - if (type.isMarkedNullable()) return false; + return isClassAvailableAtRuntime(type, false); + } + + private static boolean isClassAvailableAtRuntime(@NotNull JetType type, boolean canBeNullable) { + if (type.isMarkedNullable() && !canBeNullable) return false; TypeConstructor typeConstructor = type.getConstructor(); ClassifierDescriptor typeDeclarationDescriptor = typeConstructor.getDeclarationDescriptor(); @@ -590,8 +595,13 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor { List parameters = typeConstructor.getParameters(); if (parameters.size() != type.getArguments().size()) return false; + Iterator typeArgumentsIterator = type.getArguments().iterator(); for (TypeParameterDescriptor parameter : parameters) { if (!parameter.isReified()) return false; + TypeProjection typeArgument = typeArgumentsIterator.next(); + if (typeArgument == null) return false; + if (typeArgument.isStarProjection()) return false; + if (!isClassAvailableAtRuntime(typeArgument.getType(), true)) return false; } return true; diff --git a/compiler/testData/codegen/boxWithStdlib/reflection/classLiterals/genericArrays.kt b/compiler/testData/codegen/boxWithStdlib/reflection/classLiterals/genericArrays.kt new file mode 100644 index 00000000000..46e3ed06abd --- /dev/null +++ b/compiler/testData/codegen/boxWithStdlib/reflection/classLiterals/genericArrays.kt @@ -0,0 +1,28 @@ +import kotlin.test.* +import kotlin.reflect.* +import kotlin.reflect.jvm.* + +class Klass + +inline fun arrayClass(): KClass> = Array::class + +fun box(): String { + assertEquals("Array", arrayClass().simpleName) + assertEquals("Array", arrayClass().simpleName) + assertEquals("Array", arrayClass>().simpleName) + assertEquals("Array", arrayClass().simpleName) + assertEquals("Array", arrayClass().simpleName) + assertEquals("Array", arrayClass>().simpleName) + assertEquals("Array", arrayClass>().simpleName) + + // Should not be that way. Fix this test when backend is fixed. + assertEquals("[Ljava.lang.Object;", arrayClass().jvmName) + assertEquals("[Ljava.lang.Object;", arrayClass().jvmName) + assertEquals("[Ljava.lang.Object;", arrayClass>().jvmName) + assertEquals("[Ljava.lang.Object;", arrayClass().jvmName) + assertEquals("[Ljava.lang.Object;", arrayClass().jvmName) + assertEquals("[Ljava.lang.Object;", arrayClass>().jvmName) + assertEquals("[Ljava.lang.Object;", arrayClass>().jvmName) + + return "OK" +} \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/classLiteral/genericArrays.kt b/compiler/testData/diagnostics/tests/classLiteral/genericArrays.kt new file mode 100644 index 00000000000..a424d01030f --- /dev/null +++ b/compiler/testData/diagnostics/tests/classLiteral/genericArrays.kt @@ -0,0 +1,8 @@ +import kotlin.reflect.KClass + +fun f1(): KClass> = Array::class +fun f2(): KClass>> = Array>::class +inline fun f3() = Array::class +inline fun f4() = Array>::class +fun f5(): KClass> = Array<*>::class +fun f6(): KClass> = Array::class \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/classLiteral/genericArrays.txt b/compiler/testData/diagnostics/tests/classLiteral/genericArrays.txt new file mode 100644 index 00000000000..32ce9e100b4 --- /dev/null +++ b/compiler/testData/diagnostics/tests/classLiteral/genericArrays.txt @@ -0,0 +1,8 @@ +package + +internal fun f1(): kotlin.reflect.KClass> +internal fun f2(): kotlin.reflect.KClass>> +kotlin.inline() internal fun f3(): kotlin.reflect.KClass> +kotlin.inline() internal fun f4(): kotlin.reflect.KClass>> +internal fun f5(): kotlin.reflect.KClass> +internal fun f6(): kotlin.reflect.KClass> diff --git a/compiler/tests/org/jetbrains/kotlin/checkers/JetDiagnosticsTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/checkers/JetDiagnosticsTestGenerated.java index 46199e8b39d..4696a2ca321 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/JetDiagnosticsTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/checkers/JetDiagnosticsTestGenerated.java @@ -2328,6 +2328,12 @@ public class JetDiagnosticsTestGenerated extends AbstractJetDiagnosticsTest { doTest(fileName); } + @TestMetadata("genericArrays.kt") + public void testGenericArrays() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/classLiteral/genericArrays.kt"); + doTest(fileName); + } + @TestMetadata("genericClasses.kt") public void testGenericClasses() throws Exception { String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/classLiteral/genericClasses.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/generated/BlackBoxWithStdlibCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/generated/BlackBoxWithStdlibCodegenTestGenerated.java index 879ce52c054..ba9bee1d5dd 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/generated/BlackBoxWithStdlibCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/generated/BlackBoxWithStdlibCodegenTestGenerated.java @@ -2880,6 +2880,12 @@ public class BlackBoxWithStdlibCodegenTestGenerated extends AbstractBlackBoxCode doTestWithStdlib(fileName); } + @TestMetadata("genericArrays.kt") + public void testGenericArrays() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxWithStdlib/reflection/classLiterals/genericArrays.kt"); + doTestWithStdlib(fileName); + } + @TestMetadata("genericClass.kt") public void testGenericClass() throws Exception { String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxWithStdlib/reflection/classLiterals/genericClass.kt");