From e52a41059969a6fe530402acbc4181fedd531cb3 Mon Sep 17 00:00:00 2001 From: Ivan Kochurkin Date: Wed, 15 Sep 2021 19:28:02 +0300 Subject: [PATCH] [FIR] Initialize outer type parameters for local classes --- ...tationArgumentsResolveTransformerForIDE.kt | 4 +- ...CompilerTestFE10TestdataTestGenerated.java | 6 + .../resolve/throwableSubclass.fir.txt | 8 +- ...irOldFrontendDiagnosticsTestGenerated.java | 6 + ...DiagnosticsWithLightTreeTestGenerated.java | 6 + .../diagnostics/FirDiagnosticsList.kt | 3 + .../fir/analysis/diagnostics/FirErrors.kt | 1 + .../FirOuterClassArgumentsRequiredChecker.kt | 4 +- .../FirThrowableSubclassChecker.kt | 2 +- .../kotlin/fir/scopes/impl/FirLocalScope.kt | 27 +++-- .../converter/DeclarationsConverter.kt | 2 +- .../kotlin/fir/builder/RawFirBuilder.kt | 4 +- .../jetbrains/kotlin/fir/builder/Context.kt | 8 +- .../kotlin/fir/resolve/ResolveUtils.kt | 17 --- .../providers/impl/FirTypeResolverImpl.kt | 111 +++++++++++------- .../transformers/ScopeClassDeclaration.kt | 5 +- .../body/resolve/BodyResolveContext.kt | 72 ++++++------ .../body/resolve/FirBodyResolveTransformer.kt | 3 +- ...ControlFlowStatementsResolveTransformer.kt | 6 +- .../FirDeclarationsResolveTransformer.kt | 10 +- .../FirExpressionsResolveTransformer.kt | 2 +- .../body/resolve/LocalClassesResolution.kt | 2 +- .../FirContractResolveTransformer.kt | 4 +- .../kotlin/fir/resolve/DeclarationUtils.kt | 31 +++-- .../capturedParameters/innerLocalClass.fir.kt | 8 +- .../capturedParameters/localClass.fir.kt | 6 +- .../localWithTypeParameter.fir.kt | 4 +- .../capturedParameters/uncheckedCast.fir.kt | 6 +- .../fromSuperClassesLocal.fir.kt | 4 +- .../fromSuperClassesLocalInsideInner.fir.kt | 6 +- .../localClassWithTypeArgumentFromFunction.kt | 14 +++ ...localClassWithTypeArgumentFromFunction.txt | 31 +++++ .../tests/inner/deepInnerClass.fir.kt | 4 +- .../typealias/innerTypeAliasAsType.fir.kt | 10 +- .../tests/typealias/kt14518.fir.kt | 4 +- .../typealias/typeAliasAsBareType.fir.kt | 2 +- ...cLocalClassConstructorReference.fir.ir.txt | 32 ++--- ...cLocalClassConstructorReference.fir.kt.txt | 5 +- .../test/runners/DiagnosticTestGenerated.java | 6 + 39 files changed, 293 insertions(+), 193 deletions(-) create mode 100644 compiler/testData/diagnostics/tests/generics/localClassWithTypeArgumentFromFunction.kt create mode 100644 compiler/testData/diagnostics/tests/generics/localClassWithTypeArgumentFromFunction.txt diff --git a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/transformers/FirDesignatedAnnotationArgumentsResolveTransformerForIDE.kt b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/transformers/FirDesignatedAnnotationArgumentsResolveTransformerForIDE.kt index d02e7289f34..9acbdbe5c37 100644 --- a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/transformers/FirDesignatedAnnotationArgumentsResolveTransformerForIDE.kt +++ b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/transformers/FirDesignatedAnnotationArgumentsResolveTransformerForIDE.kt @@ -34,9 +34,7 @@ internal class FirDesignatedAnnotationArgumentsResolveTransformerForIDE( } } is FirRegularClass -> { - context.withContainingClass(nextElement) { - moveNextDeclaration(designationIterator) - } + moveNextDeclaration(designationIterator) } is FirEnumEntry -> { context.forEnumEntry { diff --git a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosisCompilerTestFE10TestdataTestGenerated.java b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosisCompilerTestFE10TestdataTestGenerated.java index 3a157e686e4..5fc6948ca6d 100644 --- a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosisCompilerTestFE10TestdataTestGenerated.java +++ b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosisCompilerTestFE10TestdataTestGenerated.java @@ -11345,6 +11345,12 @@ public class DiagnosisCompilerTestFE10TestdataTestGenerated extends AbstractDiag runTest("compiler/testData/diagnostics/tests/generics/kt9985.kt"); } + @Test + @TestMetadata("localClassWithTypeArgumentFromFunction.kt") + public void testLocalClassWithTypeArgumentFromFunction() throws Exception { + runTest("compiler/testData/diagnostics/tests/generics/localClassWithTypeArgumentFromFunction.kt"); + } + @Test @TestMetadata("Projections.kt") public void testProjections() throws Exception { diff --git a/compiler/fir/analysis-tests/testData/resolve/throwableSubclass.fir.txt b/compiler/fir/analysis-tests/testData/resolve/throwableSubclass.fir.txt index e15a7fece5c..ed4ec312038 100644 --- a/compiler/fir/analysis-tests/testData/resolve/throwableSubclass.fir.txt +++ b/compiler/fir/analysis-tests/testData/resolve/throwableSubclass.fir.txt @@ -39,8 +39,8 @@ FILE: throwableSubclass.kt } public final fun foo(): R|kotlin/Unit| { - local final class Test7 : R|kotlin/Throwable| { - public constructor(): R|Test5.Test7| { + local final class Test7 : R|kotlin/Throwable| { + public constructor(): R|Test5.Test7| { super() } @@ -50,8 +50,8 @@ FILE: throwableSubclass.kt } public final fun topLevelFun(): R|kotlin/Unit| { - local final class Test8 : R|kotlin/Error| { - public constructor(): R|Test8| { + local final class Test8 : R|kotlin/Error| { + public constructor(): R|Test8| { super() } diff --git a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsTestGenerated.java b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsTestGenerated.java index 2ef9f7b92bd..134eebd47fe 100644 --- a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsTestGenerated.java +++ b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsTestGenerated.java @@ -11345,6 +11345,12 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirDiagnosti runTest("compiler/testData/diagnostics/tests/generics/kt9985.kt"); } + @Test + @TestMetadata("localClassWithTypeArgumentFromFunction.kt") + public void testLocalClassWithTypeArgumentFromFunction() throws Exception { + runTest("compiler/testData/diagnostics/tests/generics/localClassWithTypeArgumentFromFunction.kt"); + } + @Test @TestMetadata("Projections.kt") public void testProjections() throws Exception { diff --git a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsWithLightTreeTestGenerated.java b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsWithLightTreeTestGenerated.java index 767f8d451e3..85df3275aa7 100644 --- a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsWithLightTreeTestGenerated.java +++ b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsWithLightTreeTestGenerated.java @@ -11345,6 +11345,12 @@ public class FirOldFrontendDiagnosticsWithLightTreeTestGenerated extends Abstrac runTest("compiler/testData/diagnostics/tests/generics/kt9985.kt"); } + @Test + @TestMetadata("localClassWithTypeArgumentFromFunction.kt") + public void testLocalClassWithTypeArgumentFromFunction() throws Exception { + runTest("compiler/testData/diagnostics/tests/generics/localClassWithTypeArgumentFromFunction.kt"); + } + @Test @TestMetadata("Projections.kt") public void testProjections() throws Exception { diff --git a/compiler/fir/checkers/checkers-component-generator/src/org/jetbrains/kotlin/fir/checkers/generator/diagnostics/FirDiagnosticsList.kt b/compiler/fir/checkers/checkers-component-generator/src/org/jetbrains/kotlin/fir/checkers/generator/diagnostics/FirDiagnosticsList.kt index a8bf1c8efd8..a54d4e66e0e 100644 --- a/compiler/fir/checkers/checkers-component-generator/src/org/jetbrains/kotlin/fir/checkers/generator/diagnostics/FirDiagnosticsList.kt +++ b/compiler/fir/checkers/checkers-component-generator/src/org/jetbrains/kotlin/fir/checkers/generator/diagnostics/FirDiagnosticsList.kt @@ -1102,6 +1102,9 @@ object DIAGNOSTICS_LIST : DiagnosticList("FirErrors") { } val CASTS_AND_IS_CHECKS by object : DiagnosticGroup("Casts and is-checks") { + val CANNOT_CHECK_FOR_ERASED by error { + parameter("type") + } val USELESS_CAST by warning(PositioningStrategy.AS_TYPE) val USELESS_IS_CHECK by warning { parameter("compileTimeCheckResult") diff --git a/compiler/fir/checkers/gen/org/jetbrains/kotlin/fir/analysis/diagnostics/FirErrors.kt b/compiler/fir/checkers/gen/org/jetbrains/kotlin/fir/analysis/diagnostics/FirErrors.kt index c15ad1123a5..b73de1a344e 100644 --- a/compiler/fir/checkers/gen/org/jetbrains/kotlin/fir/analysis/diagnostics/FirErrors.kt +++ b/compiler/fir/checkers/gen/org/jetbrains/kotlin/fir/analysis/diagnostics/FirErrors.kt @@ -590,6 +590,7 @@ object FirErrors { val USELESS_ELVIS_RIGHT_IS_NULL by warning0(SourceElementPositioningStrategies.USELESS_ELVIS) // Casts and is-checks + val CANNOT_CHECK_FOR_ERASED by error1() val USELESS_CAST by warning0(SourceElementPositioningStrategies.AS_TYPE) val USELESS_IS_CHECK by warning1() val IS_ENUM_ENTRY by error0() diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirOuterClassArgumentsRequiredChecker.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirOuterClassArgumentsRequiredChecker.kt index c1598b05d8e..1b9801215e4 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirOuterClassArgumentsRequiredChecker.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirOuterClassArgumentsRequiredChecker.kt @@ -11,7 +11,7 @@ import org.jetbrains.kotlin.diagnostics.DiagnosticReporter import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors import org.jetbrains.kotlin.diagnostics.reportOn import org.jetbrains.kotlin.fir.declarations.FirRegularClass -import org.jetbrains.kotlin.fir.resolve.isValidTypeParameterFromOuterClass +import org.jetbrains.kotlin.fir.resolve.isValidTypeParameterFromOuterDeclaration import org.jetbrains.kotlin.fir.resolve.toSymbol import org.jetbrains.kotlin.fir.resolve.toTypeProjections import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol @@ -47,7 +47,7 @@ object FirOuterClassArgumentsRequiredChecker : FirRegularClassChecker() { for (index in typeArguments.size until typeParameters.size) { val typeParameter = typeParameters[index] - if (!isValidTypeParameterFromOuterClass(typeParameter, declaration, context.session)) { + if (!isValidTypeParameterFromOuterDeclaration(typeParameter, declaration, context.session)) { val outerClass = typeParameter.containingDeclarationSymbol as? FirRegularClassSymbol ?: break reporter.reportOn(typeRef.source, FirErrors.OUTER_CLASS_ARGUMENTS_REQUIRED, outerClass, context) break diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirThrowableSubclassChecker.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirThrowableSubclassChecker.kt index b455aab32e1..883b657af5c 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirThrowableSubclassChecker.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirThrowableSubclassChecker.kt @@ -26,7 +26,7 @@ object FirThrowableSubclassChecker : FirClassChecker() { reporter.reportOn(declaration.typeParameters.firstOrNull()?.source, FirErrors.GENERIC_THROWABLE_SUBCLASS, context) val source = when { - (declaration as? FirRegularClass)?.isInner == true -> declaration.source + (declaration as? FirRegularClass)?.let { it.isInner || it.isLocal } == true -> declaration.source declaration is FirAnonymousObject -> (declaration.declarations.firstOrNull())?.source else -> null } diff --git a/compiler/fir/providers/src/org/jetbrains/kotlin/fir/scopes/impl/FirLocalScope.kt b/compiler/fir/providers/src/org/jetbrains/kotlin/fir/scopes/impl/FirLocalScope.kt index c44e8fd3622..9f4407f6e7a 100644 --- a/compiler/fir/providers/src/org/jetbrains/kotlin/fir/scopes/impl/FirLocalScope.kt +++ b/compiler/fir/providers/src/org/jetbrains/kotlin/fir/scopes/impl/FirLocalScope.kt @@ -8,11 +8,13 @@ package org.jetbrains.kotlin.fir.scopes.impl import kotlinx.collections.immutable.PersistentMap import kotlinx.collections.immutable.persistentMapOf import org.jetbrains.kotlin.builtins.StandardNames.BACKING_FIELD +import org.jetbrains.kotlin.fir.FirSession import org.jetbrains.kotlin.fir.declarations.FirProperty import org.jetbrains.kotlin.fir.declarations.FirRegularClass import org.jetbrains.kotlin.fir.declarations.FirSimpleFunction import org.jetbrains.kotlin.fir.declarations.FirVariable import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor +import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutorByMap import org.jetbrains.kotlin.fir.scopes.FirContainingNamesAwareScope import org.jetbrains.kotlin.fir.symbols.impl.FirClassifierSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirNamedFunctionSymbol @@ -24,29 +26,30 @@ import org.jetbrains.kotlin.name.Name class FirLocalScope private constructor( val properties: PersistentMap>, val functions: PersistentMultimap, - val classes: PersistentMap + val classes: PersistentMap, + val useSiteSession: FirSession ) : FirContainingNamesAwareScope() { - constructor() : this(persistentMapOf(), PersistentMultimap(), persistentMapOf()) + constructor(session: FirSession) : this(persistentMapOf(), PersistentMultimap(), persistentMapOf(), session) - fun storeClass(klass: FirRegularClass): FirLocalScope { + fun storeClass(klass: FirRegularClass, session: FirSession): FirLocalScope { return FirLocalScope( - properties, functions, classes.put(klass.name, klass.symbol) + properties, functions, classes.put(klass.name, klass.symbol), session ) } - fun storeFunction(function: FirSimpleFunction): FirLocalScope { + fun storeFunction(function: FirSimpleFunction, session: FirSession): FirLocalScope { return FirLocalScope( - properties, functions.put(function.name, function.symbol), classes + properties, functions.put(function.name, function.symbol), classes, session ) } - fun storeVariable(variable: FirVariable): FirLocalScope { + fun storeVariable(variable: FirVariable, session: FirSession): FirLocalScope { return FirLocalScope( - properties.put(variable.name, variable.symbol), functions, classes + properties.put(variable.name, variable.symbol), functions, classes, session ) } - fun storeBackingField(property: FirProperty): FirLocalScope { + fun storeBackingField(property: FirProperty, session: FirSession): FirLocalScope { val enhancedProperties = property.backingField?.symbol?.let { properties.put(BACKING_FIELD, it) } @@ -54,7 +57,8 @@ class FirLocalScope private constructor( return FirLocalScope( enhancedProperties ?: properties, functions, - classes + classes, + session ) } @@ -74,7 +78,8 @@ class FirLocalScope private constructor( override fun processClassifiersByNameWithSubstitution(name: Name, processor: (FirClassifierSymbol<*>, ConeSubstitutor) -> Unit) { val klass = classes[name] if (klass != null) { - processor(klass, ConeSubstitutor.Empty) + val substitution = klass.typeParameterSymbols.associateWith { it.toConeType() } + processor(klass, ConeSubstitutorByMap(substitution, useSiteSession)) } } diff --git a/compiler/fir/raw-fir/light-tree2fir/src/org/jetbrains/kotlin/fir/lightTree/converter/DeclarationsConverter.kt b/compiler/fir/raw-fir/light-tree2fir/src/org/jetbrains/kotlin/fir/lightTree/converter/DeclarationsConverter.kt index 495cc4cf087..af2ccd0fcea 100644 --- a/compiler/fir/raw-fir/light-tree2fir/src/org/jetbrains/kotlin/fir/lightTree/converter/DeclarationsConverter.kt +++ b/compiler/fir/raw-fir/light-tree2fir/src/org/jetbrains/kotlin/fir/lightTree/converter/DeclarationsConverter.kt @@ -436,7 +436,7 @@ class DeclarationsConverter( typeParameterList?.let { firTypeParameters += convertTypeParameters(it, typeConstraints, classSymbol) } - withCapturedTypeParameters(status.isInner, firTypeParameters) { + withCapturedTypeParameters(status.isInner || isLocal, firTypeParameters) { buildRegularClass { source = classNode.toFirSourceElement() moduleData = baseModuleData diff --git a/compiler/fir/raw-fir/psi2fir/src/org/jetbrains/kotlin/fir/builder/RawFirBuilder.kt b/compiler/fir/raw-fir/psi2fir/src/org/jetbrains/kotlin/fir/builder/RawFirBuilder.kt index 8e514926e3d..057d06c7895 100644 --- a/compiler/fir/raw-fir/psi2fir/src/org/jetbrains/kotlin/fir/builder/RawFirBuilder.kt +++ b/compiler/fir/raw-fir/psi2fir/src/org/jetbrains/kotlin/fir/builder/RawFirBuilder.kt @@ -1044,7 +1044,7 @@ open class RawFirBuilder( isExternal = classOrObject.hasModifier(EXTERNAL_KEYWORD) } - withCapturedTypeParameters(status.isInner, listOf()) { + withCapturedTypeParameters(status.isInner || isLocal, listOf()) { buildRegularClass { source = classOrObject.toFirSourceElement() moduleData = baseModuleData @@ -1060,7 +1060,7 @@ open class RawFirBuilder( context.appendOuterTypeParameters(ignoreLastLevel = true, typeParameters) context.pushFirTypeParameters( - status.isInner, + status.isInner || isLocal, typeParameters.subList(0, classOrObject.typeParameters.size) ) diff --git a/compiler/fir/raw-fir/raw-fir.common/src/org/jetbrains/kotlin/fir/builder/Context.kt b/compiler/fir/raw-fir/raw-fir.common/src/org/jetbrains/kotlin/fir/builder/Context.kt index 246d165f71f..7f7e644569c 100644 --- a/compiler/fir/raw-fir/raw-fir.common/src/org/jetbrains/kotlin/fir/builder/Context.kt +++ b/compiler/fir/raw-fir/raw-fir.common/src/org/jetbrains/kotlin/fir/builder/Context.kt @@ -49,8 +49,8 @@ class Context { val dispatchReceiverTypesStack = mutableListOf() var containerIsExpect: Boolean = false - fun pushFirTypeParameters(notNested: Boolean, parameters: List) { - capturedTypeParameters.add(StatusFirTypeParameterSymbolList(notNested, parameters.map { it.symbol })) + fun pushFirTypeParameters(isInnerOrLocal: Boolean, parameters: List) { + capturedTypeParameters.add(StatusFirTypeParameterSymbolList(isInnerOrLocal, parameters.map { it.symbol })) } fun popFirTypeParameters() { @@ -68,7 +68,7 @@ class Context { } } - if (!element.notNested) { + if (!element.isInnerOrLocal) { break } } @@ -119,5 +119,5 @@ class Context { } } - data class StatusFirTypeParameterSymbolList(val notNested: Boolean, val list: List = listOf()) + data class StatusFirTypeParameterSymbolList(val isInnerOrLocal: Boolean, val list: List = listOf()) } diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/ResolveUtils.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/ResolveUtils.kt index 38f2c98275f..f926da84264 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/ResolveUtils.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/ResolveUtils.kt @@ -466,20 +466,3 @@ fun FirFunction.getAsForbiddenNamedArgumentsTarget(session: FirSession): Forbidd // org.jetbrains.kotlin.fir.serialization.FirElementSerializer.functionProto // org.jetbrains.kotlin.fir.serialization.FirElementSerializer.constructorProto fun FirFunction.getHasStableParameterNames(session: FirSession): Boolean = getAsForbiddenNamedArgumentsTarget(session) == null - - - -fun FirClassLikeDeclaration.getActualTypeParametersCount(session: FirSession): Int { - var result = (if (this is FirTypeAlias) this.typeParameters else (this as FirClass).typeParameters).size - - if (this is FirRegularClass && !isInner) { - return result - } - - val containingClass = getContainingDeclaration(session) as? FirRegularClass - if (containingClass != null) { - result -= containingClass.typeParameters.size - } - - return result -} diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/providers/impl/FirTypeResolverImpl.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/providers/impl/FirTypeResolverImpl.kt index bdfdb7b511a..9a4bf479812 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/providers/impl/FirTypeResolverImpl.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/providers/impl/FirTypeResolverImpl.kt @@ -197,7 +197,7 @@ class FirTypeResolverImpl(private val session: FirSession) : FirTypeResolver() { symbol: FirBasedSymbol<*>?, substitutor: ConeSubstitutor?, areBareTypesAllowed: Boolean, - topDeclaration: FirRegularClass?, + topContainer: FirDeclaration?, isOperandOfIsOperator: Boolean ): ConeKotlinType { if (symbol == null || symbol !is FirClassifierSymbol<*>) { @@ -240,14 +240,25 @@ class FirTypeResolverImpl(private val session: FirSession) : FirTypeResolver() { if (!isPossibleBareType) { val actualSubstitutor = substitutor ?: ConeSubstitutor.Empty - val typeParameters = calculateTypeParameters(symbol) + val originalTypeParameters = collectTypeParameters(symbol) - val (typeParametersAlignedToQualifierParts, outerClasses) = getClassesAlignedToQualifierParts(symbol, qualifier, session) + val (typeParametersAlignedToQualifierParts, outerDeclarations) = getClassesAlignedToQualifierParts( + symbol, + qualifier, + session + ) - for ((index, typeParameter) in typeParameters.withIndex()) { + val actualTypeParametersCount = + when (symbol) { + is FirTypeAliasSymbol -> + outerDeclarations.sumOf { it?.let { d -> getActualTypeParametersCount(d) } ?: 0 } + else -> (symbol as FirClassSymbol<*>).typeParameterSymbols.size + } + + for ((typeParameterIndex, typeParameter) in originalTypeParameters.withIndex()) { val (parameterClass, qualifierPartIndex) = typeParametersAlignedToQualifierParts[typeParameter.symbol] ?: continue - if (index < typeArgumentsCount) { + if (typeParameterIndex < typeArgumentsCount) { // Check if type argument matches type parameter in respective qualifier part val qualifierPartArgumentsCount = qualifier[qualifierPartIndex].typeArgumentList.typeArguments.size createDiagnosticsIfExists( @@ -261,12 +272,18 @@ class FirTypeResolverImpl(private val session: FirSession) : FirTypeResolver() { } if (typeParameter !is FirOuterClassTypeParameterRef || - isValidTypeParameterFromOuterClass(typeParameter.symbol, topDeclaration, session) + isValidTypeParameterFromOuterDeclaration(typeParameter.symbol, topContainer, session) ) { val type = ConeTypeParameterTypeImpl(ConeTypeParameterLookupTag(typeParameter.symbol), isNullable = false) val substituted = actualSubstitutor.substituteOrNull(type) if (substituted == null) { - createDiagnosticsIfExists(parameterClass, qualifierPartIndex, symbol, typeRef)?.let { return it } + createDiagnosticsIfExists( + parameterClass, + qualifierPartIndex, + symbol, + typeRef, + qualifierPartArgumentsCount = null + )?.let { return it } } else { allTypeArguments.add(substituted) } @@ -276,15 +293,16 @@ class FirTypeResolverImpl(private val session: FirSession) : FirTypeResolver() { } // Check rest type arguments - if (typeArgumentsCount > typeParameters.size) { + if (typeArgumentsCount > actualTypeParametersCount) { for (index in qualifier.indices) { if (qualifier[index].typeArgumentList.typeArguments.isNotEmpty()) { - val parameterClass = outerClasses.elementAtOrNull(index) + val parameterClass = outerDeclarations.elementAtOrNull(index) createDiagnosticsIfExists( parameterClass, index, symbol, - typeRef + typeRef, + qualifierPartArgumentsCount = null )?.let { return it } } } @@ -304,43 +322,43 @@ class FirTypeResolverImpl(private val session: FirSession) : FirTypeResolver() { } } - private fun calculateTypeParameters(symbol: FirClassLikeSymbol<*>): List { - return if (symbol is FirTypeAliasSymbol) { - val typeAliasFir = symbol.fir - val typeAliasTypeParameters = typeAliasFir.typeParameters.toMutableList() - val fullyExpandedClass = typeAliasFir.fullyExpandedClass(session) - val newTypeParameters: MutableList + private fun collectTypeParameters(symbol: FirClassLikeSymbol<*>): List { + if (symbol is FirClassSymbol<*>) { + return symbol.fir.typeParameters + } - if (fullyExpandedClass != null) { // TODO: Should not be null, move to resolver? - val expandedTypeRef = typeAliasFir.expandedTypeRef + require(symbol is FirTypeAliasSymbol) - fun checkTypeArguments(typeArgument: ConeTypeProjection) { - when (typeArgument) { - is ConeTypeParameterType -> typeAliasTypeParameters.removeIf { it.symbol == typeArgument.lookupTag.symbol } - is ConeClassLikeType -> { - for (subTypeArgument in typeArgument.typeArguments) { - checkTypeArguments(subTypeArgument) - } - } - is ConeKotlinTypeProjection -> checkTypeArguments(typeArgument.type) - else -> { + val typeAliasFir = symbol.fir + val typeAliasTypeParameters = typeAliasFir.typeParameters.toMutableList() + val fullyExpandedClass = typeAliasFir.fullyExpandedClass(session) + val newTypeParameters = if (fullyExpandedClass != null) { // TODO: Should not be null, move to resolver? + val expandedTypeRef = typeAliasFir.expandedTypeRef + + fun checkTypeArguments(typeArgument: ConeTypeProjection) { + when (typeArgument) { + is ConeTypeParameterType -> typeAliasTypeParameters.removeIf { it.symbol == typeArgument.lookupTag.symbol } + is ConeClassLikeType -> { + for (subTypeArgument in typeArgument.typeArguments) { + checkTypeArguments(subTypeArgument) } } + is ConeKotlinTypeProjection -> checkTypeArguments(typeArgument.type) + else -> { + } } - - checkTypeArguments(expandedTypeRef.coneType) - newTypeParameters = fullyExpandedClass.typeParameters.toMutableList() - } else { - newTypeParameters = mutableListOf() } - for (typeParameter in typeAliasTypeParameters) { - newTypeParameters.add(typeParameter) - } - newTypeParameters + checkTypeArguments(expandedTypeRef.coneType) + fullyExpandedClass.typeParameters.toMutableList() } else { - (symbol as FirClassSymbol<*>).fir.typeParameters + mutableListOf() } + + for (typeParameter in typeAliasTypeParameters) { + newTypeParameters.add(typeParameter) + } + return newTypeParameters } @OptIn(SymbolInternals::class) @@ -373,8 +391,10 @@ class FirTypeResolverImpl(private val session: FirSession) : FirTypeResolver() { for (index in reversedOuterClasses.indices) { currentClassLikeDeclaration = reversedOuterClasses[index] - val typeParameters = if (currentClassLikeDeclaration is FirTypeAlias) currentClassLikeDeclaration.typeParameters else - (currentClassLikeDeclaration as? FirClass)?.typeParameters + val typeParameters = when (currentClassLikeDeclaration) { + is FirTypeAlias -> currentClassLikeDeclaration.typeParameters + else -> (currentClassLikeDeclaration as? FirClass)?.typeParameters + } if (currentClassLikeDeclaration != null && typeParameters != null) { for (typeParameter in typeParameters) { val typeParameterSymbol = typeParameter.symbol @@ -404,10 +424,10 @@ class FirTypeResolverImpl(private val session: FirSession) : FirTypeResolver() { qualifierPartIndex: Int, symbol: FirClassLikeSymbol<*>, userTypeRef: FirUserTypeRef, - qualifierPartArgumentsCount: Int? = null + qualifierPartArgumentsCount: Int? ): ConeClassErrorType? { // TODO: It should be TYPE_ARGUMENTS_NOT_ALLOWED diagnostics when parameterClass is null - val actualTypeParametersCount = (parameterClass ?: symbol.fir).getActualTypeParametersCount(session) + val actualTypeParametersCount = getActualTypeParametersCount(parameterClass ?: symbol.fir) if (qualifierPartArgumentsCount == null || actualTypeParametersCount != qualifierPartArgumentsCount) { val source = getTypeArgumentsOrNameSource(userTypeRef, qualifierPartIndex) @@ -425,6 +445,11 @@ class FirTypeResolverImpl(private val session: FirSession) : FirTypeResolver() { return null } + private fun getActualTypeParametersCount(element: FirClassLikeDeclaration): Int { + return (element as FirTypeParameterRefsOwner).typeParameters + .count { it !is FirOuterClassTypeParameterRef } + } + private fun getTypeArgumentsOrNameSource(typeRef: FirUserTypeRef, qualifierIndex: Int?): KtSourceElement? { val qualifierPart = if (qualifierIndex != null) typeRef.qualifier.elementAtOrNull(qualifierIndex) else null val typeArgumentsList = qualifierPart?.typeArgumentList @@ -475,7 +500,7 @@ class FirTypeResolverImpl(private val session: FirSession) : FirTypeResolver() { symbol, substitutor, areBareTypesAllowed, - scopeClassDeclaration.containingDeclarations.lastOrNull(), + scopeClassDeclaration.topContainer ?: scopeClassDeclaration.containingDeclarations.lastOrNull(), isOperandOfIsOperator ) } diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/ScopeClassDeclaration.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/ScopeClassDeclaration.kt index 15ed8c7fe1c..e1e557d849a 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/ScopeClassDeclaration.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/ScopeClassDeclaration.kt @@ -5,10 +5,11 @@ package org.jetbrains.kotlin.fir.resolve.transformers -import org.jetbrains.kotlin.fir.declarations.FirRegularClass +import org.jetbrains.kotlin.fir.declarations.FirDeclaration import org.jetbrains.kotlin.fir.scopes.FirScope data class ScopeClassDeclaration( val scopes: List, - val containingDeclarations: List + val containingDeclarations: List, + val topContainer: FirDeclaration? = null ) \ No newline at end of file diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/BodyResolveContext.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/BodyResolveContext.kt index b06c63f41a7..fc802f3f393 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/BodyResolveContext.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/BodyResolveContext.kt @@ -7,6 +7,7 @@ package org.jetbrains.kotlin.fir.resolve.transformers.body.resolve import org.jetbrains.kotlin.KtFakeSourceElementKind import org.jetbrains.kotlin.descriptors.ClassKind +import org.jetbrains.kotlin.fir.FirSession import org.jetbrains.kotlin.fir.PrivateForInline import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.declarations.impl.FirDefaultPropertyAccessor @@ -211,8 +212,8 @@ class BodyResolveContext( } @PrivateForInline - fun storeFunction(function: FirSimpleFunction) { - updateLastScope { storeFunction(function) } + fun storeFunction(function: FirSimpleFunction, session: FirSession) { + updateLastScope { storeFunction(function, session) } } @PrivateForInline @@ -251,8 +252,8 @@ class BodyResolveContext( return FirMemberTypeParameterScope(this) } - fun buildSecondaryConstructorParametersScope(constructor: FirConstructor): FirLocalScope = - constructor.valueParameters.fold(FirLocalScope()) { acc, param -> acc.storeVariable(param) } + fun buildSecondaryConstructorParametersScope(constructor: FirConstructor, session: FirSession): FirLocalScope = + constructor.valueParameters.fold(FirLocalScope(session)) { acc, param -> acc.storeVariable(param, session) } @PrivateForInline fun addInaccessibleImplicitReceiverValue( @@ -272,8 +273,8 @@ class BodyResolveContext( } @PrivateForInline - private fun storeBackingField(property: FirProperty) { - updateLastScope { storeBackingField(property) } + private fun storeBackingField(property: FirProperty, session: FirSession) { + updateLastScope { storeBackingField(property, session) } } // ANALYSIS PUBLIC API @@ -285,14 +286,14 @@ class BodyResolveContext( towerDataContextsForClassParts.primaryConstructorAllParametersScope @OptIn(PrivateForInline::class) - fun storeClassIfNotNested(klass: FirRegularClass) { + fun storeClassIfNotNested(klass: FirRegularClass, session: FirSession) { if (containerIfAny is FirClass) return - updateLastScope { storeClass(klass) } + updateLastScope { storeClass(klass, session) } } @OptIn(PrivateForInline::class) - fun storeVariable(variable: FirVariable) { - updateLastScope { storeVariable(variable) } + fun storeVariable(variable: FirVariable, session: FirSession) { + updateLastScope { storeVariable(variable, session) } } @OptIn(PrivateForInline::class) @@ -368,7 +369,7 @@ class BodyResolveContext( forContracts: Boolean = false, f: () -> T ): T { - storeClassIfNotNested(regularClass) + storeClassIfNotNested(regularClass, holder.session) if (forContracts) { return withTypeParametersOf(regularClass) { withContainerClass(regularClass, f) @@ -452,7 +453,7 @@ class BodyResolveContext( val constructor = (owner as? FirRegularClass)?.declarations?.firstOrNull { it is FirConstructor } as? FirConstructor val (primaryConstructorPureParametersScope, primaryConstructorAllParametersScope) = if (constructor?.isPrimary == true) { - constructor.scopesWithPrimaryConstructorParameters(owner) + constructor.scopesWithPrimaryConstructorParameters(owner, holder.session) } else { null to null } @@ -473,16 +474,17 @@ class BodyResolveContext( } private fun FirConstructor.scopesWithPrimaryConstructorParameters( - ownerClass: FirClass + ownerClass: FirClass, + session: FirSession ): Pair { - var parameterScope = FirLocalScope() - var allScope = FirLocalScope() + var parameterScope = FirLocalScope(session) + var allScope = FirLocalScope(session) val properties = ownerClass.declarations.filterIsInstance().associateBy { it.name } for (parameter in valueParameters) { - allScope = allScope.storeVariable(parameter) + allScope = allScope.storeVariable(parameter, session) val property = properties[parameter.name] if (property?.source?.kind != KtFakeSourceElementKind.PropertyFromParameter) { - parameterScope = parameterScope.storeVariable(parameter) + parameterScope = parameterScope.storeVariable(parameter, session) } } return parameterScope to allScope @@ -491,10 +493,11 @@ class BodyResolveContext( @OptIn(PrivateForInline::class) inline fun withSimpleFunction( simpleFunction: FirSimpleFunction, + session: FirSession, f: () -> T ): T { if (containerIfAny !is FirClass) { - storeFunction(simpleFunction) + storeFunction(simpleFunction, session) } return withTypeParametersOf(simpleFunction) { @@ -509,13 +512,13 @@ class BodyResolveContext( f: () -> T ): T { return withTowerDataCleanup { - addLocalScope(FirLocalScope()) + addLocalScope(FirLocalScope(holder.session)) if (function is FirSimpleFunction) { // Make all value parameters available in the local scope so that even one parameter that refers to another parameter, // which may not be initialized yet, can be resolved. [FirFunctionParameterChecker] will detect and report an error // if an uninitialized parameter is accessed by a preceding parameter. for (parameter in function.valueParameters) { - storeVariable(parameter) + storeVariable(parameter, holder.session) } val receiverTypeRef = function.receiverTypeRef withLabelAndReceiverType(function.name, function, receiverTypeRef?.coneType, holder, f) @@ -528,6 +531,7 @@ class BodyResolveContext( @OptIn(PrivateForInline::class) fun forConstructorBody( constructor: FirConstructor, + session: FirSession, f: () -> T ): T { return if (constructor.isPrimary) { @@ -542,7 +546,7 @@ class BodyResolveContext( } } else { withTowerDataCleanup { - addLocalScope(buildSecondaryConstructorParametersScope(constructor)) + addLocalScope(buildSecondaryConstructorParametersScope(constructor, session)) f() } } @@ -562,7 +566,7 @@ class BodyResolveContext( return f() } return withTowerDataCleanup { - addLocalScope(FirLocalScope()) + addLocalScope(FirLocalScope(holder.session)) val receiverTypeRef = anonymousFunction.receiverTypeRef val labelName = anonymousFunction.label?.name?.let { Name.identifier(it) } withContainer(anonymousFunction) { @@ -600,11 +604,12 @@ class BodyResolveContext( @OptIn(PrivateForInline::class) inline fun withAnonymousInitializer( anonymousInitializer: FirAnonymousInitializer, + session: FirSession, f: () -> T ): T { return withTowerDataCleanup { getPrimaryConstructorPureParametersScope()?.let { addLocalScope(it) } - addLocalScope(FirLocalScope()) + addLocalScope(FirLocalScope(session)) withContainer(anonymousInitializer, f) } } @@ -612,10 +617,11 @@ class BodyResolveContext( @OptIn(PrivateForInline::class) inline fun withValueParameter( valueParameter: FirValueParameter, + session: FirSession, f: () -> T ): T { if (!valueParameter.name.isSpecial || valueParameter.name != UNDERSCORE_FOR_UNUSED_VAR) { - storeVariable(valueParameter) + storeVariable(valueParameter, session) } return withContainer(valueParameter, f) } @@ -641,17 +647,17 @@ class BodyResolveContext( if (accessor is FirDefaultPropertyAccessor || accessor.body == null) { return if (accessor.isGetter) withContainer(accessor, f) else withTowerDataCleanup { - addLocalScope(FirLocalScope()) + addLocalScope(FirLocalScope(holder.session)) withContainer(accessor, f) } } return withTowerDataCleanup { val receiverTypeRef = property.receiverTypeRef - addLocalScope(FirLocalScope()) + addLocalScope(FirLocalScope(holder.session)) if (!forContracts && receiverTypeRef == null && property.returnTypeRef !is FirImplicitTypeRef && !property.isLocal && property.delegate == null ) { - storeBackingField(property) + storeBackingField(property, holder.session) } withContainer(accessor) { withLabelAndReceiverType(property.name, property, receiverTypeRef?.coneType, holder, f) @@ -731,8 +737,8 @@ class BodyResolveContext( } else { addInaccessibleImplicitReceiverValue(owningClass, holder) withTowerDataCleanup { - addLocalScope(buildSecondaryConstructorParametersScope(constructor)) - constructor.valueParameters.forEach { storeVariable(it) } + addLocalScope(buildSecondaryConstructorParametersScope(constructor, holder.session)) + constructor.valueParameters.forEach { storeVariable(it, holder.session) } f() } } @@ -747,15 +753,15 @@ class BodyResolveContext( towerDataContextForCallableReferences.remove(callableReferenceAccess) } - fun withWhenExpression(whenExpression: FirWhenExpression, f: () -> T): T { + fun withWhenExpression(whenExpression: FirWhenExpression, session: FirSession, f: () -> T): T { if (whenExpression.subjectVariable == null) return f() - return forBlock(f) + return forBlock(session, f) } @OptIn(PrivateForInline::class) - inline fun forBlock(f: () -> T): T { + inline fun forBlock(session: FirSession, f: () -> T): T { return withTowerDataCleanup { - addLocalScope(FirLocalScope()) + addLocalScope(FirLocalScope(session)) f() } } diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirBodyResolveTransformer.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirBodyResolveTransformer.kt index 9a109977605..47b1126e659 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirBodyResolveTransformer.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirBodyResolveTransformer.kt @@ -70,7 +70,8 @@ open class FirBodyResolveTransformer( typeRef, ScopeClassDeclaration( components.createCurrentScopeList(), - context.containingClassDeclarations + context.containingClassDeclarations, + context.containers.lastOrNull { it is FirTypeParameterRefsOwner && it !is FirAnonymousFunction } ) ) } diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirControlFlowStatementsResolveTransformer.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirControlFlowStatementsResolveTransformer.kt index 0afd9abd7b7..b776737b613 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirControlFlowStatementsResolveTransformer.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirControlFlowStatementsResolveTransformer.kt @@ -41,7 +41,7 @@ class FirControlFlowStatementsResolveTransformer(transformer: FirBodyResolveTran override fun transformDoWhileLoop(doWhileLoop: FirDoWhileLoop, data: ResolutionMode): FirStatement { // Do-while has a specific scope structure (its block and condition effectively share the scope) - return context.forBlock { + return context.forBlock(session) { val context = ResolutionMode.ContextIndependent doWhileLoop.also(dataFlowAnalyzer::enterDoWhileLoop) .also { @@ -61,7 +61,7 @@ class FirControlFlowStatementsResolveTransformer(transformer: FirBodyResolveTran } whenExpression.annotations.forEach { it.accept(this, data) } dataFlowAnalyzer.enterWhenExpression(whenExpression) - return context.withWhenExpression(whenExpression) with@{ + return context.withWhenExpression(whenExpression, session) with@{ @Suppress("NAME_SHADOWING") var whenExpression = whenExpression.transformSubject(transformer, ResolutionMode.ContextIndependent) @@ -164,7 +164,7 @@ class FirControlFlowStatementsResolveTransformer(transformer: FirBodyResolveTran override fun transformCatch(catch: FirCatch, data: ResolutionMode): FirCatch { dataFlowAnalyzer.enterCatchClause(catch) catch.parameter.transformReturnTypeRef(transformer, ResolutionMode.ContextIndependent) - return context.forBlock { + return context.forBlock(session) { catch.transformParameter(transformer, ResolutionMode.ContextIndependent) catch.transformBlock(transformer, ResolutionMode.ContextDependent) }.also { dataFlowAnalyzer.exitCatchClause(it) } diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirDeclarationsResolveTransformer.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirDeclarationsResolveTransformer.kt index 3e3dd983949..45a94d2907c 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirDeclarationsResolveTransformer.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirDeclarationsResolveTransformer.kt @@ -330,7 +330,7 @@ open class FirDeclarationsResolveTransformer(transformer: FirBodyResolveTransfor variable.transformAccessors() } variable.transformOtherChildren(transformer, ResolutionMode.ContextIndependent) - context.storeVariable(variable) + context.storeVariable(variable, session) dataFlowAnalyzer.exitLocalVariableDeclaration(variable, hadExplicitType) return variable } @@ -540,7 +540,7 @@ open class FirDeclarationsResolveTransformer(transformer: FirBodyResolveTransfor doTransformTypeParameters(simpleFunction) val containingDeclaration = context.containerIfAny - return context.withSimpleFunction(simpleFunction) { + return context.withSimpleFunction(simpleFunction, session) { // TODO: I think it worth creating something like runAllPhasesForLocalFunction if (containingDeclaration != null && containingDeclaration !is FirClass) { // For class members everything should be already prepared @@ -635,7 +635,7 @@ open class FirDeclarationsResolveTransformer(transformer: FirBodyResolveTransfor constructor.transformValueParameters(transformer, data) } constructor.transformDelegatedConstructor(transformer, data) - context.forConstructorBody(constructor) { + context.forConstructorBody(constructor, session) { constructor.transformBody(transformer, data) } } @@ -651,7 +651,7 @@ open class FirDeclarationsResolveTransformer(transformer: FirBodyResolveTransfor ): FirAnonymousInitializer { if (implicitTypeOnly) return anonymousInitializer dataFlowAnalyzer.enterInitBlock(anonymousInitializer) - return context.withAnonymousInitializer(anonymousInitializer) { + return context.withAnonymousInitializer(anonymousInitializer, session) { val result = transformDeclarationContent(anonymousInitializer, ResolutionMode.ContextIndependent) as FirAnonymousInitializer val graph = dataFlowAnalyzer.exitInitBlock(result) @@ -671,7 +671,7 @@ open class FirDeclarationsResolveTransformer(transformer: FirBodyResolveTransfor } dataFlowAnalyzer.enterValueParameter(valueParameter) - val result = context.withValueParameter(valueParameter) { + val result = context.withValueParameter(valueParameter, session) { transformDeclarationContent( valueParameter, withExpectedType(valueParameter.returnTypeRef) diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirExpressionsResolveTransformer.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirExpressionsResolveTransformer.kt index af5e8746ca2..4d3bf67d607 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirExpressionsResolveTransformer.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirExpressionsResolveTransformer.kt @@ -384,7 +384,7 @@ open class FirExpressionsResolveTransformer(transformer: FirBodyResolveTransform } override fun transformBlock(block: FirBlock, data: ResolutionMode): FirStatement { - context.forBlock { + context.forBlock(session) { transformBlockInCurrentScope(block, data) } return block diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/LocalClassesResolution.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/LocalClassesResolution.kt index 53b73c82424..99270b5dd10 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/LocalClassesResolution.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/LocalClassesResolution.kt @@ -22,7 +22,7 @@ fun F.runAllPhasesForLocalClass( ): F { if (status is FirResolvedDeclarationStatus) return this if (this is FirRegularClass) { - components.context.storeClassIfNotNested(this) + components.context.storeClassIfNotNested(this, components.session) } this.transformAnnotations(transformer, ResolutionMode.ContextIndependent) val localClassesNavigationInfo = collectLocalClassesNavigationInfo() diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/contracts/FirContractResolveTransformer.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/contracts/FirContractResolveTransformer.kt index d6013ba7ea8..49a53545368 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/contracts/FirContractResolveTransformer.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/contracts/FirContractResolveTransformer.kt @@ -71,7 +71,7 @@ open class FirContractResolveTransformer( return simpleFunction } @Suppress("UNCHECKED_CAST") - return context.withSimpleFunction(simpleFunction) { + return context.withSimpleFunction(simpleFunction, session) { context.forFunctionBody(simpleFunction, components) { transformContractDescriptionOwner(simpleFunction) } @@ -129,7 +129,7 @@ open class FirContractResolveTransformer( ): T { val valueParameters = owner.valueParameters for (valueParameter in valueParameters) { - context.storeVariable(valueParameter) + context.storeVariable(valueParameter, session) } val contractCall = contractDescription.contractCall.transformSingle(transformer, ResolutionMode.ContextIndependent) val resolvedId = contractCall.toResolvedCallableSymbol()?.callableId ?: return transformOwnerWithUnresolvedContract(owner) diff --git a/compiler/fir/semantics/src/org/jetbrains/kotlin/fir/resolve/DeclarationUtils.kt b/compiler/fir/semantics/src/org/jetbrains/kotlin/fir/resolve/DeclarationUtils.kt index a6dcc8708d0..19185eb6b1d 100644 --- a/compiler/fir/semantics/src/org/jetbrains/kotlin/fir/resolve/DeclarationUtils.kt +++ b/compiler/fir/semantics/src/org/jetbrains/kotlin/fir/resolve/DeclarationUtils.kt @@ -32,31 +32,38 @@ fun FirClassLikeDeclaration.getContainingDeclaration(session: FirSession): FirCl return null } -fun isValidTypeParameterFromOuterClass( +fun isValidTypeParameterFromOuterDeclaration( typeParameterSymbol: FirTypeParameterSymbol, - classDeclaration: FirRegularClass?, + declaration: FirDeclaration?, session: FirSession ): Boolean { - if (classDeclaration == null) { + if (declaration == null) { return true // Extra check is required because of classDeclaration will be resolved later } - fun containsTypeParameter(currentClassDeclaration: FirRegularClass): Boolean { - if (currentClassDeclaration.typeParameters.any { it.symbol == typeParameterSymbol }) { - return true - } - - for (superTypeRef in currentClassDeclaration.superTypeRefs) { - val superClassFir = superTypeRef.firClassLike(session) - if (superClassFir == null || superClassFir is FirRegularClass && containsTypeParameter(superClassFir)) { + fun containsTypeParameter(currentDeclaration: FirDeclaration?): Boolean { + if (currentDeclaration is FirTypeParameterRefsOwner) { + if (currentDeclaration.typeParameters.any { it.symbol == typeParameterSymbol }) { return true } + + if (currentDeclaration is FirCallableDeclaration) { + val containingClassId = currentDeclaration.symbol.callableId.classId ?: return true + return containsTypeParameter(session.symbolProvider.getClassLikeSymbolByClassId(containingClassId)?.fir) + } else if (currentDeclaration is FirClass) { + for (superTypeRef in currentDeclaration.superTypeRefs) { + val superClassFir = superTypeRef.firClassLike(session) + if (superClassFir == null || superClassFir is FirRegularClass && containsTypeParameter(superClassFir)) { + return true + } + } + } } return false } - return containsTypeParameter(classDeclaration) + return containsTypeParameter(declaration) } fun FirTypeRef.firClassLike(session: FirSession): FirClassLikeDeclaration? { diff --git a/compiler/testData/diagnostics/tests/generics/capturedParameters/innerLocalClass.fir.kt b/compiler/testData/diagnostics/tests/generics/capturedParameters/innerLocalClass.fir.kt index dbc0e0a3748..4026d7754f3 100644 --- a/compiler/testData/diagnostics/tests/generics/capturedParameters/innerLocalClass.fir.kt +++ b/compiler/testData/diagnostics/tests/generics/capturedParameters/innerLocalClass.fir.kt @@ -19,14 +19,14 @@ private class Outer { private var doubleStringInt = Outer().Inner().foo()() private fun bar() { - doubleCharSequenceInt = doubleStringNumber + doubleCharSequenceInt = doubleStringNumber doubleCharSequenceInt = doubleStringInt doubleStringInt = Outer().Inner().foo()() - doubleStringInt.e.checkType { _() } - doubleStringInt.f.checkType { _() } - doubleStringInt.g.checkType { _() } + doubleStringInt.e.checkType { _() } + doubleStringInt.f.checkType { _() } + doubleStringInt.g.checkType { _() } } } } diff --git a/compiler/testData/diagnostics/tests/generics/capturedParameters/localClass.fir.kt b/compiler/testData/diagnostics/tests/generics/capturedParameters/localClass.fir.kt index a9647b110b2..d49c57ff12d 100644 --- a/compiler/testData/diagnostics/tests/generics/capturedParameters/localClass.fir.kt +++ b/compiler/testData/diagnostics/tests/generics/capturedParameters/localClass.fir.kt @@ -14,11 +14,11 @@ class Q { private var y = foo()() fun bar() { - x = y + x = y x = foo()() y = foo()() - x.prop.checkType { _() } - y.prop.checkType { _() } + x.prop.checkType { _() } + y.prop.checkType { _() } } } diff --git a/compiler/testData/diagnostics/tests/generics/capturedParameters/localWithTypeParameter.fir.kt b/compiler/testData/diagnostics/tests/generics/capturedParameters/localWithTypeParameter.fir.kt index 6e6ebf9ecfc..a7ff90eb7b9 100644 --- a/compiler/testData/diagnostics/tests/generics/capturedParameters/localWithTypeParameter.fir.kt +++ b/compiler/testData/diagnostics/tests/generics/capturedParameters/localWithTypeParameter.fir.kt @@ -15,8 +15,8 @@ class Q { private var x = foo()() fun bar() { - x.e.checkType { _() } - x.f.checkType { _() } + x.e.checkType { _() } + x.f.checkType { _() } x.g.checkType { _() } } } diff --git a/compiler/testData/diagnostics/tests/generics/capturedParameters/uncheckedCast.fir.kt b/compiler/testData/diagnostics/tests/generics/capturedParameters/uncheckedCast.fir.kt index 27616233816..a14746666b3 100644 --- a/compiler/testData/diagnostics/tests/generics/capturedParameters/uncheckedCast.fir.kt +++ b/compiler/testData/diagnostics/tests/generics/capturedParameters/uncheckedCast.fir.kt @@ -1,16 +1,16 @@ fun foo(x: Any, y: Any) : Any { class C // without E? - if(x is C) { + if(x is C) { return x } if (1 == 2) { - x as C + x as C } if (2 == 3) { - x as? C + x as? C } class Outer { diff --git a/compiler/testData/diagnostics/tests/generics/innerClasses/implicitArguments/fromSuperClassesLocal.fir.kt b/compiler/testData/diagnostics/tests/generics/innerClasses/implicitArguments/fromSuperClassesLocal.fir.kt index 7533319fb20..c8f20b87288 100644 --- a/compiler/testData/diagnostics/tests/generics/innerClasses/implicitArguments/fromSuperClassesLocal.fir.kt +++ b/compiler/testData/diagnostics/tests/generics/innerClasses/implicitArguments/fromSuperClassesLocal.fir.kt @@ -41,10 +41,10 @@ fun test() { var x = foobar() x = foobar() - x().foo().a() checkType { _>() } + x().foo().a() checkType { _>() } x().bar() checkType { _>() } - x = foobar() + x = foobar() var y = noParameters() y = noParameters() diff --git a/compiler/testData/diagnostics/tests/generics/innerClasses/implicitArguments/fromSuperClassesLocalInsideInner.fir.kt b/compiler/testData/diagnostics/tests/generics/innerClasses/implicitArguments/fromSuperClassesLocalInsideInner.fir.kt index 73bb0a2bf36..49576cdaf5b 100644 --- a/compiler/testData/diagnostics/tests/generics/innerClasses/implicitArguments/fromSuperClassesLocalInsideInner.fir.kt +++ b/compiler/testData/diagnostics/tests/generics/innerClasses/implicitArguments/fromSuperClassesLocalInsideInner.fir.kt @@ -42,11 +42,11 @@ class Outer { var x = foobar() x = foobar() - x().foo().a() checkType { _>() } + x().foo().a() checkType { _>() } x().bar() checkType { _>() } - x = foobar() - x = z.foobar() + x = foobar() + x = z.foobar() var y = noParameters() y = noParameters() diff --git a/compiler/testData/diagnostics/tests/generics/localClassWithTypeArgumentFromFunction.kt b/compiler/testData/diagnostics/tests/generics/localClassWithTypeArgumentFromFunction.kt new file mode 100644 index 00000000000..1380e6b608d --- /dev/null +++ b/compiler/testData/diagnostics/tests/generics/localClassWithTypeArgumentFromFunction.kt @@ -0,0 +1,14 @@ +// FIR_IDENTICAL +class C1 + +class C2 { + fun test() { + class LocalClass + C1() + } +} + +class A { + private inner class Inner + private val test = ArrayList() +} diff --git a/compiler/testData/diagnostics/tests/generics/localClassWithTypeArgumentFromFunction.txt b/compiler/testData/diagnostics/tests/generics/localClassWithTypeArgumentFromFunction.txt new file mode 100644 index 00000000000..828488777b0 --- /dev/null +++ b/compiler/testData/diagnostics/tests/generics/localClassWithTypeArgumentFromFunction.txt @@ -0,0 +1,31 @@ +package + +public final class A { + public constructor A() + private final val test: kotlin.collections.ArrayList.Inner> /* = java.util.ArrayList.Inner> */ + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String + + private final inner class Inner /*captured type parameters: /*0*/ T*/ { + public constructor Inner() + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String + } +} + +public final class C1 { + public constructor C1() + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +public final class C2 { + public constructor C2() + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public final fun test(): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} diff --git a/compiler/testData/diagnostics/tests/inner/deepInnerClass.fir.kt b/compiler/testData/diagnostics/tests/inner/deepInnerClass.fir.kt index abf66cb2ff0..cc69e3f5c34 100644 --- a/compiler/testData/diagnostics/tests/inner/deepInnerClass.fir.kt +++ b/compiler/testData/diagnostics/tests/inner/deepInnerClass.fir.kt @@ -4,8 +4,8 @@ class A { class B { fun test() { class C() : PT> { - companion object : PT> { - } + companion object : PT> { + } inner class D : PT> } diff --git a/compiler/testData/diagnostics/tests/typealias/innerTypeAliasAsType.fir.kt b/compiler/testData/diagnostics/tests/typealias/innerTypeAliasAsType.fir.kt index b0586ac0586..b41536cc81e 100644 --- a/compiler/testData/diagnostics/tests/typealias/innerTypeAliasAsType.fir.kt +++ b/compiler/testData/diagnostics/tests/typealias/innerTypeAliasAsType.fir.kt @@ -18,12 +18,12 @@ class Outer { fun test5(x: GenericInnerAlias) = x fun test6(x: GenericInnerAlias) = x } -fun test1(x: Outer.NestedAlias) = x -fun test2(x: Outer.NestedAlias) = x +fun test1(x: Outer.NestedAlias) = x +fun test2(x: Outer.NestedAlias) = x fun test3(x: Outer.NestedAlias) = x -fun test4(x: Outer.GenericNestedAlias) = x -fun test5(x: Outer.GenericNestedAlias) = x -fun test6(x: Outer.GenericNestedAlias) = x +fun test4(x: Outer.GenericNestedAlias) = x +fun test5(x: Outer.GenericNestedAlias) = x +fun test6(x: Outer.GenericNestedAlias) = x fun test7(x: Outer.GenericNestedAlias) = x fun test8(x: Outer.GenericNestedAlias) = x fun test9(x: Outer.InnerAlias) = x diff --git a/compiler/testData/diagnostics/tests/typealias/kt14518.fir.kt b/compiler/testData/diagnostics/tests/typealias/kt14518.fir.kt index 046f7dd03cb..dac0393b6ed 100644 --- a/compiler/testData/diagnostics/tests/typealias/kt14518.fir.kt +++ b/compiler/testData/diagnostics/tests/typealias/kt14518.fir.kt @@ -6,5 +6,5 @@ class OuterClass { } typealias ON1 = OuterClass.NestedClass -typealias ON2 = OuterClass.NestedType -typealias ON3 = OuterClass.NestedType +typealias ON2 = OuterClass.NestedType +typealias ON3 = OuterClass.NestedType diff --git a/compiler/testData/diagnostics/tests/typealias/typeAliasAsBareType.fir.kt b/compiler/testData/diagnostics/tests/typealias/typeAliasAsBareType.fir.kt index 4c57c4a7261..ce0dceabb07 100644 --- a/compiler/testData/diagnostics/tests/typealias/typeAliasAsBareType.fir.kt +++ b/compiler/testData/diagnostics/tests/typealias/typeAliasAsBareType.fir.kt @@ -30,6 +30,6 @@ fun testWrong4(x: List) = x is ReadableList fun testLocal(x: Any) { class C typealias CA = C - if (x is C) {} + if (x is C) {} if (x is CA) {} } diff --git a/compiler/testData/ir/irText/expressions/callableReferences/genericLocalClassConstructorReference.fir.ir.txt b/compiler/testData/ir/irText/expressions/callableReferences/genericLocalClassConstructorReference.fir.ir.txt index 51160dd6d86..968abae760d 100644 --- a/compiler/testData/ir/irText/expressions/callableReferences/genericLocalClassConstructorReference.fir.ir.txt +++ b/compiler/testData/ir/irText/expressions/callableReferences/genericLocalClassConstructorReference.fir.ir.txt @@ -70,9 +70,9 @@ FILE fqName: fileName:/genericLocalClassConstructorReference.kt $receiver: VALUE_PARAMETER name: type:.Rec.> BLOCK_BODY CLASS CLASS name:PLocal modality:FINAL visibility:local superTypes:[.L..PLocal>] - $this: VALUE_PARAMETER INSTANCE_RECEIVER name: type:..PLocal..PLocal> + $this: VALUE_PARAMETER INSTANCE_RECEIVER name: type:..PLocal..PLocal, PT of .> TYPE_PARAMETER name:LT index:0 variance: superTypes:[kotlin.Any?] - CONSTRUCTOR visibility:public <> (lt:LT of ..PLocal, pt:PT of .) returnType:..PLocal..PLocal> [primary] + CONSTRUCTOR visibility:public <> (lt:LT of ..PLocal, pt:PT of .) returnType:..PLocal..PLocal, PT of .> [primary] VALUE_PARAMETER name:lt index:0 type:LT of ..PLocal VALUE_PARAMETER name:pt index:1 type:PT of . BLOCK_BODY @@ -84,13 +84,13 @@ FILE fqName: fileName:/genericLocalClassConstructorReference.kt FIELD PROPERTY_BACKING_FIELD name:pt type:PT of . visibility:private [final] EXPRESSION_BODY GET_VAR 'pt: PT of . declared in ..PLocal.' type=PT of . origin=INITIALIZE_PROPERTY_FROM_PARAMETER - FUN DEFAULT_PROPERTY_ACCESSOR name: visibility:public modality:FINAL <> ($this:..PLocal..PLocal>) returnType:PT of . + FUN DEFAULT_PROPERTY_ACCESSOR name: visibility:public modality:FINAL <> ($this:..PLocal..PLocal, PT of .>) returnType:PT of . correspondingProperty: PROPERTY name:pt visibility:public modality:FINAL [val] - $this: VALUE_PARAMETER name: type:..PLocal..PLocal> + $this: VALUE_PARAMETER name: type:..PLocal..PLocal, PT of .> BLOCK_BODY RETURN type=kotlin.Nothing from='public final fun (): PT of . declared in ..PLocal' GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:pt type:PT of . visibility:private [final]' type=PT of . origin=null - receiver: GET_VAR ': ..PLocal..PLocal> declared in ..PLocal.' type=..PLocal..PLocal> origin=null + receiver: GET_VAR ': ..PLocal..PLocal, PT of .> declared in ..PLocal.' type=..PLocal..PLocal, PT of .> origin=null PROPERTY FAKE_OVERRIDE name:ll visibility:public modality:FINAL [fake_override,val] overridden: public final ll: LL of .L [val] @@ -113,24 +113,24 @@ FILE fqName: fileName:/genericLocalClassConstructorReference.kt public open fun toString (): kotlin.String [fake_override] declared in .L $this: VALUE_PARAMETER name: type:kotlin.Any RETURN type=kotlin.Nothing from='public final fun (): .L.> declared in ' - CALL 'public final fun foo2 (t1: T1 of .foo2, t2: T2 of .foo2, bb: kotlin.Function2.foo2, T2 of .foo2, R of .foo2>): R of .foo2 declared in ' type=..PLocal.> origin=null + CALL 'public final fun foo2 (t1: T1 of .foo2, t2: T2 of .foo2, bb: kotlin.Function2.foo2, T2 of .foo2, R of .foo2>): R of .foo2 declared in ' type=..PLocal., PT of .> origin=null : PT of . : PT of . - : ..PLocal.> + : ..PLocal., PT of .> t1: CALL 'public final fun (): T of .Rec declared in .Rec' type=PT of . origin=GET_PROPERTY $this: GET_VAR ': .Rec.> declared in .' type=.Rec.> origin=null t2: CALL 'public final fun (): T of .Rec declared in .Rec' type=PT of . origin=GET_PROPERTY $this: GET_VAR ': .Rec.> declared in .' type=.Rec.> origin=null - bb: FUNCTION_REFERENCE 'public constructor (lt: LT of ..PLocal, pt: PT of .) [primary] declared in ..PLocal' type=kotlin.reflect.KFunction2., PT of ., ..PLocal.>> origin=null reflectionTarget= + bb: FUNCTION_REFERENCE 'public constructor (lt: LT of ..PLocal, pt: PT of .) [primary] declared in ..PLocal' type=kotlin.reflect.KFunction2., PT of ., ..PLocal., PT of .>> origin=null reflectionTarget= : PT of . FUN name:fn visibility:public modality:FINAL ($receiver:.Rec.fn>) returnType:.L.fn> TYPE_PARAMETER name:FT index:0 variance: superTypes:[kotlin.Any?] $receiver: VALUE_PARAMETER name: type:.Rec.fn> BLOCK_BODY CLASS CLASS name:FLocal modality:FINAL visibility:local superTypes:[.L.fn.FLocal>] - $this: VALUE_PARAMETER INSTANCE_RECEIVER name: type:.fn.FLocal.fn.FLocal> + $this: VALUE_PARAMETER INSTANCE_RECEIVER name: type:.fn.FLocal.fn.FLocal, FT of .fn> TYPE_PARAMETER name:LT index:0 variance: superTypes:[kotlin.Any?] - CONSTRUCTOR visibility:public <> (lt:LT of .fn.FLocal, pt:FT of .fn) returnType:.fn.FLocal.fn.FLocal> [primary] + CONSTRUCTOR visibility:public <> (lt:LT of .fn.FLocal, pt:FT of .fn) returnType:.fn.FLocal.fn.FLocal, FT of .fn> [primary] VALUE_PARAMETER name:lt index:0 type:LT of .fn.FLocal VALUE_PARAMETER name:pt index:1 type:FT of .fn BLOCK_BODY @@ -142,13 +142,13 @@ FILE fqName: fileName:/genericLocalClassConstructorReference.kt FIELD PROPERTY_BACKING_FIELD name:pt type:FT of .fn visibility:private [final] EXPRESSION_BODY GET_VAR 'pt: FT of .fn declared in .fn.FLocal.' type=FT of .fn origin=INITIALIZE_PROPERTY_FROM_PARAMETER - FUN DEFAULT_PROPERTY_ACCESSOR name: visibility:public modality:FINAL <> ($this:.fn.FLocal.fn.FLocal>) returnType:FT of .fn + FUN DEFAULT_PROPERTY_ACCESSOR name: visibility:public modality:FINAL <> ($this:.fn.FLocal.fn.FLocal, FT of .fn>) returnType:FT of .fn correspondingProperty: PROPERTY name:pt visibility:public modality:FINAL [val] - $this: VALUE_PARAMETER name: type:.fn.FLocal.fn.FLocal> + $this: VALUE_PARAMETER name: type:.fn.FLocal.fn.FLocal, FT of .fn> BLOCK_BODY RETURN type=kotlin.Nothing from='public final fun (): FT of .fn declared in .fn.FLocal' GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:pt type:FT of .fn visibility:private [final]' type=FT of .fn origin=null - receiver: GET_VAR ': .fn.FLocal.fn.FLocal> declared in .fn.FLocal.' type=.fn.FLocal.fn.FLocal> origin=null + receiver: GET_VAR ': .fn.FLocal.fn.FLocal, FT of .fn> declared in .fn.FLocal.' type=.fn.FLocal.fn.FLocal, FT of .fn> origin=null PROPERTY FAKE_OVERRIDE name:ll visibility:public modality:FINAL [fake_override,val] overridden: public final ll: LL of .L [val] @@ -171,15 +171,15 @@ FILE fqName: fileName:/genericLocalClassConstructorReference.kt public open fun toString (): kotlin.String [fake_override] declared in .L $this: VALUE_PARAMETER name: type:kotlin.Any RETURN type=kotlin.Nothing from='public final fun fn (): .L.fn> declared in ' - CALL 'public final fun foo2 (t1: T1 of .foo2, t2: T2 of .foo2, bb: kotlin.Function2.foo2, T2 of .foo2, R of .foo2>): R of .foo2 declared in ' type=.fn.FLocal.fn> origin=null + CALL 'public final fun foo2 (t1: T1 of .foo2, t2: T2 of .foo2, bb: kotlin.Function2.foo2, T2 of .foo2, R of .foo2>): R of .foo2 declared in ' type=.fn.FLocal.fn, FT of .fn> origin=null : FT of .fn : FT of .fn - : .fn.FLocal.fn> + : .fn.FLocal.fn, FT of .fn> t1: CALL 'public final fun (): T of .Rec declared in .Rec' type=FT of .fn origin=GET_PROPERTY $this: GET_VAR ': .Rec.fn> declared in .fn' type=.Rec.fn> origin=null t2: CALL 'public final fun (): T of .Rec declared in .Rec' type=FT of .fn origin=GET_PROPERTY $this: GET_VAR ': .Rec.fn> declared in .fn' type=.Rec.fn> origin=null - bb: FUNCTION_REFERENCE 'public constructor (lt: LT of .fn.FLocal, pt: FT of .fn) [primary] declared in .fn.FLocal' type=kotlin.reflect.KFunction2.fn, FT of .fn, .fn.FLocal.fn>> origin=null reflectionTarget= + bb: FUNCTION_REFERENCE 'public constructor (lt: LT of .fn.FLocal, pt: FT of .fn) [primary] declared in .fn.FLocal' type=kotlin.reflect.KFunction2.fn, FT of .fn, .fn.FLocal.fn, FT of .fn>> origin=null reflectionTarget= : FT of .fn FUN name:foo2 visibility:public modality:FINAL (t1:T1 of .foo2, t2:T2 of .foo2, bb:kotlin.Function2.foo2, T2 of .foo2, R of .foo2>) returnType:R of .foo2 TYPE_PARAMETER name:T1 index:0 variance: superTypes:[kotlin.Any?] diff --git a/compiler/testData/ir/irText/expressions/callableReferences/genericLocalClassConstructorReference.fir.kt.txt b/compiler/testData/ir/irText/expressions/callableReferences/genericLocalClassConstructorReference.fir.kt.txt index d454c6a0216..dd3d4028785 100644 --- a/compiler/testData/ir/irText/expressions/callableReferences/genericLocalClassConstructorReference.fir.kt.txt +++ b/compiler/testData/ir/irText/expressions/callableReferences/genericLocalClassConstructorReference.fir.kt.txt @@ -39,7 +39,7 @@ val Rec.p: L } - return foo2>(t1 = .(), t2 = .(), bb = PLocal::/*()*/) + return foo2>(t1 = .(), t2 = .(), bb = PLocal::/*()*/) } fun Rec.fn(): L { @@ -56,9 +56,10 @@ fun Rec.fn(): L { } - return foo2>(t1 = .(), t2 = .(), bb = FLocal::/*()*/) + return foo2>(t1 = .(), t2 = .(), bb = FLocal::/*()*/) } fun foo2(t1: T1, t2: T2, bb: Function2): R { return bb.invoke(p1 = t1, p2 = t2) } + diff --git a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticTestGenerated.java b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticTestGenerated.java index 58d258e2b4c..b16c76b5eda 100644 --- a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticTestGenerated.java +++ b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticTestGenerated.java @@ -11351,6 +11351,12 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest { runTest("compiler/testData/diagnostics/tests/generics/kt9985.kt"); } + @Test + @TestMetadata("localClassWithTypeArgumentFromFunction.kt") + public void testLocalClassWithTypeArgumentFromFunction() throws Exception { + runTest("compiler/testData/diagnostics/tests/generics/localClassWithTypeArgumentFromFunction.kt"); + } + @Test @TestMetadata("Projections.kt") public void testProjections() throws Exception {