diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/ExpressionCodegen.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/ExpressionCodegen.java index b690b8f9c1d..63303aa6331 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/ExpressionCodegen.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/ExpressionCodegen.java @@ -41,8 +41,6 @@ import org.jetbrains.kotlin.codegen.pseudoInsns.PseudoInsnsPackage; import org.jetbrains.kotlin.codegen.signature.BothSignatureWriter; import org.jetbrains.kotlin.codegen.state.GenerationState; import org.jetbrains.kotlin.codegen.state.JetTypeMapper; -import org.jetbrains.kotlin.codegen.intrinsics.CheckCast; -import org.jetbrains.kotlin.codegen.intrinsics.InstanceOf; import org.jetbrains.kotlin.codegen.when.SwitchCodegen; import org.jetbrains.kotlin.codegen.when.SwitchCodegenUtil; import org.jetbrains.kotlin.descriptors.*; @@ -3820,7 +3818,7 @@ The "returned" value of try expression with no finally is either the last expres private void generateInstanceOfInstruction(@NotNull JetType jetType) { Type type = boxType(asmType(jetType)); putReifierMarkerIfTypeIsReifiedParameter(jetType, ReifiedTypeInliner.INSTANCEOF_MARKER_METHOD_NAME); - InstanceOf.instanceOf(v, jetType, type); + TypeIntrinsics.instanceOf(v, jetType, type); } @NotNull @@ -3829,7 +3827,7 @@ The "returned" value of try expression with no finally is either the last expres putReifierMarkerIfTypeIsReifiedParameter(jetType, safeAs ? ReifiedTypeInliner.SAFE_CHECKCAST_MARKER_METHOD_NAME : ReifiedTypeInliner.CHECKCAST_MARKER_METHOD_NAME); - CheckCast.checkcast(v, jetType, type, safeAs); + TypeIntrinsics.checkcast(v, jetType, type, safeAs); return StackValue.onStack(type); } diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/ReifiedTypeInliner.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/ReifiedTypeInliner.kt index 4467c143fba..58220b60251 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/ReifiedTypeInliner.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/ReifiedTypeInliner.kt @@ -20,9 +20,8 @@ import com.google.common.collect.ImmutableSet import org.jetbrains.kotlin.codegen.AsmUtil import org.jetbrains.kotlin.codegen.JvmCodegenUtil import org.jetbrains.kotlin.codegen.context.MethodContext -import org.jetbrains.kotlin.codegen.intrinsics.CheckCast -import org.jetbrains.kotlin.codegen.intrinsics.InstanceOf import org.jetbrains.kotlin.codegen.intrinsics.IntrinsicMethods +import org.jetbrains.kotlin.codegen.intrinsics.TypeIntrinsics import org.jetbrains.kotlin.resolve.DescriptorUtils import org.jetbrains.kotlin.resolve.jvm.AsmTypes import org.jetbrains.kotlin.types.JetType @@ -169,14 +168,14 @@ public class ReifiedTypeInliner(private val parametersMapping: ReifiedTypeParame private fun processCheckcast(insn: MethodInsnNode, instructions: InsnList, jetType: JetType, asmType: Type, safe: Boolean) = rewriteNextTypeInsn(insn, Opcodes.CHECKCAST) { instanceofInsn: AbstractInsnNode -> if (instanceofInsn !is TypeInsnNode) return false - CheckCast.checkcast(instanceofInsn, instructions, jetType, asmType, safe) + TypeIntrinsics.checkcast(instanceofInsn, instructions, jetType, asmType, safe) return true } private fun processInstanceof(insn: MethodInsnNode, instructions: InsnList, jetType: JetType, asmType: Type) = rewriteNextTypeInsn(insn, Opcodes.INSTANCEOF) { instanceofInsn: AbstractInsnNode -> if (instanceofInsn !is TypeInsnNode) return false - InstanceOf.instanceOf(instanceofInsn, instructions, jetType, asmType) + TypeIntrinsics.instanceOf(instanceofInsn, instructions, jetType, asmType) return true } diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/intrinsics/CheckCast.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/intrinsics/CheckCast.kt deleted file mode 100644 index 8f969d7dd94..00000000000 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/intrinsics/CheckCast.kt +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Copyright 2010-2015 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.jetbrains.kotlin.codegen.intrinsics - -import org.jetbrains.kotlin.resolve.DescriptorUtils -import org.jetbrains.kotlin.types.JetType -import org.jetbrains.kotlin.types.TypeUtils -import org.jetbrains.org.objectweb.asm.Opcodes -import org.jetbrains.org.objectweb.asm.Type -import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter -import org.jetbrains.org.objectweb.asm.tree.InsnList -import org.jetbrains.org.objectweb.asm.tree.MethodInsnNode -import org.jetbrains.org.objectweb.asm.tree.TypeInsnNode - -object CheckCast { - private val INTRINSICS_CLASS = "kotlin/jvm/internal/TypeIntrinsics" - - private val CHECKCAST_METHOD_NAME = hashMapOf( - "kotlin.MutableIterator" to "asMutableIterator", - "kotlin.MutableIterable" to "asMutableIterable", - "kotlin.MutableCollection" to "asMutableCollection", - "kotlin.MutableList" to "asMutableList", - "kotlin.MutableListIterator" to "asMutableListIterator", - "kotlin.MutableSet" to "asMutableSet", - "kotlin.MutableMap" to "asMutableMap", - "kotlin.MutableMap.MutableEntry" to "asMutableMapEntry" - ) - - public @JvmStatic fun checkcast(v: InstructionAdapter, jetType: JetType, boxedAsmType: Type, safe: Boolean) { - val intrinsicMethodName = getCheckcastIntrinsicMethodName(jetType, safe) - if (intrinsicMethodName == null) { - v.checkcast(boxedAsmType) - } - else { - val signature = getCheckcastIntrinsicMethodSignature(boxedAsmType) - v.invokestatic(INTRINSICS_CLASS, intrinsicMethodName, signature, false) - } - } - - public @JvmStatic fun checkcast(checkcastInsn: TypeInsnNode, instructions: InsnList, jetType: JetType, asmType: Type, safe: Boolean) { - val intrinsicMethodName = getCheckcastIntrinsicMethodName(jetType, safe) - if (intrinsicMethodName == null) { - checkcastInsn.desc = asmType.internalName - } - else { - val signature = getCheckcastIntrinsicMethodSignature(asmType) - val invokeNode = MethodInsnNode(Opcodes.INVOKESTATIC, INTRINSICS_CLASS, intrinsicMethodName, signature, false) - instructions.insertBefore(checkcastInsn, invokeNode) - instructions.remove(checkcastInsn) - } - } - - private fun getCheckcastIntrinsicMethodName(jetType: JetType, safe: Boolean): String? { - if (safe) return null - val classDescriptor = TypeUtils.getClassDescriptor(jetType) ?: return null - val classFqName = DescriptorUtils.getFqName(classDescriptor).asString() - return CHECKCAST_METHOD_NAME[classFqName] - } - - private fun getCheckcastIntrinsicMethodSignature(asmType: Type): String = - Type.getMethodDescriptor(asmType, Type.getObjectType("java/lang/Object")); - -} \ No newline at end of file diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/intrinsics/InstanceOf.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/intrinsics/InstanceOf.kt deleted file mode 100644 index 95368028a8a..00000000000 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/intrinsics/InstanceOf.kt +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright 2010-2015 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.jetbrains.kotlin.codegen.intrinsics - -import org.jetbrains.kotlin.resolve.DescriptorUtils -import org.jetbrains.kotlin.types.JetType -import org.jetbrains.kotlin.types.TypeUtils -import org.jetbrains.org.objectweb.asm.Opcodes -import org.jetbrains.org.objectweb.asm.Type -import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter -import org.jetbrains.org.objectweb.asm.tree.InsnList -import org.jetbrains.org.objectweb.asm.tree.MethodInsnNode -import org.jetbrains.org.objectweb.asm.tree.TypeInsnNode - -object InstanceOf { - private val INTRINSICS_CLASS = "kotlin/jvm/internal/TypeIntrinsics" - - private val INSTANCEOF_METHOD_SIGNATURE = - Type.getMethodDescriptor(Type.BOOLEAN_TYPE, Type.getObjectType("java/lang/Object")) - - private val INSTANCEOF_METHOD_NAME = hashMapOf( - "kotlin.MutableIterator" to "isMutableIterator", - "kotlin.MutableIterable" to "isMutableIterable", - "kotlin.MutableCollection" to "isMutableCollection", - "kotlin.MutableList" to "isMutableList", - "kotlin.MutableListIterator" to "isMutableListIterator", - "kotlin.MutableSet" to "isMutableSet", - "kotlin.MutableMap" to "isMutableMap", - "kotlin.MutableMap.MutableEntry" to "isMutableMapEntry" - ) - - public @JvmStatic fun instanceOf(v: InstructionAdapter, jetType: JetType, boxedAsmType: Type) { - val intrinsicMethodName = getInstanceOfIntrinsicMethodName(jetType) - if (intrinsicMethodName == null) { - v.instanceOf(boxedAsmType) - } - else { - v.invokestatic(INTRINSICS_CLASS, intrinsicMethodName, INSTANCEOF_METHOD_SIGNATURE, false) - } - } - - public @JvmStatic fun instanceOf(instanceofInsn: TypeInsnNode, instructions: InsnList, jetType: JetType, asmType: Type) { - val intrinsicMethodName = getInstanceOfIntrinsicMethodName(jetType) - if (intrinsicMethodName == null) { - instanceofInsn.desc = asmType.internalName - } - else { - val invokeNode = MethodInsnNode(Opcodes.INVOKESTATIC, INTRINSICS_CLASS, intrinsicMethodName, INSTANCEOF_METHOD_SIGNATURE, false) - instructions.insertBefore(instanceofInsn, invokeNode) - instructions.remove(instanceofInsn) - } - } - - private fun getInstanceOfIntrinsicMethodName(jetType: JetType): String? { - val classDescriptor = TypeUtils.getClassDescriptor(jetType) ?: return null - val classFqName = DescriptorUtils.getFqName(classDescriptor).asString() - return INSTANCEOF_METHOD_NAME[classFqName] - } -} \ No newline at end of file diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/intrinsics/TypeIntrinsics.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/intrinsics/TypeIntrinsics.kt new file mode 100644 index 00000000000..b70cadea1cb --- /dev/null +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/intrinsics/TypeIntrinsics.kt @@ -0,0 +1,219 @@ +/* + * Copyright 2010-2015 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.kotlin.codegen.intrinsics + +import org.jetbrains.kotlin.resolve.DescriptorUtils +import org.jetbrains.kotlin.types.JetType +import org.jetbrains.kotlin.types.TypeUtils +import org.jetbrains.org.objectweb.asm.Opcodes +import org.jetbrains.org.objectweb.asm.Type +import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter +import org.jetbrains.org.objectweb.asm.tree.* +import kotlin.text.Regex + +public object TypeIntrinsics { + public @JvmStatic fun instanceOf(v: InstructionAdapter, jetType: JetType, boxedAsmType: Type) { + val functionTypeArity = getFunctionTypeArity(jetType) + if (functionTypeArity >= 0) { + v.iconst(functionTypeArity) + v.typeIntrinsic(IS_FUNCTON_OF_ARITY_METHOD_NAME, IS_FUNCTON_OF_ARITY_DESCRIPTOR) + return + } + + val isMutableCollectionMethodName = getIsMutableCollectionMethodName(jetType) + if (isMutableCollectionMethodName != null) { + v.typeIntrinsic(isMutableCollectionMethodName, IS_MUTABLE_COLLECTION_METHOD_DESCRIPTOR) + return + } + + v.instanceOf(boxedAsmType) + } + + private fun iconstNode(value: Int): AbstractInsnNode = + if (value >= -1 && value <= 5) { + InsnNode(Opcodes.ICONST_0 + value) + } + else if (value >= java.lang.Byte.MIN_VALUE && value <= java.lang.Byte.MAX_VALUE) { + IntInsnNode(Opcodes.BIPUSH, value) + } + else if (value >= java.lang.Short.MIN_VALUE && value <= java.lang.Short.MAX_VALUE) { + IntInsnNode(Opcodes.SIPUSH, value) + } + else { + LdcInsnNode(Integer(value)) + } + + public @JvmStatic fun instanceOf(instanceofInsn: TypeInsnNode, instructions: InsnList, jetType: JetType, asmType: Type) { + val functionTypeArity = getFunctionTypeArity(jetType) + if (functionTypeArity >= 0) { + instructions.insertBefore(instanceofInsn, iconstNode(functionTypeArity)) + instructions.insertBefore(instanceofInsn, + typeIntrinsicNode(IS_FUNCTON_OF_ARITY_METHOD_NAME, IS_FUNCTON_OF_ARITY_DESCRIPTOR)) + instructions.remove(instanceofInsn) + return + } + + val isMutableCollectionMethodName = getIsMutableCollectionMethodName(jetType) + if (isMutableCollectionMethodName != null) { + instructions.insertBefore(instanceofInsn, + typeIntrinsicNode(isMutableCollectionMethodName, IS_MUTABLE_COLLECTION_METHOD_DESCRIPTOR)) + instructions.remove(instanceofInsn) + return + } + + instanceofInsn.desc = asmType.internalName + } + + public @JvmStatic fun checkcast(v: InstructionAdapter, jetType: JetType, asmType: Type, safe: Boolean) { + if (safe) { + v.checkcast(asmType) + return + } + + val functionTypeArity = getFunctionTypeArity(jetType) + if (functionTypeArity >= 0) { + v.iconst(functionTypeArity) + if (safe) { + v.typeIntrinsic(BEFORE_SAFE_CHECKCAST_TO_FUNCTION_OF_ARITY, BEFORE_SAFE_CHECKCAST_TO_FUNCTION_OF_ARITY_DESCRIPTOR) + } + else { + v.typeIntrinsic(BEFORE_CHECKCAST_TO_FUNCTION_OF_ARITY, BEFORE_CHECKCAST_TO_FUNCTION_OF_ARITY_DESCRIPTOR) + } + v.checkcast(asmType) + return + } + + val asMutableCollectionMethodName = getAsMutableCollectionMethodName(jetType) + if (asMutableCollectionMethodName != null) { + v.typeIntrinsic(asMutableCollectionMethodName, getAsMutableCollectionDescriptor(asmType)) + return + } + + v.checkcast(asmType) + } + + public @JvmStatic fun checkcast(checkcastInsn: TypeInsnNode, instructions: InsnList, jetType: JetType, asmType: Type, safe: Boolean) { + if (safe) { + checkcastInsn.desc = asmType.internalName + return + } + + val functionTypeArity = getFunctionTypeArity(jetType) + if (functionTypeArity >= 0) { + instructions.insertBefore(checkcastInsn, iconstNode(functionTypeArity)) + + val beforeCheckcast = if (safe) + typeIntrinsicNode(BEFORE_SAFE_CHECKCAST_TO_FUNCTION_OF_ARITY, BEFORE_SAFE_CHECKCAST_TO_FUNCTION_OF_ARITY_DESCRIPTOR) + else + typeIntrinsicNode(BEFORE_CHECKCAST_TO_FUNCTION_OF_ARITY, BEFORE_CHECKCAST_TO_FUNCTION_OF_ARITY_DESCRIPTOR) + instructions.insertBefore(checkcastInsn, beforeCheckcast) + + instructions.insertBefore(checkcastInsn, TypeInsnNode(Opcodes.CHECKCAST, asmType.internalName)) + instructions.remove(checkcastInsn) + return + } + + val asMutableCollectionMethodName = getAsMutableCollectionMethodName(jetType) + if (asMutableCollectionMethodName != null) { + instructions.insertBefore(checkcastInsn, + typeIntrinsicNode(asMutableCollectionMethodName, getAsMutableCollectionDescriptor(asmType))) + instructions.remove(checkcastInsn) + return + } + + checkcastInsn.desc = asmType.internalName + } + + private val INTRINSICS_CLASS = "kotlin/jvm/internal/TypeIntrinsics" + + private val IS_FUNCTON_OF_ARITY_METHOD_NAME = "isFunctionOfArity" + + private val IS_FUNCTON_OF_ARITY_DESCRIPTOR = + Type.getMethodDescriptor(Type.BOOLEAN_TYPE, Type.getObjectType("java/lang/Object"), Type.INT_TYPE) + + private val IS_MUTABLE_COLLECTION_METHOD_NAME = hashMapOf( + "kotlin.MutableIterator" to "isMutableIterator", + "kotlin.MutableIterable" to "isMutableIterable", + "kotlin.MutableCollection" to "isMutableCollection", + "kotlin.MutableList" to "isMutableList", + "kotlin.MutableListIterator" to "isMutableListIterator", + "kotlin.MutableSet" to "isMutableSet", + "kotlin.MutableMap" to "isMutableMap", + "kotlin.MutableMap.MutableEntry" to "isMutableMapEntry" + ) + + private val IS_MUTABLE_COLLECTION_METHOD_DESCRIPTOR = + Type.getMethodDescriptor(Type.BOOLEAN_TYPE, Type.getObjectType("java/lang/Object")) + + private fun getClassFqName(jetType: JetType): String? { + val classDescriptor = TypeUtils.getClassDescriptor(jetType) ?: return null + return DescriptorUtils.getFqName(classDescriptor).asString() + } + + private val KOTLIN_FUNCTION_INTERFACE_REGEX = Regex("^kotlin\\.Function([0-9]+)$") + + /** + * @return function type arity (non-negative), or -1 if the given type is not a function type + */ + private fun getFunctionTypeArity(jetType: JetType): Int { + val classFqName = getClassFqName(jetType) ?: return -1 + val match = KOTLIN_FUNCTION_INTERFACE_REGEX.match(classFqName) ?: return -1 + return Integer.valueOf(match.groups[1]!!.value) + } + + private fun typeIntrinsicNode(methodName: String, methodDescriptor: String): MethodInsnNode = + MethodInsnNode(Opcodes.INVOKESTATIC, INTRINSICS_CLASS, methodName, methodDescriptor, false) + + private fun InstructionAdapter.typeIntrinsic(methodName: String, methodDescriptor: String) { + invokestatic(INTRINSICS_CLASS, methodName, methodDescriptor, false) + } + + private fun getIsMutableCollectionMethodName(jetType: JetType): String? = + IS_MUTABLE_COLLECTION_METHOD_NAME[getClassFqName(jetType)] + + private val CHECKCAST_METHOD_NAME = hashMapOf( + "kotlin.MutableIterator" to "asMutableIterator", + "kotlin.MutableIterable" to "asMutableIterable", + "kotlin.MutableCollection" to "asMutableCollection", + "kotlin.MutableList" to "asMutableList", + "kotlin.MutableListIterator" to "asMutableListIterator", + "kotlin.MutableSet" to "asMutableSet", + "kotlin.MutableMap" to "asMutableMap", + "kotlin.MutableMap.MutableEntry" to "asMutableMapEntry" + ) + + private fun getAsMutableCollectionMethodName(jetType: JetType): String? { + val classDescriptor = TypeUtils.getClassDescriptor(jetType) ?: return null + val classFqName = DescriptorUtils.getFqName(classDescriptor).asString() + return CHECKCAST_METHOD_NAME[classFqName] + } + + private val OBJECT_TYPE = Type.getObjectType("java/lang/Object") + + private fun getAsMutableCollectionDescriptor(asmType: Type): String = + Type.getMethodDescriptor(asmType, OBJECT_TYPE); + + private val BEFORE_CHECKCAST_TO_FUNCTION_OF_ARITY = "beforeCheckcastToFunctionOfArity" + + private val BEFORE_CHECKCAST_TO_FUNCTION_OF_ARITY_DESCRIPTOR = + Type.getMethodDescriptor(OBJECT_TYPE, OBJECT_TYPE, Type.INT_TYPE) + + private val BEFORE_SAFE_CHECKCAST_TO_FUNCTION_OF_ARITY = "beforeSafeCheckcastToFunctionOfArity" + + private val BEFORE_SAFE_CHECKCAST_TO_FUNCTION_OF_ARITY_DESCRIPTOR = + Type.getMethodDescriptor(OBJECT_TYPE, OBJECT_TYPE, Type.INT_TYPE) +} \ No newline at end of file diff --git a/compiler/testData/codegen/boxWithJava/casts/javaTypeIsFunK/JFun.java b/compiler/testData/codegen/boxWithJava/casts/javaTypeIsFunK/JFun.java new file mode 100644 index 00000000000..5554bd18c15 --- /dev/null +++ b/compiler/testData/codegen/boxWithJava/casts/javaTypeIsFunK/JFun.java @@ -0,0 +1,5 @@ +class JFun implements kotlin.jvm.functions.Function0 { + public String invoke() { + return "OK"; + } +} \ No newline at end of file diff --git a/compiler/testData/codegen/boxWithJava/casts/javaTypeIsFunK/javaTypeIsFunK.kt b/compiler/testData/codegen/boxWithJava/casts/javaTypeIsFunK/javaTypeIsFunK.kt new file mode 100644 index 00000000000..f249b74f519 --- /dev/null +++ b/compiler/testData/codegen/boxWithJava/casts/javaTypeIsFunK/javaTypeIsFunK.kt @@ -0,0 +1,6 @@ +fun box(): String { + val jfun = JFun() + val jf = jfun as Any + if (jf is Function0<*>) return jfun() + else return "Failed: jf is Function0<*>" +} \ No newline at end of file diff --git a/compiler/testData/codegen/boxWithStdlib/casts/asFunKBig.kt b/compiler/testData/codegen/boxWithStdlib/casts/asFunKBig.kt new file mode 100644 index 00000000000..0821f40f7b6 --- /dev/null +++ b/compiler/testData/codegen/boxWithStdlib/casts/asFunKBig.kt @@ -0,0 +1,250 @@ +// This is a big, ugly, semi-auto generated test. +// Use corresponding 'Small' test for debug. + +import kotlin.test.* + +fun fn0() {} +fun fn1(x0: Any) {} +fun fn2(x0: Any, x1: Any) {} +fun fn3(x0: Any, x1: Any, x2: Any) {} +fun fn4(x0: Any, x1: Any, x2: Any, x3: Any) {} +fun fn5(x0: Any, x1: Any, x2: Any, x3: Any, x4: Any) {} +fun fn6(x0: Any, x1: Any, x2: Any, x3: Any, x4: Any, x5: Any) {} +fun fn7(x0: Any, x1: Any, x2: Any, x3: Any, x4: Any, x5: Any, x6: Any) {} +fun fn8(x0: Any, x1: Any, x2: Any, x3: Any, x4: Any, x5: Any, x6: Any, x7: Any) {} +fun fn9(x0: Any, x1: Any, x2: Any, x3: Any, x4: Any, x5: Any, x6: Any, x7: Any, x8: Any) {} +fun fn10(x0: Any, x1: Any, x2: Any, x3: Any, x4: Any, x5: Any, x6: Any, x7: Any, x8: Any, x9: Any) {} +fun fn11(x0: Any, x1: Any, x2: Any, x3: Any, x4: Any, x5: Any, x6: Any, x7: Any, x8: Any, x9: Any, x10: Any) {} +fun fn12(x0: Any, x1: Any, x2: Any, x3: Any, x4: Any, x5: Any, x6: Any, x7: Any, x8: Any, x9: Any, x10: Any, x11: Any) {} +fun fn13(x0: Any, x1: Any, x2: Any, x3: Any, x4: Any, x5: Any, x6: Any, x7: Any, x8: Any, x9: Any, x10: Any, x11: Any, x12: Any) {} +fun fn14(x0: Any, x1: Any, x2: Any, x3: Any, x4: Any, x5: Any, x6: Any, x7: Any, x8: Any, x9: Any, x10: Any, x11: Any, x12: Any, x13: Any) {} +fun fn15(x0: Any, x1: Any, x2: Any, x3: Any, x4: Any, x5: Any, x6: Any, x7: Any, x8: Any, x9: Any, x10: Any, x11: Any, x12: Any, x13: Any, x14: Any) {} +fun fn16(x0: Any, x1: Any, x2: Any, x3: Any, x4: Any, x5: Any, x6: Any, x7: Any, x8: Any, x9: Any, x10: Any, x11: Any, x12: Any, x13: Any, x14: Any, x15: Any) {} +fun fn17(x0: Any, x1: Any, x2: Any, x3: Any, x4: Any, x5: Any, x6: Any, x7: Any, x8: Any, x9: Any, x10: Any, x11: Any, x12: Any, x13: Any, x14: Any, x15: Any, x16: Any) {} +fun fn18(x0: Any, x1: Any, x2: Any, x3: Any, x4: Any, x5: Any, x6: Any, x7: Any, x8: Any, x9: Any, x10: Any, x11: Any, x12: Any, x13: Any, x14: Any, x15: Any, x16: Any, x17: Any) {} +fun fn19(x0: Any, x1: Any, x2: Any, x3: Any, x4: Any, x5: Any, x6: Any, x7: Any, x8: Any, x9: Any, x10: Any, x11: Any, x12: Any, x13: Any, x14: Any, x15: Any, x16: Any, x17: Any, x18: Any) {} +fun fn20(x0: Any, x1: Any, x2: Any, x3: Any, x4: Any, x5: Any, x6: Any, x7: Any, x8: Any, x9: Any, x10: Any, x11: Any, x12: Any, x13: Any, x14: Any, x15: Any, x16: Any, x17: Any, x18: Any, x19: Any) {} +fun fn21(x0: Any, x1: Any, x2: Any, x3: Any, x4: Any, x5: Any, x6: Any, x7: Any, x8: Any, x9: Any, x10: Any, x11: Any, x12: Any, x13: Any, x14: Any, x15: Any, x16: Any, x17: Any, x18: Any, x19: Any, x20: Any) {} +fun fn22(x0: Any, x1: Any, x2: Any, x3: Any, x4: Any, x5: Any, x6: Any, x7: Any, x8: Any, x9: Any, x10: Any, x11: Any, x12: Any, x13: Any, x14: Any, x15: Any, x16: Any, x17: Any, x18: Any, x19: Any, x20: Any, x21: Any) {} + +val fns = arrayOf(::fn0, ::fn1, ::fn2, ::fn3, ::fn4, ::fn5, ::fn6, ::fn7, ::fn8, ::fn9, + ::fn10, ::fn11, ::fn12, ::fn13, ::fn14, ::fn15, ::fn16, ::fn17, ::fn18, ::fn19, + ::fn20, ::fn21, ::fn22) + +inline fun asFailsWithCCE(operation: String, crossinline block: () -> Unit) { + assertFailsWith(ClassCastException::class.java, "$operation should throw an exception") { + block() + } +} + +inline fun asSucceeds(operation: String, block: () -> Unit) { + block() +} + +interface TestFnBase { + fun testGood(x: Any) + fun testBad(x: Any) +} + +object TestFn0 : TestFnBase { + override fun testGood(x: Any) { x as Function0<*> } + override fun testBad(x: Any) = + asFailsWithCCE("x as Function0<*>") { + x as Function0<*> + } +} + +object TestFn1 : TestFnBase { + override fun testGood(x: Any) { x as Function1<*, *> } + override fun testBad(x: Any) = + asFailsWithCCE("x as Function1<*, *>") { + x as Function1<*, *> + } +} + +object TestFn2 : TestFnBase { + override fun testGood(x: Any) { x as Function2<*, *, *> } + override fun testBad(x: Any) = + asFailsWithCCE("x as Function2<*, *, *>") { + x as Function2<*, *, *> + } +} + +object TestFn3 : TestFnBase { + override fun testGood(x: Any) { x as Function3<*, *, *, *> } + override fun testBad(x: Any) = + asFailsWithCCE("x as Function3<*, *, *, *>") { + x as Function3<*, *, *, *> + } +} + +object TestFn4 : TestFnBase { + override fun testGood(x: Any) { x as Function4<*, *, *, *, *> } + override fun testBad(x: Any) = + asFailsWithCCE("x as Function4<*, *, *, *, *>") { + x as Function4<*, *, *, *, *> + } +} + +object TestFn5 : TestFnBase { + override fun testGood(x: Any) { x as Function5<*, *, *, *, *, *> } + override fun testBad(x: Any) = + asFailsWithCCE("x as Function5<*, *, *, *, *, *>") { + x as Function5<*, *, *, *, *, *> + } +} + +object TestFn6 : TestFnBase { + override fun testGood(x: Any) { x as Function6<*, *, *, *, *, *, *> } + override fun testBad(x: Any) = + asFailsWithCCE("x as Function6<*, *, *, *, *, *, *>") { + x as Function6<*, *, *, *, *, *, *> + } +} + +object TestFn7 : TestFnBase { + override fun testGood(x: Any) { x as Function7<*, *, *, *, *, *, *, *> } + override fun testBad(x: Any) = + asFailsWithCCE("x as Function7<*, *, *, *, *, *, *, *>") { + x as Function7<*, *, *, *, *, *, *, *> + } +} + +object TestFn8 : TestFnBase { + override fun testGood(x: Any) { x as Function8<*, *, *, *, *, *, *, *, *> } + override fun testBad(x: Any) = + asFailsWithCCE("x as Function8<*, *, *, *, *, *, *, *, *>") { + x as Function8<*, *, *, *, *, *, *, *, *> + } +} + +object TestFn9 : TestFnBase { + override fun testGood(x: Any) { x as Function9<*, *, *, *, *, *, *, *, *, *> } + override fun testBad(x: Any) = + asFailsWithCCE("x as Function9<*, *, *, *, *, *, *, *, *, *>") { + x as Function9<*, *, *, *, *, *, *, *, *, *> + } +} + +object TestFn10 : TestFnBase { + override fun testGood(x: Any) { x as Function10<*, *, *, *, *, *, *, *, *, *, *> } + override fun testBad(x: Any) = + asFailsWithCCE("x as Function10<*, *, *, *, *, *, *, *, *, *, *>") { + x as Function10<*, *, *, *, *, *, *, *, *, *, *> + } +} + +object TestFn11 : TestFnBase { + override fun testGood(x: Any) { x as Function11<*, *, *, *, *, *, *, *, *, *, *, *> } + override fun testBad(x: Any) = + asFailsWithCCE("x as Function11<*, *, *, *, *, *, *, *, *, *, *, *>") { + x as Function11<*, *, *, *, *, *, *, *, *, *, *, *> + } +} + +object TestFn12 : TestFnBase { + override fun testGood(x: Any) { x as Function12<*, *, *, *, *, *, *, *, *, *, *, *, *> } + override fun testBad(x: Any) = + asFailsWithCCE("x as Function12<*, *, *, *, *, *, *, *, *, *, *, *, *>") { + x as Function12<*, *, *, *, *, *, *, *, *, *, *, *, *> + } +} + +object TestFn13 : TestFnBase { + override fun testGood(x: Any) { x as Function13<*, *, *, *, *, *, *, *, *, *, *, *, *, *> } + override fun testBad(x: Any) = + asFailsWithCCE("x as Function13<*, *, *, *, *, *, *, *, *, *, *, *, *, *>") { + x as Function13<*, *, *, *, *, *, *, *, *, *, *, *, *, *> + } +} + +object TestFn14 : TestFnBase { + override fun testGood(x: Any) { x as Function14<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *> } + override fun testBad(x: Any) = + asFailsWithCCE("x as Function14<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *>") { + x as Function14<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *> + } +} + +object TestFn15 : TestFnBase { + override fun testGood(x: Any) { x as Function15<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *> } + override fun testBad(x: Any) = + asFailsWithCCE("x as Function15<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *>") { + x as Function15<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *> + } +} + +object TestFn16 : TestFnBase { + override fun testGood(x: Any) { x as Function16<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *> } + override fun testBad(x: Any) = + asFailsWithCCE("x as Function16<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *>") { + x as Function16<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *> + } +} + +object TestFn17 : TestFnBase { + override fun testGood(x: Any) { x as Function17<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *> } + override fun testBad(x: Any) = + asFailsWithCCE("x as Function17<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *>") { + x as Function17<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *> + } +} + +object TestFn18 : TestFnBase { + override fun testGood(x: Any) { x as Function18<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *> } + override fun testBad(x: Any) = + asFailsWithCCE("x as Function18<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *>") { + x as Function18<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *> + } +} + +object TestFn19 : TestFnBase { + override fun testGood(x: Any) { x as Function19<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *> } + override fun testBad(x: Any) = + asFailsWithCCE("x as Function19<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *>") { + x as Function19<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *> + } +} + +object TestFn20 : TestFnBase { + override fun testGood(x: Any) { x as Function20<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *> } + override fun testBad(x: Any) = + asFailsWithCCE("x as Function20<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *>") { + x as Function20<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *> + } +} + +object TestFn21 : TestFnBase { + override fun testGood(x: Any) { x as Function21<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *> } + override fun testBad(x: Any) = + asFailsWithCCE("x as Function21<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *>") { + x as Function21<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *> + } +} + +object TestFn22 : TestFnBase { + override fun testGood(x: Any) { x as Function22<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *> } + override fun testBad(x: Any) = + asFailsWithCCE("x as Function22<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *>") { + x as Function22<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *> + } +} + +val tests = arrayOf(TestFn0, TestFn1, TestFn2, TestFn3, TestFn4, TestFn5, TestFn6, TestFn7, TestFn8, TestFn9, + TestFn10, TestFn11, TestFn12, TestFn13, TestFn14, TestFn15, TestFn16, TestFn17, TestFn18, TestFn19, + TestFn20, TestFn21, TestFn22) + +fun box(): String { + for (fnI in 0 .. 22) { + for (testI in 0 .. 22) { + if (fnI == testI) { + tests[testI].testGood(fns[fnI]) + } + else { + tests[testI].testBad(fns[fnI]) + } + } + } + + return "OK" +} \ No newline at end of file diff --git a/compiler/testData/codegen/boxWithStdlib/casts/asFunKSmall.kt b/compiler/testData/codegen/boxWithStdlib/casts/asFunKSmall.kt new file mode 100644 index 00000000000..142496c9f9b --- /dev/null +++ b/compiler/testData/codegen/boxWithStdlib/casts/asFunKSmall.kt @@ -0,0 +1,44 @@ +fun fn0() {} +fun fn1(x: Any) {} + +inline fun asFailsWithCCE(operation: String, block: () -> Unit) { + try { + block() + } + catch (e: java.lang.ClassCastException) { + return + } + catch (e: Throwable) { + throw AssertionError("$operation: should throw ClassCastException, got $e") + } + throw AssertionError("$operation: should throw ClassCastException, no exception thrown") +} + +inline fun asSucceeds(operation: String, block: () -> Unit) { + try { + block() + } + catch (e: Throwable) { + throw AssertionError("$operation: should not throw exceptions, got $e") + } +} + +class MyFun: Function + +fun box(): String { + val f0 = ::fn0 as Any + val f1 = ::fn1 as Any + + val myFun = MyFun() as Any + + asSucceeds("f0 as Function0<*>") { f0 as Function0<*> } + asFailsWithCCE("f0 as Function1<*, *>") { f0 as Function1<*, *> } + asFailsWithCCE("f1 as Function0<*>") { f1 as Function0<*> } + asSucceeds("f1 as Function1<*, *>") { f1 as Function1<*, *> } + + asFailsWithCCE("myFun as Function0<*>") { myFun as Function0<*> } + asFailsWithCCE("myFun as Function1<*, *>") { myFun as Function1<*, *> } + + + return "OK" +} \ No newline at end of file diff --git a/compiler/testData/codegen/boxWithStdlib/casts/isFunKBig.kt b/compiler/testData/codegen/boxWithStdlib/casts/isFunKBig.kt new file mode 100644 index 00000000000..939ac15626a --- /dev/null +++ b/compiler/testData/codegen/boxWithStdlib/casts/isFunKBig.kt @@ -0,0 +1,177 @@ +// This is a big, ugly, semi-auto generated test. +// Use corresponding 'Small' test for debug. + +fun fn0() {} +fun fn1(x0: Any) {} +fun fn2(x0: Any, x1: Any) {} +fun fn3(x0: Any, x1: Any, x2: Any) {} +fun fn4(x0: Any, x1: Any, x2: Any, x3: Any) {} +fun fn5(x0: Any, x1: Any, x2: Any, x3: Any, x4: Any) {} +fun fn6(x0: Any, x1: Any, x2: Any, x3: Any, x4: Any, x5: Any) {} +fun fn7(x0: Any, x1: Any, x2: Any, x3: Any, x4: Any, x5: Any, x6: Any) {} +fun fn8(x0: Any, x1: Any, x2: Any, x3: Any, x4: Any, x5: Any, x6: Any, x7: Any) {} +fun fn9(x0: Any, x1: Any, x2: Any, x3: Any, x4: Any, x5: Any, x6: Any, x7: Any, x8: Any) {} +fun fn10(x0: Any, x1: Any, x2: Any, x3: Any, x4: Any, x5: Any, x6: Any, x7: Any, x8: Any, x9: Any) {} +fun fn11(x0: Any, x1: Any, x2: Any, x3: Any, x4: Any, x5: Any, x6: Any, x7: Any, x8: Any, x9: Any, x10: Any) {} +fun fn12(x0: Any, x1: Any, x2: Any, x3: Any, x4: Any, x5: Any, x6: Any, x7: Any, x8: Any, x9: Any, x10: Any, x11: Any) {} +fun fn13(x0: Any, x1: Any, x2: Any, x3: Any, x4: Any, x5: Any, x6: Any, x7: Any, x8: Any, x9: Any, x10: Any, x11: Any, x12: Any) {} +fun fn14(x0: Any, x1: Any, x2: Any, x3: Any, x4: Any, x5: Any, x6: Any, x7: Any, x8: Any, x9: Any, x10: Any, x11: Any, x12: Any, x13: Any) {} +fun fn15(x0: Any, x1: Any, x2: Any, x3: Any, x4: Any, x5: Any, x6: Any, x7: Any, x8: Any, x9: Any, x10: Any, x11: Any, x12: Any, x13: Any, x14: Any) {} +fun fn16(x0: Any, x1: Any, x2: Any, x3: Any, x4: Any, x5: Any, x6: Any, x7: Any, x8: Any, x9: Any, x10: Any, x11: Any, x12: Any, x13: Any, x14: Any, x15: Any) {} +fun fn17(x0: Any, x1: Any, x2: Any, x3: Any, x4: Any, x5: Any, x6: Any, x7: Any, x8: Any, x9: Any, x10: Any, x11: Any, x12: Any, x13: Any, x14: Any, x15: Any, x16: Any) {} +fun fn18(x0: Any, x1: Any, x2: Any, x3: Any, x4: Any, x5: Any, x6: Any, x7: Any, x8: Any, x9: Any, x10: Any, x11: Any, x12: Any, x13: Any, x14: Any, x15: Any, x16: Any, x17: Any) {} +fun fn19(x0: Any, x1: Any, x2: Any, x3: Any, x4: Any, x5: Any, x6: Any, x7: Any, x8: Any, x9: Any, x10: Any, x11: Any, x12: Any, x13: Any, x14: Any, x15: Any, x16: Any, x17: Any, x18: Any) {} +fun fn20(x0: Any, x1: Any, x2: Any, x3: Any, x4: Any, x5: Any, x6: Any, x7: Any, x8: Any, x9: Any, x10: Any, x11: Any, x12: Any, x13: Any, x14: Any, x15: Any, x16: Any, x17: Any, x18: Any, x19: Any) {} +fun fn21(x0: Any, x1: Any, x2: Any, x3: Any, x4: Any, x5: Any, x6: Any, x7: Any, x8: Any, x9: Any, x10: Any, x11: Any, x12: Any, x13: Any, x14: Any, x15: Any, x16: Any, x17: Any, x18: Any, x19: Any, x20: Any) {} +fun fn22(x0: Any, x1: Any, x2: Any, x3: Any, x4: Any, x5: Any, x6: Any, x7: Any, x8: Any, x9: Any, x10: Any, x11: Any, x12: Any, x13: Any, x14: Any, x15: Any, x16: Any, x17: Any, x18: Any, x19: Any, x20: Any, x21: Any) {} + +val fns = arrayOf(::fn0, ::fn1, ::fn2, ::fn3, ::fn4, ::fn5, ::fn6, ::fn7, ::fn8, ::fn9, + ::fn10, ::fn11, ::fn12, ::fn13, ::fn14, ::fn15, ::fn16, ::fn17, ::fn18, ::fn19, + ::fn20, ::fn21, ::fn22) + +abstract class TestFnBase(val type: String) { + abstract fun testGood(x: Any) + abstract fun testBad(x: Any) + + protected fun assertIs(x: Any, condition: Boolean) { + assert(condition) { "x is $type: failed for $x" } + } + + protected fun assertIsNot(x: Any, condition: Boolean) { + assert(condition) { "x !is $type: failed for $x" } + } +} + +object TestFn0 : TestFnBase("Function0<*>") { + override fun testGood(x: Any) { assertIs(x, x is Function0<*>) } + override fun testBad(x: Any) { assertIsNot(x, x !is Function0<*>) } +} + +object TestFn1 : TestFnBase("Function1<*, *>") { + override fun testGood(x: Any) { assertIs(x, x is Function1<*, *>) } + override fun testBad(x: Any) { assertIsNot(x, x !is Function1<*, *>) } +} + +object TestFn2 : TestFnBase("Function2<*, *, *>") { + override fun testGood(x: Any) { assertIs(x, x is Function2<*, *, *>) } + override fun testBad(x: Any) { assertIsNot(x, x !is Function2<*, *, *>) } +} + +object TestFn3 : TestFnBase("Function3<*, *, *, *>") { + override fun testGood(x: Any) { assertIs(x, x is Function3<*, *, *, *>) } + override fun testBad(x: Any) { assertIsNot(x, x !is Function3<*, *, *, *>) } +} + +object TestFn4 : TestFnBase("Function4<*, *, *, *, *>") { + override fun testGood(x: Any) { assertIs(x, x is Function4<*, *, *, *, *>) } + override fun testBad(x: Any) { assertIsNot(x, x !is Function4<*, *, *, *, *>) } +} + +object TestFn5 : TestFnBase("Function5<*, *, *, *, *, *>") { + override fun testGood(x: Any) { assertIs(x, x is Function5<*, *, *, *, *, *>) } + override fun testBad(x: Any) { assertIsNot(x, x !is Function5<*, *, *, *, *, *>) } +} + +object TestFn6 : TestFnBase("Function6<*, *, *, *, *, *, *>") { + override fun testGood(x: Any) { assertIs(x, x is Function6<*, *, *, *, *, *, *>) } + override fun testBad(x: Any) { assertIsNot(x, x !is Function6<*, *, *, *, *, *, *>) } +} + +object TestFn7 : TestFnBase("Function7<*, *, *, *, *, *, *, *>") { + override fun testGood(x: Any) { assertIs(x, x is Function7<*, *, *, *, *, *, *, *>) } + override fun testBad(x: Any) { assertIsNot(x, x !is Function7<*, *, *, *, *, *, *, *>) } +} + +object TestFn8 : TestFnBase("Function8<*, *, *, *, *, *, *, *, *>") { + override fun testGood(x: Any) { assertIs(x, x is Function8<*, *, *, *, *, *, *, *, *>) } + override fun testBad(x: Any) { assertIsNot(x, x !is Function8<*, *, *, *, *, *, *, *, *>) } +} + +object TestFn9 : TestFnBase("Function9<*, *, *, *, *, *, *, *, *, *>") { + override fun testGood(x: Any) { assertIs(x, x is Function9<*, *, *, *, *, *, *, *, *, *>) } + override fun testBad(x: Any) { assertIsNot(x, x !is Function9<*, *, *, *, *, *, *, *, *, *>) } +} + +object TestFn10 : TestFnBase("Function10<*, *, *, *, *, *, *, *, *, *, *>") { + override fun testGood(x: Any) { assertIs(x, x is Function10<*, *, *, *, *, *, *, *, *, *, *>) } + override fun testBad(x: Any) { assertIsNot(x, x !is Function10<*, *, *, *, *, *, *, *, *, *, *>) } +} + +object TestFn11 : TestFnBase("Function11<*, *, *, *, *, *, *, *, *, *, *, *>") { + override fun testGood(x: Any) { assertIs(x, x is Function11<*, *, *, *, *, *, *, *, *, *, *, *>) } + override fun testBad(x: Any) { assertIsNot(x, x !is Function11<*, *, *, *, *, *, *, *, *, *, *, *>) } +} + +object TestFn12 : TestFnBase("Function12<*, *, *, *, *, *, *, *, *, *, *, *, *>") { + override fun testGood(x: Any) { assertIs(x, x is Function12<*, *, *, *, *, *, *, *, *, *, *, *, *>) } + override fun testBad(x: Any) { assertIsNot(x, x !is Function12<*, *, *, *, *, *, *, *, *, *, *, *, *>) } +} + +object TestFn13 : TestFnBase("Function13<*, *, *, *, *, *, *, *, *, *, *, *, *, *>") { + override fun testGood(x: Any) { assertIs(x, x is Function13<*, *, *, *, *, *, *, *, *, *, *, *, *, *>) } + override fun testBad(x: Any) { assertIsNot(x, x !is Function13<*, *, *, *, *, *, *, *, *, *, *, *, *, *>) } +} + +object TestFn14 : TestFnBase("Function14<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *>") { + override fun testGood(x: Any) { assertIs(x, x is Function14<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *>) } + override fun testBad(x: Any) { assertIsNot(x, x !is Function14<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *>) } +} + +object TestFn15 : TestFnBase("Function15<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *>") { + override fun testGood(x: Any) { assertIs(x, x is Function15<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *>) } + override fun testBad(x: Any) { assertIsNot(x, x !is Function15<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *>) } +} + +object TestFn16 : TestFnBase("Function16<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *>") { + override fun testGood(x: Any) { assertIs(x, x is Function16<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *>) } + override fun testBad(x: Any) { assertIsNot(x, x !is Function16<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *>) } +} + +object TestFn17 : TestFnBase("Function17<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *>") { + override fun testGood(x: Any) { assertIs(x, x is Function17<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *>) } + override fun testBad(x: Any) { assertIsNot(x, x !is Function17<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *>) } +} + +object TestFn18 : TestFnBase("Function18<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *>") { + override fun testGood(x: Any) { assertIs(x, x is Function18<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *>) } + override fun testBad(x: Any) { assertIsNot(x, x !is Function18<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *>) } +} + +object TestFn19 : TestFnBase("Function19<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *>") { + override fun testGood(x: Any) { assertIs(x, x is Function19<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *>) } + override fun testBad(x: Any) { assertIsNot(x, x !is Function19<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *>) } +} + +object TestFn20 : TestFnBase("Function20<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *>") { + override fun testGood(x: Any) { assertIs(x, x is Function20<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *>) } + override fun testBad(x: Any) { assertIsNot(x, x !is Function20<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *>) } +} + +object TestFn21 : TestFnBase("Function21<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *>") { + override fun testGood(x: Any) { assertIs(x, x is Function21<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *>) } + override fun testBad(x: Any) { assertIsNot(x, x !is Function21<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *>) } +} + +object TestFn22 : TestFnBase("Function22<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *>") { + override fun testGood(x: Any) { assertIs(x, x is Function22<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *>) } + override fun testBad(x: Any) { assertIsNot(x, x !is Function22<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *>) } +} + +val tests = arrayOf(TestFn0, TestFn1, TestFn2, TestFn3, TestFn4, TestFn5, TestFn6, TestFn7, TestFn8, TestFn9, + TestFn10, TestFn11, TestFn12, TestFn13, TestFn14, TestFn15, TestFn16, TestFn17, TestFn18, TestFn19, + TestFn20, TestFn21, TestFn22) + +fun box(): String { + for (fnI in 0 .. 22) { + for (testI in 0 .. 22) { + if (fnI == testI) { + tests[testI].testGood(fns[fnI]) + } + else { + tests[testI].testBad(fns[fnI]) + } + } + } + + return "OK" +} \ No newline at end of file diff --git a/compiler/testData/codegen/boxWithStdlib/casts/isFunKSmall.kt b/compiler/testData/codegen/boxWithStdlib/casts/isFunKSmall.kt new file mode 100644 index 00000000000..b6545373f4b --- /dev/null +++ b/compiler/testData/codegen/boxWithStdlib/casts/isFunKSmall.kt @@ -0,0 +1,55 @@ +fun fn0() {} +fun fn1(x: Any) {} + +val lambda0 = {} as () -> Unit +val lambda1 = { x: Any -> } as (Any) -> Unit + +fun Any.extFun() {} + +var Any.extProp: String + get() = "extProp" + set(x: String) {} + +class A { + fun foo() {} +} + +fun box(): String { + val f0 = ::fn0 as Any + val f1 = ::fn1 as Any + + val ef = Any::extFun as Any + val epg = Any::extProp.getter + val eps = Any::extProp.setter + + val afoo = A::foo + + fun local0() {} + fun local1(x: Any) {} + + val localFun0 = ::local0 as Any + val localFun1 = ::local1 as Any + + assert(f0 is Function0<*>) { "Failed: f0 is Function0<*>" } + assert(f1 is Function1<*, *>) { "Failed: f1 is Function1<*, *>" } + assert(f0 !is Function1<*, *>) { "Failed: f0 !is Function1<*, *>" } + assert(f1 !is Function0<*>) { "Failed: f1 !is Function0<*>" } + + assert(lambda0 is Function0<*>) { "Failed: lambda0 is Function0<*>" } + assert(lambda1 is Function1<*, *>) { "Failed: lambda1 is Function1<*, *>" } + assert(lambda0 !is Function1<*, *>) { "Failed: lambda0 !is Function1<*, *>" } + assert(lambda1 !is Function0<*>) { "Failed: lambda1 !is Function0<*>" } + + assert(localFun0 is Function0<*>) { "Failed: localFun0 is Function0<*>" } + assert(localFun1 is Function1<*, *>) { "Failed: localFun1 is Function1<*, *>" } + assert(localFun0 !is Function1<*, *>) { "Failed: localFun0 !is Function1<*, *>" } + assert(localFun1 !is Function0<*>) { "Failed: localFun1 !is Function0<*>" } + + assert(ef is Function1<*, *>) { "Failed: ef is Function1<*, *>" } + assert(epg is Function1<*, *>) { "Failed: epg is Function1<*, *>"} + assert(eps is Function2<*, *, *>) { "Failed: eps is Function2<*, *, *>"} + + assert(afoo is Function1<*, *>) { "afoo is Function1<*, *>" } + + return "OK" +} \ No newline at end of file diff --git a/compiler/testData/codegen/boxWithStdlib/casts/reifiedAsFunKBig.kt b/compiler/testData/codegen/boxWithStdlib/casts/reifiedAsFunKBig.kt new file mode 100644 index 00000000000..ca137b1ed67 --- /dev/null +++ b/compiler/testData/codegen/boxWithStdlib/casts/reifiedAsFunKBig.kt @@ -0,0 +1,273 @@ +// This is a big, ugly, semi-auto generated test. +// Use corresponding 'Small' test for debug. + +import kotlin.test.* + +fun fn0() {} +fun fn1(x0: Any) {} +fun fn2(x0: Any, x1: Any) {} +fun fn3(x0: Any, x1: Any, x2: Any) {} +fun fn4(x0: Any, x1: Any, x2: Any, x3: Any) {} +fun fn5(x0: Any, x1: Any, x2: Any, x3: Any, x4: Any) {} +fun fn6(x0: Any, x1: Any, x2: Any, x3: Any, x4: Any, x5: Any) {} +fun fn7(x0: Any, x1: Any, x2: Any, x3: Any, x4: Any, x5: Any, x6: Any) {} +fun fn8(x0: Any, x1: Any, x2: Any, x3: Any, x4: Any, x5: Any, x6: Any, x7: Any) {} +fun fn9(x0: Any, x1: Any, x2: Any, x3: Any, x4: Any, x5: Any, x6: Any, x7: Any, x8: Any) {} +fun fn10(x0: Any, x1: Any, x2: Any, x3: Any, x4: Any, x5: Any, x6: Any, x7: Any, x8: Any, x9: Any) {} +fun fn11(x0: Any, x1: Any, x2: Any, x3: Any, x4: Any, x5: Any, x6: Any, x7: Any, x8: Any, x9: Any, x10: Any) {} +fun fn12(x0: Any, x1: Any, x2: Any, x3: Any, x4: Any, x5: Any, x6: Any, x7: Any, x8: Any, x9: Any, x10: Any, x11: Any) {} +fun fn13(x0: Any, x1: Any, x2: Any, x3: Any, x4: Any, x5: Any, x6: Any, x7: Any, x8: Any, x9: Any, x10: Any, x11: Any, x12: Any) {} +fun fn14(x0: Any, x1: Any, x2: Any, x3: Any, x4: Any, x5: Any, x6: Any, x7: Any, x8: Any, x9: Any, x10: Any, x11: Any, x12: Any, x13: Any) {} +fun fn15(x0: Any, x1: Any, x2: Any, x3: Any, x4: Any, x5: Any, x6: Any, x7: Any, x8: Any, x9: Any, x10: Any, x11: Any, x12: Any, x13: Any, x14: Any) {} +fun fn16(x0: Any, x1: Any, x2: Any, x3: Any, x4: Any, x5: Any, x6: Any, x7: Any, x8: Any, x9: Any, x10: Any, x11: Any, x12: Any, x13: Any, x14: Any, x15: Any) {} +fun fn17(x0: Any, x1: Any, x2: Any, x3: Any, x4: Any, x5: Any, x6: Any, x7: Any, x8: Any, x9: Any, x10: Any, x11: Any, x12: Any, x13: Any, x14: Any, x15: Any, x16: Any) {} +fun fn18(x0: Any, x1: Any, x2: Any, x3: Any, x4: Any, x5: Any, x6: Any, x7: Any, x8: Any, x9: Any, x10: Any, x11: Any, x12: Any, x13: Any, x14: Any, x15: Any, x16: Any, x17: Any) {} +fun fn19(x0: Any, x1: Any, x2: Any, x3: Any, x4: Any, x5: Any, x6: Any, x7: Any, x8: Any, x9: Any, x10: Any, x11: Any, x12: Any, x13: Any, x14: Any, x15: Any, x16: Any, x17: Any, x18: Any) {} +fun fn20(x0: Any, x1: Any, x2: Any, x3: Any, x4: Any, x5: Any, x6: Any, x7: Any, x8: Any, x9: Any, x10: Any, x11: Any, x12: Any, x13: Any, x14: Any, x15: Any, x16: Any, x17: Any, x18: Any, x19: Any) {} +fun fn21(x0: Any, x1: Any, x2: Any, x3: Any, x4: Any, x5: Any, x6: Any, x7: Any, x8: Any, x9: Any, x10: Any, x11: Any, x12: Any, x13: Any, x14: Any, x15: Any, x16: Any, x17: Any, x18: Any, x19: Any, x20: Any) {} +fun fn22(x0: Any, x1: Any, x2: Any, x3: Any, x4: Any, x5: Any, x6: Any, x7: Any, x8: Any, x9: Any, x10: Any, x11: Any, x12: Any, x13: Any, x14: Any, x15: Any, x16: Any, x17: Any, x18: Any, x19: Any, x20: Any, x21: Any) {} + +val fns = arrayOf(::fn0, ::fn1, ::fn2, ::fn3, ::fn4, ::fn5, ::fn6, ::fn7, ::fn8, ::fn9, + ::fn10, ::fn11, ::fn12, ::fn13, ::fn14, ::fn15, ::fn16, ::fn17, ::fn18, ::fn19, + ::fn20, ::fn21, ::fn22) + +inline fun reifiedAsSucceeds(x: Any, operation: String) { + x as T +} + +inline fun reifiedAsFailsWithCCE(x: Any, operation: String) { + assertFailsWith(ClassCastException::class.java, "$operation should throw an exception") { + x as T + } +} + +interface TestFnBase { + fun testGood(x: Any) + fun testBad(x: Any) +} + +object TestFn0 : TestFnBase { + override fun testGood(x: Any) = + reifiedAsSucceeds>( + x, "x as Function0<*>") + override fun testBad(x: Any) = + reifiedAsFailsWithCCE>( + x, "x as Function0<*>") +} + +object TestFn1 : TestFnBase { + override fun testGood(x: Any) = + reifiedAsSucceeds>( + x, "x as Function1<*, *>") + override fun testBad(x: Any) = + reifiedAsFailsWithCCE>( + x, "x as Function1<*, *>") +} + +object TestFn2 : TestFnBase { + override fun testGood(x: Any) = + reifiedAsSucceeds>( + x, "x as Function2<*, *, *>") + override fun testBad(x: Any) = + reifiedAsFailsWithCCE>( + x, "x as Function2<*, *, *>") +} + +object TestFn3 : TestFnBase { + override fun testGood(x: Any) = + reifiedAsSucceeds>( + x, "x as Function3<*, *, *, *>") + override fun testBad(x: Any) = + reifiedAsFailsWithCCE>( + x, "x as Function3<*, *, *, *>") +} + +object TestFn4 : TestFnBase { + override fun testGood(x: Any) = + reifiedAsSucceeds>( + x, "x as Function4<*, *, *, *, *>") + override fun testBad(x: Any) = + reifiedAsFailsWithCCE>( + x, "x as Function4<*, *, *, *, *>") +} + +object TestFn5 : TestFnBase { + override fun testGood(x: Any) = + reifiedAsSucceeds>( + x, "x as Function5<*, *, *, *, *, *>") + override fun testBad(x: Any) = + reifiedAsFailsWithCCE>( + x, "x as Function5<*, *, *, *, *, *>") +} + +object TestFn6 : TestFnBase { + override fun testGood(x: Any) = + reifiedAsSucceeds>( + x, "x as Function6<*, *, *, *, *, *, *>") + override fun testBad(x: Any) = + reifiedAsFailsWithCCE>( + x, "x as Function6<*, *, *, *, *, *, *>") +} + +object TestFn7 : TestFnBase { + override fun testGood(x: Any) = + reifiedAsSucceeds>( + x, "x as Function7<*, *, *, *, *, *, *, *>") + override fun testBad(x: Any) = + reifiedAsFailsWithCCE>( + x, "x as Function7<*, *, *, *, *, *, *, *>") +} + +object TestFn8 : TestFnBase { + override fun testGood(x: Any) = + reifiedAsSucceeds>( + x, "x as Function8<*, *, *, *, *, *, *, *, *>") + override fun testBad(x: Any) = + reifiedAsFailsWithCCE>( + x, "x as Function8<*, *, *, *, *, *, *, *, *>") +} + +object TestFn9 : TestFnBase { + override fun testGood(x: Any) = + reifiedAsSucceeds>( + x, "x as Function9<*, *, *, *, *, *, *, *, *, *>") + override fun testBad(x: Any) = + reifiedAsFailsWithCCE>( + x, "x as Function9<*, *, *, *, *, *, *, *, *, *>") +} + +object TestFn10 : TestFnBase { + override fun testGood(x: Any) = + reifiedAsSucceeds>( + x, "x as Function10<*, *, *, *, *, *, *, *, *, *, *>") + override fun testBad(x: Any) = + reifiedAsFailsWithCCE>( + x, "x as Function10<*, *, *, *, *, *, *, *, *, *, *>") +} + +object TestFn11 : TestFnBase { + override fun testGood(x: Any) = + reifiedAsSucceeds>( + x, "x as Function11<*, *, *, *, *, *, *, *, *, *, *, *>") + override fun testBad(x: Any) = + reifiedAsFailsWithCCE>( + x, "x as Function11<*, *, *, *, *, *, *, *, *, *, *, *>") +} + +object TestFn12 : TestFnBase { + override fun testGood(x: Any) = + reifiedAsSucceeds>( + x, "x as Function12<*, *, *, *, *, *, *, *, *, *, *, *, *>") + override fun testBad(x: Any) = + reifiedAsFailsWithCCE>( + x, "x as Function12<*, *, *, *, *, *, *, *, *, *, *, *, *>") +} + +object TestFn13 : TestFnBase { + override fun testGood(x: Any) = + reifiedAsSucceeds>( + x, "x as Function13<*, *, *, *, *, *, *, *, *, *, *, *, *, *>") + override fun testBad(x: Any) = + reifiedAsFailsWithCCE>( + x, "x as Function13<*, *, *, *, *, *, *, *, *, *, *, *, *, *>") +} + +object TestFn14 : TestFnBase { + override fun testGood(x: Any) = + reifiedAsSucceeds>( + x, "x as Function14<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *>") + override fun testBad(x: Any) = + reifiedAsFailsWithCCE>( + x, "x as Function14<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *>") +} + +object TestFn15 : TestFnBase { + override fun testGood(x: Any) = + reifiedAsSucceeds>( + x, "x as Function15<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *>") + override fun testBad(x: Any) = + reifiedAsFailsWithCCE>( + x, "x as Function15<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *>") +} + +object TestFn16 : TestFnBase { + override fun testGood(x: Any) = + reifiedAsSucceeds>( + x, "x as Function16<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *>") + override fun testBad(x: Any) = + reifiedAsFailsWithCCE>( + x, "x as Function16<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *>") +} + +object TestFn17 : TestFnBase { + override fun testGood(x: Any) = + reifiedAsSucceeds>( + x, "x as Function17<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *>") + override fun testBad(x: Any) = + reifiedAsFailsWithCCE>( + x, "x as Function17<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *>") +} + +object TestFn18 : TestFnBase { + override fun testGood(x: Any) = + reifiedAsSucceeds>( + x, "x as Function18<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *>") + override fun testBad(x: Any) = + reifiedAsFailsWithCCE>( + x, "x as Function18<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *>") +} + +object TestFn19 : TestFnBase { + override fun testGood(x: Any) = + reifiedAsSucceeds>( + x, "x as Function19<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *>") + override fun testBad(x: Any) = + reifiedAsFailsWithCCE>( + x, "x as Function19<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *>") +} + +object TestFn20 : TestFnBase { + override fun testGood(x: Any) = + reifiedAsSucceeds>( + x, "x as Function20<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *>") + override fun testBad(x: Any) = + reifiedAsFailsWithCCE>( + x, "x as Function20<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *>") +} + +object TestFn21 : TestFnBase { + override fun testGood(x: Any) = + reifiedAsSucceeds>( + x, "x as Function21<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *>") + override fun testBad(x: Any) = + reifiedAsFailsWithCCE>( + x, "x as Function21<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *>") +} + +object TestFn22 : TestFnBase { + override fun testGood(x: Any) = + reifiedAsSucceeds>( + x, "x as Function22<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *>") + override fun testBad(x: Any) = + reifiedAsFailsWithCCE>( + x, "x as Function22<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *>") +} + +val tests = arrayOf(TestFn0, TestFn1, TestFn2, TestFn3, TestFn4, TestFn5, TestFn6, TestFn7, TestFn8, TestFn9, + TestFn10, TestFn11, TestFn12, TestFn13, TestFn14, TestFn15, TestFn16, TestFn17, TestFn18, TestFn19, + TestFn20, TestFn21, TestFn22) + +fun box(): String { + for (fnI in 0 .. 22) { + for (testI in 0 .. 22) { + if (fnI == testI) { + tests[testI].testGood(fns[fnI]) + } + else { + tests[testI].testBad(fns[fnI]) + } + } + } + + return "OK" +} \ No newline at end of file diff --git a/compiler/testData/codegen/boxWithStdlib/casts/reifiedAsFunKSmall.kt b/compiler/testData/codegen/boxWithStdlib/casts/reifiedAsFunKSmall.kt new file mode 100644 index 00000000000..aa5b8872a63 --- /dev/null +++ b/compiler/testData/codegen/boxWithStdlib/casts/reifiedAsFunKSmall.kt @@ -0,0 +1,36 @@ +fun fn0() {} +fun fn1(x: Any) {} + +inline fun reifiedAsSucceeds(x: Any, operation: String) { + try { + x as T + } + catch (e: Throwable) { + throw AssertionError("$operation: should not throw exceptions, got $e") + } +} + +inline fun reifiedAsFailsWithCCE(x: Any, operation: String) { + try { + x as T + } + catch (e: java.lang.ClassCastException) { + return + } + catch (e: Throwable) { + throw AssertionError("$operation: should throw ClassCastException, got $e") + } + throw AssertionError("$operation: should fail with CCE, no exception thrown") +} + +fun box(): String { + val f0 = ::fn0 as Any + val f1 = ::fn1 as Any + + reifiedAsSucceeds>(f0, "f0 as Function0<*>") + reifiedAsFailsWithCCE>(f0, "f0 as Function1<*, *>") + reifiedAsFailsWithCCE>(f1, "f1 as Function0<*>") + reifiedAsSucceeds>(f1, "f1 as Function1<*, *>") + + return "OK" +} \ No newline at end of file diff --git a/compiler/testData/codegen/boxWithStdlib/casts/reifiedIsFunKBig.kt b/compiler/testData/codegen/boxWithStdlib/casts/reifiedIsFunKBig.kt new file mode 100644 index 00000000000..ec9872c7620 --- /dev/null +++ b/compiler/testData/codegen/boxWithStdlib/casts/reifiedIsFunKBig.kt @@ -0,0 +1,191 @@ +// This is a big, ugly, semi-auto generated test. +// Use corresponding 'Small' test for debug. + +fun fn0() {} +fun fn1(x0: Any) {} +fun fn2(x0: Any, x1: Any) {} +fun fn3(x0: Any, x1: Any, x2: Any) {} +fun fn4(x0: Any, x1: Any, x2: Any, x3: Any) {} +fun fn5(x0: Any, x1: Any, x2: Any, x3: Any, x4: Any) {} +fun fn6(x0: Any, x1: Any, x2: Any, x3: Any, x4: Any, x5: Any) {} +fun fn7(x0: Any, x1: Any, x2: Any, x3: Any, x4: Any, x5: Any, x6: Any) {} +fun fn8(x0: Any, x1: Any, x2: Any, x3: Any, x4: Any, x5: Any, x6: Any, x7: Any) {} +fun fn9(x0: Any, x1: Any, x2: Any, x3: Any, x4: Any, x5: Any, x6: Any, x7: Any, x8: Any) {} +fun fn10(x0: Any, x1: Any, x2: Any, x3: Any, x4: Any, x5: Any, x6: Any, x7: Any, x8: Any, x9: Any) {} +fun fn11(x0: Any, x1: Any, x2: Any, x3: Any, x4: Any, x5: Any, x6: Any, x7: Any, x8: Any, x9: Any, x10: Any) {} +fun fn12(x0: Any, x1: Any, x2: Any, x3: Any, x4: Any, x5: Any, x6: Any, x7: Any, x8: Any, x9: Any, x10: Any, x11: Any) {} +fun fn13(x0: Any, x1: Any, x2: Any, x3: Any, x4: Any, x5: Any, x6: Any, x7: Any, x8: Any, x9: Any, x10: Any, x11: Any, x12: Any) {} +fun fn14(x0: Any, x1: Any, x2: Any, x3: Any, x4: Any, x5: Any, x6: Any, x7: Any, x8: Any, x9: Any, x10: Any, x11: Any, x12: Any, x13: Any) {} +fun fn15(x0: Any, x1: Any, x2: Any, x3: Any, x4: Any, x5: Any, x6: Any, x7: Any, x8: Any, x9: Any, x10: Any, x11: Any, x12: Any, x13: Any, x14: Any) {} +fun fn16(x0: Any, x1: Any, x2: Any, x3: Any, x4: Any, x5: Any, x6: Any, x7: Any, x8: Any, x9: Any, x10: Any, x11: Any, x12: Any, x13: Any, x14: Any, x15: Any) {} +fun fn17(x0: Any, x1: Any, x2: Any, x3: Any, x4: Any, x5: Any, x6: Any, x7: Any, x8: Any, x9: Any, x10: Any, x11: Any, x12: Any, x13: Any, x14: Any, x15: Any, x16: Any) {} +fun fn18(x0: Any, x1: Any, x2: Any, x3: Any, x4: Any, x5: Any, x6: Any, x7: Any, x8: Any, x9: Any, x10: Any, x11: Any, x12: Any, x13: Any, x14: Any, x15: Any, x16: Any, x17: Any) {} +fun fn19(x0: Any, x1: Any, x2: Any, x3: Any, x4: Any, x5: Any, x6: Any, x7: Any, x8: Any, x9: Any, x10: Any, x11: Any, x12: Any, x13: Any, x14: Any, x15: Any, x16: Any, x17: Any, x18: Any) {} +fun fn20(x0: Any, x1: Any, x2: Any, x3: Any, x4: Any, x5: Any, x6: Any, x7: Any, x8: Any, x9: Any, x10: Any, x11: Any, x12: Any, x13: Any, x14: Any, x15: Any, x16: Any, x17: Any, x18: Any, x19: Any) {} +fun fn21(x0: Any, x1: Any, x2: Any, x3: Any, x4: Any, x5: Any, x6: Any, x7: Any, x8: Any, x9: Any, x10: Any, x11: Any, x12: Any, x13: Any, x14: Any, x15: Any, x16: Any, x17: Any, x18: Any, x19: Any, x20: Any) {} +fun fn22(x0: Any, x1: Any, x2: Any, x3: Any, x4: Any, x5: Any, x6: Any, x7: Any, x8: Any, x9: Any, x10: Any, x11: Any, x12: Any, x13: Any, x14: Any, x15: Any, x16: Any, x17: Any, x18: Any, x19: Any, x20: Any, x21: Any) {} + +val fns = arrayOf(::fn0, ::fn1, ::fn2, ::fn3, ::fn4, ::fn5, ::fn6, ::fn7, ::fn8, ::fn9, + ::fn10, ::fn11, ::fn12, ::fn13, ::fn14, ::fn15, ::fn16, ::fn17, ::fn18, ::fn19, + ::fn20, ::fn21, ::fn22) + +inline fun assertReifiedIs(x: Any, type: String) { + val answer: Boolean + try { + answer = x is T + } + catch (e: Throwable) { + throw AssertionError("$x is $type: should not throw exceptions, got $e") + } + assert(answer) { "$x is $type: failed" } +} + +inline fun assertReifiedIsNot(x: Any, type: String) { + val answer: Boolean + try { + answer = x !is T + } + catch (e: Throwable) { + throw AssertionError("$x !is $type: should not throw exceptions, got $e") + } + assert(answer) { "$x !is $type: failed" } +} + +abstract class TestFnBase(val type: String) { + abstract fun testGood(x: Any) + abstract fun testBad(x: Any) +} + +object TestFn0 : TestFnBase("Function0<*>") { + override fun testGood(x: Any) { assertReifiedIs>(x, type) } + override fun testBad(x: Any) { assertReifiedIsNot>(x, type) } +} + +object TestFn1 : TestFnBase("Function1<*, *>") { + override fun testGood(x: Any) { assertReifiedIs>(x, type) } + override fun testBad(x: Any) { assertReifiedIsNot>(x, type) } +} + +object TestFn2 : TestFnBase("Function2<*, *, *>") { + override fun testGood(x: Any) { assertReifiedIs>(x, type) } + override fun testBad(x: Any) { assertReifiedIsNot>(x, type) } +} + +object TestFn3 : TestFnBase("Function3<*, *, *, *>") { + override fun testGood(x: Any) { assertReifiedIs>(x, type) } + override fun testBad(x: Any) { assertReifiedIsNot>(x, type) } +} + +object TestFn4 : TestFnBase("Function4<*, *, *, *, *>") { + override fun testGood(x: Any) { assertReifiedIs>(x, type) } + override fun testBad(x: Any) { assertReifiedIsNot>(x, type) } +} + +object TestFn5 : TestFnBase("Function5<*, *, *, *, *, *>") { + override fun testGood(x: Any) { assertReifiedIs>(x, type) } + override fun testBad(x: Any) { assertReifiedIsNot>(x, type) } +} + +object TestFn6 : TestFnBase("Function6<*, *, *, *, *, *, *>") { + override fun testGood(x: Any) { assertReifiedIs>(x, type) } + override fun testBad(x: Any) { assertReifiedIsNot>(x, type) } +} + +object TestFn7 : TestFnBase("Function7<*, *, *, *, *, *, *, *>") { + override fun testGood(x: Any) { assertReifiedIs>(x, type) } + override fun testBad(x: Any) { assertReifiedIsNot>(x, type) } +} + +object TestFn8 : TestFnBase("Function8<*, *, *, *, *, *, *, *, *>") { + override fun testGood(x: Any) { assertReifiedIs>(x, type) } + override fun testBad(x: Any) { assertReifiedIsNot>(x, type) } +} + +object TestFn9 : TestFnBase("Function9<*, *, *, *, *, *, *, *, *, *>") { + override fun testGood(x: Any) { assertReifiedIs>(x, type) } + override fun testBad(x: Any) { assertReifiedIsNot>(x, type) } +} + +object TestFn10 : TestFnBase("Function10<*, *, *, *, *, *, *, *, *, *, *>") { + override fun testGood(x: Any) { assertReifiedIs>(x, type) } + override fun testBad(x: Any) { assertReifiedIsNot>(x, type) } +} + +object TestFn11 : TestFnBase("Function11<*, *, *, *, *, *, *, *, *, *, *, *>") { + override fun testGood(x: Any) { assertReifiedIs>(x, type) } + override fun testBad(x: Any) { assertReifiedIsNot>(x, type) } +} + +object TestFn12 : TestFnBase("Function12<*, *, *, *, *, *, *, *, *, *, *, *, *>") { + override fun testGood(x: Any) { assertReifiedIs>(x, type) } + override fun testBad(x: Any) { assertReifiedIsNot>(x, type) } +} + +object TestFn13 : TestFnBase("Function13<*, *, *, *, *, *, *, *, *, *, *, *, *, *>") { + override fun testGood(x: Any) { assertReifiedIs>(x, type) } + override fun testBad(x: Any) { assertReifiedIsNot>(x, type) } +} + +object TestFn14 : TestFnBase("Function14<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *>") { + override fun testGood(x: Any) { assertReifiedIs>(x, type) } + override fun testBad(x: Any) { assertReifiedIsNot>(x, type) } +} + +object TestFn15 : TestFnBase("Function15<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *>") { + override fun testGood(x: Any) { assertReifiedIs>(x, type) } + override fun testBad(x: Any) { assertReifiedIsNot>(x, type) } +} + +object TestFn16 : TestFnBase("Function16<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *>") { + override fun testGood(x: Any) { assertReifiedIs>(x, type) } + override fun testBad(x: Any) { assertReifiedIsNot>(x, type) } +} + +object TestFn17 : TestFnBase("Function17<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *>") { + override fun testGood(x: Any) { assertReifiedIs>(x, type) } + override fun testBad(x: Any) { assertReifiedIsNot>(x, type) } +} + +object TestFn18 : TestFnBase("Function18<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *>") { + override fun testGood(x: Any) { assertReifiedIs>(x, type) } + override fun testBad(x: Any) { assertReifiedIsNot>(x, type) } +} + +object TestFn19 : TestFnBase("Function19<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *>") { + override fun testGood(x: Any) { assertReifiedIs>(x, type) } + override fun testBad(x: Any) { assertReifiedIsNot>(x, type) } +} + +object TestFn20 : TestFnBase("Function20<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *>") { + override fun testGood(x: Any) { assertReifiedIs>(x, type) } + override fun testBad(x: Any) { assertReifiedIsNot>(x, type) } +} + +object TestFn21 : TestFnBase("Function21<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *>") { + override fun testGood(x: Any) { assertReifiedIs>(x, type) } + override fun testBad(x: Any) { assertReifiedIsNot>(x, type) } +} + +object TestFn22 : TestFnBase("Function22<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *>") { + override fun testGood(x: Any) { assertReifiedIs>(x, type) } + override fun testBad(x: Any) { assertReifiedIsNot>(x, type) } +} + +val tests = arrayOf(TestFn0, TestFn1, TestFn2, TestFn3, TestFn4, TestFn5, TestFn6, TestFn7, TestFn8, TestFn9, + TestFn10, TestFn11, TestFn12, TestFn13, TestFn14, TestFn15, TestFn16, TestFn17, TestFn18, TestFn19, + TestFn20, TestFn21, TestFn22) + +fun box(): String { + for (fnI in 0 .. 22) { + for (testI in 0 .. 22) { + if (fnI == testI) { + tests[testI].testGood(fns[fnI]) + } + else { + tests[testI].testBad(fns[fnI]) + } + } + } + + return "OK" +} \ No newline at end of file diff --git a/compiler/testData/codegen/boxWithStdlib/casts/reifiedIsFunKSmall.kt b/compiler/testData/codegen/boxWithStdlib/casts/reifiedIsFunKSmall.kt new file mode 100644 index 00000000000..cf85d18a8c8 --- /dev/null +++ b/compiler/testData/codegen/boxWithStdlib/casts/reifiedIsFunKSmall.kt @@ -0,0 +1,36 @@ +fun fn0() {} +fun fn1(x: Any) {} + +inline fun assertReifiedIs(x: Any, type: String) { + val answer: Boolean + try { + answer = x is T + } + catch (e: Throwable) { + throw AssertionError("$x is $type: should not throw exceptions, got $e") + } + assert(answer) { "$x is $type: failed" } +} + +inline fun assertReifiedIsNot(x: Any, type: String) { + val answer: Boolean + try { + answer = x !is T + } + catch (e: Throwable) { + throw AssertionError("$x !is $type: should not throw exceptions, got $e") + } + assert(answer) { "$x !is $type: failed" } +} + +fun box(): String { + val f0 = ::fn0 as Any + val f1 = ::fn1 as Any + + assertReifiedIs>(f0, "Function0<*>") + assertReifiedIs>(f1, "Function1<*, *>") + assertReifiedIsNot>(f1, "Function0<*>") + assertReifiedIsNot>(f0, "Function1<*, *>") + + return "OK" +} \ No newline at end of file diff --git a/compiler/testData/codegen/boxWithStdlib/casts/reifiedSafeAsFunKBig.kt b/compiler/testData/codegen/boxWithStdlib/casts/reifiedSafeAsFunKBig.kt new file mode 100644 index 00000000000..204734a9db7 --- /dev/null +++ b/compiler/testData/codegen/boxWithStdlib/casts/reifiedSafeAsFunKBig.kt @@ -0,0 +1,285 @@ +// This is a big, ugly, semi-auto generated test. +// Use corresponding 'Small' test for debug. + +fun fn0() {} +fun fn1(x0: Any) {} +fun fn2(x0: Any, x1: Any) {} +fun fn3(x0: Any, x1: Any, x2: Any) {} +fun fn4(x0: Any, x1: Any, x2: Any, x3: Any) {} +fun fn5(x0: Any, x1: Any, x2: Any, x3: Any, x4: Any) {} +fun fn6(x0: Any, x1: Any, x2: Any, x3: Any, x4: Any, x5: Any) {} +fun fn7(x0: Any, x1: Any, x2: Any, x3: Any, x4: Any, x5: Any, x6: Any) {} +fun fn8(x0: Any, x1: Any, x2: Any, x3: Any, x4: Any, x5: Any, x6: Any, x7: Any) {} +fun fn9(x0: Any, x1: Any, x2: Any, x3: Any, x4: Any, x5: Any, x6: Any, x7: Any, x8: Any) {} +fun fn10(x0: Any, x1: Any, x2: Any, x3: Any, x4: Any, x5: Any, x6: Any, x7: Any, x8: Any, x9: Any) {} +fun fn11(x0: Any, x1: Any, x2: Any, x3: Any, x4: Any, x5: Any, x6: Any, x7: Any, x8: Any, x9: Any, x10: Any) {} +fun fn12(x0: Any, x1: Any, x2: Any, x3: Any, x4: Any, x5: Any, x6: Any, x7: Any, x8: Any, x9: Any, x10: Any, x11: Any) {} +fun fn13(x0: Any, x1: Any, x2: Any, x3: Any, x4: Any, x5: Any, x6: Any, x7: Any, x8: Any, x9: Any, x10: Any, x11: Any, x12: Any) {} +fun fn14(x0: Any, x1: Any, x2: Any, x3: Any, x4: Any, x5: Any, x6: Any, x7: Any, x8: Any, x9: Any, x10: Any, x11: Any, x12: Any, x13: Any) {} +fun fn15(x0: Any, x1: Any, x2: Any, x3: Any, x4: Any, x5: Any, x6: Any, x7: Any, x8: Any, x9: Any, x10: Any, x11: Any, x12: Any, x13: Any, x14: Any) {} +fun fn16(x0: Any, x1: Any, x2: Any, x3: Any, x4: Any, x5: Any, x6: Any, x7: Any, x8: Any, x9: Any, x10: Any, x11: Any, x12: Any, x13: Any, x14: Any, x15: Any) {} +fun fn17(x0: Any, x1: Any, x2: Any, x3: Any, x4: Any, x5: Any, x6: Any, x7: Any, x8: Any, x9: Any, x10: Any, x11: Any, x12: Any, x13: Any, x14: Any, x15: Any, x16: Any) {} +fun fn18(x0: Any, x1: Any, x2: Any, x3: Any, x4: Any, x5: Any, x6: Any, x7: Any, x8: Any, x9: Any, x10: Any, x11: Any, x12: Any, x13: Any, x14: Any, x15: Any, x16: Any, x17: Any) {} +fun fn19(x0: Any, x1: Any, x2: Any, x3: Any, x4: Any, x5: Any, x6: Any, x7: Any, x8: Any, x9: Any, x10: Any, x11: Any, x12: Any, x13: Any, x14: Any, x15: Any, x16: Any, x17: Any, x18: Any) {} +fun fn20(x0: Any, x1: Any, x2: Any, x3: Any, x4: Any, x5: Any, x6: Any, x7: Any, x8: Any, x9: Any, x10: Any, x11: Any, x12: Any, x13: Any, x14: Any, x15: Any, x16: Any, x17: Any, x18: Any, x19: Any) {} +fun fn21(x0: Any, x1: Any, x2: Any, x3: Any, x4: Any, x5: Any, x6: Any, x7: Any, x8: Any, x9: Any, x10: Any, x11: Any, x12: Any, x13: Any, x14: Any, x15: Any, x16: Any, x17: Any, x18: Any, x19: Any, x20: Any) {} +fun fn22(x0: Any, x1: Any, x2: Any, x3: Any, x4: Any, x5: Any, x6: Any, x7: Any, x8: Any, x9: Any, x10: Any, x11: Any, x12: Any, x13: Any, x14: Any, x15: Any, x16: Any, x17: Any, x18: Any, x19: Any, x20: Any, x21: Any) {} + +val fns = arrayOf(::fn0, ::fn1, ::fn2, ::fn3, ::fn4, ::fn5, ::fn6, ::fn7, ::fn8, ::fn9, + ::fn10, ::fn11, ::fn12, ::fn13, ::fn14, ::fn15, ::fn16, ::fn17, ::fn18, ::fn19, + ::fn20, ::fn21, ::fn22) + +inline fun reifiedSafeAsReturnsNonNull(x: Any?, operation: String) { + val y = try { + x as? T + } + catch (e: Throwable) { + throw AssertionError("$operation: should not throw exceptions, got $e") + } + if (y == null) { + throw AssertionError("$operation: should return non-null, got null") + } +} + +inline fun reifiedSafeAsReturnsNull(x: Any?, operation: String) { + val y = try { + x as? T + } + catch (e: Throwable) { + throw AssertionError("$operation: should not throw exceptions, got $e") + } + if (y != null) { + throw AssertionError("$operation: should return null, got $y") + } +} + +interface TestFnBase { + fun testGood(x: Any) + fun testBad(x: Any) +} + +object TestFn0 : TestFnBase { + override fun testGood(x: Any) = + reifiedSafeAsReturnsNonNull>( + x, "x as? Function0<*>") + override fun testBad(x: Any) = + reifiedSafeAsReturnsNull>( + x, "x as? Function0<*>") +} + +object TestFn1 : TestFnBase { + override fun testGood(x: Any) = + reifiedSafeAsReturnsNonNull>( + x, "x as? Function1<*, *>") + override fun testBad(x: Any) = + reifiedSafeAsReturnsNull>( + x, "x as? Function1<*, *>") +} + +object TestFn2 : TestFnBase { + override fun testGood(x: Any) = + reifiedSafeAsReturnsNonNull>( + x, "x as? Function2<*, *, *>") + override fun testBad(x: Any) = + reifiedSafeAsReturnsNull>( + x, "x as? Function2<*, *, *>") +} + +object TestFn3 : TestFnBase { + override fun testGood(x: Any) = + reifiedSafeAsReturnsNonNull>( + x, "x as? Function3<*, *, *, *>") + override fun testBad(x: Any) = + reifiedSafeAsReturnsNull>( + x, "x as? Function3<*, *, *, *>") +} + +object TestFn4 : TestFnBase { + override fun testGood(x: Any) = + reifiedSafeAsReturnsNonNull>( + x, "x as? Function4<*, *, *, *, *>") + override fun testBad(x: Any) = + reifiedSafeAsReturnsNull>( + x, "x as? Function4<*, *, *, *, *>") +} + +object TestFn5 : TestFnBase { + override fun testGood(x: Any) = + reifiedSafeAsReturnsNonNull>( + x, "x as? Function5<*, *, *, *, *, *>") + override fun testBad(x: Any) = + reifiedSafeAsReturnsNull>( + x, "x as? Function5<*, *, *, *, *, *>") +} + +object TestFn6 : TestFnBase { + override fun testGood(x: Any) = + reifiedSafeAsReturnsNonNull>( + x, "x as? Function6<*, *, *, *, *, *, *>") + override fun testBad(x: Any) = + reifiedSafeAsReturnsNull>( + x, "x as? Function6<*, *, *, *, *, *, *>") +} + +object TestFn7 : TestFnBase { + override fun testGood(x: Any) = + reifiedSafeAsReturnsNonNull>( + x, "x as? Function7<*, *, *, *, *, *, *, *>") + override fun testBad(x: Any) = + reifiedSafeAsReturnsNull>( + x, "x as? Function7<*, *, *, *, *, *, *, *>") +} + +object TestFn8 : TestFnBase { + override fun testGood(x: Any) = + reifiedSafeAsReturnsNonNull>( + x, "x as? Function8<*, *, *, *, *, *, *, *, *>") + override fun testBad(x: Any) = + reifiedSafeAsReturnsNull>( + x, "x as? Function8<*, *, *, *, *, *, *, *, *>") +} + +object TestFn9 : TestFnBase { + override fun testGood(x: Any) = + reifiedSafeAsReturnsNonNull>( + x, "x as? Function9<*, *, *, *, *, *, *, *, *, *>") + override fun testBad(x: Any) = + reifiedSafeAsReturnsNull>( + x, "x as? Function9<*, *, *, *, *, *, *, *, *, *>") +} + +object TestFn10 : TestFnBase { + override fun testGood(x: Any) = + reifiedSafeAsReturnsNonNull>( + x, "x as? Function10<*, *, *, *, *, *, *, *, *, *, *>") + override fun testBad(x: Any) = + reifiedSafeAsReturnsNull>( + x, "x as? Function10<*, *, *, *, *, *, *, *, *, *, *>") +} + +object TestFn11 : TestFnBase { + override fun testGood(x: Any) = + reifiedSafeAsReturnsNonNull>( + x, "x as? Function11<*, *, *, *, *, *, *, *, *, *, *, *>") + override fun testBad(x: Any) = + reifiedSafeAsReturnsNull>( + x, "x as? Function11<*, *, *, *, *, *, *, *, *, *, *, *>") +} + +object TestFn12 : TestFnBase { + override fun testGood(x: Any) = + reifiedSafeAsReturnsNonNull>( + x, "x as? Function12<*, *, *, *, *, *, *, *, *, *, *, *, *>") + override fun testBad(x: Any) = + reifiedSafeAsReturnsNull>( + x, "x as? Function12<*, *, *, *, *, *, *, *, *, *, *, *, *>") +} + +object TestFn13 : TestFnBase { + override fun testGood(x: Any) = + reifiedSafeAsReturnsNonNull>( + x, "x as? Function13<*, *, *, *, *, *, *, *, *, *, *, *, *, *>") + override fun testBad(x: Any) = + reifiedSafeAsReturnsNull>( + x, "x as? Function13<*, *, *, *, *, *, *, *, *, *, *, *, *, *>") +} + +object TestFn14 : TestFnBase { + override fun testGood(x: Any) = + reifiedSafeAsReturnsNonNull>( + x, "x as? Function14<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *>") + override fun testBad(x: Any) = + reifiedSafeAsReturnsNull>( + x, "x as? Function14<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *>") +} + +object TestFn15 : TestFnBase { + override fun testGood(x: Any) = + reifiedSafeAsReturnsNonNull>( + x, "x as? Function15<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *>") + override fun testBad(x: Any) = + reifiedSafeAsReturnsNull>( + x, "x as? Function15<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *>") +} + +object TestFn16 : TestFnBase { + override fun testGood(x: Any) = + reifiedSafeAsReturnsNonNull>( + x, "x as? Function16<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *>") + override fun testBad(x: Any) = + reifiedSafeAsReturnsNull>( + x, "x as? Function16<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *>") +} + +object TestFn17 : TestFnBase { + override fun testGood(x: Any) = + reifiedSafeAsReturnsNonNull>( + x, "x as? Function17<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *>") + override fun testBad(x: Any) = + reifiedSafeAsReturnsNull>( + x, "x as? Function17<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *>") +} + +object TestFn18 : TestFnBase { + override fun testGood(x: Any) = + reifiedSafeAsReturnsNonNull>( + x, "x as? Function18<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *>") + override fun testBad(x: Any) = + reifiedSafeAsReturnsNull>( + x, "x as? Function18<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *>") +} + +object TestFn19 : TestFnBase { + override fun testGood(x: Any) = + reifiedSafeAsReturnsNonNull>( + x, "x as? Function19<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *>") + override fun testBad(x: Any) = + reifiedSafeAsReturnsNull>( + x, "x as? Function19<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *>") +} + +object TestFn20 : TestFnBase { + override fun testGood(x: Any) = + reifiedSafeAsReturnsNonNull>( + x, "x as? Function20<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *>") + override fun testBad(x: Any) = + reifiedSafeAsReturnsNull>( + x, "x as? Function20<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *>") +} + +object TestFn21 : TestFnBase { + override fun testGood(x: Any) = + reifiedSafeAsReturnsNonNull>( + x, "x as? Function21<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *>") + override fun testBad(x: Any) = + reifiedSafeAsReturnsNull>( + x, "x as? Function21<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *>") +} + +object TestFn22 : TestFnBase { + override fun testGood(x: Any) = + reifiedSafeAsReturnsNonNull>( + x, "x as? Function22<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *>") + override fun testBad(x: Any) = + reifiedSafeAsReturnsNull>( + x, "x as? Function22<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *>") +} + +val tests = arrayOf(TestFn0, TestFn1, TestFn2, TestFn3, TestFn4, TestFn5, TestFn6, TestFn7, TestFn8, TestFn9, + TestFn10, TestFn11, TestFn12, TestFn13, TestFn14, TestFn15, TestFn16, TestFn17, TestFn18, TestFn19, + TestFn20, TestFn21, TestFn22) + +fun box(): String { + for (fnI in 0 .. 22) { + for (testI in 0 .. 22) { + if (fnI == testI) { + tests[testI].testGood(fns[fnI]) + } + else { + tests[testI].testBad(fns[fnI]) + } + } + } + + return "OK" +} \ No newline at end of file diff --git a/compiler/testData/codegen/boxWithStdlib/casts/reifiedSafeAsFunKSmall.kt b/compiler/testData/codegen/boxWithStdlib/casts/reifiedSafeAsFunKSmall.kt new file mode 100644 index 00000000000..a5df751581b --- /dev/null +++ b/compiler/testData/codegen/boxWithStdlib/casts/reifiedSafeAsFunKSmall.kt @@ -0,0 +1,41 @@ +fun fn0() {} +fun fn1(x: Any) {} + +inline fun reifiedSafeAsReturnsNonNull(x: Any?, operation: String) { + val y = try { + x as? T + } + catch (e: Throwable) { + throw AssertionError("$operation: should not throw exceptions, got $e") + } + if (y == null) { + throw AssertionError("$operation: should return non-null, got null") + } +} + +inline fun reifiedSafeAsReturnsNull(x: Any?, operation: String) { + val y = try { + x as? T + } + catch (e: Throwable) { + throw AssertionError("$operation: should not throw exceptions, got $e") + } + if (y != null) { + throw AssertionError("$operation: should return null, got $y") + } +} + +fun box(): String { + val f0 = ::fn0 as Any + val f1 = ::fn1 as Any + + reifiedSafeAsReturnsNonNull>(f0, "f0 as Function0<*>") + reifiedSafeAsReturnsNull>(f0, "f0 as Function1<*, *>") + reifiedSafeAsReturnsNull>(f1, "f1 as Function0<*>") + reifiedSafeAsReturnsNonNull>(f1, "f1 as Function1<*, *>") + + reifiedSafeAsReturnsNull>(null, "null as Function0<*>") + reifiedSafeAsReturnsNull>(null, "null as Function1<*, *>") + + return "OK" +} \ No newline at end of file diff --git a/compiler/testData/codegen/boxWithStdlib/casts/safeAsFunKBig.kt b/compiler/testData/codegen/boxWithStdlib/casts/safeAsFunKBig.kt new file mode 100644 index 00000000000..fb6ed2f26d6 --- /dev/null +++ b/compiler/testData/codegen/boxWithStdlib/casts/safeAsFunKBig.kt @@ -0,0 +1,327 @@ +// This is a big, ugly, semi-auto generated test. +// Use corresponding 'Small' test for debug. + +fun fn0() {} +fun fn1(x0: Any) {} +fun fn2(x0: Any, x1: Any) {} +fun fn3(x0: Any, x1: Any, x2: Any) {} +fun fn4(x0: Any, x1: Any, x2: Any, x3: Any) {} +fun fn5(x0: Any, x1: Any, x2: Any, x3: Any, x4: Any) {} +fun fn6(x0: Any, x1: Any, x2: Any, x3: Any, x4: Any, x5: Any) {} +fun fn7(x0: Any, x1: Any, x2: Any, x3: Any, x4: Any, x5: Any, x6: Any) {} +fun fn8(x0: Any, x1: Any, x2: Any, x3: Any, x4: Any, x5: Any, x6: Any, x7: Any) {} +fun fn9(x0: Any, x1: Any, x2: Any, x3: Any, x4: Any, x5: Any, x6: Any, x7: Any, x8: Any) {} +fun fn10(x0: Any, x1: Any, x2: Any, x3: Any, x4: Any, x5: Any, x6: Any, x7: Any, x8: Any, x9: Any) {} +fun fn11(x0: Any, x1: Any, x2: Any, x3: Any, x4: Any, x5: Any, x6: Any, x7: Any, x8: Any, x9: Any, x10: Any) {} +fun fn12(x0: Any, x1: Any, x2: Any, x3: Any, x4: Any, x5: Any, x6: Any, x7: Any, x8: Any, x9: Any, x10: Any, x11: Any) {} +fun fn13(x0: Any, x1: Any, x2: Any, x3: Any, x4: Any, x5: Any, x6: Any, x7: Any, x8: Any, x9: Any, x10: Any, x11: Any, x12: Any) {} +fun fn14(x0: Any, x1: Any, x2: Any, x3: Any, x4: Any, x5: Any, x6: Any, x7: Any, x8: Any, x9: Any, x10: Any, x11: Any, x12: Any, x13: Any) {} +fun fn15(x0: Any, x1: Any, x2: Any, x3: Any, x4: Any, x5: Any, x6: Any, x7: Any, x8: Any, x9: Any, x10: Any, x11: Any, x12: Any, x13: Any, x14: Any) {} +fun fn16(x0: Any, x1: Any, x2: Any, x3: Any, x4: Any, x5: Any, x6: Any, x7: Any, x8: Any, x9: Any, x10: Any, x11: Any, x12: Any, x13: Any, x14: Any, x15: Any) {} +fun fn17(x0: Any, x1: Any, x2: Any, x3: Any, x4: Any, x5: Any, x6: Any, x7: Any, x8: Any, x9: Any, x10: Any, x11: Any, x12: Any, x13: Any, x14: Any, x15: Any, x16: Any) {} +fun fn18(x0: Any, x1: Any, x2: Any, x3: Any, x4: Any, x5: Any, x6: Any, x7: Any, x8: Any, x9: Any, x10: Any, x11: Any, x12: Any, x13: Any, x14: Any, x15: Any, x16: Any, x17: Any) {} +fun fn19(x0: Any, x1: Any, x2: Any, x3: Any, x4: Any, x5: Any, x6: Any, x7: Any, x8: Any, x9: Any, x10: Any, x11: Any, x12: Any, x13: Any, x14: Any, x15: Any, x16: Any, x17: Any, x18: Any) {} +fun fn20(x0: Any, x1: Any, x2: Any, x3: Any, x4: Any, x5: Any, x6: Any, x7: Any, x8: Any, x9: Any, x10: Any, x11: Any, x12: Any, x13: Any, x14: Any, x15: Any, x16: Any, x17: Any, x18: Any, x19: Any) {} +fun fn21(x0: Any, x1: Any, x2: Any, x3: Any, x4: Any, x5: Any, x6: Any, x7: Any, x8: Any, x9: Any, x10: Any, x11: Any, x12: Any, x13: Any, x14: Any, x15: Any, x16: Any, x17: Any, x18: Any, x19: Any, x20: Any) {} +fun fn22(x0: Any, x1: Any, x2: Any, x3: Any, x4: Any, x5: Any, x6: Any, x7: Any, x8: Any, x9: Any, x10: Any, x11: Any, x12: Any, x13: Any, x14: Any, x15: Any, x16: Any, x17: Any, x18: Any, x19: Any, x20: Any, x21: Any) {} + +val fns = arrayOf(::fn0, ::fn1, ::fn2, ::fn3, ::fn4, ::fn5, ::fn6, ::fn7, ::fn8, ::fn9, + ::fn10, ::fn11, ::fn12, ::fn13, ::fn14, ::fn15, ::fn16, ::fn17, ::fn18, ::fn19, + ::fn20, ::fn21, ::fn22) + +inline fun safeAsReturnsNull(operation: String, cast: () -> Any?) { + try { + val x = cast() + assert(x == null) { "$operation: should return null, got $x" } + } + catch (e: Throwable) { + throw AssertionError("$operation: should not throw exceptions, got $e") + } +} + +inline fun safeAsReturnsNonNull(operation: String, cast: () -> Any?) { + try { + val x = cast() + assert(x != null) { "$operation: should return non-null" } + } + catch (e: Throwable) { + throw AssertionError("$operation: should not throw exceptions, got $e") + } +} + +interface TestFnBase { + abstract fun testGood(x: Any) + abstract fun testBad(x: Any) +} + +object TestFn0 : TestFnBase { + override fun testGood(x: Any) = + safeAsReturnsNonNull("x as? Function0<*>") { + x as? Function0<*> + } + override fun testBad(x: Any) = + safeAsReturnsNull("x as? Function0<*>") { + x as? Function0<*> + } +} + +object TestFn1 : TestFnBase { + override fun testGood(x: Any) = + safeAsReturnsNonNull("x as? Function1<*, *>") { + x as? Function1<*, *> + } + override fun testBad(x: Any) = + safeAsReturnsNull("x as? Function1<*, *>") { + x as? Function1<*, *> + } +} + +object TestFn2 : TestFnBase { + override fun testGood(x: Any) = + safeAsReturnsNonNull("x as? Function2<*, *, *>") { + x as? Function2<*, *, *> + } + override fun testBad(x: Any) = + safeAsReturnsNull("x as? Function2<*, *, *>") { + x as? Function2<*, *, *> + } +} + +object TestFn3 : TestFnBase { + override fun testGood(x: Any) = + safeAsReturnsNonNull("x as? Function3<*, *, *, *>") { + x as? Function3<*, *, *, *> + } + override fun testBad(x: Any) = + safeAsReturnsNull("x as? Function3<*, *, *, *>") { + x as? Function3<*, *, *, *> + } +} + +object TestFn4 : TestFnBase { + override fun testGood(x: Any) = + safeAsReturnsNonNull("x as? Function4<*, *, *, *, *>") { + x as? Function4<*, *, *, *, *> + } + override fun testBad(x: Any) = + safeAsReturnsNull("x as? Function4<*, *, *, *, *>") { + x as? Function4<*, *, *, *, *> + } +} + +object TestFn5 : TestFnBase { + override fun testGood(x: Any) = + safeAsReturnsNonNull("x as? Function5<*, *, *, *, *, *>") { + x as? Function5<*, *, *, *, *, *> + } + override fun testBad(x: Any) = + safeAsReturnsNull("x as? Function5<*, *, *, *, *, *>") { + x as? Function5<*, *, *, *, *, *> + } +} + +object TestFn6 : TestFnBase { + override fun testGood(x: Any) = + safeAsReturnsNonNull("x as? Function6<*, *, *, *, *, *, *>") { + x as? Function6<*, *, *, *, *, *, *> + } + override fun testBad(x: Any) = + safeAsReturnsNull("x as? Function6<*, *, *, *, *, *, *>") { + x as? Function6<*, *, *, *, *, *, *> + } +} + +object TestFn7 : TestFnBase { + override fun testGood(x: Any) = + safeAsReturnsNonNull("x as? Function7<*, *, *, *, *, *, *, *>") { + x as? Function7<*, *, *, *, *, *, *, *> + } + override fun testBad(x: Any) = + safeAsReturnsNull("x as? Function7<*, *, *, *, *, *, *, *>") { + x as? Function7<*, *, *, *, *, *, *, *> + } +} + +object TestFn8 : TestFnBase { + override fun testGood(x: Any) = + safeAsReturnsNonNull("x as? Function8<*, *, *, *, *, *, *, *, *>") { + x as? Function8<*, *, *, *, *, *, *, *, *> + } + override fun testBad(x: Any) = + safeAsReturnsNull("x as? Function8<*, *, *, *, *, *, *, *, *>") { + x as? Function8<*, *, *, *, *, *, *, *, *> + } +} + +object TestFn9 : TestFnBase { + override fun testGood(x: Any) = + safeAsReturnsNonNull("x as? Function9<*, *, *, *, *, *, *, *, *, *>") { + x as? Function9<*, *, *, *, *, *, *, *, *, *> + } + override fun testBad(x: Any) = + safeAsReturnsNull("x as? Function9<*, *, *, *, *, *, *, *, *, *>") { + x as? Function9<*, *, *, *, *, *, *, *, *, *> + } +} + +object TestFn10 : TestFnBase { + override fun testGood(x: Any) = + safeAsReturnsNonNull("x as? Function10<*, *, *, *, *, *, *, *, *, *, *>") { + x as? Function10<*, *, *, *, *, *, *, *, *, *, *> + } + override fun testBad(x: Any) = + safeAsReturnsNull("x as? Function10<*, *, *, *, *, *, *, *, *, *, *>") { + x as? Function10<*, *, *, *, *, *, *, *, *, *, *> + } +} + +object TestFn11 : TestFnBase { + override fun testGood(x: Any) = + safeAsReturnsNonNull("x as? Function11<*, *, *, *, *, *, *, *, *, *, *, *>") { + x as? Function11<*, *, *, *, *, *, *, *, *, *, *, *> + } + override fun testBad(x: Any) = + safeAsReturnsNull("x as? Function11<*, *, *, *, *, *, *, *, *, *, *, *>") { + x as? Function11<*, *, *, *, *, *, *, *, *, *, *, *> + } +} + +object TestFn12 : TestFnBase { + override fun testGood(x: Any) = + safeAsReturnsNonNull("x as? Function12<*, *, *, *, *, *, *, *, *, *, *, *, *>") { + x as? Function12<*, *, *, *, *, *, *, *, *, *, *, *, *> + } + override fun testBad(x: Any) = + safeAsReturnsNull("x as? Function12<*, *, *, *, *, *, *, *, *, *, *, *, *>") { + x as? Function12<*, *, *, *, *, *, *, *, *, *, *, *, *> + } +} + +object TestFn13 : TestFnBase { + override fun testGood(x: Any) = + safeAsReturnsNonNull("x as? Function13<*, *, *, *, *, *, *, *, *, *, *, *, *, *>") { + x as? Function13<*, *, *, *, *, *, *, *, *, *, *, *, *, *> + } + override fun testBad(x: Any) = + safeAsReturnsNull("x as? Function13<*, *, *, *, *, *, *, *, *, *, *, *, *, *>") { + x as? Function13<*, *, *, *, *, *, *, *, *, *, *, *, *, *> + } +} + +object TestFn14 : TestFnBase { + override fun testGood(x: Any) = + safeAsReturnsNonNull("x as? Function14<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *>") { + x as? Function14<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *> + } + override fun testBad(x: Any) = + safeAsReturnsNull("x as? Function14<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *>") { + x as? Function14<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *> + } +} + +object TestFn15 : TestFnBase { + override fun testGood(x: Any) = + safeAsReturnsNonNull("x as? Function15<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *>") { + x as? Function15<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *> + } + override fun testBad(x: Any) = + safeAsReturnsNull("x as? Function15<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *>") { + x as? Function15<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *> + } +} + +object TestFn16 : TestFnBase { + override fun testGood(x: Any) = + safeAsReturnsNonNull("x as? Function16<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *>") { + x as? Function16<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *> + } + override fun testBad(x: Any) = + safeAsReturnsNull("x as? Function16<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *>") { + x as? Function16<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *> + } +} + +object TestFn17 : TestFnBase { + override fun testGood(x: Any) = + safeAsReturnsNonNull("x as? Function17<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *>") { + x as? Function17<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *> + } + override fun testBad(x: Any) = + safeAsReturnsNull("x as? Function17<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *>") { + x as? Function17<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *> + } +} + +object TestFn18 : TestFnBase { + override fun testGood(x: Any) = + safeAsReturnsNonNull("x as? Function18<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *>") { + x as? Function18<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *> + } + override fun testBad(x: Any) = + safeAsReturnsNull("x as? Function18<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *>") { + x as? Function18<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *> + } +} + +object TestFn19 : TestFnBase { + override fun testGood(x: Any) = + safeAsReturnsNonNull("x as? Function19<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *>") { + x as? Function19<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *> + } + override fun testBad(x: Any) = + safeAsReturnsNull("x as? Function19<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *>") { + x as? Function19<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *> + } +} + +object TestFn20 : TestFnBase { + override fun testGood(x: Any) = + safeAsReturnsNonNull("x as? Function20<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *>") { + x as? Function20<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *> + } + override fun testBad(x: Any) = + safeAsReturnsNull("x as? Function20<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *>") { + x as? Function20<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *> + } +} + +object TestFn21 : TestFnBase { + override fun testGood(x: Any) = + safeAsReturnsNonNull("x as? Function21<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *>") { + x as? Function21<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *> + } + override fun testBad(x: Any) = + safeAsReturnsNull("x as? Function21<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *>") { + x as? Function21<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *> + } +} + +object TestFn22 : TestFnBase { + override fun testGood(x: Any) = + safeAsReturnsNonNull("x as? Function22<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *>") { + x as? Function22<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *> + } + override fun testBad(x: Any) = + safeAsReturnsNull("x as? Function22<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *>") { + x as? Function22<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *> + } +} + +val tests = arrayOf(TestFn0, TestFn1, TestFn2, TestFn3, TestFn4, TestFn5, TestFn6, TestFn7, TestFn8, TestFn9, + TestFn10, TestFn11, TestFn12, TestFn13, TestFn14, TestFn15, TestFn16, TestFn17, TestFn18, TestFn19, + TestFn20, TestFn21, TestFn22) + +fun box(): String { + for (fnI in 0 .. 22) { + for (testI in 0 .. 22) { + if (fnI == testI) { + tests[testI].testGood(fns[fnI]) + } + else { + tests[testI].testBad(fns[fnI]) + } + } + } + + return "OK" +} \ No newline at end of file diff --git a/compiler/testData/codegen/boxWithStdlib/casts/safeAsFunKSmall.kt b/compiler/testData/codegen/boxWithStdlib/casts/safeAsFunKSmall.kt new file mode 100644 index 00000000000..4f922b04e83 --- /dev/null +++ b/compiler/testData/codegen/boxWithStdlib/casts/safeAsFunKSmall.kt @@ -0,0 +1,34 @@ +fun fn0() {} +fun fn1(x: Any) {} + +inline fun safeAsReturnsNull(operation: String, cast: () -> Any?) { + try { + val x = cast() + assert(x == null) { "$operation: should return null, got $x" } + } + catch (e: Throwable) { + throw AssertionError("$operation: should not throw exceptions, got $e") + } +} + +inline fun safeAsReturnsNonNull(operation: String, cast: () -> Any?) { + try { + val x = cast() + assert(x != null) { "$operation: should return non-null" } + } + catch (e: Throwable) { + throw AssertionError("$operation: should not throw exceptions, got $e") + } +} + +fun box(): String { + val f0 = ::fn0 as Any + val f1 = ::fn1 as Any + + safeAsReturnsNonNull("f0 as? Function0<*>") { f0 as? Function0<*> } + safeAsReturnsNull("f0 as? Function1<*, *>") { f0 as? Function1<*, *> } + safeAsReturnsNull("f1 as? Function0<*>") { f1 as? Function0<*> } + safeAsReturnsNonNull("f1 as? Function1<*, *>") { f1 as? Function1<*, *> } + + return "OK" +} \ No newline at end of file diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/generated/BlackBoxWithJavaCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/generated/BlackBoxWithJavaCodegenTestGenerated.java index 35c63755834..d2ecefc82ea 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/generated/BlackBoxWithJavaCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/generated/BlackBoxWithJavaCodegenTestGenerated.java @@ -143,6 +143,22 @@ public class BlackBoxWithJavaCodegenTestGenerated extends AbstractBlackBoxCodege } + @TestMetadata("compiler/testData/codegen/boxWithJava/casts") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class Casts extends AbstractBlackBoxCodegenTest { + public void testAllFilesPresentInCasts() throws Exception { + JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/boxWithJava/casts"), Pattern.compile("^([^\\.]+)$"), true); + } + + @TestMetadata("javaTypeIsFunK") + public void testJavaTypeIsFunK() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxWithJava/casts/javaTypeIsFunK/"); + doTestWithJava(fileName); + } + + } + @TestMetadata("compiler/testData/codegen/boxWithJava/fileClasses") @TestDataPath("$PROJECT_ROOT") @RunWith(JUnit3RunnerWithInners.class) diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/generated/BlackBoxWithStdlibCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/generated/BlackBoxWithStdlibCodegenTestGenerated.java index 03b9d4807f7..a566ebbe515 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/generated/BlackBoxWithStdlibCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/generated/BlackBoxWithStdlibCodegenTestGenerated.java @@ -916,6 +916,18 @@ public class BlackBoxWithStdlibCodegenTestGenerated extends AbstractBlackBoxCode JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/boxWithStdlib/casts"), Pattern.compile("^(.+)\\.kt$"), true); } + @TestMetadata("asFunKBig.kt") + public void testAsFunKBig() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxWithStdlib/casts/asFunKBig.kt"); + doTestWithStdlib(fileName); + } + + @TestMetadata("asFunKSmall.kt") + public void testAsFunKSmall() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxWithStdlib/casts/asFunKSmall.kt"); + doTestWithStdlib(fileName); + } + @TestMetadata("asWithGeneric.kt") public void testAsWithGeneric() throws Exception { String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxWithStdlib/casts/asWithGeneric.kt"); @@ -928,30 +940,90 @@ public class BlackBoxWithStdlibCodegenTestGenerated extends AbstractBlackBoxCode doTestWithStdlib(fileName); } + @TestMetadata("isFunKBig.kt") + public void testIsFunKBig() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxWithStdlib/casts/isFunKBig.kt"); + doTestWithStdlib(fileName); + } + + @TestMetadata("isFunKSmall.kt") + public void testIsFunKSmall() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxWithStdlib/casts/isFunKSmall.kt"); + doTestWithStdlib(fileName); + } + @TestMetadata("isWithMutable.kt") public void testIsWithMutable() throws Exception { String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxWithStdlib/casts/isWithMutable.kt"); doTestWithStdlib(fileName); } + @TestMetadata("reifiedAsFunKBig.kt") + public void testReifiedAsFunKBig() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxWithStdlib/casts/reifiedAsFunKBig.kt"); + doTestWithStdlib(fileName); + } + + @TestMetadata("reifiedAsFunKSmall.kt") + public void testReifiedAsFunKSmall() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxWithStdlib/casts/reifiedAsFunKSmall.kt"); + doTestWithStdlib(fileName); + } + @TestMetadata("reifiedAsWithMutable.kt") public void testReifiedAsWithMutable() throws Exception { String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxWithStdlib/casts/reifiedAsWithMutable.kt"); doTestWithStdlib(fileName); } + @TestMetadata("reifiedIsFunKBig.kt") + public void testReifiedIsFunKBig() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxWithStdlib/casts/reifiedIsFunKBig.kt"); + doTestWithStdlib(fileName); + } + + @TestMetadata("reifiedIsFunKSmall.kt") + public void testReifiedIsFunKSmall() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxWithStdlib/casts/reifiedIsFunKSmall.kt"); + doTestWithStdlib(fileName); + } + @TestMetadata("reifiedIsWithMutable.kt") public void testReifiedIsWithMutable() throws Exception { String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxWithStdlib/casts/reifiedIsWithMutable.kt"); doTestWithStdlib(fileName); } + @TestMetadata("reifiedSafeAsFunKBig.kt") + public void testReifiedSafeAsFunKBig() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxWithStdlib/casts/reifiedSafeAsFunKBig.kt"); + doTestWithStdlib(fileName); + } + + @TestMetadata("reifiedSafeAsFunKSmall.kt") + public void testReifiedSafeAsFunKSmall() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxWithStdlib/casts/reifiedSafeAsFunKSmall.kt"); + doTestWithStdlib(fileName); + } + @TestMetadata("reifiedSafeAsWithMutable.kt") public void testReifiedSafeAsWithMutable() throws Exception { String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxWithStdlib/casts/reifiedSafeAsWithMutable.kt"); doTestWithStdlib(fileName); } + @TestMetadata("safeAsFunKBig.kt") + public void testSafeAsFunKBig() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxWithStdlib/casts/safeAsFunKBig.kt"); + doTestWithStdlib(fileName); + } + + @TestMetadata("safeAsFunKSmall.kt") + public void testSafeAsFunKSmall() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxWithStdlib/casts/safeAsFunKSmall.kt"); + doTestWithStdlib(fileName); + } + @TestMetadata("safeAsWithMutable.kt") public void testSafeAsWithMutable() throws Exception { String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxWithStdlib/casts/safeAsWithMutable.kt"); diff --git a/core/runtime.jvm/src/kotlin/jvm/internal/TypeIntrinsics.java b/core/runtime.jvm/src/kotlin/jvm/internal/TypeIntrinsics.java index de0f2f9e505..77d50703152 100644 --- a/core/runtime.jvm/src/kotlin/jvm/internal/TypeIntrinsics.java +++ b/core/runtime.jvm/src/kotlin/jvm/internal/TypeIntrinsics.java @@ -16,16 +16,21 @@ package kotlin.jvm.internal; +import kotlin.Function; +import kotlin.jvm.functions.*; import kotlin.jvm.internal.markers.*; import java.util.*; @SuppressWarnings("unused") public class TypeIntrinsics { + private static T sanitizeStackTrace(T throwable) { + return Intrinsics.sanitizeStackTrace(throwable, TypeIntrinsics.class.getName()); + } + public static void throwCce(Object argument, String requestedClassName) { String argumentClassName = argument == null ? "null" : argument.getClass().getName(); - ClassCastException classCastException = new ClassCastException(argumentClassName + " cannot be cast to " + requestedClassName); - throw Intrinsics.sanitizeStackTrace(classCastException, TypeIntrinsics.class.getName()); + throw sanitizeStackTrace(new ClassCastException(argumentClassName + " cannot be cast to " + requestedClassName)); } public static void throwCce(ClassCastException e) { @@ -183,4 +188,102 @@ public class TypeIntrinsics { } return result; } + + public static int getFunctionArity(Object obj) { + if (obj instanceof FunctionImpl) { + return ((FunctionImpl) obj).getArity(); + } + else if (obj instanceof Function0) { + return 0; + } + else if (obj instanceof Function1) { + return 1; + } + else if (obj instanceof Function2) { + return 2; + } + else if (obj instanceof Function3) { + return 3; + } + else if (obj instanceof Function4) { + return 4; + } + else if (obj instanceof Function5) { + return 5; + } + else if (obj instanceof Function6) { + return 6; + } + else if (obj instanceof Function7) { + return 7; + } + else if (obj instanceof Function8) { + return 8; + } + else if (obj instanceof Function9) { + return 9; + } + else if (obj instanceof Function10) { + return 10; + } + else if (obj instanceof Function11) { + return 11; + } + else if (obj instanceof Function12) { + return 12; + } + else if (obj instanceof Function13) { + return 13; + } + else if (obj instanceof Function14) { + return 14; + } + else if (obj instanceof Function15) { + return 15; + } + else if (obj instanceof Function16) { + return 16; + } + else if (obj instanceof Function17) { + return 17; + } + else if (obj instanceof Function18) { + return 18; + } + else if (obj instanceof Function19) { + return 19; + } + else if (obj instanceof Function20) { + return 20; + } + else if (obj instanceof Function21) { + return 21; + } + else if (obj instanceof Function22) { + return 22; + } + else { + return -1; + } + } + + public static boolean isFunctionOfArity(Object obj, int arity) { + return obj instanceof Function && getFunctionArity(obj) == arity; + } + + public static Object beforeCheckcastToFunctionOfArity(Object obj, int arity) { + // TODO should we instead inline bytecode for this in TypeIntrinsics.kt? + if (obj != null && !isFunctionOfArity(obj, arity)) { + throwCce(obj, "kotlin.jvm.functions.Function" + arity); + } + return obj; + } + + public static Object beforeSafeCheckcastToFunctionOfArity(Object obj, int arity) { + // TODO should we instead inline bytecode for this in TypeIntrinsics.kt? + if (obj == null || !isFunctionOfArity(obj, arity)) { + return null; + } + return obj; + } }