From 5f9357eb41cd0bfc4de8eed1fcb152748e118a05 Mon Sep 17 00:00:00 2001 From: Jinseong Jeon Date: Tue, 9 Feb 2021 23:37:29 -0800 Subject: [PATCH] FIR: transform implicit type ref in anonymous function arguments & body ^KT-45010 Fixed --- ...irOldFrontendDiagnosticsTestGenerated.java | 6 ++++ ...rCallCompletionResultsWriterTransformer.kt | 33 ++++++++++++++++++- .../lambdaArgumentOfInapplicableCall.fir.kt | 6 ++++ .../lambdaArgumentOfInapplicableCall.kt | 6 ++++ .../lambdaArgumentOfInapplicableCall.txt | 3 ++ .../test/runners/DiagnosticTestGenerated.java | 6 ++++ 6 files changed, 59 insertions(+), 1 deletion(-) create mode 100644 compiler/testData/diagnostics/testsWithStdLib/resolve/lambdaArgumentOfInapplicableCall.fir.kt create mode 100644 compiler/testData/diagnostics/testsWithStdLib/resolve/lambdaArgumentOfInapplicableCall.kt create mode 100644 compiler/testData/diagnostics/testsWithStdLib/resolve/lambdaArgumentOfInapplicableCall.txt 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 b377e3129e6..57943e90f00 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 @@ -34693,6 +34693,12 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirDiagnosti runTest("compiler/testData/diagnostics/testsWithStdLib/resolve/kt4711.kt"); } + @Test + @TestMetadata("lambdaArgumentOfInapplicableCall.kt") + public void testLambdaArgumentOfInapplicableCall() throws Exception { + runTest("compiler/testData/diagnostics/testsWithStdLib/resolve/lambdaArgumentOfInapplicableCall.kt"); + } + @Test @TestMetadata("samAgainstFunctionalType.kt") public void testSamAgainstFunctionalType() throws Exception { diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirCallCompletionResultsWriterTransformer.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirCallCompletionResultsWriterTransformer.kt index fe7d1d2ad96..11b470461b0 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirCallCompletionResultsWriterTransformer.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirCallCompletionResultsWriterTransformer.kt @@ -9,6 +9,7 @@ import org.jetbrains.kotlin.descriptors.ClassKind import org.jetbrains.kotlin.fir.* import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.diagnostics.ConeSimpleDiagnostic +import org.jetbrains.kotlin.fir.diagnostics.DiagnosticKind import org.jetbrains.kotlin.fir.expressions.* import org.jetbrains.kotlin.fir.references.builder.buildErrorNamedReference import org.jetbrains.kotlin.fir.references.builder.buildResolvedCallableReference @@ -436,7 +437,10 @@ class FirCallCompletionResultsWriterTransformer( // Control flow info is necessary prerequisite because we collect return expressions in that function // // Example: second lambda in the call like list.filter({}, {}) - if (!dataFlowAnalyzer.isThereControlFlowInfoForAnonymousFunction(anonymousFunction)) return anonymousFunction.compose() + if (!dataFlowAnalyzer.isThereControlFlowInfoForAnonymousFunction(anonymousFunction)) { + // But, don't leave implicit type refs behind + return transformImplicitTypeRefInAnonymousFunction(anonymousFunction) + } val expectedType = data?.getExpectedType(anonymousFunction)?.let { expectedArgumentType -> // From the argument mapping, the expected type of this anonymous function would be: @@ -509,6 +513,33 @@ class FirCallCompletionResultsWriterTransformer( return result } + private fun transformImplicitTypeRefInAnonymousFunction( + anonymousFunction: FirAnonymousFunction + ): CompositeTransformResult { + val implicitTypeTransformer = object : FirDefaultTransformer() { + override fun transformElement(element: E, data: Nothing?): CompositeTransformResult { + @Suppress("UNCHECKED_CAST") + return (element.transformChildren(this, data) as E).compose() + } + + override fun transformImplicitTypeRef( + implicitTypeRef: FirImplicitTypeRef, + data: Nothing? + ): CompositeTransformResult = + buildErrorTypeRef { + source = implicitTypeRef.source + // NB: this error message assumes that it is used only if CFG for the anonymous function is not available + diagnostic = ConeSimpleDiagnostic("Cannot infer type w/o CFG", DiagnosticKind.InferenceError) + }.compose() + + } + // NB: if we transform simply all children, there would be too many type error reports. + anonymousFunction.transformReturnTypeRef(implicitTypeTransformer, null) + anonymousFunction.transformValueParameters(implicitTypeTransformer, null) + anonymousFunction.transformBody(implicitTypeTransformer, null) + return anonymousFunction.compose() + } + override fun transformReturnExpression( returnExpression: FirReturnExpression, data: ExpectedArgumentType? diff --git a/compiler/testData/diagnostics/testsWithStdLib/resolve/lambdaArgumentOfInapplicableCall.fir.kt b/compiler/testData/diagnostics/testsWithStdLib/resolve/lambdaArgumentOfInapplicableCall.fir.kt new file mode 100644 index 00000000000..77ad857b90f --- /dev/null +++ b/compiler/testData/diagnostics/testsWithStdLib/resolve/lambdaArgumentOfInapplicableCall.fir.kt @@ -0,0 +1,6 @@ +// KT-45010 +fun foo(map: MutableMap) { + map.getOrPut("Not an Int") { + "Hello" + " world" + } +} diff --git a/compiler/testData/diagnostics/testsWithStdLib/resolve/lambdaArgumentOfInapplicableCall.kt b/compiler/testData/diagnostics/testsWithStdLib/resolve/lambdaArgumentOfInapplicableCall.kt new file mode 100644 index 00000000000..c0230d29839 --- /dev/null +++ b/compiler/testData/diagnostics/testsWithStdLib/resolve/lambdaArgumentOfInapplicableCall.kt @@ -0,0 +1,6 @@ +// KT-45010 +fun foo(map: MutableMap) { + map.getOrPut("Not an Int") { + "Hello" + " world" + } +} diff --git a/compiler/testData/diagnostics/testsWithStdLib/resolve/lambdaArgumentOfInapplicableCall.txt b/compiler/testData/diagnostics/testsWithStdLib/resolve/lambdaArgumentOfInapplicableCall.txt new file mode 100644 index 00000000000..0b1efc91e1b --- /dev/null +++ b/compiler/testData/diagnostics/testsWithStdLib/resolve/lambdaArgumentOfInapplicableCall.txt @@ -0,0 +1,3 @@ +package + +public fun foo(/*0*/ map: kotlin.collections.MutableMap): kotlin.Unit 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 f9a9f827efc..65516cfb384 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 @@ -34789,6 +34789,12 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest { runTest("compiler/testData/diagnostics/testsWithStdLib/resolve/kt4711.kt"); } + @Test + @TestMetadata("lambdaArgumentOfInapplicableCall.kt") + public void testLambdaArgumentOfInapplicableCall() throws Exception { + runTest("compiler/testData/diagnostics/testsWithStdLib/resolve/lambdaArgumentOfInapplicableCall.kt"); + } + @Test @TestMetadata("samAgainstFunctionalType.kt") public void testSamAgainstFunctionalType() throws Exception { -- GitLab