[NI] Don't consider Nothing-constraint as proper to complete call

Follow-up of 9b3e17f0. There we decided to complete call if a type
 variable from a return type has proper lower constraints, now we refine
 this rule wrt `Nothing`-like constraints to avoid inferring type variables
 to Nothing, which is quite useless

 #KT-30370 Fixed
This commit is contained in:
Mikhail Zarechenskiy
2019-03-11 13:55:07 +03:00
parent 77ab15ec65
commit 1594c1fc6b
7 changed files with 62 additions and 4 deletions
@@ -8,6 +8,7 @@ package org.jetbrains.kotlin.resolve.calls.components
import org.jetbrains.kotlin.resolve.calls.inference.NewConstraintSystem
import org.jetbrains.kotlin.resolve.calls.inference.components.KotlinConstraintSystemCompleter
import org.jetbrains.kotlin.resolve.calls.inference.components.KotlinConstraintSystemCompleter.ConstraintSystemCompletionMode
import org.jetbrains.kotlin.resolve.calls.inference.components.TrivialConstraintTypeInferenceOracle
import org.jetbrains.kotlin.resolve.calls.inference.model.ConstraintStorage.Empty.hasContradiction
import org.jetbrains.kotlin.resolve.calls.inference.model.ExpectedTypeConstraintPosition
import org.jetbrains.kotlin.resolve.calls.model.*
@@ -21,7 +22,8 @@ import org.jetbrains.kotlin.types.typeUtil.isPrimitiveNumberType
class KotlinCallCompleter(
private val postponedArgumentsAnalyzer: PostponedArgumentsAnalyzer,
private val kotlinConstraintSystemCompleter: KotlinConstraintSystemCompleter
private val kotlinConstraintSystemCompleter: KotlinConstraintSystemCompleter,
private val trivialConstraintTypeInferenceOracle: TrivialConstraintTypeInferenceOracle
) {
fun runCompletion(
@@ -172,7 +174,7 @@ class KotlinCallCompleter(
// This means that there will be no new LOWER constraints =>
// it's possible to complete call now if there are proper LOWER constraints
csBuilder.isTypeVariable(currentReturnType) ->
if (hasProperLowerConstraints(currentReturnType))
if (hasProperNonTrivialLowerConstraints(currentReturnType))
ConstraintSystemCompletionMode.FULL
else
ConstraintSystemCompletionMode.PARTIAL
@@ -181,13 +183,14 @@ class KotlinCallCompleter(
}
}
private fun KotlinResolutionCandidate.hasProperLowerConstraints(typeVariable: UnwrappedType): Boolean {
private fun KotlinResolutionCandidate.hasProperNonTrivialLowerConstraints(typeVariable: UnwrappedType): Boolean {
assert(csBuilder.isTypeVariable(typeVariable)) { "$typeVariable is not a type variable" }
val constructor = typeVariable.constructor
val variableWithConstraints = csBuilder.currentStorage().notFixedTypeVariables[constructor] ?: return false
return variableWithConstraints.constraints.any {
it.kind.isLower() && csBuilder.isProperType(it.type) && !it.type.isIntegerValueType()
!trivialConstraintTypeInferenceOracle.isTrivialConstraint(it) && !it.type.isIntegerValueType() &&
it.kind.isLower() && csBuilder.isProperType(it.type)
}
}
@@ -0,0 +1,30 @@
// !LANGUAGE: +NewInference
// WITH_RUNTIME
inline fun <T> foo(f: () -> T): String {
return (f() as? Inv<T>)?.result() ?: "Bad"
}
class Inv<T> {
fun result(): String = "OK"
}
fun <K> create(): Inv<K> = Inv()
fun test(b: Boolean): String {
return foo {
if (!b) {
return@foo create<String>()
}
if (b) {
create()
} else {
null
}
}
}
fun box(): String {
return test(true)
}
@@ -11834,6 +11834,11 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
public void testKt10822() throws Exception {
runTest("compiler/testData/codegen/box/inference/kt10822.kt");
}
@TestMetadata("lastExpressionOfLambdaWithNothingConstraint.kt")
public void testLastExpressionOfLambdaWithNothingConstraint() throws Exception {
runTest("compiler/testData/codegen/box/inference/lastExpressionOfLambdaWithNothingConstraint.kt");
}
}
@TestMetadata("compiler/testData/codegen/box/inlineClasses")
@@ -11834,6 +11834,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
public void testKt10822() throws Exception {
runTest("compiler/testData/codegen/box/inference/kt10822.kt");
}
@TestMetadata("lastExpressionOfLambdaWithNothingConstraint.kt")
public void testLastExpressionOfLambdaWithNothingConstraint() throws Exception {
runTest("compiler/testData/codegen/box/inference/lastExpressionOfLambdaWithNothingConstraint.kt");
}
}
@TestMetadata("compiler/testData/codegen/box/inlineClasses")
@@ -11839,6 +11839,11 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
public void testKt10822() throws Exception {
runTest("compiler/testData/codegen/box/inference/kt10822.kt");
}
@TestMetadata("lastExpressionOfLambdaWithNothingConstraint.kt")
public void testLastExpressionOfLambdaWithNothingConstraint() throws Exception {
runTest("compiler/testData/codegen/box/inference/lastExpressionOfLambdaWithNothingConstraint.kt");
}
}
@TestMetadata("compiler/testData/codegen/box/inlineClasses")
@@ -9419,6 +9419,11 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest {
public void testKt10822() throws Exception {
runTest("compiler/testData/codegen/box/inference/kt10822.kt");
}
@TestMetadata("lastExpressionOfLambdaWithNothingConstraint.kt")
public void testLastExpressionOfLambdaWithNothingConstraint() throws Exception {
runTest("compiler/testData/codegen/box/inference/lastExpressionOfLambdaWithNothingConstraint.kt");
}
}
@TestMetadata("compiler/testData/codegen/box/inlineClasses")
@@ -10514,6 +10514,11 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest {
public void testKt10822() throws Exception {
runTest("compiler/testData/codegen/box/inference/kt10822.kt");
}
@TestMetadata("lastExpressionOfLambdaWithNothingConstraint.kt")
public void testLastExpressionOfLambdaWithNothingConstraint() throws Exception {
runTest("compiler/testData/codegen/box/inference/lastExpressionOfLambdaWithNothingConstraint.kt");
}
}
@TestMetadata("compiler/testData/codegen/box/inlineClasses")