From 7e3dfb245bffd485272b0de80d00911199ef502e Mon Sep 17 00:00:00 2001 From: Ilya Chernikov Date: Wed, 6 May 2020 22:30:09 +0200 Subject: [PATCH] Avoid skipping lambda argument processing in case of explicit type param #KT-38691 fixed --- ...irOldFrontendDiagnosticsTestGenerated.java | 5 +++++ .../components/PostponeArgumentsChecks.kt | 21 ++++++++++++++----- .../inference/regressions/kt38691.fir.kt | 14 +++++++++++++ .../tests/inference/regressions/kt38691.kt | 14 +++++++++++++ .../tests/inference/regressions/kt38691.txt | 13 ++++++++++++ .../checkers/DiagnosticsTestGenerated.java | 5 +++++ .../DiagnosticsUsingJavacTestGenerated.java | 5 +++++ 7 files changed, 72 insertions(+), 5 deletions(-) create mode 100644 compiler/testData/diagnostics/tests/inference/regressions/kt38691.fir.kt create mode 100644 compiler/testData/diagnostics/tests/inference/regressions/kt38691.kt create mode 100644 compiler/testData/diagnostics/tests/inference/regressions/kt38691.txt diff --git a/compiler/fir/analysis-tests/tests/org/jetbrains/kotlin/fir/FirOldFrontendDiagnosticsTestGenerated.java b/compiler/fir/analysis-tests/tests/org/jetbrains/kotlin/fir/FirOldFrontendDiagnosticsTestGenerated.java index 2ef8a32b41d..64097ca3d60 100644 --- a/compiler/fir/analysis-tests/tests/org/jetbrains/kotlin/fir/FirOldFrontendDiagnosticsTestGenerated.java +++ b/compiler/fir/analysis-tests/tests/org/jetbrains/kotlin/fir/FirOldFrontendDiagnosticsTestGenerated.java @@ -11561,6 +11561,11 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirOldFronte runTest("compiler/testData/diagnostics/tests/inference/regressions/kt37650.kt"); } + @TestMetadata("kt38691.kt") + public void testKt38691() throws Exception { + runTest("compiler/testData/diagnostics/tests/inference/regressions/kt38691.kt"); + } + @TestMetadata("kt4420.kt") public void testKt4420() throws Exception { runTest("compiler/testData/diagnostics/tests/inference/regressions/kt4420.kt"); diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/PostponeArgumentsChecks.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/PostponeArgumentsChecks.kt index ec6f82b9ec0..27ffe26da58 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/PostponeArgumentsChecks.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/PostponeArgumentsChecks.kt @@ -20,11 +20,10 @@ import org.jetbrains.kotlin.builtins.* import org.jetbrains.kotlin.descriptors.annotations.Annotations import org.jetbrains.kotlin.resolve.calls.inference.ConstraintSystemBuilder import org.jetbrains.kotlin.resolve.calls.inference.components.NewTypeSubstitutor -import org.jetbrains.kotlin.resolve.calls.inference.model.ArgumentConstraintPosition -import org.jetbrains.kotlin.resolve.calls.inference.model.LHSArgumentConstraintPosition -import org.jetbrains.kotlin.resolve.calls.inference.model.TypeVariableForLambdaReturnType +import org.jetbrains.kotlin.resolve.calls.inference.model.* import org.jetbrains.kotlin.resolve.calls.model.* import org.jetbrains.kotlin.types.ErrorUtils +import org.jetbrains.kotlin.types.KotlinType import org.jetbrains.kotlin.types.UnwrappedType import org.jetbrains.kotlin.types.Variance import org.jetbrains.kotlin.types.typeUtil.builtIns @@ -63,8 +62,20 @@ private fun preprocessLambdaArgument( forceResolution: Boolean = false, returnTypeVariable: TypeVariableForLambdaReturnType? = null ): ResolvedAtom { - if (expectedType != null && !forceResolution && csBuilder.isTypeVariable(expectedType)) { - return LambdaWithTypeVariableAsExpectedTypeAtom(argument, expectedType) + + if (expectedType != null && !forceResolution) { + // postpone lambda processing if expected type is a type variable that could be fixed into something non-trivial + val expectedTypeVariableWithConstraints = csBuilder.currentStorage().notFixedTypeVariables[expectedType.constructor] + + if (expectedTypeVariableWithConstraints != null) { + val explicitTypeArgument = expectedTypeVariableWithConstraints.constraints.find { + it.kind == ConstraintKind.EQUALITY && it.position.from is ExplicitTypeParameterConstraintPosition + }?.type as? KotlinType + + if (explicitTypeArgument == null || explicitTypeArgument.arguments.isNotEmpty()) { + return LambdaWithTypeVariableAsExpectedTypeAtom(argument, expectedType) + } + } } val resolvedArgument = extractLambdaInfoFromFunctionalType(expectedType, argument, returnTypeVariable) diff --git a/compiler/testData/diagnostics/tests/inference/regressions/kt38691.fir.kt b/compiler/testData/diagnostics/tests/inference/regressions/kt38691.fir.kt new file mode 100644 index 00000000000..b7043dfd76d --- /dev/null +++ b/compiler/testData/diagnostics/tests/inference/regressions/kt38691.fir.kt @@ -0,0 +1,14 @@ +// !LANGUAGE: +NewInference +// !DIAGNOSTICS: -UNUSED_PARAMETER -UNUSED_VARIABLE + +class Inv +fun materializeInv() = Inv() +fun foo(x: Inv, y: X) = materializeInv() +fun foo(x: Inv, y: () -> X) = materializeInv() + +fun main(fn: () -> R) { + fun bar(): R = null as R + val x1 = foo(materializeInv()) { fn() } // OVERLOAD_RESOLUTION_AMBIGUITY only in NI + val x2 = foo(materializeInv(), fn) // OK + val x3 = foo(materializeInv(), ::bar) // OK +} diff --git a/compiler/testData/diagnostics/tests/inference/regressions/kt38691.kt b/compiler/testData/diagnostics/tests/inference/regressions/kt38691.kt new file mode 100644 index 00000000000..07db5b4e2fb --- /dev/null +++ b/compiler/testData/diagnostics/tests/inference/regressions/kt38691.kt @@ -0,0 +1,14 @@ +// !LANGUAGE: +NewInference +// !DIAGNOSTICS: -UNUSED_PARAMETER -UNUSED_VARIABLE + +class Inv +fun materializeInv() = Inv() +fun foo(x: Inv, y: X) = materializeInv() +fun foo(x: Inv, y: () -> X) = materializeInv() + +fun main(fn: () -> R) { + fun bar(): R = null as R + val x1 = foo(materializeInv()) { fn() } // OVERLOAD_RESOLUTION_AMBIGUITY only in NI + val x2 = foo(materializeInv(), fn) // OK + val x3 = foo(materializeInv(), ::bar) // OK +} diff --git a/compiler/testData/diagnostics/tests/inference/regressions/kt38691.txt b/compiler/testData/diagnostics/tests/inference/regressions/kt38691.txt new file mode 100644 index 00000000000..9e0fd239984 --- /dev/null +++ b/compiler/testData/diagnostics/tests/inference/regressions/kt38691.txt @@ -0,0 +1,13 @@ +package + +public fun foo(/*0*/ x: Inv, /*1*/ y: () -> X): Inv +public fun foo(/*0*/ x: Inv, /*1*/ y: X): Inv +public fun main(/*0*/ fn: () -> R): kotlin.Unit +public fun materializeInv(): Inv + +public final class Inv { + public constructor Inv() + 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 94fe68ce5e0..6b1392955de 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java @@ -11568,6 +11568,11 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTestWithFirVali runTest("compiler/testData/diagnostics/tests/inference/regressions/kt37650.kt"); } + @TestMetadata("kt38691.kt") + public void testKt38691() throws Exception { + runTest("compiler/testData/diagnostics/tests/inference/regressions/kt38691.kt"); + } + @TestMetadata("kt4420.kt") public void testKt4420() throws Exception { runTest("compiler/testData/diagnostics/tests/inference/regressions/kt4420.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsUsingJavacTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsUsingJavacTestGenerated.java index 5fd00971eb5..b12bda8f987 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsUsingJavacTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsUsingJavacTestGenerated.java @@ -11563,6 +11563,11 @@ public class DiagnosticsUsingJavacTestGenerated extends AbstractDiagnosticsUsing runTest("compiler/testData/diagnostics/tests/inference/regressions/kt37650.kt"); } + @TestMetadata("kt38691.kt") + public void testKt38691() throws Exception { + runTest("compiler/testData/diagnostics/tests/inference/regressions/kt38691.kt"); + } + @TestMetadata("kt4420.kt") public void testKt4420() throws Exception { runTest("compiler/testData/diagnostics/tests/inference/regressions/kt4420.kt");