Fix coercion to Unit with equal Nothing constraint
#KT-39669 Fixed
This commit is contained in:
+5
@@ -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");
|
||||
|
||||
+2
-1
@@ -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
|
||||
}
|
||||
|
||||
+6
-2
@@ -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() }
|
||||
}
|
||||
}
|
||||
|
||||
Vendored
+53
@@ -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 }
|
||||
}
|
||||
}
|
||||
}
|
||||
Vendored
+53
@@ -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<!> }
|
||||
}
|
||||
}
|
||||
}
|
||||
Vendored
+23
@@ -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");
|
||||
|
||||
Generated
+5
@@ -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");
|
||||
|
||||
Reference in New Issue
Block a user