From bfb46befa5fbe0289dda83200b7354324482ac5c Mon Sep 17 00:00:00 2001 From: Victor Petukhov Date: Fri, 18 Sep 2020 10:25:27 +0300 Subject: [PATCH] Mark projection of a nullable captured type as not null during simplification constrains with it and a nullable type variable ^KT-41913 Fixed --- ...irOldFrontendDiagnosticsTestGenerated.java | 5 +++ ...ctTypeCheckerContextForConstraintSystem.kt | 10 ++--- ...bleCaptruredTypeAgainstNullableVariable.kt | 38 +++++++++++++++++++ ...leCaptruredTypeAgainstNullableVariable.txt | 23 +++++++++++ .../checkers/DiagnosticsTestGenerated.java | 5 +++ .../DiagnosticsUsingJavacTestGenerated.java | 5 +++ 6 files changed, 79 insertions(+), 7 deletions(-) create mode 100644 compiler/testData/diagnostics/tests/inference/capturedTypes/nullableCaptruredTypeAgainstNullableVariable.kt create mode 100644 compiler/testData/diagnostics/tests/inference/capturedTypes/nullableCaptruredTypeAgainstNullableVariable.txt 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 f8d08311aed..d61973d0317 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 @@ -10684,6 +10684,11 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirOldFronte runTest("compiler/testData/diagnostics/tests/inference/capturedTypes/notApproximateWhenCopyDescriptors.kt"); } + @TestMetadata("nullableCaptruredTypeAgainstNullableVariable.kt") + public void testNullableCaptruredTypeAgainstNullableVariable() throws Exception { + runTest("compiler/testData/diagnostics/tests/inference/capturedTypes/nullableCaptruredTypeAgainstNullableVariable.kt"); + } + @TestMetadata("overApproximationForInCaptured.kt") public void testOverApproximationForInCaptured() throws Exception { runTest("compiler/testData/diagnostics/tests/inference/capturedTypes/overApproximationForInCaptured.kt"); diff --git a/compiler/resolution.common/src/org/jetbrains/kotlin/resolve/calls/inference/components/AbstractTypeCheckerContextForConstraintSystem.kt b/compiler/resolution.common/src/org/jetbrains/kotlin/resolve/calls/inference/components/AbstractTypeCheckerContextForConstraintSystem.kt index 2dcbce8046d..a1fe386674a 100644 --- a/compiler/resolution.common/src/org/jetbrains/kotlin/resolve/calls/inference/components/AbstractTypeCheckerContextForConstraintSystem.kt +++ b/compiler/resolution.common/src/org/jetbrains/kotlin/resolve/calls/inference/components/AbstractTypeCheckerContextForConstraintSystem.kt @@ -209,20 +209,16 @@ abstract class AbstractTypeCheckerContextForConstraintSystem : AbstractTypeCheck if (typeVariable.isMarkedNullable()) { val typeVariableTypeConstructor = typeVariable.typeConstructor() val subTypeConstructor = subType.typeConstructor() - - if ( + val resultType = if ( !subTypeConstructor.isTypeVariable() && typeVariableTypeConstructor.isTypeVariable() && (typeVariableTypeConstructor as TypeVariableTypeConstructorMarker).isContainedInInvariantOrContravariantPositions() ) { - if (subType.isCapturedType()) { - (subType as CapturedTypeMarker).withNotNullProjection() - } else { - subType.withNullability(false) - } + subType.withNullability(false) } else { subType.makeDefinitelyNotNullOrNotNull() } + if (resultType is CapturedTypeMarker) resultType.withNotNullProjection() else resultType } else subType is FlexibleTypeMarker -> { diff --git a/compiler/testData/diagnostics/tests/inference/capturedTypes/nullableCaptruredTypeAgainstNullableVariable.kt b/compiler/testData/diagnostics/tests/inference/capturedTypes/nullableCaptruredTypeAgainstNullableVariable.kt new file mode 100644 index 00000000000..927fe761cfd --- /dev/null +++ b/compiler/testData/diagnostics/tests/inference/capturedTypes/nullableCaptruredTypeAgainstNullableVariable.kt @@ -0,0 +1,38 @@ +// !DIAGNOSTICS: -CAST_NEVER_SUCCEEDS -REDUNDANT_PROJECTION + +// FILE: Foo.java +public class Foo extends Bar { + public Foo(L x) { + super(x); + } +} + +// FILE: main.kt +fun Bar.foo(): T = null as T +fun Bar.bar(): T = null as T +fun Foo.boo1(): T = null as T +fun Foo.boo2(): T = null as T + +open class Bar(val x: K) + +fun main(x: Foo, y: Bar, z1: Foo, z2: Bar) { + x.foo() + x.bar() + x.boo1() + x.boo2() + + y.foo() + y.bar() + y.boo1() + y.boo2() + + z1.foo() + z1.bar() + z1.boo1() + z1.boo2() + + z2.foo() + z2.bar() + z2.boo1() + z2.boo2() +} diff --git a/compiler/testData/diagnostics/tests/inference/capturedTypes/nullableCaptruredTypeAgainstNullableVariable.txt b/compiler/testData/diagnostics/tests/inference/capturedTypes/nullableCaptruredTypeAgainstNullableVariable.txt new file mode 100644 index 00000000000..255dde6e5ba --- /dev/null +++ b/compiler/testData/diagnostics/tests/inference/capturedTypes/nullableCaptruredTypeAgainstNullableVariable.txt @@ -0,0 +1,23 @@ +package + +public fun main(/*0*/ x: Foo, /*1*/ y: Bar, /*2*/ z1: Foo, /*3*/ z2: Bar): kotlin.Unit +public fun Bar.bar(): T +public fun Foo.boo1(): T +public fun Foo.boo2(): T +public fun Bar.foo(): T + +public open class Bar { + public constructor Bar(/*0*/ x: K) + public final val x: 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 +} + +public open class Foo : Bar { + public constructor Foo(/*0*/ x: L!) + public final override /*1*/ /*fake_override*/ val x: L! + 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 a3873696367..6fd2a9076f0 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java @@ -10691,6 +10691,11 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTestWithFirVali runTest("compiler/testData/diagnostics/tests/inference/capturedTypes/notApproximateWhenCopyDescriptors.kt"); } + @TestMetadata("nullableCaptruredTypeAgainstNullableVariable.kt") + public void testNullableCaptruredTypeAgainstNullableVariable() throws Exception { + runTest("compiler/testData/diagnostics/tests/inference/capturedTypes/nullableCaptruredTypeAgainstNullableVariable.kt"); + } + @TestMetadata("overApproximationForInCaptured.kt") public void testOverApproximationForInCaptured() throws Exception { runTest("compiler/testData/diagnostics/tests/inference/capturedTypes/overApproximationForInCaptured.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsUsingJavacTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsUsingJavacTestGenerated.java index 0ebbd7f2aa8..7111a668576 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsUsingJavacTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsUsingJavacTestGenerated.java @@ -10686,6 +10686,11 @@ public class DiagnosticsUsingJavacTestGenerated extends AbstractDiagnosticsUsing runTest("compiler/testData/diagnostics/tests/inference/capturedTypes/notApproximateWhenCopyDescriptors.kt"); } + @TestMetadata("nullableCaptruredTypeAgainstNullableVariable.kt") + public void testNullableCaptruredTypeAgainstNullableVariable() throws Exception { + runTest("compiler/testData/diagnostics/tests/inference/capturedTypes/nullableCaptruredTypeAgainstNullableVariable.kt"); + } + @TestMetadata("overApproximationForInCaptured.kt") public void testOverApproximationForInCaptured() throws Exception { runTest("compiler/testData/diagnostics/tests/inference/capturedTypes/overApproximationForInCaptured.kt");