From c588bc604d2eabf68be063cff91b9685fccd2ef6 Mon Sep 17 00:00:00 2001 From: Victor Petukhov Date: Mon, 6 Jul 2020 16:23:52 +0300 Subject: [PATCH] NI: do substitution stub types during updating trace for lambda (these stub types can appear from the builder inference as postponed variables) ^KT-40060 Fixed --- .../ir/FirBlackBoxCodegenTestGenerated.java | 5 ++++ .../calls/tower/ResolvedAtomCompleter.kt | 28 +++++++++++++++++-- ...teStubTypeIntolambdaParameterDescriptor.kt | 24 ++++++++++++++++ .../codegen/BlackBoxCodegenTestGenerated.java | 5 ++++ .../LightAnalysisModeTestGenerated.java | 5 ++++ .../ir/IrBlackBoxCodegenTestGenerated.java | 5 ++++ .../impl/VariableDescriptorImpl.java | 3 +- .../IrJsCodegenBoxES6TestGenerated.java | 10 +++---- .../IrJsCodegenBoxTestGenerated.java | 10 +++---- .../semantics/JsCodegenBoxTestGenerated.java | 10 +++---- 10 files changed, 87 insertions(+), 18 deletions(-) create mode 100644 compiler/testData/codegen/box/builderInference/substituteStubTypeIntolambdaParameterDescriptor.kt diff --git a/compiler/fir/fir2ir/tests/org/jetbrains/kotlin/codegen/ir/FirBlackBoxCodegenTestGenerated.java b/compiler/fir/fir2ir/tests/org/jetbrains/kotlin/codegen/ir/FirBlackBoxCodegenTestGenerated.java index 8d9ed6fceab..fc23a157949 100644 --- a/compiler/fir/fir2ir/tests/org/jetbrains/kotlin/codegen/ir/FirBlackBoxCodegenTestGenerated.java +++ b/compiler/fir/fir2ir/tests/org/jetbrains/kotlin/codegen/ir/FirBlackBoxCodegenTestGenerated.java @@ -1707,6 +1707,11 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT public void testLackOfNullCheckOnNullableInsideBuild() throws Exception { runTest("compiler/testData/codegen/box/builderInference/lackOfNullCheckOnNullableInsideBuild.kt"); } + + @TestMetadata("substituteStubTypeIntolambdaParameterDescriptor.kt") + public void testSubstituteStubTypeIntolambdaParameterDescriptor() throws Exception { + runTest("compiler/testData/codegen/box/builderInference/substituteStubTypeIntolambdaParameterDescriptor.kt"); + } } @TestMetadata("compiler/testData/codegen/box/builtinStubMethods") diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tower/ResolvedAtomCompleter.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tower/ResolvedAtomCompleter.kt index d1cd7bfaec5..4f405b74530 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tower/ResolvedAtomCompleter.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tower/ResolvedAtomCompleter.kt @@ -10,6 +10,7 @@ import org.jetbrains.kotlin.builtins.createFunctionType import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.descriptors.impl.FunctionDescriptorImpl import org.jetbrains.kotlin.descriptors.impl.ReceiverParameterDescriptorImpl +import org.jetbrains.kotlin.descriptors.impl.ValueParameterDescriptorImpl import org.jetbrains.kotlin.psi.KtElement import org.jetbrains.kotlin.psi.KtExpression import org.jetbrains.kotlin.psi.KtNamedFunction @@ -209,13 +210,24 @@ class ResolvedAtomCompleter( resultSubstitutor.safeSubstitute(lambda.returnType) } + val approximatedValueParameterTypes = lambda.parameters.map { + // Do substitution and approximation only for stub types, which can appear from builder inference (as postponed variables) + if (it is StubType) { + typeApproximator.approximateDeclarationType( + resultSubstitutor.safeSubstitute(it), + local = true, + languageVersionSettings = topLevelCallContext.languageVersionSettings + ) + } else it + } + val approximatedReturnType = typeApproximator.approximateDeclarationType( returnType, local = true, languageVersionSettings = topLevelCallContext.languageVersionSettings ) - updateTraceForLambda(lambda, topLevelTrace, approximatedReturnType) + updateTraceForLambda(lambda, topLevelTrace, approximatedReturnType, approximatedValueParameterTypes) for (lambdaResult in resultArgumentsInfo.nonErrorArguments) { val resultValueArgument = lambdaResult as? PSIKotlinCallArgument ?: continue @@ -235,7 +247,12 @@ class ResolvedAtomCompleter( } } - private fun updateTraceForLambda(lambda: ResolvedLambdaAtom, trace: BindingTrace, returnType: UnwrappedType) { + private fun updateTraceForLambda( + lambda: ResolvedLambdaAtom, + trace: BindingTrace, + returnType: UnwrappedType, + valueParameters: List + ) { val psiCallArgument = lambda.atom.psiCallArgument val ktArgumentExpression: KtExpression @@ -254,8 +271,15 @@ class ResolvedAtomCompleter( val functionDescriptor = trace.bindingContext.get(BindingContext.FUNCTION, ktFunction) as? FunctionDescriptorImpl ?: throw AssertionError("No function descriptor for resolved lambda argument") + functionDescriptor.setReturnType(returnType) + for ((i, valueParameter) in functionDescriptor.valueParameters.withIndex()) { + if (valueParameter !is ValueParameterDescriptorImpl || valueParameter.type !is StubType) + continue + valueParameter.setOutType(valueParameters[i]) + } + val existingLambdaType = trace.getType(ktArgumentExpression) if (existingLambdaType == null) { if (ktFunction is KtNamedFunction && ktFunction.nameIdentifier != null) return // it's a statement diff --git a/compiler/testData/codegen/box/builderInference/substituteStubTypeIntolambdaParameterDescriptor.kt b/compiler/testData/codegen/box/builderInference/substituteStubTypeIntolambdaParameterDescriptor.kt new file mode 100644 index 00000000000..b4c5fea00ff --- /dev/null +++ b/compiler/testData/codegen/box/builderInference/substituteStubTypeIntolambdaParameterDescriptor.kt @@ -0,0 +1,24 @@ +// IGNORE_BACKEND_FIR: JVM_IR +// WITH_RUNTIME + +import kotlin.experimental.ExperimentalTypeInference + +class TypeDefinition { + fun parse(parser: (serializedValue: String) -> K?): Unit {} + fun serialize(parser: (value: K) -> Any?): Unit {} +} + +@OptIn(ExperimentalTypeInference::class) +fun defineType(@BuilderInference definition: TypeDefinition.() -> Unit): Unit {} + +fun test() { + defineType { + parse { it as Int } + serialize { it.toString() } + } +} + +fun box(): String { + test() + return "OK" +} diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java index d4e8961cec8..a7cba8b9b13 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java @@ -1727,6 +1727,11 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { public void testLackOfNullCheckOnNullableInsideBuild() throws Exception { runTest("compiler/testData/codegen/box/builderInference/lackOfNullCheckOnNullableInsideBuild.kt"); } + + @TestMetadata("substituteStubTypeIntolambdaParameterDescriptor.kt") + public void testSubstituteStubTypeIntolambdaParameterDescriptor() throws Exception { + runTest("compiler/testData/codegen/box/builderInference/substituteStubTypeIntolambdaParameterDescriptor.kt"); + } } @TestMetadata("compiler/testData/codegen/box/builtinStubMethods") diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java index 2707ac7aac9..d373276e05b 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java @@ -1727,6 +1727,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes public void testLackOfNullCheckOnNullableInsideBuild() throws Exception { runTest("compiler/testData/codegen/box/builderInference/lackOfNullCheckOnNullableInsideBuild.kt"); } + + @TestMetadata("substituteStubTypeIntolambdaParameterDescriptor.kt") + public void testSubstituteStubTypeIntolambdaParameterDescriptor() throws Exception { + runTest("compiler/testData/codegen/box/builderInference/substituteStubTypeIntolambdaParameterDescriptor.kt"); + } } @TestMetadata("compiler/testData/codegen/box/builtinStubMethods") diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java index f86e9508633..43cc85e8fa5 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java @@ -1707,6 +1707,11 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes public void testLackOfNullCheckOnNullableInsideBuild() throws Exception { runTest("compiler/testData/codegen/box/builderInference/lackOfNullCheckOnNullableInsideBuild.kt"); } + + @TestMetadata("substituteStubTypeIntolambdaParameterDescriptor.kt") + public void testSubstituteStubTypeIntolambdaParameterDescriptor() throws Exception { + runTest("compiler/testData/codegen/box/builderInference/substituteStubTypeIntolambdaParameterDescriptor.kt"); + } } @TestMetadata("compiler/testData/codegen/box/builtinStubMethods") diff --git a/core/descriptors/src/org/jetbrains/kotlin/descriptors/impl/VariableDescriptorImpl.java b/core/descriptors/src/org/jetbrains/kotlin/descriptors/impl/VariableDescriptorImpl.java index fcb022f7c1c..7db3c6fc9f9 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/descriptors/impl/VariableDescriptorImpl.java +++ b/core/descriptors/src/org/jetbrains/kotlin/descriptors/impl/VariableDescriptorImpl.java @@ -22,6 +22,7 @@ import org.jetbrains.kotlin.descriptors.*; import org.jetbrains.kotlin.descriptors.annotations.Annotations; import org.jetbrains.kotlin.name.Name; import org.jetbrains.kotlin.types.KotlinType; +import org.jetbrains.kotlin.types.StubType; import java.util.Collection; import java.util.Collections; @@ -49,7 +50,7 @@ public abstract class VariableDescriptorImpl extends DeclarationDescriptorNonRoo } public void setOutType(KotlinType outType) { - assert this.outType == null; + assert this.outType == null || this.outType instanceof StubType; this.outType = outType; } diff --git a/js/js.tests/test/org/jetbrains/kotlin/js/test/es6/semantics/IrJsCodegenBoxES6TestGenerated.java b/js/js.tests/test/org/jetbrains/kotlin/js/test/es6/semantics/IrJsCodegenBoxES6TestGenerated.java index 8f4199a5d7e..f3fd2ff4edc 100644 --- a/js/js.tests/test/org/jetbrains/kotlin/js/test/es6/semantics/IrJsCodegenBoxES6TestGenerated.java +++ b/js/js.tests/test/org/jetbrains/kotlin/js/test/es6/semantics/IrJsCodegenBoxES6TestGenerated.java @@ -41,11 +41,6 @@ public class IrJsCodegenBoxES6TestGenerated extends AbstractIrJsCodegenBoxES6Tes KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/annotations"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JS_IR_ES6, true); } - @TestMetadata("constValInAnnotation.kt") - public void testConstValInAnnotation() throws Exception { - runTest("compiler/testData/codegen/box/annotations/constValInAnnotation.kt"); - } - @TestMetadata("nestedAnnotation.kt") public void testNestedAnnotation() throws Exception { runTest("compiler/testData/codegen/box/annotations/nestedAnnotation.kt"); @@ -1327,6 +1322,11 @@ public class IrJsCodegenBoxES6TestGenerated extends AbstractIrJsCodegenBoxES6Tes public void testLackOfNullCheckOnNullableInsideBuild() throws Exception { runTest("compiler/testData/codegen/box/builderInference/lackOfNullCheckOnNullableInsideBuild.kt"); } + + @TestMetadata("substituteStubTypeIntolambdaParameterDescriptor.kt") + public void testSubstituteStubTypeIntolambdaParameterDescriptor() throws Exception { + runTest("compiler/testData/codegen/box/builderInference/substituteStubTypeIntolambdaParameterDescriptor.kt"); + } } @TestMetadata("compiler/testData/codegen/box/builtinStubMethods") diff --git a/js/js.tests/test/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenBoxTestGenerated.java b/js/js.tests/test/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenBoxTestGenerated.java index e0350ec9902..d8417ea1750 100644 --- a/js/js.tests/test/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenBoxTestGenerated.java +++ b/js/js.tests/test/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenBoxTestGenerated.java @@ -41,11 +41,6 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest { KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/annotations"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JS_IR, true); } - @TestMetadata("constValInAnnotation.kt") - public void testConstValInAnnotation() throws Exception { - runTest("compiler/testData/codegen/box/annotations/constValInAnnotation.kt"); - } - @TestMetadata("nestedAnnotation.kt") public void testNestedAnnotation() throws Exception { runTest("compiler/testData/codegen/box/annotations/nestedAnnotation.kt"); @@ -1337,6 +1332,11 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest { public void testLackOfNullCheckOnNullableInsideBuild() throws Exception { runTest("compiler/testData/codegen/box/builderInference/lackOfNullCheckOnNullableInsideBuild.kt"); } + + @TestMetadata("substituteStubTypeIntolambdaParameterDescriptor.kt") + public void testSubstituteStubTypeIntolambdaParameterDescriptor() throws Exception { + runTest("compiler/testData/codegen/box/builderInference/substituteStubTypeIntolambdaParameterDescriptor.kt"); + } } @TestMetadata("compiler/testData/codegen/box/builtinStubMethods") diff --git a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java index 4cb258467a0..2088c5d49d1 100644 --- a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java +++ b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java @@ -41,11 +41,6 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest { KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/annotations"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JS, true); } - @TestMetadata("constValInAnnotation.kt") - public void testConstValInAnnotation() throws Exception { - runTest("compiler/testData/codegen/box/annotations/constValInAnnotation.kt"); - } - @TestMetadata("nestedAnnotation.kt") public void testNestedAnnotation() throws Exception { runTest("compiler/testData/codegen/box/annotations/nestedAnnotation.kt"); @@ -1337,6 +1332,11 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest { public void testLackOfNullCheckOnNullableInsideBuild() throws Exception { runTest("compiler/testData/codegen/box/builderInference/lackOfNullCheckOnNullableInsideBuild.kt"); } + + @TestMetadata("substituteStubTypeIntolambdaParameterDescriptor.kt") + public void testSubstituteStubTypeIntolambdaParameterDescriptor() throws Exception { + runTest("compiler/testData/codegen/box/builderInference/substituteStubTypeIntolambdaParameterDescriptor.kt"); + } } @TestMetadata("compiler/testData/codegen/box/builtinStubMethods")