From cbf1d773f75aee5440479f532d001c5a9fc51684 Mon Sep 17 00:00:00 2001 From: Dmitriy Novozhilov Date: Wed, 6 Mar 2019 11:34:47 +0300 Subject: [PATCH] NI. Coerce return type of lambda function descriptor to Unit. #KT-30242 Fixed --- .../calls/tower/ResolvedAtomCompleter.kt | 28 ++++++-- .../tests/inference/coercionToUnit/kt30242.kt | 64 +++++++++++++++++++ .../inference/coercionToUnit/kt30242.txt | 18 ++++++ .../checkers/DiagnosticsTestGenerated.java | 5 ++ .../DiagnosticsUsingJavacTestGenerated.java | 5 ++ 5 files changed, 115 insertions(+), 5 deletions(-) create mode 100644 compiler/testData/diagnostics/tests/inference/coercionToUnit/kt30242.kt create mode 100644 compiler/testData/diagnostics/tests/inference/coercionToUnit/kt30242.txt 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 e533ca8f39c..38660494f2a 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 @@ -31,13 +31,12 @@ import org.jetbrains.kotlin.resolve.calls.tasks.ExplicitReceiverKind import org.jetbrains.kotlin.resolve.calls.tasks.TracingStrategyImpl import org.jetbrains.kotlin.resolve.calls.util.CallMaker import org.jetbrains.kotlin.resolve.deprecation.DeprecationResolver -import org.jetbrains.kotlin.types.IndexedParametersSubstitution -import org.jetbrains.kotlin.types.TypeUtils -import org.jetbrains.kotlin.types.UnwrappedType -import org.jetbrains.kotlin.types.Variance +import org.jetbrains.kotlin.types.* import org.jetbrains.kotlin.types.expressions.DoubleColonExpressionResolver import org.jetbrains.kotlin.types.expressions.ExpressionTypingServices import org.jetbrains.kotlin.types.typeUtil.asTypeProjection +import org.jetbrains.kotlin.types.typeUtil.isUnit +import org.jetbrains.kotlin.utils.addToStdlib.safeAs class ResolvedAtomCompleter( private val resultSubstitutor: NewTypeSubstitutor, @@ -108,8 +107,27 @@ class ResolvedAtomCompleter( return resolvedCall } + private val ResolvedLambdaAtom.isCoercedToUnit: Boolean + get() { + val returnTypes = + resultArguments.mapNotNull { + val type = it.safeAs()?.receiver?.receiverValue?.type ?: return@mapNotNull null + val unwrappedType = when (type) { + is WrappedType -> type.unwrap() + is UnwrappedType -> type + } + resultSubstitutor.safeSubstitute(unwrappedType) + } + val commonReturnType = CommonSupertypes.commonSupertype(returnTypes) + return commonReturnType.isUnit() + } + private fun completeLambda(lambda: ResolvedLambdaAtom) { - val returnType = resultSubstitutor.safeSubstitute(lambda.returnType) + val returnType = if (lambda.isCoercedToUnit) { + builtIns.unitType + } else { + resultSubstitutor.safeSubstitute(lambda.returnType) + } updateTraceForLambda(lambda, topLevelTrace, returnType) diff --git a/compiler/testData/diagnostics/tests/inference/coercionToUnit/kt30242.kt b/compiler/testData/diagnostics/tests/inference/coercionToUnit/kt30242.kt new file mode 100644 index 00000000000..88859a3e087 --- /dev/null +++ b/compiler/testData/diagnostics/tests/inference/coercionToUnit/kt30242.kt @@ -0,0 +1,64 @@ +// !WITH_NEW_INFERENCE +// !DIAGNOSTICS: -UNUSED_PARAMETER +// ISSUE: KT-30242 + +class A + +fun println(s: String = "") {} + +fun foo(f: () -> Any) {} + +fun test1(b: Boolean) { + foo { + if (b) { + println("meh") + } + } +} + +fun test2(b: Boolean) { + foo { + when { + b -> println("meh") + } + } +} + +fun test3(b: Boolean) { + foo { + if (b) { + return@foo A() + } + } +} + +fun test4(b: Boolean) { + foo { + if (b) { + return@foo println("meh") + } + + if (b) { + println() + } + } +} + +fun bar(block: () -> String) {} + +fun test_5(b: Boolean) { + bar { + if (b) { + println("meh") + } + } +} + +fun test_6(b: Boolean) { + foo { + if (b) { + return@foo Unit + } + if (b) {} + } +} \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/inference/coercionToUnit/kt30242.txt b/compiler/testData/diagnostics/tests/inference/coercionToUnit/kt30242.txt new file mode 100644 index 00000000000..0f8b73f7584 --- /dev/null +++ b/compiler/testData/diagnostics/tests/inference/coercionToUnit/kt30242.txt @@ -0,0 +1,18 @@ +package + +public fun bar(/*0*/ block: () -> kotlin.String): kotlin.Unit +public fun foo(/*0*/ f: () -> kotlin.Any): kotlin.Unit +public fun println(/*0*/ s: kotlin.String = ...): kotlin.Unit +public fun test1(/*0*/ b: kotlin.Boolean): kotlin.Unit +public fun test2(/*0*/ b: kotlin.Boolean): kotlin.Unit +public fun test3(/*0*/ b: kotlin.Boolean): kotlin.Unit +public fun test4(/*0*/ b: kotlin.Boolean): kotlin.Unit +public fun test_5(/*0*/ b: kotlin.Boolean): kotlin.Unit +public fun test_6(/*0*/ b: kotlin.Boolean): kotlin.Unit + +public final class A { + public constructor A() + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} diff --git a/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java index 7aa173791f7..ac6d8c09f60 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java @@ -9805,6 +9805,11 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTest { runTest("compiler/testData/diagnostics/tests/inference/coercionToUnit/indirectCoercionWithExpectedType.kt"); } + @TestMetadata("kt30242.kt") + public void testKt30242() throws Exception { + runTest("compiler/testData/diagnostics/tests/inference/coercionToUnit/kt30242.kt"); + } + @TestMetadata("noCoercion.kt") public void testNoCoercion() throws Exception { runTest("compiler/testData/diagnostics/tests/inference/coercionToUnit/noCoercion.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsUsingJavacTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsUsingJavacTestGenerated.java index 96e3b60f822..6588e3c76f4 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsUsingJavacTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsUsingJavacTestGenerated.java @@ -9800,6 +9800,11 @@ public class DiagnosticsUsingJavacTestGenerated extends AbstractDiagnosticsUsing runTest("compiler/testData/diagnostics/tests/inference/coercionToUnit/indirectCoercionWithExpectedType.kt"); } + @TestMetadata("kt30242.kt") + public void testKt30242() throws Exception { + runTest("compiler/testData/diagnostics/tests/inference/coercionToUnit/kt30242.kt"); + } + @TestMetadata("noCoercion.kt") public void testNoCoercion() throws Exception { runTest("compiler/testData/diagnostics/tests/inference/coercionToUnit/noCoercion.kt");