[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.
This commit is contained in:
+5
@@ -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");
|
||||
|
||||
+11
-2
@@ -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(
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
// FIR_IDENTICAL
|
||||
// !DIAGNOSTICS: -UNUSED_PARAMETER -UNUSED_ANONYMOUS_PARAMETER
|
||||
// !LANGUAGE: +NewInference
|
||||
|
||||
fun <T, VR : T> 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`
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
package
|
||||
|
||||
public fun </*0*/ T, /*1*/ VR : T> 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
|
||||
@@ -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");
|
||||
|
||||
Generated
+5
@@ -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");
|
||||
|
||||
Reference in New Issue
Block a user