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");
|
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")
|
@TestMetadata("coercionWithExpectedType.kt")
|
||||||
public void testCoercionWithExpectedType() throws Exception {
|
public void testCoercionWithExpectedType() throws Exception {
|
||||||
runTest("compiler/testData/diagnostics/tests/inference/coercionToUnit/coercionWithExpectedType.kt");
|
runTest("compiler/testData/diagnostics/tests/inference/coercionToUnit/coercionWithExpectedType.kt");
|
||||||
|
|||||||
+2
-1
@@ -35,6 +35,7 @@ class PostponedArgumentsAnalyzer(
|
|||||||
fun canBeProper(type: KotlinTypeMarker): Boolean
|
fun canBeProper(type: KotlinTypeMarker): Boolean
|
||||||
|
|
||||||
fun hasUpperOrEqualUnitConstraint(type: KotlinTypeMarker): Boolean
|
fun hasUpperOrEqualUnitConstraint(type: KotlinTypeMarker): Boolean
|
||||||
|
fun hasEqualNothingConstraint(type: KotlinTypeMarker): Boolean
|
||||||
|
|
||||||
// mutable operations
|
// mutable operations
|
||||||
fun addOtherSystem(otherSystem: ConstraintStorage)
|
fun addOtherSystem(otherSystem: ConstraintStorage)
|
||||||
@@ -122,7 +123,7 @@ class PostponedArgumentsAnalyzer(
|
|||||||
c.canBeProper(rawReturnType) -> substitute(rawReturnType)
|
c.canBeProper(rawReturnType) -> substitute(rawReturnType)
|
||||||
|
|
||||||
// For Unit-coercion
|
// For Unit-coercion
|
||||||
c.hasUpperOrEqualUnitConstraint(rawReturnType) -> builtIns.unitType
|
c.hasUpperOrEqualUnitConstraint(rawReturnType) && !c.hasEqualNothingConstraint(rawReturnType) -> builtIns.unitType
|
||||||
|
|
||||||
else -> null
|
else -> null
|
||||||
}
|
}
|
||||||
|
|||||||
+6
-2
@@ -386,9 +386,13 @@ class NewConstraintSystemImpl(
|
|||||||
// PostponedArgumentsAnalyzer.Context
|
// PostponedArgumentsAnalyzer.Context
|
||||||
override fun hasUpperOrEqualUnitConstraint(type: KotlinTypeMarker): Boolean {
|
override fun hasUpperOrEqualUnitConstraint(type: KotlinTypeMarker): Boolean {
|
||||||
checkState(State.BUILDING, State.COMPLETION, State.FREEZED)
|
checkState(State.BUILDING, State.COMPLETION, State.FREEZED)
|
||||||
|
|
||||||
val constraints = storage.notFixedTypeVariables[type.typeConstructor()]?.constraints ?: return false
|
val constraints = storage.notFixedTypeVariables[type.typeConstructor()]?.constraints ?: return false
|
||||||
|
|
||||||
return constraints.any { (it.kind == ConstraintKind.UPPER || it.kind == ConstraintKind.EQUALITY) && it.type.isUnit() }
|
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");
|
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")
|
@TestMetadata("coercionWithExpectedType.kt")
|
||||||
public void testCoercionWithExpectedType() throws Exception {
|
public void testCoercionWithExpectedType() throws Exception {
|
||||||
runTest("compiler/testData/diagnostics/tests/inference/coercionToUnit/coercionWithExpectedType.kt");
|
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");
|
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")
|
@TestMetadata("coercionWithExpectedType.kt")
|
||||||
public void testCoercionWithExpectedType() throws Exception {
|
public void testCoercionWithExpectedType() throws Exception {
|
||||||
runTest("compiler/testData/diagnostics/tests/inference/coercionToUnit/coercionWithExpectedType.kt");
|
runTest("compiler/testData/diagnostics/tests/inference/coercionToUnit/coercionWithExpectedType.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user