Calculate empty array literal types in FIR2IR instead of deserializer

This commit handles situations when some annotation in deserialized code
has an empty array literal argument [] or even non-empty [something].
Before this commit, we tried to guess a type of this array by "resolving"
the relevant annotation class and looking into the corresponding
parameter. Sometimes it can work, but also it can provoke recursive
resolve e.g. when the annotation class is a nested class in the same scope.
In this commit we changed the behavior in the following way:
- first, for non-empty array literals in deserialized code we just
take the array type from the corresponding array literal element
- second, for empty array literals we no more try to "guess" anything.
Instead we approximate array type as Array<Any>, and later at FIR2IR
stage we use the corresponding parameter type instead. At FIR2IR stage,
everything is already resolved and problems with recursions are no more
possible.

#KT-62598 Fixed
This commit is contained in:
Mikhail Glukhikh
2023-10-17 17:20:57 +02:00
committed by Space Team
parent 19a95f2fb4
commit 290adda8fc
16 changed files with 249 additions and 42 deletions
@@ -533,6 +533,12 @@ public class LLFirBlackBoxCodegenBasedTestGenerated extends AbstractLLFirBlackBo
runTest("compiler/testData/codegen/box/annotations/instances/annotationInstancesEmptyDefaultLowered.kt");
}
@Test
@TestMetadata("AnnotationInstantiationWithArray.kt")
public void testAnnotationInstantiationWithArray() throws Exception {
runTest("compiler/testData/codegen/box/annotations/instances/AnnotationInstantiationWithArray.kt");
}
@Test
@TestMetadata("annotationJvmHashCode.kt")
public void testAnnotationJvmHashCode() throws Exception {
@@ -19574,6 +19580,12 @@ public class LLFirBlackBoxCodegenBasedTestGenerated extends AbstractLLFirBlackBo
runTest("compiler/testData/codegen/box/fir/selectingLambdas.kt");
}
@Test
@TestMetadata("StackOverflowInAnnotationLoader.kt")
public void testStackOverflowInAnnotationLoader() throws Exception {
runTest("compiler/testData/codegen/box/fir/StackOverflowInAnnotationLoader.kt");
}
@Test
@TestMetadata("staticImportFromEnum.kt")
public void testStaticImportFromEnum() throws Exception {
@@ -533,6 +533,12 @@ public class LLFirReversedBlackBoxCodegenBasedTestGenerated extends AbstractLLFi
runTest("compiler/testData/codegen/box/annotations/instances/annotationInstancesEmptyDefaultLowered.kt");
}
@Test
@TestMetadata("AnnotationInstantiationWithArray.kt")
public void testAnnotationInstantiationWithArray() throws Exception {
runTest("compiler/testData/codegen/box/annotations/instances/AnnotationInstantiationWithArray.kt");
}
@Test
@TestMetadata("annotationJvmHashCode.kt")
public void testAnnotationJvmHashCode() throws Exception {
@@ -19574,6 +19580,12 @@ public class LLFirReversedBlackBoxCodegenBasedTestGenerated extends AbstractLLFi
runTest("compiler/testData/codegen/box/fir/selectingLambdas.kt");
}
@Test
@TestMetadata("StackOverflowInAnnotationLoader.kt")
public void testStackOverflowInAnnotationLoader() throws Exception {
runTest("compiler/testData/codegen/box/fir/StackOverflowInAnnotationLoader.kt");
}
@Test
@TestMetadata("staticImportFromEnum.kt")
public void testStaticImportFromEnum() throws Exception {
@@ -774,12 +774,10 @@ fun IrActualizedResult?.extractFirDeclarations(): Set<FirDeclaration>? {
// This method is intended to be used for default values of annotation parameters (compile-time strings, numbers, enum values, KClasses)
// where they are needed and may produce incorrect results for values that may be encountered outside annotations.
fun FirExpression.asCompileTimeIrInitializer(components: Fir2IrComponents): IrExpressionBody? {
return when (val elem = this.accept(Fir2IrVisitor(components, Fir2IrConversionScope(components.configuration)), null)) {
is IrExpressionBody -> elem
is IrExpression -> components.irFactory.createExpressionBody(elem)
else -> null
}
fun FirExpression.asCompileTimeIrInitializer(components: Fir2IrComponents, expectedType: ConeKotlinType? = null): IrExpressionBody {
val visitor = Fir2IrVisitor(components, Fir2IrConversionScope(components.configuration))
val expression = visitor.convertToIrExpression(this, expectedType = expectedType)
return components.irFactory.createExpressionBody(expression)
}
/**
@@ -894,7 +894,12 @@ class Fir2IrVisitor(
internal fun convertToIrExpression(
expression: FirExpression,
isDelegate: Boolean = false
isDelegate: Boolean = false,
// This argument is used for a corner case with deserialized empty array literals
// These array literals normally have a type of Array<Any>,
// so FIR2IR should instead use a type of corresponding property
// See also KT-62598
expectedType: ConeKotlinType? = null,
): IrExpression {
return when (expression) {
is FirBlock -> expression.convertToIrExpressionOrBlock(
@@ -908,6 +913,7 @@ class Fir2IrVisitor(
else -> {
when (val unwrappedExpression = expression.unwrapArgument()) {
is FirCallableReferenceAccess -> convertCallableReferenceAccess(unwrappedExpression, isDelegate)
is FirArrayLiteral -> convertToArrayLiteral(unwrappedExpression, expectedType)
else -> expression.accept(this, null) as IrExpression
}
}
@@ -1577,9 +1583,13 @@ class Fir2IrVisitor(
classifierStorage.getOrCreateIrClass(it).symbol
}
private fun convertToArrayLiteral(arrayLiteral: FirArrayLiteral): IrVararg {
private fun convertToArrayLiteral(
arrayLiteral: FirArrayLiteral,
// See comment to convertToIrExpression
expectedType: ConeKotlinType?,
): IrVararg {
return arrayLiteral.convertWithOffsets { startOffset, endOffset ->
val arrayType = arrayLiteral.resolvedType.toIrType()
val arrayType = (expectedType ?: arrayLiteral.resolvedType).toIrType()
val elementType = arrayType.getArrayElementType(irBuiltIns)
IrVarargImpl(
startOffset, endOffset,
@@ -1590,10 +1600,6 @@ class Fir2IrVisitor(
}
}
override fun visitArrayLiteral(arrayLiteral: FirArrayLiteral, data: Any?): IrElement = whileAnalysing(session, arrayLiteral) {
return convertToArrayLiteral(arrayLiteral)
}
override fun visitAugmentedArraySetCall(
augmentedArraySetCall: FirAugmentedArraySetCall,
data: Any?
@@ -1032,10 +1032,17 @@ class CallAndReferenceGenerator(
parameter: FirValueParameter?,
substitutor: ConeSubstitutor,
): IrExpression {
var irArgument = visitor.convertToIrExpression(argument)
if (parameter != null) {
val parameterConeType = parameter?.returnTypeRef?.coneType
// Normally argument type should be correct itself.
// However, for deserialized annotations it's possible to have imprecise Array<Any> type
// for empty integer literal arguments.
// In this case we have to use parameter type itself which is more precise, like Array<String> or IntArray.
// See KT-62598 and its fix for details.
val expectedType = parameterConeType.takeIf { visitor.annotationMode && parameterConeType?.isArrayType == true }
var irArgument = visitor.convertToIrExpression(argument, expectedType = expectedType)
if (parameterConeType != null) {
with(visitor.implicitCastInserter) {
irArgument = irArgument.cast(argument, argument.resolvedType, parameter.returnTypeRef.coneType)
irArgument = irArgument.cast(argument, argument.resolvedType, parameterConeType)
}
}
with(adapterGenerator) {
@@ -18,6 +18,7 @@ import org.jetbrains.kotlin.fir.declarations.impl.FirDefaultPropertySetter
import org.jetbrains.kotlin.fir.declarations.utils.*
import org.jetbrains.kotlin.fir.expressions.FirConstExpression
import org.jetbrains.kotlin.fir.expressions.FirExpression
import org.jetbrains.kotlin.fir.types.coneType
import org.jetbrains.kotlin.fir.types.resolvedType
import org.jetbrains.kotlin.ir.ObsoleteDescriptorBasedAPI
import org.jetbrains.kotlin.ir.declarations.*
@@ -95,7 +96,9 @@ class Fir2IrLazyProperty(
private fun toIrInitializer(initializer: FirExpression?): IrExpressionBody? {
// Annotations need full initializer information to instantiate them correctly
return when {
containingClass?.classKind?.isAnnotationClass == true -> initializer?.asCompileTimeIrInitializer(components)
containingClass?.classKind?.isAnnotationClass == true -> initializer?.asCompileTimeIrInitializer(
components, fir.returnTypeRef.coneType
)
// Setting initializers to every other class causes some cryptic errors in lowerings
initializer is FirConstExpression<*> -> {
val constType = with(typeConverter) { initializer.resolvedType.toIrType() }
@@ -534,6 +534,12 @@ public class FirLightTreeBlackBoxCodegenTestGenerated extends AbstractFirLightTr
runTest("compiler/testData/codegen/box/annotations/instances/annotationInstancesEmptyDefaultLowered.kt");
}
@Test
@TestMetadata("AnnotationInstantiationWithArray.kt")
public void testAnnotationInstantiationWithArray() throws Exception {
runTest("compiler/testData/codegen/box/annotations/instances/AnnotationInstantiationWithArray.kt");
}
@Test
@TestMetadata("annotationJvmHashCode.kt")
public void testAnnotationJvmHashCode() throws Exception {
@@ -534,6 +534,12 @@ public class FirLightTreeBlackBoxCodegenWithIrFakeOverrideGeneratorTestGenerated
runTest("compiler/testData/codegen/box/annotations/instances/annotationInstancesEmptyDefaultLowered.kt");
}
@Test
@TestMetadata("AnnotationInstantiationWithArray.kt")
public void testAnnotationInstantiationWithArray() throws Exception {
runTest("compiler/testData/codegen/box/annotations/instances/AnnotationInstantiationWithArray.kt");
}
@Test
@TestMetadata("annotationJvmHashCode.kt")
public void testAnnotationJvmHashCode() throws Exception {
@@ -534,6 +534,12 @@ public class FirPsiBlackBoxCodegenTestGenerated extends AbstractFirPsiBlackBoxCo
runTest("compiler/testData/codegen/box/annotations/instances/annotationInstancesEmptyDefaultLowered.kt");
}
@Test
@TestMetadata("AnnotationInstantiationWithArray.kt")
public void testAnnotationInstantiationWithArray() throws Exception {
runTest("compiler/testData/codegen/box/annotations/instances/AnnotationInstantiationWithArray.kt");
}
@Test
@TestMetadata("annotationJvmHashCode.kt")
public void testAnnotationJvmHashCode() throws Exception {
@@ -7,18 +7,11 @@ package org.jetbrains.kotlin.fir.java.deserialization
import org.jetbrains.kotlin.SpecialJvmAnnotations
import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.declarations.isJavaOrEnhancement
import org.jetbrains.kotlin.fir.deserialization.toQualifiedPropertyAccessExpression
import org.jetbrains.kotlin.fir.expressions.*
import org.jetbrains.kotlin.fir.expressions.builder.*
import org.jetbrains.kotlin.fir.java.createConstantOrError
import org.jetbrains.kotlin.fir.languageVersionSettings
import org.jetbrains.kotlin.fir.resolve.ScopeSession
import org.jetbrains.kotlin.fir.resolve.providers.getRegularClassSymbolByClassId
import org.jetbrains.kotlin.fir.resolve.providers.symbolProvider
import org.jetbrains.kotlin.fir.scopes.getProperties
import org.jetbrains.kotlin.fir.scopes.impl.declaredMemberScope
import org.jetbrains.kotlin.fir.scopes.unsubstitutedScope
import org.jetbrains.kotlin.fir.symbols.ConeClassLikeLookupTag
import org.jetbrains.kotlin.fir.types.*
import org.jetbrains.kotlin.fir.types.builder.buildResolvedTypeRef
@@ -99,10 +92,22 @@ internal class AnnotationsLoader(private val session: FirSession, private val ko
override fun visitEnd() {
visitExpression(name, buildArrayLiteral {
@OptIn(UnresolvedExpressionTypeAccess::class)
// 1. Calculate array literal type using its element, if any
// 2. If array literal is empty, try to "guess" type (works only for default values)
// 3. If both ways don't work, use Array<Any> as an approximation; later FIR2IR will calculate more precise type
// See KT-62598
// Note: we suppose that (1) can be dropped without real semantic changes;
// in this case array literal argument types will be always Array<Any> at FIR level (even for non-empty literals),
// but at IR level we will still have a real array type, like Array<String> or IntArray
// Maybe we can drop also (2), see KT-62929, with the same consequences
// Anyway, FIR provides no guarantees on having exact type of deserialized array literals in annotations,
// including non-empty ones.
elements.firstOrNull()?.coneTypeOrNull?.createOutArrayType()?.let {
coneTypeOrNull = it
} ?: guessArrayTypeIfNeeded(name, elements)?.let {
coneTypeOrNull = it.coneTypeOrNull
} ?: run {
coneTypeOrNull = StandardClassIds.Any.constructClassLikeType().createOutArrayType()
}
argumentList = buildArgumentList {
arguments += elements
@@ -136,7 +141,6 @@ internal class AnnotationsLoader(private val session: FirSession, private val ko
return object : AnnotationsLoaderVisitorImpl(enumEntryReferenceCreator) {
private val argumentMap = mutableMapOf<Name, FirExpression>()
private val scopeSession: ScopeSession = ScopeSession()
override fun visitExpression(name: Name?, expr: FirExpression) {
if (name != null) argumentMap[name] = expr
@@ -145,21 +149,9 @@ internal class AnnotationsLoader(private val session: FirSession, private val ko
override val visitNullNames: Boolean = false
override fun guessArrayTypeIfNeeded(name: Name?, arrayOfElements: List<FirExpression>): FirTypeRef? {
// Needed if we load a default value which is another annotation that has array value in it. e.g.:
// To instantiate Deprecated() we need a default value for ReplaceWith() that has imports: Array<String> with default value [].
if (name == null) return null
// Note: generally we are not allowed to resolve anything, as this is might lead to recursive resolve problems
// However, K1 deserializer did exactly the same and no issues were reported.
val classSymbol = session.symbolProvider.getRegularClassSymbolByClassId(annotationClassId) ?: return null
// We need to enhance java classes, but we can't call unsubstitutedScope unconditionally because
// for Kotlin types, it will resolve the class to the SUPER_TYPES phase which can lead to a contract violation.
val scope = if (classSymbol.isJavaOrEnhancement) {
classSymbol.unsubstitutedScope(session, scopeSession, withForcedTypeCalculator = false, memberRequiredPhase = null)
} else {
classSymbol.declaredMemberScope(session, memberRequiredPhase = null)
}
val propS = scope.getProperties(name).firstOrNull()
return propS?.resolvedReturnTypeRef
// Array<Any> will be created, later FIR2IR will use more precise type
// See KT-62598
return null
}
override fun visitEnd() {
@@ -0,0 +1,110 @@
Module: lib
FILE fqName:a fileName:/AnnotationInstantiationWithArrayLib.kt
CLASS ANNOTATION_CLASS name:Outer modality:OPEN visibility:public superTypes:[kotlin.Annotation]
$this: VALUE_PARAMETER INSTANCE_RECEIVER name:<this> type:a.Outer
CONSTRUCTOR visibility:public <> (array:kotlin.Array<a.Outer.Inner>) returnType:a.Outer [primary]
VALUE_PARAMETER name:array index:0 type:kotlin.Array<a.Outer.Inner>
EXPRESSION_BODY
VARARG type=kotlin.Array<a.Outer.Inner> varargElementType=a.Outer.Inner
CONSTRUCTOR_CALL 'public constructor <init> (v: kotlin.IntArray) declared in a.Outer.Inner' type=a.Outer.Inner origin=null
v: VARARG type=kotlin.IntArray varargElementType=kotlin.Int
CONST Int type=kotlin.Int value=1
CONSTRUCTOR_CALL 'public constructor <init> (v: kotlin.IntArray) declared in a.Outer.Inner' type=a.Outer.Inner origin=null
v: VARARG type=kotlin.IntArray varargElementType=kotlin.Int
CONST Int type=kotlin.Int value=2
CONSTRUCTOR_CALL 'public constructor <init> (v: kotlin.IntArray) declared in a.Outer.Inner' type=a.Outer.Inner origin=null
v: VARARG type=kotlin.IntArray varargElementType=kotlin.Int
BLOCK_BODY
DELEGATING_CONSTRUCTOR_CALL 'public constructor <init> () declared in kotlin.Any'
INSTANCE_INITIALIZER_CALL classDescriptor='CLASS ANNOTATION_CLASS name:Outer modality:OPEN visibility:public superTypes:[kotlin.Annotation]'
PROPERTY name:array visibility:public modality:FINAL [val]
FIELD PROPERTY_BACKING_FIELD name:array type:kotlin.Array<a.Outer.Inner> visibility:private [final]
EXPRESSION_BODY
GET_VAR 'array: kotlin.Array<a.Outer.Inner> declared in a.Outer.<init>' type=kotlin.Array<a.Outer.Inner> origin=INITIALIZE_PROPERTY_FROM_PARAMETER
FUN DEFAULT_PROPERTY_ACCESSOR name:<get-array> visibility:public modality:FINAL <> ($this:a.Outer) returnType:kotlin.Array<a.Outer.Inner>
correspondingProperty: PROPERTY name:array visibility:public modality:FINAL [val]
$this: VALUE_PARAMETER name:<this> type:a.Outer
BLOCK_BODY
RETURN type=kotlin.Nothing from='public final fun <get-array> (): kotlin.Array<a.Outer.Inner> declared in a.Outer'
GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:array type:kotlin.Array<a.Outer.Inner> visibility:private [final]' type=kotlin.Array<a.Outer.Inner> origin=null
receiver: GET_VAR '<this>: a.Outer declared in a.Outer.<get-array>' type=a.Outer origin=null
CLASS ANNOTATION_CLASS name:Inner modality:OPEN visibility:public superTypes:[kotlin.Annotation]
$this: VALUE_PARAMETER INSTANCE_RECEIVER name:<this> type:a.Outer.Inner
CONSTRUCTOR visibility:public <> (v:kotlin.IntArray) returnType:a.Outer.Inner [primary]
VALUE_PARAMETER name:v index:0 type:kotlin.IntArray
EXPRESSION_BODY
VARARG type=kotlin.IntArray varargElementType=kotlin.Int
BLOCK_BODY
DELEGATING_CONSTRUCTOR_CALL 'public constructor <init> () declared in kotlin.Any'
INSTANCE_INITIALIZER_CALL classDescriptor='CLASS ANNOTATION_CLASS name:Inner modality:OPEN visibility:public superTypes:[kotlin.Annotation]'
PROPERTY name:v visibility:public modality:FINAL [val]
FIELD PROPERTY_BACKING_FIELD name:v type:kotlin.IntArray visibility:private [final]
EXPRESSION_BODY
GET_VAR 'v: kotlin.IntArray declared in a.Outer.Inner.<init>' type=kotlin.IntArray origin=INITIALIZE_PROPERTY_FROM_PARAMETER
FUN DEFAULT_PROPERTY_ACCESSOR name:<get-v> visibility:public modality:FINAL <> ($this:a.Outer.Inner) returnType:kotlin.IntArray
correspondingProperty: PROPERTY name:v visibility:public modality:FINAL [val]
$this: VALUE_PARAMETER name:<this> type:a.Outer.Inner
BLOCK_BODY
RETURN type=kotlin.Nothing from='public final fun <get-v> (): kotlin.IntArray declared in a.Outer.Inner'
GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:v type:kotlin.IntArray visibility:private [final]' type=kotlin.IntArray origin=null
receiver: GET_VAR '<this>: a.Outer.Inner declared in a.Outer.Inner.<get-v>' type=a.Outer.Inner origin=null
FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean [fake_override,operator]
overridden:
public open fun equals (other: kotlin.Any?): kotlin.Boolean declared in kotlin.Annotation
$this: VALUE_PARAMETER name:<this> type:kotlin.Any
VALUE_PARAMETER name:other index:0 type:kotlin.Any?
FUN FAKE_OVERRIDE name:hashCode visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.Int [fake_override]
overridden:
public open fun hashCode (): kotlin.Int declared in kotlin.Annotation
$this: VALUE_PARAMETER name:<this> type:kotlin.Any
FUN FAKE_OVERRIDE name:toString visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.String [fake_override]
overridden:
public open fun toString (): kotlin.String declared in kotlin.Annotation
$this: VALUE_PARAMETER name:<this> type:kotlin.Any
FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean [fake_override,operator]
overridden:
public open fun equals (other: kotlin.Any?): kotlin.Boolean declared in kotlin.Annotation
$this: VALUE_PARAMETER name:<this> type:kotlin.Any
VALUE_PARAMETER name:other index:0 type:kotlin.Any?
FUN FAKE_OVERRIDE name:hashCode visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.Int [fake_override]
overridden:
public open fun hashCode (): kotlin.Int declared in kotlin.Annotation
$this: VALUE_PARAMETER name:<this> type:kotlin.Any
FUN FAKE_OVERRIDE name:toString visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.String [fake_override]
overridden:
public open fun toString (): kotlin.String declared in kotlin.Annotation
$this: VALUE_PARAMETER name:<this> type:kotlin.Any
Module: app
FILE fqName:test fileName:/AnnotationInstantiationWithArrayApp.kt
CLASS CLASS name:C modality:FINAL visibility:public superTypes:[kotlin.Any]
$this: VALUE_PARAMETER INSTANCE_RECEIVER name:<this> type:test.C
CONSTRUCTOR visibility:public <> () returnType:test.C [primary]
BLOCK_BODY
DELEGATING_CONSTRUCTOR_CALL 'public constructor <init> () declared in kotlin.Any'
INSTANCE_INITIALIZER_CALL classDescriptor='CLASS CLASS name:C modality:FINAL visibility:public superTypes:[kotlin.Any]'
FUN name:six visibility:public modality:FINAL <> ($this:test.C) returnType:a.Outer
$this: VALUE_PARAMETER name:<this> type:test.C
BLOCK_BODY
RETURN type=kotlin.Nothing from='public final fun six (): a.Outer declared in test.C'
CONSTRUCTOR_CALL 'public constructor <init> (array: kotlin.Array<a.Outer.Inner>) declared in a.Outer' type=a.Outer origin=null
FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean [fake_override,operator]
overridden:
public open fun equals (other: kotlin.Any?): kotlin.Boolean declared in kotlin.Any
$this: VALUE_PARAMETER name:<this> type:kotlin.Any
VALUE_PARAMETER name:other index:0 type:kotlin.Any?
FUN FAKE_OVERRIDE name:hashCode visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.Int [fake_override]
overridden:
public open fun hashCode (): kotlin.Int declared in kotlin.Any
$this: VALUE_PARAMETER name:<this> type:kotlin.Any
FUN FAKE_OVERRIDE name:toString visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.String [fake_override]
overridden:
public open fun toString (): kotlin.String declared in kotlin.Any
$this: VALUE_PARAMETER name:<this> type:kotlin.Any
FUN name:box visibility:public modality:FINAL <> () returnType:kotlin.String
BLOCK_BODY
TYPE_OP type=kotlin.Unit origin=IMPLICIT_COERCION_TO_UNIT typeOperand=kotlin.Unit
CALL 'public open fun toString (): kotlin.String declared in a.Outer' type=kotlin.String origin=null
$this: CALL 'public final fun six (): a.Outer declared in test.C' type=a.Outer origin=null
$this: CONSTRUCTOR_CALL 'public constructor <init> () declared in test.C' type=test.C origin=null
RETURN type=kotlin.Nothing from='public final fun box (): kotlin.String declared in test'
CONST String type=kotlin.String value="OK"
@@ -0,0 +1,33 @@
// TARGET_BACKEND: JVM_IR
// FIR_IDENTICAL
// DUMP_IR
// WITH_STDLIB
// ISSUE: KT-62598
// This test is a simplified version of annotations/instances/multimoduleCreation.kt with potential deserialized annotation resolve problems
// MODULE: lib
// FILE: AnnotationInstantiationWithArrayLib.kt
package a
annotation class Outer(
val array: Array<Inner> = [Inner([1]), Inner([2]), Inner([])]
) {
annotation class Inner(val v: IntArray = [])
}
// MODULE: app(lib)
// FILE: AnnotationInstantiationWithArrayApp.kt
package test
import a.*
class C {
fun six(): Outer = Outer()
}
fun box(): String {
C().six().toString()
return "OK"
}
@@ -52,7 +52,6 @@ interface HolderWithEmpty {
import Holder
import ByteHolder
import HolderWithDefault
// This line still provokes SOE in K2
//import HolderWithEmpty
import HolderWithEmpty
fun box() = "OK"
@@ -534,6 +534,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
runTest("compiler/testData/codegen/box/annotations/instances/annotationInstancesEmptyDefaultLowered.kt");
}
@Test
@TestMetadata("AnnotationInstantiationWithArray.kt")
public void testAnnotationInstantiationWithArray() throws Exception {
runTest("compiler/testData/codegen/box/annotations/instances/AnnotationInstantiationWithArray.kt");
}
@Test
@TestMetadata("annotationJvmHashCode.kt")
public void testAnnotationJvmHashCode() throws Exception {
@@ -534,6 +534,12 @@ public class IrBlackBoxCodegenWithIrInlinerTestGenerated extends AbstractIrBlack
runTest("compiler/testData/codegen/box/annotations/instances/annotationInstancesEmptyDefaultLowered.kt");
}
@Test
@TestMetadata("AnnotationInstantiationWithArray.kt")
public void testAnnotationInstantiationWithArray() throws Exception {
runTest("compiler/testData/codegen/box/annotations/instances/AnnotationInstantiationWithArray.kt");
}
@Test
@TestMetadata("annotationJvmHashCode.kt")
public void testAnnotationJvmHashCode() throws Exception {
@@ -483,6 +483,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
runTest("compiler/testData/codegen/box/annotations/instances/annotationInstancesEmptyDefaultLowered.kt");
}
@TestMetadata("AnnotationInstantiationWithArray.kt")
public void testAnnotationInstantiationWithArray() throws Exception {
runTest("compiler/testData/codegen/box/annotations/instances/AnnotationInstantiationWithArray.kt");
}
@TestMetadata("annotationJvmHashCode.kt")
public void testAnnotationJvmHashCode() throws Exception {
runTest("compiler/testData/codegen/box/annotations/instances/annotationJvmHashCode.kt");