From 05872fc6a8a82674ed4de7caa002928ad19cce51 Mon Sep 17 00:00:00 2001 From: Mikhail Glukhikh Date: Fri, 7 May 2021 14:10:05 +0300 Subject: [PATCH] Support captured types in ConeTypeCompatibilityChecker --- .../problems/capturedTypeInEquality.fir.txt | 30 +++++++++++++++++++ .../problems/capturedTypeInEquality.kt | 23 ++++++++++++++ .../runners/FirDiagnosticTestGenerated.java | 6 ++++ ...DiagnosticsWithLightTreeTestGenerated.java | 6 ++++ .../checkers/ConeTypeCompatibilityChecker.kt | 6 ++-- ...nosisCompilerFirTestdataTestGenerated.java | 5 ++++ 6 files changed, 74 insertions(+), 2 deletions(-) create mode 100644 compiler/fir/analysis-tests/testData/resolveWithStdlib/problems/capturedTypeInEquality.fir.txt create mode 100644 compiler/fir/analysis-tests/testData/resolveWithStdlib/problems/capturedTypeInEquality.kt diff --git a/compiler/fir/analysis-tests/testData/resolveWithStdlib/problems/capturedTypeInEquality.fir.txt b/compiler/fir/analysis-tests/testData/resolveWithStdlib/problems/capturedTypeInEquality.fir.txt new file mode 100644 index 00000000000..2212c2dee4a --- /dev/null +++ b/compiler/fir/analysis-tests/testData/resolveWithStdlib/problems/capturedTypeInEquality.fir.txt @@ -0,0 +1,30 @@ +FILE: capturedTypeInEquality.kt + public abstract interface FirTargetElement : R|kotlin/Any| { + } + public abstract interface FirFunction|> : R|FirTargetElement| { + } + public abstract interface FirPropertyAccessor : R|FirFunction| { + } + public abstract interface FirProperty : R|kotlin/Any| { + public abstract val getter: R|FirPropertyAccessor| + public get(): R|FirPropertyAccessor| + + } + public abstract interface FirTarget : R|kotlin/Any| { + public abstract val labeledElement: R|E| + public get(): R|E| + + } + public final fun foo(target: R|FirTarget>|, property: R|FirProperty|): R|kotlin/Unit| { + lval functionTarget: R|FirFunction<*>| = R|/target|.R|SubstitutionOverride|>| + lval x: R|kotlin/Int?| = (R|/functionTarget| as? R|FirFunction|)?.{ $subj$.R|kotlin/let||, R|kotlin/Int|>( = let@fun (it: R|FirFunction<*>|): R|kotlin/Int| { + when () { + ===(R|/property|.R|/FirProperty.getter|, R|/functionTarget|) -> { + ^@let Int(1) + } + } + + ^ Int(0) + } + ) } + } diff --git a/compiler/fir/analysis-tests/testData/resolveWithStdlib/problems/capturedTypeInEquality.kt b/compiler/fir/analysis-tests/testData/resolveWithStdlib/problems/capturedTypeInEquality.kt new file mode 100644 index 00000000000..4cc67362737 --- /dev/null +++ b/compiler/fir/analysis-tests/testData/resolveWithStdlib/problems/capturedTypeInEquality.kt @@ -0,0 +1,23 @@ +interface FirTargetElement + +interface FirFunction> : FirTargetElement + +interface FirPropertyAccessor : FirFunction + +interface FirProperty { + val getter: FirPropertyAccessor +} + +interface FirTarget { + val labeledElement: E +} + +fun foo(target: FirTarget>, property: FirProperty) { + val functionTarget = target.labeledElement + val x = (functionTarget as? FirFunction)?.let { + if (property.getter === functionTarget) { + return@let 1 + } + 0 + } +} \ No newline at end of file diff --git a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirDiagnosticTestGenerated.java b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirDiagnosticTestGenerated.java index 235beae2374..a7a8e223e9a 100644 --- a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirDiagnosticTestGenerated.java +++ b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirDiagnosticTestGenerated.java @@ -5293,6 +5293,12 @@ public class FirDiagnosticTestGenerated extends AbstractFirDiagnosticTest { KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/fir/analysis-tests/testData/resolveWithStdlib/problems"), Pattern.compile("^([^.]+)\\.kt$"), null, true); } + @Test + @TestMetadata("capturedTypeInEquality.kt") + public void testCapturedTypeInEquality() throws Exception { + runTest("compiler/fir/analysis-tests/testData/resolveWithStdlib/problems/capturedTypeInEquality.kt"); + } + @Test @TestMetadata("DeepCopyIrTree.kt") public void testDeepCopyIrTree() throws Exception { diff --git a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirDiagnosticsWithLightTreeTestGenerated.java b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirDiagnosticsWithLightTreeTestGenerated.java index a7fb070b344..0e115e0b38b 100644 --- a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirDiagnosticsWithLightTreeTestGenerated.java +++ b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirDiagnosticsWithLightTreeTestGenerated.java @@ -5293,6 +5293,12 @@ public class FirDiagnosticsWithLightTreeTestGenerated extends AbstractFirDiagnos KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/fir/analysis-tests/testData/resolveWithStdlib/problems"), Pattern.compile("^([^.]+)\\.kt$"), null, true); } + @Test + @TestMetadata("capturedTypeInEquality.kt") + public void testCapturedTypeInEquality() throws Exception { + runTest("compiler/fir/analysis-tests/testData/resolveWithStdlib/problems/capturedTypeInEquality.kt"); + } + @Test @TestMetadata("DeepCopyIrTree.kt") public void testDeepCopyIrTree() throws Exception { diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/ConeTypeCompatibilityChecker.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/ConeTypeCompatibilityChecker.kt index 917e5593b6d..f761e7f53cd 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/ConeTypeCompatibilityChecker.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/ConeTypeCompatibilityChecker.kt @@ -234,7 +234,8 @@ internal object ConeTypeCompatibilityChecker { is ConeDefinitelyNotNullType -> original.collectUpperBounds() is ConeIntersectionType -> intersectedTypes.flatMap { it.collectUpperBounds() }.toSet() is ConeFlexibleType -> upperBound.collectUpperBounds() - is ConeCapturedType, is ConeStubType, is ConeIntegerLiteralType -> throw IllegalStateException("$this should not reach here") + is ConeCapturedType -> constructor.supertypes?.flatMap { it.collectUpperBounds() }?.toSet().orEmpty() + is ConeStubType, is ConeIntegerLiteralType -> throw IllegalStateException("$this should not reach here") } } @@ -256,7 +257,8 @@ internal object ConeTypeCompatibilityChecker { is ConeDefinitelyNotNullType -> original.collectLowerBounds() is ConeIntersectionType -> intersectedTypes.flatMap { it.collectLowerBounds() }.toSet() is ConeFlexibleType -> lowerBound.collectLowerBounds() - is ConeCapturedType, is ConeStubType, is ConeIntegerLiteralType -> throw IllegalStateException("$this should not reach here") + is ConeCapturedType -> constructor.supertypes?.flatMap { it.collectLowerBounds() }?.toSet().orEmpty() + is ConeStubType, is ConeIntegerLiteralType -> throw IllegalStateException("$this should not reach here") } } diff --git a/idea/idea-frontend-fir/idea-fir-low-level-api/tests/org/jetbrains/kotlin/idea/fir/low/level/api/diagnostic/compiler/based/DiagnosisCompilerFirTestdataTestGenerated.java b/idea/idea-frontend-fir/idea-fir-low-level-api/tests/org/jetbrains/kotlin/idea/fir/low/level/api/diagnostic/compiler/based/DiagnosisCompilerFirTestdataTestGenerated.java index a20c44c674a..80606da74b7 100644 --- a/idea/idea-frontend-fir/idea-fir-low-level-api/tests/org/jetbrains/kotlin/idea/fir/low/level/api/diagnostic/compiler/based/DiagnosisCompilerFirTestdataTestGenerated.java +++ b/idea/idea-frontend-fir/idea-fir-low-level-api/tests/org/jetbrains/kotlin/idea/fir/low/level/api/diagnostic/compiler/based/DiagnosisCompilerFirTestdataTestGenerated.java @@ -4770,6 +4770,11 @@ public class DiagnosisCompilerFirTestdataTestGenerated extends AbstractDiagnosis KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/fir/analysis-tests/testData/resolveWithStdlib/problems"), Pattern.compile("^([^.]+)\\.kt$"), null, true); } + @TestMetadata("capturedTypeInEquality.kt") + public void testCapturedTypeInEquality() throws Exception { + runTest("compiler/fir/analysis-tests/testData/resolveWithStdlib/problems/capturedTypeInEquality.kt"); + } + @TestMetadata("DeepCopyIrTree.kt") public void testDeepCopyIrTree() throws Exception { runTest("compiler/fir/analysis-tests/testData/resolveWithStdlib/problems/DeepCopyIrTree.kt");