diff --git a/compiler/fir/analysis-tests/tests/org/jetbrains/kotlin/fir/FirOldFrontendDiagnosticsTestGenerated.java b/compiler/fir/analysis-tests/tests/org/jetbrains/kotlin/fir/FirOldFrontendDiagnosticsTestGenerated.java index 1c57e074a8d..13fbfa7bc11 100644 --- a/compiler/fir/analysis-tests/tests/org/jetbrains/kotlin/fir/FirOldFrontendDiagnosticsTestGenerated.java +++ b/compiler/fir/analysis-tests/tests/org/jetbrains/kotlin/fir/FirOldFrontendDiagnosticsTestGenerated.java @@ -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"); diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/PostponedArgumentsAnalyzer.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/PostponedArgumentsAnalyzer.kt index bf3c6e3aa45..5b627811850 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/PostponedArgumentsAnalyzer.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/PostponedArgumentsAnalyzer.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 } diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/model/NewConstraintSystemImpl.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/model/NewConstraintSystemImpl.kt index 81eaa00eb68..e222993d602 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/model/NewConstraintSystemImpl.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/model/NewConstraintSystemImpl.kt @@ -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() } + } } diff --git a/compiler/testData/diagnostics/tests/inference/coercionToUnit/coercionToUnitWithNothingType.fir.kt b/compiler/testData/diagnostics/tests/inference/coercionToUnit/coercionToUnitWithNothingType.fir.kt new file mode 100644 index 00000000000..bd7cd0c840e --- /dev/null +++ b/compiler/testData/diagnostics/tests/inference/coercionToUnit/coercionToUnitWithNothingType.fir.kt @@ -0,0 +1,53 @@ +// !DIAGNOSTICS: -UNUSED_PARAMETER + +// FILE: A.java + +public class A { + public static T flexible(T x) { return x; } +} + + +// FILE: test.kt + +class Inv + +fun launch(block: () -> Unit) {} +fun run(block: () -> T): T = block() +fun run(inv: Inv, block: () -> T): T = block() + +fun test(i: Inv, iUnit: Inv) { + launch { + run { TODO("") } + } + launch { + run { TODO("") } + } + launch { + run { "" } + } + launch { + run { null } + } + launch { + run { null } + } + launch { + run(i) { TODO() } + } + launch { + run(A.flexible(i)) { TODO() } + } + launch { + run(A.flexible(iUnit)) { 42 } + } + launch { + @Suppress("UNSUPPORTED") + run { "" } + } + + if (iUnit is String) { + launch { + run(A.flexible(iUnit)) { 42 } + } + } +} diff --git a/compiler/testData/diagnostics/tests/inference/coercionToUnit/coercionToUnitWithNothingType.kt b/compiler/testData/diagnostics/tests/inference/coercionToUnit/coercionToUnitWithNothingType.kt new file mode 100644 index 00000000000..c12790a34b9 --- /dev/null +++ b/compiler/testData/diagnostics/tests/inference/coercionToUnit/coercionToUnitWithNothingType.kt @@ -0,0 +1,53 @@ +// !DIAGNOSTICS: -UNUSED_PARAMETER + +// FILE: A.java + +public class A { + public static T flexible(T x) { return x; } +} + + +// FILE: test.kt + +class Inv + +fun launch(block: () -> Unit) {} +fun run(block: () -> T): T = block() +fun run(inv: Inv, block: () -> T): T = block() + +fun test(i: Inv, iUnit: Inv) { + launch { + run { TODO("") } + } + launch { + run { TODO("") } + } + launch { + run { "" } + } + launch { + run { null } + } + launch { + run { null } + } + launch { + run(i) { TODO() } + } + launch { + run(A.flexible(i)) { TODO() } + } + launch { + run(A.flexible(iUnit)) { 42 } + } + launch { + @Suppress("UNSUPPORTED") + run { "" } + } + + if (iUnit is String) { + launch { + run(A.flexible(iUnit)) { 42 } + } + } +} \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/inference/coercionToUnit/coercionToUnitWithNothingType.txt b/compiler/testData/diagnostics/tests/inference/coercionToUnit/coercionToUnitWithNothingType.txt new file mode 100644 index 00000000000..8a100b091d5 --- /dev/null +++ b/compiler/testData/diagnostics/tests/inference/coercionToUnit/coercionToUnitWithNothingType.txt @@ -0,0 +1,23 @@ +package + +public fun launch(/*0*/ block: () -> kotlin.Unit): kotlin.Unit +public fun run(/*0*/ block: () -> T): T +public fun run(/*0*/ inv: Inv, /*1*/ block: () -> T): T +public fun test(/*0*/ i: Inv, /*1*/ iUnit: Inv): 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 flexible(/*0*/ x: T!): T! +} + +public final class Inv { + public constructor Inv() + 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 +} diff --git a/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java index ec0b4b9cd5e..d2fc13bede4 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java @@ -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"); diff --git a/compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsUsingJavacTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsUsingJavacTestGenerated.java index 2f1c9252215..7abab81c5c7 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsUsingJavacTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsUsingJavacTestGenerated.java @@ -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");