From 896fbbd1a3db32022f845e4ebe54dbd4bfd821a4 Mon Sep 17 00:00:00 2001 From: Pavel Kirpichenkov Date: Thu, 17 Sep 2020 14:39:22 +0300 Subject: [PATCH] [NI] Add extra ordering for ready-for-fixation variables Helps fixing to more specific type in the following situations: Type1 <: Var1 Var2 <: Var1 Var2 <: Type2 Type1 and Type2 may also be nullable and non-nullable versions of the same type. Note that no additional constraints can be inferred from such constraints before fixation. Resulting types for variables will always Type1 and Type2 may also be nullable and non-nullable versions of the same type. Fixing Var1 first will make Var2's type more specific while fixing Var2 first will make Var1's type less specific. The first is preferrable in general. --- .../fir/FirOldFrontendDiagnosticsTestGenerated.java | 5 +++++ .../inference/components/VariableFixationFinder.kt | 13 +++++++++++-- .../tests/inference/regressions/kt41394.kt | 12 ++++++++++++ .../tests/inference/regressions/kt41394.txt | 5 +++++ .../kotlin/checkers/DiagnosticsTestGenerated.java | 5 +++++ .../javac/DiagnosticsUsingJavacTestGenerated.java | 5 +++++ 6 files changed, 43 insertions(+), 2 deletions(-) create mode 100644 compiler/testData/diagnostics/tests/inference/regressions/kt41394.kt create mode 100644 compiler/testData/diagnostics/tests/inference/regressions/kt41394.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 dde88a06cbf..f8d08311aed 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 @@ -11965,6 +11965,11 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirOldFronte runTest("compiler/testData/diagnostics/tests/inference/regressions/kt41386.kt"); } + @TestMetadata("kt41394.kt") + public void testKt41394() throws Exception { + runTest("compiler/testData/diagnostics/tests/inference/regressions/kt41394.kt"); + } + @TestMetadata("kt4420.kt") public void testKt4420() throws Exception { runTest("compiler/testData/diagnostics/tests/inference/regressions/kt4420.kt"); diff --git a/compiler/resolution.common/src/org/jetbrains/kotlin/resolve/calls/inference/components/VariableFixationFinder.kt b/compiler/resolution.common/src/org/jetbrains/kotlin/resolve/calls/inference/components/VariableFixationFinder.kt index f0d2f8ff214..b5165624d5a 100644 --- a/compiler/resolution.common/src/org/jetbrains/kotlin/resolve/calls/inference/components/VariableFixationFinder.kt +++ b/compiler/resolution.common/src/org/jetbrains/kotlin/resolve/calls/inference/components/VariableFixationFinder.kt @@ -42,7 +42,8 @@ class VariableFixationFinder( WITH_TRIVIAL_OR_NON_PROPER_CONSTRAINTS, // proper trivial constraint from arguments, Nothing <: T RELATED_TO_ANY_OUTPUT_TYPE, FROM_INCORPORATION_OF_DECLARED_UPPER_BOUND, - READY_FOR_FIXATION, + READY_FOR_FIXATION_UPPER, + READY_FOR_FIXATION_LOWER, READY_FOR_FIXATION_REIFIED, } @@ -59,7 +60,8 @@ class VariableFixationFinder( variableHasOnlyIncorporatedConstraintsFromDeclaredUpperBound(variable) -> TypeVariableFixationReadiness.FROM_INCORPORATION_OF_DECLARED_UPPER_BOUND isReified(variable) -> TypeVariableFixationReadiness.READY_FOR_FIXATION_REIFIED - else -> TypeVariableFixationReadiness.READY_FOR_FIXATION + !variableHasLowerProperConstraint(variable) -> TypeVariableFixationReadiness.READY_FOR_FIXATION_UPPER + else -> TypeVariableFixationReadiness.READY_FOR_FIXATION_LOWER } fun isTypeVariableHasProperConstraint(context: Context, typeVariable: TypeConstructorMarker): Boolean { @@ -135,6 +137,13 @@ class VariableFixationFinder( private fun Context.isReified(variable: TypeConstructorMarker): Boolean = notFixedTypeVariables[variable]?.typeVariable?.let { isReified(it) } ?: false + + private fun Context.variableHasLowerProperConstraint(variable: TypeConstructorMarker): Boolean = + notFixedTypeVariables[variable]?.constraints?.let { constraints -> + constraints.any { + it.kind.isLower() && isProperArgumentConstraint(it) + } + } ?: false } inline fun TypeSystemInferenceExtensionContext.isProperTypeForFixation( diff --git a/compiler/testData/diagnostics/tests/inference/regressions/kt41394.kt b/compiler/testData/diagnostics/tests/inference/regressions/kt41394.kt new file mode 100644 index 00000000000..9ec5b6d6359 --- /dev/null +++ b/compiler/testData/diagnostics/tests/inference/regressions/kt41394.kt @@ -0,0 +1,12 @@ +// FIR_IDENTICAL +// !DIAGNOSTICS: -UNUSED_PARAMETER -UNUSED_ANONYMOUS_PARAMETER +// !LANGUAGE: +NewInference + +fun foo(x: T, fn: (VR?/*T?*/, T) -> Unit) {} + +fun takeInt(x: Int) {} + +fun main(x: Int) { + foo(x) { prev: Int?, new -> takeInt(new) } // `new` is `Int` in OI, `Int?` in NI + // It seems, `VR` has been fixed to `Int?` instead of `Int` +} \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/inference/regressions/kt41394.txt b/compiler/testData/diagnostics/tests/inference/regressions/kt41394.txt new file mode 100644 index 00000000000..6e5c42d8b2c --- /dev/null +++ b/compiler/testData/diagnostics/tests/inference/regressions/kt41394.txt @@ -0,0 +1,5 @@ +package + +public fun foo(/*0*/ x: T, /*1*/ fn: (VR?, T) -> kotlin.Unit): kotlin.Unit +public fun main(/*0*/ x: kotlin.Int): kotlin.Unit +public fun takeInt(/*0*/ x: kotlin.Int): kotlin.Unit diff --git a/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java index c92cea38c31..a3873696367 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java @@ -11972,6 +11972,11 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTestWithFirVali runTest("compiler/testData/diagnostics/tests/inference/regressions/kt41386.kt"); } + @TestMetadata("kt41394.kt") + public void testKt41394() throws Exception { + runTest("compiler/testData/diagnostics/tests/inference/regressions/kt41394.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 66b886766bd..0ebbd7f2aa8 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsUsingJavacTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsUsingJavacTestGenerated.java @@ -11967,6 +11967,11 @@ public class DiagnosticsUsingJavacTestGenerated extends AbstractDiagnosticsUsing runTest("compiler/testData/diagnostics/tests/inference/regressions/kt41386.kt"); } + @TestMetadata("kt41394.kt") + public void testKt41394() throws Exception { + runTest("compiler/testData/diagnostics/tests/inference/regressions/kt41394.kt"); + } + @TestMetadata("kt4420.kt") public void testKt4420() throws Exception { runTest("compiler/testData/diagnostics/tests/inference/regressions/kt4420.kt");