Fix coercion to Unit with equal Nothing constraint

#KT-39669 Fixed
This commit is contained in:
Mikhail Zarechenskiy
2020-06-23 01:38:04 +03:00
parent a06c8786df
commit e7cee9c6e1
8 changed files with 152 additions and 3 deletions
@@ -10536,6 +10536,11 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirOldFronte
runTest("compiler/testData/diagnostics/tests/inference/coercionToUnit/coercionToUnitReference.kt");
}
@TestMetadata("coercionToUnitWithNothingType.kt")
public void testCoercionToUnitWithNothingType() throws Exception {
runTest("compiler/testData/diagnostics/tests/inference/coercionToUnit/coercionToUnitWithNothingType.kt");
}
@TestMetadata("coercionWithExpectedType.kt")
public void testCoercionWithExpectedType() throws Exception {
runTest("compiler/testData/diagnostics/tests/inference/coercionToUnit/coercionWithExpectedType.kt");
@@ -35,6 +35,7 @@ class PostponedArgumentsAnalyzer(
fun canBeProper(type: KotlinTypeMarker): Boolean
fun hasUpperOrEqualUnitConstraint(type: KotlinTypeMarker): Boolean
fun hasEqualNothingConstraint(type: KotlinTypeMarker): Boolean
// mutable operations
fun addOtherSystem(otherSystem: ConstraintStorage)
@@ -122,7 +123,7 @@ class PostponedArgumentsAnalyzer(
c.canBeProper(rawReturnType) -> substitute(rawReturnType)
// For Unit-coercion
c.hasUpperOrEqualUnitConstraint(rawReturnType) -> builtIns.unitType
c.hasUpperOrEqualUnitConstraint(rawReturnType) && !c.hasEqualNothingConstraint(rawReturnType) -> builtIns.unitType
else -> null
}
@@ -386,9 +386,13 @@ class NewConstraintSystemImpl(
// PostponedArgumentsAnalyzer.Context
override fun hasUpperOrEqualUnitConstraint(type: KotlinTypeMarker): Boolean {
checkState(State.BUILDING, State.COMPLETION, State.FREEZED)
val constraints = storage.notFixedTypeVariables[type.typeConstructor()]?.constraints ?: return false
return constraints.any { (it.kind == ConstraintKind.UPPER || it.kind == ConstraintKind.EQUALITY) && it.type.isUnit() }
}
override fun hasEqualNothingConstraint(type: KotlinTypeMarker): Boolean {
checkState(State.BUILDING, State.COMPLETION, State.FREEZED)
val constraints = storage.notFixedTypeVariables[type.typeConstructor()]?.constraints ?: return false
return constraints.any { (it.kind == ConstraintKind.EQUALITY) && it.type.isNothing() }
}
}
@@ -0,0 +1,53 @@
// !DIAGNOSTICS: -UNUSED_PARAMETER
// FILE: A.java
public class A {
public static <T> T flexible(T x) { return x; }
}
// FILE: test.kt
class Inv<K>
fun launch(block: () -> Unit) {}
fun <T> run(block: () -> T): T = block()
fun <T> run(inv: Inv<T>, block: () -> T): T = block()
fun test(i: Inv<Nothing>, iUnit: Inv<Unit>) {
launch {
run<Nothing> { TODO("") }
}
launch {
run { TODO("") }
}
launch {
run<String> { "" }
}
launch {
run<Nothing?> { null }
}
launch {
run { null }
}
launch {
run(i) { TODO() }
}
launch {
run(A.flexible(i)) { TODO() }
}
launch {
run(A.flexible(iUnit)) { 42 }
}
launch {
@Suppress("UNSUPPORTED")
<!INAPPLICABLE_CANDIDATE!>run<!><dynamic> { "" }
}
if (iUnit is String) {
launch {
run(A.flexible(iUnit)) { 42 }
}
}
}
@@ -0,0 +1,53 @@
// !DIAGNOSTICS: -UNUSED_PARAMETER
// FILE: A.java
public class A {
public static <T> T flexible(T x) { return x; }
}
// FILE: test.kt
class Inv<K>
fun launch(block: () -> Unit) {}
fun <T> run(block: () -> T): T = block()
fun <T> run(inv: Inv<T>, block: () -> T): T = block()
fun test(i: Inv<Nothing>, iUnit: Inv<Unit>) {
launch {
run<Nothing> { TODO("") }
}
launch {
run { TODO("") }
}
launch {
run<String> { "" }
}
launch {
run<Nothing?> { null }
}
launch {
run { <!UNUSED_EXPRESSION!>null<!> }
}
launch {
run(i) { TODO() }
}
launch {
run(A.flexible(i)) { TODO() }
}
launch {
run(A.flexible(iUnit)) { <!UNUSED_EXPRESSION!>42<!> }
}
launch {
@Suppress("UNSUPPORTED")
run<dynamic> { <!UNUSED_EXPRESSION!>""<!> }
}
if (iUnit is <!INCOMPATIBLE_TYPES!>String<!>) {
launch {
run(A.flexible(iUnit)) { <!UNUSED_EXPRESSION!>42<!> }
}
}
}
@@ -0,0 +1,23 @@
package
public fun launch(/*0*/ block: () -> kotlin.Unit): kotlin.Unit
public fun </*0*/ T> run(/*0*/ block: () -> T): T
public fun </*0*/ T> run(/*0*/ inv: Inv<T>, /*1*/ block: () -> T): T
public fun test(/*0*/ i: Inv<kotlin.Nothing>, /*1*/ iUnit: Inv<kotlin.Unit>): kotlin.Unit
public open class A {
public constructor A()
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
// Static members
public open fun </*0*/ T : kotlin.Any!> flexible(/*0*/ x: T!): T!
}
public final class Inv</*0*/ K> {
public constructor Inv</*0*/ K>()
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
}
@@ -10543,6 +10543,11 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTestWithFirVali
runTest("compiler/testData/diagnostics/tests/inference/coercionToUnit/coercionToUnitReference.kt");
}
@TestMetadata("coercionToUnitWithNothingType.kt")
public void testCoercionToUnitWithNothingType() throws Exception {
runTest("compiler/testData/diagnostics/tests/inference/coercionToUnit/coercionToUnitWithNothingType.kt");
}
@TestMetadata("coercionWithExpectedType.kt")
public void testCoercionWithExpectedType() throws Exception {
runTest("compiler/testData/diagnostics/tests/inference/coercionToUnit/coercionWithExpectedType.kt");
@@ -10538,6 +10538,11 @@ public class DiagnosticsUsingJavacTestGenerated extends AbstractDiagnosticsUsing
runTest("compiler/testData/diagnostics/tests/inference/coercionToUnit/coercionToUnitReference.kt");
}
@TestMetadata("coercionToUnitWithNothingType.kt")
public void testCoercionToUnitWithNothingType() throws Exception {
runTest("compiler/testData/diagnostics/tests/inference/coercionToUnit/coercionToUnitWithNothingType.kt");
}
@TestMetadata("coercionWithExpectedType.kt")
public void testCoercionWithExpectedType() throws Exception {
runTest("compiler/testData/diagnostics/tests/inference/coercionToUnit/coercionWithExpectedType.kt");