From 0026560bd7dd82ee682ee9664959f83d5d5a2e33 Mon Sep 17 00:00:00 2001 From: Tianyu Geng Date: Mon, 26 Jul 2021 15:56:56 -0700 Subject: [PATCH] FIR: substitute the whole lambda body after builder inference --- .../inference/FirBuilderInferenceSession.kt | 11 +++++----- .../fir/resolve/inference/FirCallCompleter.kt | 6 ++++- .../inference/builderInference/nullability.kt | 1 - .../constraints/violating.fir.kt | 6 ++--- .../stubTypes/memberScope.fir.kt | 22 +++++++++---------- .../ir/irText/expressions/kt47082.fir.kt.txt | 3 ++- .../ir/irText/expressions/kt47082.fir.txt | 8 +++---- 7 files changed, 30 insertions(+), 27 deletions(-) diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/FirBuilderInferenceSession.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/FirBuilderInferenceSession.kt index 6a54f511fd3..8c629c0a162 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/FirBuilderInferenceSession.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/FirBuilderInferenceSession.kt @@ -7,6 +7,7 @@ package org.jetbrains.kotlin.fir.resolve.inference import org.jetbrains.kotlin.fir.FirElement import org.jetbrains.kotlin.fir.declarations.FirAnnotatedDeclaration +import org.jetbrains.kotlin.fir.declarations.FirAnonymousFunction import org.jetbrains.kotlin.fir.declarations.hasAnnotation import org.jetbrains.kotlin.fir.expressions.FirArgumentList import org.jetbrains.kotlin.fir.expressions.FirResolvable @@ -28,6 +29,7 @@ import org.jetbrains.kotlin.resolve.descriptorUtil.BUILDER_INFERENCE_ANNOTATION_ import org.jetbrains.kotlin.types.model.TypeConstructorMarker class FirBuilderInferenceSession( + private val lambda: FirAnonymousFunction, resolutionContext: ResolutionContext, private val stubsForPostponedVariables: Map, ) : AbstractManyCandidatesInferenceSession(resolutionContext) { @@ -225,19 +227,16 @@ class FirBuilderInferenceSession( return introducedConstraint } - // TODO: besides calls, perhaps use the stub type substitutor for all top-level expressions inside the lambda private fun updateCalls(commonSystem: NewConstraintSystemImpl) { val nonFixedToVariablesSubstitutor = createNonFixedTypeToVariableSubstitutor() val commonSystemSubstitutor = commonSystem.buildCurrentSubstitutor() as ConeSubstitutor val nonFixedTypesToResultSubstitutor = ConeComposedSubstitutor(commonSystemSubstitutor, nonFixedToVariablesSubstitutor) - val completionResultsWriter = components.callCompleter.createCompletionResultsWriter(nonFixedTypesToResultSubstitutor) val stubTypeSubstitutor = FirStubTypeTransformer(nonFixedTypesToResultSubstitutor) - for ((completedCall, _) in commonCalls) { - completedCall.transformSingle(stubTypeSubstitutor, null) - // TODO: support diagnostics, see [CoroutineInferenceSession#updateCalls] - } + lambda.transformSingle(stubTypeSubstitutor, null) + // TODO: support diagnostics, see [CoroutineInferenceSession#updateCalls] + val completionResultsWriter = components.callCompleter.createCompletionResultsWriter(nonFixedTypesToResultSubstitutor) for ((call, _) in partiallyResolvedCalls) { call.transformSingle(completionResultsWriter, null) // TODO: support diagnostics, see [CoroutineInferenceSession#updateCalls] 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 d9f16fed9bb..c741bb9e8f8 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 @@ -272,7 +272,11 @@ class FirCallCompleter( val builderInferenceSession = runIf(stubsForPostponedVariables.isNotEmpty()) { @Suppress("UNCHECKED_CAST") - FirBuilderInferenceSession(transformer.resolutionContext, stubsForPostponedVariables as Map) + FirBuilderInferenceSession( + lambdaArgument, + transformer.resolutionContext, + stubsForPostponedVariables as Map + ) } transformer.context.withAnonymousFunctionTowerDataContext(lambdaArgument.symbol) { diff --git a/compiler/testData/codegen/box/inference/builderInference/nullability.kt b/compiler/testData/codegen/box/inference/builderInference/nullability.kt index 2c897f5ad2c..f719dbabc12 100644 --- a/compiler/testData/codegen/box/inference/builderInference/nullability.kt +++ b/compiler/testData/codegen/box/inference/builderInference/nullability.kt @@ -1,7 +1,6 @@ // !LANGUAGE: +UnrestrictedBuilderInference // !DIAGNOSTICS: -DEPRECATION -EXPERIMENTAL_IS_NOT_ENABLED // WITH_RUNTIME -// IGNORE_BACKEND_FIR: JVM_IR // DONT_TARGET_EXACT_BACKEND: WASM // FILE: main.kt diff --git a/compiler/testData/diagnostics/tests/inference/builderInference/constraints/violating.fir.kt b/compiler/testData/diagnostics/tests/inference/builderInference/constraints/violating.fir.kt index f6731acebde..cf262c15c9a 100644 --- a/compiler/testData/diagnostics/tests/inference/builderInference/constraints/violating.fir.kt +++ b/compiler/testData/diagnostics/tests/inference/builderInference/constraints/violating.fir.kt @@ -10,7 +10,7 @@ fun main() { buildList { add(3) object : A { - override fun foo(): MutableList = this@buildList + override fun foo(): MutableList = this@buildList } } buildList { @@ -19,12 +19,12 @@ fun main() { } buildList { add("3") - val x: MutableList = this@buildList + val x: MutableList = this@buildList } buildList { val y: CharSequence = "" add(y) - val x: MutableList = this@buildList + val x: MutableList = this@buildList } buildList { add("") diff --git a/compiler/testData/diagnostics/tests/inference/builderInference/stubTypes/memberScope.fir.kt b/compiler/testData/diagnostics/tests/inference/builderInference/stubTypes/memberScope.fir.kt index 675106f6275..2b772126b58 100644 --- a/compiler/testData/diagnostics/tests/inference/builderInference/stubTypes/memberScope.fir.kt +++ b/compiler/testData/diagnostics/tests/inference/builderInference/stubTypes/memberScope.fir.kt @@ -37,8 +37,8 @@ fun test() { get()?.hashCode() get()?.equals(1) val x = get() - x?.hashCode() - x?.equals(1) + x?.hashCode() + x?.equals(1) x.equals("") } val ret3 = build { @@ -50,20 +50,20 @@ fun test() { get()?.hashCode() get()?.equals(1) val x = get() - x?.hashCode() - x?.equals(1) + x?.hashCode() + x?.equals(1) if (get() == null) {} if (get() === null) {} if (x != null) { - x?.hashCode() - x?.equals(1) + x?.hashCode() + x?.equals(1) x.equals("") x.hashCode() x.toString() x.test() - x?.test2() + x?.test2() x.test2() } @@ -166,8 +166,8 @@ fun test() { get()?.hashCode() get()?.equals(1) val x = get() - x?.hashCode() - x?.equals(1) + x?.hashCode() + x?.equals(1) if (get() == null) {} if (get() === null) {} @@ -296,8 +296,8 @@ fun test() { get()?.hashCode() get()?.equals(1) val x = get() - x?.hashCode() - x?.equals(1) + x?.hashCode() + x?.equals(1) if (get() == null) {} if (get() === null) {} diff --git a/compiler/testData/ir/irText/expressions/kt47082.fir.kt.txt b/compiler/testData/ir/irText/expressions/kt47082.fir.kt.txt index f8b9aec78df..fc0ff9bc90e 100644 --- a/compiler/testData/ir/irText/expressions/kt47082.fir.kt.txt +++ b/compiler/testData/ir/irText/expressions/kt47082.fir.kt.txt @@ -19,7 +19,7 @@ fun > Receiver.toChannel(destination: C): C { } fun foo(r: Receiver): R { - return produce(block = local fun Derived.() { + return produce(block = local fun Derived.() { r.toChannel>(destination = ) /*~> Unit */ } ) @@ -28,3 +28,4 @@ fun foo(r: Receiver): R { fun box(): String { return "OK" } + diff --git a/compiler/testData/ir/irText/expressions/kt47082.fir.txt b/compiler/testData/ir/irText/expressions/kt47082.fir.txt index 39377efad42..bed18a2041c 100644 --- a/compiler/testData/ir/irText/expressions/kt47082.fir.txt +++ b/compiler/testData/ir/irText/expressions/kt47082.fir.txt @@ -72,16 +72,16 @@ FILE fqName: fileName:/kt47082.kt RETURN type=kotlin.Nothing from='public final fun foo (r: .Receiver.foo>): R of .foo declared in ' CALL 'public final fun produce (block: @[ExtensionFunctionType] kotlin.Function1<.Derived.produce>, kotlin.Unit>): E of .produce declared in ' type=R of .foo origin=null : R of .foo - block: FUN_EXPR type=kotlin.Function1<.Derived.foo>, kotlin.Unit> origin=LAMBDA - FUN LOCAL_FUNCTION_FOR_LAMBDA name: visibility:local modality:FINAL <> ($receiver:.Derived.foo>) returnType:kotlin.Unit - $receiver: VALUE_PARAMETER name: type:.Derived.foo> + block: FUN_EXPR type=kotlin.Function1<.Derived, kotlin.Unit> origin=LAMBDA + FUN LOCAL_FUNCTION_FOR_LAMBDA name: visibility:local modality:FINAL <> ($receiver:.Derived) returnType:kotlin.Unit + $receiver: VALUE_PARAMETER name: type:.Derived BLOCK_BODY TYPE_OP type=kotlin.Unit origin=IMPLICIT_COERCION_TO_UNIT typeOperand=kotlin.Unit CALL 'public final fun toChannel (destination: C of .toChannel): C of .toChannel declared in ' type=.Derived origin=null : R of .foo : .Derived $receiver: GET_VAR 'r: .Receiver.foo> declared in .foo' type=.Receiver.foo> origin=null - destination: GET_VAR ': .Derived.foo> declared in .foo.' type=.Derived origin=null + destination: GET_VAR ': .Derived declared in .foo.' type=.Derived origin=null FUN name:box visibility:public modality:FINAL <> () returnType:kotlin.String BLOCK_BODY RETURN type=kotlin.Nothing from='public final fun box (): kotlin.String declared in '