[NI] Don't avoid Nothing-like constraints if Nothing was in initial type

#KT-32081 Fixed
 #KT-32951 Fixed
This commit is contained in:
Mikhail Zarechenskiy
2019-06-20 12:58:32 +03:00
parent 4b2175c8f8
commit f3e4c9cdb3
9 changed files with 119 additions and 2 deletions

View File

@@ -10265,6 +10265,16 @@ public class FirDiagnosticsSmokeTestGenerated extends AbstractFirDiagnosticsSmok
runTest("compiler/testData/diagnostics/tests/inference/nothingType/kt24490.kt");
}
@TestMetadata("kt32051.kt")
public void testKt32051() throws Exception {
runTest("compiler/testData/diagnostics/tests/inference/nothingType/kt32051.kt");
}
@TestMetadata("kt32081.kt")
public void testKt32081() throws Exception {
runTest("compiler/testData/diagnostics/tests/inference/nothingType/kt32081.kt");
}
@TestMetadata("lambdaNothingAndExpectedType.kt")
public void testLambdaNothingAndExpectedType() throws Exception {
runTest("compiler/testData/diagnostics/tests/inference/nothingType/lambdaNothingAndExpectedType.kt");

View File

@@ -158,7 +158,10 @@ class ConstraintIncorporator(
) {
if (targetVariable in getNestedTypeVariables(newConstraint)) return
if (!containsConstrainingTypeWithoutProjection(newConstraint, otherConstraint)) return
if (trivialConstraintTypeInferenceOracle.isGeneratedConstraintTrivial(otherConstraint, newConstraint, isSubtype)) return
if (trivialConstraintTypeInferenceOracle.isGeneratedConstraintTrivial(
baseConstraint, otherConstraint, newConstraint, isSubtype
)
) return
val derivedFrom = (baseConstraint.derivedFrom + otherConstraint.derivedFrom).toMutableSet()
if (otherVariable in derivedFrom) return

View File

@@ -35,6 +35,7 @@ class TrivialConstraintTypeInferenceOracle(context: TypeSystemInferenceExtension
// but can change result of the constraint system.
// Therefore, here we avoid adding such trivial constraints to have stable constraint system
fun isGeneratedConstraintTrivial(
baseConstraint: Constraint,
otherConstraint: Constraint,
generatedConstraintType: KotlinTypeMarker,
isSubtype: Boolean
@@ -42,8 +43,9 @@ class TrivialConstraintTypeInferenceOracle(context: TypeSystemInferenceExtension
if (isSubtype && generatedConstraintType.isNothing()) return true
if (!isSubtype && generatedConstraintType.isNullableAny()) return true
// If type that will be used to generate new constraint already contains `Nothing(?)`,
// If types from constraints that will be used to generate new constraint already contains `Nothing(?)`,
// then we can't decide that resulting constraint will be useless
if (baseConstraint.type.contains { it.isNothingOrNullableNothing() }) return false
if (otherConstraint.type.contains { it.isNothingOrNullableNothing() }) return false
// It's important to preserve constraints with nullable Nothing: `Nothing? <: T` (see implicitNothingConstraintFromReturn.kt test)

View File

@@ -0,0 +1,32 @@
// !DIAGNOSTICS: -UNUSED_PARAMETER -UNUSED_EXPRESSION
interface LevelA
interface LevelB : LevelA
class BiType<out X, out Y> {
fun <X> pullXb(x: X): BiType<X, LevelB> = TODO()
fun <Y> pullYb(y: Y): BiType<LevelB, Y> = TODO()
fun <X> pullXn(x: X): BiType<X, Nothing> = TODO()
fun <Y> pullYn(y: Y): BiType<Nothing, Y> = TODO()
}
fun <X> adjustIt(fn: () -> X): X = TODO()
fun <X> adjustIt(f1: () -> X, f2: () -> X): X = TODO()
fun <X> callAdjustIt(t: BiType<*, *>, x: X, level: LevelA) {
val x1 = adjustIt({ t.pullXb(x) })
<!DEBUG_INFO_EXPRESSION_TYPE("BiType<X, LevelB>")!>x1<!>
val x2 = adjustIt({ t.pullXn(x) })
<!DEBUG_INFO_EXPRESSION_TYPE("BiType<X, kotlin.Nothing>")!>x2<!>
val x3 = adjustIt({ t.pullXb(x) }, { t.pullYb(level) })
<!DEBUG_INFO_EXPRESSION_TYPE("BiType<kotlin.Any?, LevelA>")!>x3<!>
val x4 = adjustIt({ t.pullXn(x) }, { t.pullYn(level) })
<!DEBUG_INFO_EXPRESSION_TYPE("BiType<X, LevelA>")!>x4<!>
}

View File

@@ -0,0 +1,28 @@
package
public fun </*0*/ X> adjustIt(/*0*/ fn: () -> X): X
public fun </*0*/ X> adjustIt(/*0*/ f1: () -> X, /*1*/ f2: () -> X): X
public fun </*0*/ X> callAdjustIt(/*0*/ t: BiType<*, *>, /*1*/ x: X, /*2*/ level: LevelA): kotlin.Unit
public final class BiType</*0*/ out X, /*1*/ out Y> {
public constructor BiType</*0*/ out X, /*1*/ out Y>()
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 final fun </*0*/ X> pullXb(/*0*/ x: X): BiType<X, LevelB>
public final fun </*0*/ X> pullXn(/*0*/ x: X): BiType<X, kotlin.Nothing>
public final fun </*0*/ Y> pullYb(/*0*/ y: Y): BiType<LevelB, Y>
public final fun </*0*/ Y> pullYn(/*0*/ y: Y): BiType<kotlin.Nothing, Y>
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
public interface LevelA {
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
}
public interface LevelB : LevelA {
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
}

View File

@@ -0,0 +1,10 @@
// !DIAGNOSTICS: -UNUSED_PARAMETER
fun <T> select(x: T, y: T): T = x
fun foo(x: Int, stringNothing: Out2<String, Nothing>): Out2<String, Int> =
select(x.right(), stringNothing)
fun <R> R.right(): Out2<Nothing, R> = TODO()
class Out2<out K, out V>

View File

@@ -0,0 +1,12 @@
package
public fun foo(/*0*/ x: kotlin.Int, /*1*/ stringNothing: Out2<kotlin.String, kotlin.Nothing>): Out2<kotlin.String, kotlin.Int>
public fun </*0*/ T> select(/*0*/ x: T, /*1*/ y: T): T
public fun </*0*/ R> R.right(): Out2<kotlin.Nothing, R>
public final class Out2</*0*/ out K, /*1*/ out V> {
public constructor Out2</*0*/ out K, /*1*/ out V>()
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
}

View File

@@ -10272,6 +10272,16 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTest {
runTest("compiler/testData/diagnostics/tests/inference/nothingType/kt24490.kt");
}
@TestMetadata("kt32051.kt")
public void testKt32051() throws Exception {
runTest("compiler/testData/diagnostics/tests/inference/nothingType/kt32051.kt");
}
@TestMetadata("kt32081.kt")
public void testKt32081() throws Exception {
runTest("compiler/testData/diagnostics/tests/inference/nothingType/kt32081.kt");
}
@TestMetadata("lambdaNothingAndExpectedType.kt")
public void testLambdaNothingAndExpectedType() throws Exception {
runTest("compiler/testData/diagnostics/tests/inference/nothingType/lambdaNothingAndExpectedType.kt");

View File

@@ -10267,6 +10267,16 @@ public class DiagnosticsUsingJavacTestGenerated extends AbstractDiagnosticsUsing
runTest("compiler/testData/diagnostics/tests/inference/nothingType/kt24490.kt");
}
@TestMetadata("kt32051.kt")
public void testKt32051() throws Exception {
runTest("compiler/testData/diagnostics/tests/inference/nothingType/kt32051.kt");
}
@TestMetadata("kt32081.kt")
public void testKt32081() throws Exception {
runTest("compiler/testData/diagnostics/tests/inference/nothingType/kt32081.kt");
}
@TestMetadata("lambdaNothingAndExpectedType.kt")
public void testLambdaNothingAndExpectedType() throws Exception {
runTest("compiler/testData/diagnostics/tests/inference/nothingType/lambdaNothingAndExpectedType.kt");