diff --git a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/LLFirBlackBoxCodegenBasedTestGenerated.java b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/LLFirBlackBoxCodegenBasedTestGenerated.java index 90eb4324cb8..f98c4e5dbeb 100644 --- a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/LLFirBlackBoxCodegenBasedTestGenerated.java +++ b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/LLFirBlackBoxCodegenBasedTestGenerated.java @@ -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 { diff --git a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/LLFirReversedBlackBoxCodegenBasedTestGenerated.java b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/LLFirReversedBlackBoxCodegenBasedTestGenerated.java index b19c064a1a3..71f1184e8d1 100644 --- a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/LLFirReversedBlackBoxCodegenBasedTestGenerated.java +++ b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/LLFirReversedBlackBoxCodegenBasedTestGenerated.java @@ -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 { diff --git a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/ConversionUtils.kt b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/ConversionUtils.kt index fcfa50b7fb5..509c9c0e1c8 100644 --- a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/ConversionUtils.kt +++ b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/ConversionUtils.kt @@ -774,12 +774,10 @@ fun IrActualizedResult?.extractFirDeclarations(): Set? { // 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) } /** diff --git a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrVisitor.kt b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrVisitor.kt index 89fa6e73a47..a2d800daf17 100644 --- a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrVisitor.kt +++ b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrVisitor.kt @@ -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, + // 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? diff --git a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/CallAndReferenceGenerator.kt b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/CallAndReferenceGenerator.kt index 97e067b6a0b..7fbe28fc42a 100644 --- a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/CallAndReferenceGenerator.kt +++ b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/CallAndReferenceGenerator.kt @@ -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 type + // for empty integer literal arguments. + // In this case we have to use parameter type itself which is more precise, like Array 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) { diff --git a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/lazy/Fir2IrLazyProperty.kt b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/lazy/Fir2IrLazyProperty.kt index 7475486732c..3658ed0561e 100644 --- a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/lazy/Fir2IrLazyProperty.kt +++ b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/lazy/Fir2IrLazyProperty.kt @@ -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() } diff --git a/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirLightTreeBlackBoxCodegenTestGenerated.java b/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirLightTreeBlackBoxCodegenTestGenerated.java index 2ebc34439a1..d9ca30d4bdb 100644 --- a/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirLightTreeBlackBoxCodegenTestGenerated.java +++ b/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirLightTreeBlackBoxCodegenTestGenerated.java @@ -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 { diff --git a/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirLightTreeBlackBoxCodegenWithIrFakeOverrideGeneratorTestGenerated.java b/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirLightTreeBlackBoxCodegenWithIrFakeOverrideGeneratorTestGenerated.java index 7dfadd62224..035872fe736 100644 --- a/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirLightTreeBlackBoxCodegenWithIrFakeOverrideGeneratorTestGenerated.java +++ b/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirLightTreeBlackBoxCodegenWithIrFakeOverrideGeneratorTestGenerated.java @@ -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 { diff --git a/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirPsiBlackBoxCodegenTestGenerated.java b/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirPsiBlackBoxCodegenTestGenerated.java index 0523fa4c5a2..6aca275fbf7 100644 --- a/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirPsiBlackBoxCodegenTestGenerated.java +++ b/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirPsiBlackBoxCodegenTestGenerated.java @@ -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 { diff --git a/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/deserialization/AnnotationsLoader.kt b/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/deserialization/AnnotationsLoader.kt index b6eee699ce9..a621e54b18b 100644 --- a/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/deserialization/AnnotationsLoader.kt +++ b/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/deserialization/AnnotationsLoader.kt @@ -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 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 at FIR level (even for non-empty literals), + // but at IR level we will still have a real array type, like Array 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() - 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): 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 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 will be created, later FIR2IR will use more precise type + // See KT-62598 + return null } override fun visitEnd() { diff --git a/compiler/testData/codegen/box/annotations/instances/AnnotationInstantiationWithArray.ir.txt b/compiler/testData/codegen/box/annotations/instances/AnnotationInstantiationWithArray.ir.txt new file mode 100644 index 00000000000..0b1fd24cf6e --- /dev/null +++ b/compiler/testData/codegen/box/annotations/instances/AnnotationInstantiationWithArray.ir.txt @@ -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: type:a.Outer + CONSTRUCTOR visibility:public <> (array:kotlin.Array) returnType:a.Outer [primary] + VALUE_PARAMETER name:array index:0 type:kotlin.Array + EXPRESSION_BODY + VARARG type=kotlin.Array varargElementType=a.Outer.Inner + CONSTRUCTOR_CALL 'public constructor (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 (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 (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 () 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 visibility:private [final] + EXPRESSION_BODY + GET_VAR 'array: kotlin.Array declared in a.Outer.' type=kotlin.Array origin=INITIALIZE_PROPERTY_FROM_PARAMETER + FUN DEFAULT_PROPERTY_ACCESSOR name: visibility:public modality:FINAL <> ($this:a.Outer) returnType:kotlin.Array + correspondingProperty: PROPERTY name:array visibility:public modality:FINAL [val] + $this: VALUE_PARAMETER name: type:a.Outer + BLOCK_BODY + RETURN type=kotlin.Nothing from='public final fun (): kotlin.Array declared in a.Outer' + GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:array type:kotlin.Array visibility:private [final]' type=kotlin.Array origin=null + receiver: GET_VAR ': a.Outer declared in a.Outer.' type=a.Outer origin=null + CLASS ANNOTATION_CLASS name:Inner modality:OPEN visibility:public superTypes:[kotlin.Annotation] + $this: VALUE_PARAMETER INSTANCE_RECEIVER name: 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 () 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.' type=kotlin.IntArray origin=INITIALIZE_PROPERTY_FROM_PARAMETER + FUN DEFAULT_PROPERTY_ACCESSOR name: visibility:public modality:FINAL <> ($this:a.Outer.Inner) returnType:kotlin.IntArray + correspondingProperty: PROPERTY name:v visibility:public modality:FINAL [val] + $this: VALUE_PARAMETER name: type:a.Outer.Inner + BLOCK_BODY + RETURN type=kotlin.Nothing from='public final fun (): 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 ': a.Outer.Inner declared in a.Outer.Inner.' 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: 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: 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: 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: 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: 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: 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: type:test.C + CONSTRUCTOR visibility:public <> () returnType:test.C [primary] + BLOCK_BODY + DELEGATING_CONSTRUCTOR_CALL 'public constructor () 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: type:test.C + BLOCK_BODY + RETURN type=kotlin.Nothing from='public final fun six (): a.Outer declared in test.C' + CONSTRUCTOR_CALL 'public constructor (array: kotlin.Array) 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: 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: 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: 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 () 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" diff --git a/compiler/testData/codegen/box/annotations/instances/AnnotationInstantiationWithArray.kt b/compiler/testData/codegen/box/annotations/instances/AnnotationInstantiationWithArray.kt new file mode 100644 index 00000000000..cbd7e93dc62 --- /dev/null +++ b/compiler/testData/codegen/box/annotations/instances/AnnotationInstantiationWithArray.kt @@ -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([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" +} diff --git a/compiler/testData/codegen/box/fir/StackOverflowInAnnotationLoader.kt b/compiler/testData/codegen/box/fir/StackOverflowInAnnotationLoader.kt index 707cebc0861..e670a54d715 100644 --- a/compiler/testData/codegen/box/fir/StackOverflowInAnnotationLoader.kt +++ b/compiler/testData/codegen/box/fir/StackOverflowInAnnotationLoader.kt @@ -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" diff --git a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenTestGenerated.java b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenTestGenerated.java index 259880650f6..bd6583f413a 100644 --- a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenTestGenerated.java +++ b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenTestGenerated.java @@ -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 { diff --git a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenWithIrInlinerTestGenerated.java b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenWithIrInlinerTestGenerated.java index b84279f147c..870f8d280ca 100644 --- a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenWithIrInlinerTestGenerated.java +++ b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenWithIrInlinerTestGenerated.java @@ -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 { diff --git a/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java b/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java index 9022fff780c..9feb71498f1 100644 --- a/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java +++ b/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java @@ -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");