From 810aee60dbdab3fce841de44c9aaa6c76f3c47ca Mon Sep 17 00:00:00 2001 From: Victor Petukhov Date: Mon, 6 Sep 2021 18:30:41 +0300 Subject: [PATCH] Get nested builder inference sessions properly, across delegated inference sessions too ^KT-48445 Fixed --- .../DelegatedPropertyInferenceSession.kt | 13 ++++ .../inference/BuilderInferenceSession.kt | 19 +++-- .../calls/tower/ManyCandidatesResolver.kt | 5 ++ .../box/inference/builderInference/kt48445.kt | 70 +++++++++---------- 4 files changed, 67 insertions(+), 40 deletions(-) diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/DelegatedPropertyInferenceSession.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/DelegatedPropertyInferenceSession.kt index 759c5149ede..95be35525a4 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/DelegatedPropertyInferenceSession.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/DelegatedPropertyInferenceSession.kt @@ -10,6 +10,7 @@ import org.jetbrains.kotlin.descriptors.CallableDescriptor import org.jetbrains.kotlin.descriptors.FunctionDescriptor import org.jetbrains.kotlin.descriptors.VariableDescriptorWithAccessors import org.jetbrains.kotlin.resolve.calls.components.* +import org.jetbrains.kotlin.resolve.calls.inference.BuilderInferenceSession import org.jetbrains.kotlin.resolve.calls.inference.ConstraintSystemBuilder import org.jetbrains.kotlin.resolve.calls.inference.NewConstraintSystem import org.jetbrains.kotlin.resolve.calls.inference.components.ConstraintSystemCompletionMode @@ -37,6 +38,18 @@ class DelegatedPropertyInferenceSession( ) : ManyCandidatesResolver( psiCallResolver, postponedArgumentsAnalyzer, kotlinConstraintSystemCompleter, callComponents, builtIns ) { + init { + if (parentSession is ManyCandidatesResolver<*>) { + parentSession.addNestedInferenceSession(this) + } + } + + fun getNestedBuilderInferenceSessions(): List { + val builderInferenceSessions = nestedInferenceSessions.filterIsInstance() + val delegatedPropertyInferenceSessions = nestedInferenceSessions.filterIsInstance() + + return builderInferenceSessions + delegatedPropertyInferenceSessions.map { it.getNestedBuilderInferenceSessions() }.flatten() + } override fun prepareForCompletion(commonSystem: NewConstraintSystem, resolvedCallsInfo: List) { val csBuilder = commonSystem.getBuilder() diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/inference/BuilderInferenceSession.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/inference/BuilderInferenceSession.kt index 9f1a97fc7a0..19d238af407 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/inference/BuilderInferenceSession.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/inference/BuilderInferenceSession.kt @@ -6,7 +6,6 @@ package org.jetbrains.kotlin.resolve.calls.inference import org.jetbrains.kotlin.builtins.KotlinBuiltIns -import org.jetbrains.kotlin.config.LanguageFeature import org.jetbrains.kotlin.descriptors.CallableDescriptor import org.jetbrains.kotlin.descriptors.ModuleDescriptor import org.jetbrains.kotlin.descriptors.impl.* @@ -60,14 +59,12 @@ class BuilderInferenceSession( ) : ManyCandidatesResolver( psiCallResolver, postponedArgumentsAnalyzer, kotlinConstraintSystemCompleter, callComponents, builtIns ) { - private var nestedBuilderInferenceSessions: MutableSet = mutableSetOf() - private lateinit var lambda: ResolvedLambdaAtom private val commonSystem = NewConstraintSystemImpl(callComponents.constraintInjector, builtIns, callComponents.kotlinTypeRefiner) init { - if (topLevelCallContext.inferenceSession is BuilderInferenceSession) { - topLevelCallContext.inferenceSession.nestedBuilderInferenceSessions.add(this) + if (topLevelCallContext.inferenceSession is ManyCandidatesResolver<*>) { + topLevelCallContext.inferenceSession.addNestedInferenceSession(this) } stubsForPostponedVariables.keys.forEach(commonSystem::registerVariable) } @@ -266,6 +263,16 @@ class BuilderInferenceSession( return commonSystem.fixedTypeVariables.cast() // TODO: SUB } + @OptIn(ExperimentalStdlibApi::class) + private fun getNestedBuilderInferenceSessions() = buildList { + for (nestedSession in nestedInferenceSessions) { + when (nestedSession) { + is BuilderInferenceSession -> add(nestedSession) + is DelegatedPropertyInferenceSession -> addAll(nestedSession.getNestedBuilderInferenceSessions()) + } + } + } + /* * We update calls in top-down way: * - updating calls within top-level builder inference call @@ -279,6 +286,8 @@ class BuilderInferenceSession( commonSystem.errors ) + val nestedBuilderInferenceSessions = getNestedBuilderInferenceSessions() + for (nestedSession in nestedBuilderInferenceSessions) { // TODO: exclude injected variables nestedSession.updateAllCalls( diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tower/ManyCandidatesResolver.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tower/ManyCandidatesResolver.kt index 946b7f25e28..9e843f0cf50 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tower/ManyCandidatesResolver.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tower/ManyCandidatesResolver.kt @@ -30,6 +30,11 @@ abstract class ManyCandidatesResolver( protected val partiallyResolvedCallsInfo = arrayListOf() private val errorCallsInfo = arrayListOf>() private val completedCalls = hashSetOf() + protected val nestedInferenceSessions = hashSetOf>() + + fun addNestedInferenceSession(inferenceSession: ManyCandidatesResolver<*>) { + nestedInferenceSessions.add(inferenceSession) + } open fun prepareForCompletion(commonSystem: NewConstraintSystem, resolvedCallsInfo: List) { // do nothing diff --git a/compiler/testData/codegen/box/inference/builderInference/kt48445.kt b/compiler/testData/codegen/box/inference/builderInference/kt48445.kt index e3a9e9aa83e..faa047472a4 100644 --- a/compiler/testData/codegen/box/inference/builderInference/kt48445.kt +++ b/compiler/testData/codegen/box/inference/builderInference/kt48445.kt @@ -14,39 +14,39 @@ internal class TowerDataElementsForName() { } } -//internal class TowerDataElementsForName2() { -// @OptIn(ExperimentalStdlibApi::class) -// val reversedFilteredLocalScopes = buildList { -// val reversedFilteredLocalScopes by lazy(LazyThreadSafetyMode.NONE) { -// @OptIn(ExperimentalStdlibApi::class) -// buildList { -// for (i in lastIndex downTo 0) { -// add("") -// } -// } -// } -// add(reversedFilteredLocalScopes) -// } -//} -// -//internal class TowerDataElementsForName3() { -// val reversedFilteredLocalScopes by lazy(LazyThreadSafetyMode.NONE) { -// @OptIn(ExperimentalStdlibApi::class) -// buildList l1@ { -// for (i in lastIndex downTo 0) { -// val reversedFilteredLocalScopes by lazy(LazyThreadSafetyMode.NONE) { -// @OptIn(ExperimentalStdlibApi::class) -// buildList { -// for (i in lastIndex downTo 0) { -// add("") -// this@l1.add("") -// } -// } -// } -// } -// } -// } -//} +internal class TowerDataElementsForName2() { + @OptIn(ExperimentalStdlibApi::class) + val reversedFilteredLocalScopes = buildList { + val reversedFilteredLocalScopes by lazy(LazyThreadSafetyMode.NONE) { + @OptIn(ExperimentalStdlibApi::class) + buildList { + for (i in lastIndex downTo 0) { + add("") + } + } + } + add(reversedFilteredLocalScopes) + } +} + +internal class TowerDataElementsForName3() { + val reversedFilteredLocalScopes by lazy(LazyThreadSafetyMode.NONE) { + @OptIn(ExperimentalStdlibApi::class) + buildList l1@ { + for (i in lastIndex downTo 0) { + val reversedFilteredLocalScopes by lazy(LazyThreadSafetyMode.NONE) { + @OptIn(ExperimentalStdlibApi::class) + buildList { + for (i in lastIndex downTo 0) { + add("") + this@l1.add("") + } + } + } + } + } + } +} // mute due to KT-48633 //internal class TowerDataElementsForName4() { @@ -68,8 +68,8 @@ internal class TowerDataElementsForName() { fun box(): String { val x1 = TowerDataElementsForName().reversedFilteredLocalScopes -// val x2 = TowerDataElementsForName2().reversedFilteredLocalScopes -// val x3 = TowerDataElementsForName3().reversedFilteredLocalScopes + val x2 = TowerDataElementsForName2().reversedFilteredLocalScopes + val x3 = TowerDataElementsForName3().reversedFilteredLocalScopes // val x4 = TowerDataElementsForName4().reversedFilteredLocalScopes return "OK" } \ No newline at end of file