diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/FirCallResolver.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/FirCallResolver.kt index 025de4f0ff4..61f658a3130 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/FirCallResolver.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/FirCallResolver.kt @@ -5,7 +5,6 @@ package org.jetbrains.kotlin.fir -import org.jetbrains.kotlin.fir.declarations.FirFile import org.jetbrains.kotlin.fir.declarations.FirMemberDeclaration import org.jetbrains.kotlin.fir.expressions.* import org.jetbrains.kotlin.fir.expressions.builder.buildExpressionStub @@ -46,7 +45,6 @@ class FirCallResolver( components: BodyResolveComponents, topLevelScopes: List, localScopes: List, - override val implicitReceiverStack: ImplicitReceiverStack, private val qualifiedResolver: FirQualifiedNameResolver, ) : BodyResolveComponents by components { diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/dfa/FirDataFlowAnalyzer.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/dfa/FirDataFlowAnalyzer.kt index 95b472752c5..bb31930c6e1 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/dfa/FirDataFlowAnalyzer.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/dfa/FirDataFlowAnalyzer.kt @@ -39,7 +39,8 @@ abstract class FirDataFlowAnalyzer( fun createFirDataFlowAnalyzer( components: FirAbstractBodyResolveTransformer.BodyResolveTransformerComponents ): FirDataFlowAnalyzer<*> = object : FirDataFlowAnalyzer(components) { - private val receiverStack: ImplicitReceiverStackImpl = components.implicitReceiverStack as ImplicitReceiverStackImpl + private val receiverStack: ImplicitReceiverStackImpl + get() = components.implicitReceiverStack as ImplicitReceiverStackImpl override val logicSystem: PersistentLogicSystem = object : PersistentLogicSystem(components.inferenceComponents.ctx) { override fun processUpdatedReceiverVariable(flow: PersistentFlow, variable: RealVariable) { diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/FirCallCompleter.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/FirCallCompleter.kt index f8e4d3e23aa..aca3a4478e5 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/FirCallCompleter.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/FirCallCompleter.kt @@ -140,14 +140,14 @@ class FirCallCompleter( private inner class LambdaAnalyzerImpl : LambdaAnalyzer { override fun analyzeAndGetLambdaReturnArguments( - lambdaArgument: FirAnonymousFunction, - isSuspend: Boolean, + lambdaAtom: ResolvedLambdaAtom, receiverType: ConeKotlinType?, parameters: List, expectedReturnType: ConeKotlinType?, rawReturnType: ConeKotlinType, stubsForPostponedVariables: Map ): ReturnArgumentsAnalysisResult { + val lambdaArgument: FirAnonymousFunction = lambdaAtom.atom val needItParam = lambdaArgument.valueParameters.isEmpty() && parameters.size == 1 val itParam = when { @@ -185,7 +185,9 @@ class FirCallCompleter( lambdaArgument.replaceValueParameters(lambdaArgument.valueParameters + listOfNotNull(itParam)) lambdaArgument.replaceReturnTypeRef(expectedReturnTypeRef ?: noExpectedType) - lambdaArgument.transformSingle(transformer, ResolutionMode.LambdaResolution(expectedReturnTypeRef)) + transformer.components.withImplicitReceiverStack(lambdaAtom.implicitReceiverStack) { + lambdaArgument.transformSingle(transformer, ResolutionMode.LambdaResolution(expectedReturnTypeRef)) + } val returnArguments = dataFlowAnalyzer.returnExpressionsOfAnonymousFunction(lambdaArgument) diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/PostponedArguments.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/PostponedArguments.kt index 5776ea882aa..d58564f4555 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/PostponedArguments.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/PostponedArguments.kt @@ -9,12 +9,10 @@ import org.jetbrains.kotlin.fir.FirSession import org.jetbrains.kotlin.fir.declarations.FirAnonymousFunction import org.jetbrains.kotlin.fir.expressions.FirCallableReferenceAccess import org.jetbrains.kotlin.fir.expressions.FirStatement -import org.jetbrains.kotlin.fir.resolve.DoubleColonLHS +import org.jetbrains.kotlin.fir.resolve.* import org.jetbrains.kotlin.fir.resolve.calls.Candidate import org.jetbrains.kotlin.fir.resolve.calls.CandidateApplicability import org.jetbrains.kotlin.fir.resolve.calls.isExtensionFunctionType -import org.jetbrains.kotlin.fir.resolve.createFunctionalType -import org.jetbrains.kotlin.fir.resolve.fullyExpandedType import org.jetbrains.kotlin.fir.symbols.StandardClassIds import org.jetbrains.kotlin.fir.symbols.impl.ConeClassLikeLookupTagImpl import org.jetbrains.kotlin.fir.types.* @@ -36,8 +34,8 @@ fun Candidate.preprocessLambdaArgument( } val resolvedArgument = - extractLambdaInfoFromFunctionalType(expectedType, expectedTypeRef, argument, bodyResolveComponents.session) - ?: extraLambdaInfo(expectedType, argument, csBuilder, bodyResolveComponents.session) + extractLambdaInfoFromFunctionalType(expectedType, expectedTypeRef, argument, bodyResolveComponents.session, bodyResolveComponents) + ?: extraLambdaInfo(expectedType, argument, csBuilder, bodyResolveComponents.session, bodyResolveComponents) if (expectedType != null) { // TODO: add SAM conversion processing @@ -106,7 +104,8 @@ private fun extraLambdaInfo( expectedType: ConeKotlinType?, argument: FirAnonymousFunction, csBuilder: ConstraintSystemBuilder, - session: FirSession + session: FirSession, + components: BodyResolveComponents ): ResolvedLambdaAtom { val isSuspend = expectedType?.isSuspendFunctionType(session) ?: false @@ -130,18 +129,27 @@ private fun extraLambdaInfo( val newTypeVariableUsed = returnType == typeVariable.defaultType if (newTypeVariableUsed) csBuilder.registerVariable(typeVariable) - return ResolvedLambdaAtom(argument, isSuspend, receiverType, parameters, returnType, typeVariable.takeIf { newTypeVariableUsed }) + return ResolvedLambdaAtom( + argument, + isSuspend, + receiverType, + parameters, + returnType, + typeVariable.takeIf { newTypeVariableUsed }, + components.implicitReceiverStack.snapshot() + ) } internal fun extractLambdaInfoFromFunctionalType( expectedType: ConeKotlinType?, expectedTypeRef: FirTypeRef, argument: FirAnonymousFunction, - session: FirSession + session: FirSession, + components: BodyResolveComponents ): ResolvedLambdaAtom? { if (expectedType == null) return null if (expectedType is ConeFlexibleType) { - return extractLambdaInfoFromFunctionalType(expectedType.lowerBound, expectedTypeRef, argument, session) + return extractLambdaInfoFromFunctionalType(expectedType.lowerBound, expectedTypeRef, argument, session, components) } if (!expectedType.isBuiltinFunctionalType(session)) return null @@ -155,7 +163,8 @@ internal fun extractLambdaInfoFromFunctionalType( receiverType, parameters, returnType, - typeVariableForLambdaReturnType = null + typeVariableForLambdaReturnType = null, + components.implicitReceiverStack.snapshot() ) } @@ -199,7 +208,8 @@ class ResolvedLambdaAtom( val receiver: ConeKotlinType?, val parameters: List, val returnType: ConeKotlinType, - val typeVariableForLambdaReturnType: TypeVariableForLambdaReturnType? + val typeVariableForLambdaReturnType: TypeVariableForLambdaReturnType?, + val implicitReceiverStack: ImplicitReceiverStack ) : PostponedResolvedAtomMarker { override var analyzed: Boolean = false diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/PostponedArgumentsAnalyzer.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/PostponedArgumentsAnalyzer.kt index 4eff8a6ee12..94120894168 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/PostponedArgumentsAnalyzer.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/PostponedArgumentsAnalyzer.kt @@ -6,7 +6,6 @@ package org.jetbrains.kotlin.fir.resolve.inference import org.jetbrains.kotlin.fir.FirCallResolver -import org.jetbrains.kotlin.fir.declarations.FirAnonymousFunction import org.jetbrains.kotlin.fir.expressions.FirExpression import org.jetbrains.kotlin.fir.expressions.FirStatement import org.jetbrains.kotlin.fir.references.builder.buildErrorNamedReference @@ -32,8 +31,7 @@ data class ReturnArgumentsAnalysisResult( interface LambdaAnalyzer { fun analyzeAndGetLambdaReturnArguments( - lambdaArgument: FirAnonymousFunction, - isSuspend: Boolean, + lambdaAtom: ResolvedLambdaAtom, receiverType: ConeKotlinType?, parameters: List, expectedReturnType: ConeKotlinType?, // null means, that return type is not proper i.e. it depends on some type variables @@ -128,8 +126,7 @@ class PostponedArgumentsAnalyzer( } val (returnArguments, inferenceSession) = lambdaAnalyzer.analyzeAndGetLambdaReturnArguments( - lambda.atom, - lambda.isSuspend, + lambda, receiver, parameters, expectedTypeForReturnArguments, diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirAbstractBodyResolveTransformer.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirAbstractBodyResolveTransformer.kt index f5529150de4..870b02bd2ca 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirAbstractBodyResolveTransformer.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirAbstractBodyResolveTransformer.kt @@ -106,7 +106,10 @@ abstract class FirAbstractBodyResolveTransformer(phase: FirResolvePhase) : FirAb override val symbolProvider: FirSymbolProvider = session.firSymbolProvider override val returnTypeCalculator: ReturnTypeCalculator = transformer.returnTypeCalculator - override val implicitReceiverStack: ImplicitReceiverStack = ImplicitReceiverStackImpl() + + @set:PrivateForInline + override var implicitReceiverStack: ImplicitReceiverStack = ImplicitReceiverStackImpl() + override val inferenceComponents: InferenceComponents = inferenceComponents(session, returnTypeCalculator, scopeSession) override val resolutionStageRunner: ResolutionStageRunner = ResolutionStageRunner(inferenceComponents) override val samResolver: FirSamResolver = FirSamResolverImpl(session, scopeSession) @@ -116,7 +119,6 @@ abstract class FirAbstractBodyResolveTransformer(phase: FirResolvePhase) : FirAb this, topLevelScopes, localScopes, - implicitReceiverStack, qualifiedResolver ) val typeResolverTransformer = FirSpecificTypeResolverTransformer( @@ -147,6 +149,17 @@ abstract class FirAbstractBodyResolveTransformer(phase: FirResolvePhase) : FirAb containerIfAny = prevContainer return result } + + @UseExperimental(PrivateForInline::class) + inline fun withImplicitReceiverStack(implicitReceiverStack: ImplicitReceiverStack, f: () -> T): T { + val existedStack = this.implicitReceiverStack + this.implicitReceiverStack = implicitReceiverStack + return try { + f() + } finally { + this.implicitReceiverStack = existedStack + } + } } } 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 df20f0e00c2..16f998e34c6 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 @@ -489,7 +489,7 @@ class FirDeclarationsResolveTransformer(transformer: FirBodyResolveTransformer) val expectedTypeRef = (data as? ResolutionMode.WithExpectedType)?.expectedTypeRef ?: buildImplicitTypeRef() val resolvedLambdaAtom = (expectedTypeRef as? FirResolvedTypeRef)?.let { extractLambdaInfoFromFunctionalType( - it.type, it, anonymousFunction, session + it.type, it, anonymousFunction, session, components ) } var af = anonymousFunction diff --git a/compiler/fir/resolve/testData/resolveWithStdlib/problems/withInInitializer.kt b/compiler/fir/resolve/testData/resolveWithStdlib/withInInitializer.kt similarity index 79% rename from compiler/fir/resolve/testData/resolveWithStdlib/problems/withInInitializer.kt rename to compiler/fir/resolve/testData/resolveWithStdlib/withInInitializer.kt index 8bc8b2c2c5a..46af0b0b8e1 100644 --- a/compiler/fir/resolve/testData/resolveWithStdlib/problems/withInInitializer.kt +++ b/compiler/fir/resolve/testData/resolveWithStdlib/withInInitializer.kt @@ -7,7 +7,7 @@ class Second { val test = with(data) { list.filterIsInstance().filter { - it == member + it == member } } } \ No newline at end of file diff --git a/compiler/fir/resolve/testData/resolveWithStdlib/problems/withInInitializer.txt b/compiler/fir/resolve/testData/resolveWithStdlib/withInInitializer.txt similarity index 94% rename from compiler/fir/resolve/testData/resolveWithStdlib/problems/withInInitializer.txt rename to compiler/fir/resolve/testData/resolveWithStdlib/withInInitializer.txt index 75b29a9e794..5e84b38e1f6 100644 --- a/compiler/fir/resolve/testData/resolveWithStdlib/problems/withInInitializer.txt +++ b/compiler/fir/resolve/testData/resolveWithStdlib/withInInitializer.txt @@ -21,7 +21,7 @@ FILE: withInInitializer.kt public final val test: R|kotlin/collections/List| = R|kotlin/with||>(this@R|/Second|.R|/Second.data|, = with@fun R|First|.(): R|kotlin/collections/List| { ^ this@R|/Second|.R|/Second.list|.R|kotlin/collections/filterIsInstance|().R|kotlin/collections/filter|( = filter@fun (it: R|kotlin/Int|): R|kotlin/Boolean| { - ^ ==(R|/it|, #) + ^ ==(R|/it|, this@R|special/anonymous|.R|/First.member|) } ) } diff --git a/compiler/fir/resolve/tests/org/jetbrains/kotlin/fir/FirDiagnosticsWithStdlibTestGenerated.java b/compiler/fir/resolve/tests/org/jetbrains/kotlin/fir/FirDiagnosticsWithStdlibTestGenerated.java index d0c87906b83..d0f450ea239 100644 --- a/compiler/fir/resolve/tests/org/jetbrains/kotlin/fir/FirDiagnosticsWithStdlibTestGenerated.java +++ b/compiler/fir/resolve/tests/org/jetbrains/kotlin/fir/FirDiagnosticsWithStdlibTestGenerated.java @@ -288,6 +288,11 @@ public class FirDiagnosticsWithStdlibTestGenerated extends AbstractFirDiagnostic runTest("compiler/fir/resolve/testData/resolveWithStdlib/whenAsLambdaReturnStatement.kt"); } + @TestMetadata("withInInitializer.kt") + public void testWithInInitializer() throws Exception { + runTest("compiler/fir/resolve/testData/resolveWithStdlib/withInInitializer.kt"); + } + @TestMetadata("compiler/fir/resolve/testData/resolveWithStdlib/callableReferences") @TestDataPath("$PROJECT_ROOT") @RunWith(JUnit3RunnerWithInners.class) @@ -714,11 +719,6 @@ public class FirDiagnosticsWithStdlibTestGenerated extends AbstractFirDiagnostic public void testWeakHashMap() throws Exception { runTest("compiler/fir/resolve/testData/resolveWithStdlib/problems/weakHashMap.kt"); } - - @TestMetadata("withInInitializer.kt") - public void testWithInInitializer() throws Exception { - runTest("compiler/fir/resolve/testData/resolveWithStdlib/problems/withInInitializer.kt"); - } } @TestMetadata("compiler/fir/resolve/testData/resolveWithStdlib/smartcasts")