From 65e90743dfd4afb091299d4dda8abb438a774734 Mon Sep 17 00:00:00 2001 From: Denis Zharkov Date: Tue, 7 Apr 2020 14:18:55 +0300 Subject: [PATCH] FIR: Fix hanging inference case with intersection types --- .../intersectionTypesInConstraints.kt | 16 +++++++++++++ .../intersectionTypesInConstraints.txt | 24 +++++++++++++++++++ .../fir/FirDiagnosticsTestGenerated.java | 5 ++++ ...DiagnosticsWithLightTreeTestGenerated.java | 5 ++++ .../jetbrains/kotlin/fir/types/ConeTypes.kt | 19 +++++++++++++++ 5 files changed, 69 insertions(+) create mode 100644 compiler/fir/analysis-tests/testData/resolve/inference/intersectionTypesInConstraints.kt create mode 100644 compiler/fir/analysis-tests/testData/resolve/inference/intersectionTypesInConstraints.txt diff --git a/compiler/fir/analysis-tests/testData/resolve/inference/intersectionTypesInConstraints.kt b/compiler/fir/analysis-tests/testData/resolve/inference/intersectionTypesInConstraints.kt new file mode 100644 index 00000000000..d7c4257373e --- /dev/null +++ b/compiler/fir/analysis-tests/testData/resolve/inference/intersectionTypesInConstraints.kt @@ -0,0 +1,16 @@ +// FILE: MyList.java +public interface MyList extends java.util.List, I {} + +// FILE: main.kt + +fun elemAndList(r: R, t: MutableList): R = TODO() + +interface I +class A : Comparable, I +class B : Comparable, I + +fun test() { + elemAndList(A(), list(B())) +} + +fun list(value: T): MyList = TODO() diff --git a/compiler/fir/analysis-tests/testData/resolve/inference/intersectionTypesInConstraints.txt b/compiler/fir/analysis-tests/testData/resolve/inference/intersectionTypesInConstraints.txt new file mode 100644 index 00000000000..a8ada8cc029 --- /dev/null +++ b/compiler/fir/analysis-tests/testData/resolve/inference/intersectionTypesInConstraints.txt @@ -0,0 +1,24 @@ +FILE: main.kt + public final fun elemAndList(r: R|R|, t: R|kotlin/collections/MutableList|): R|R| { + ^elemAndList R|kotlin/TODO|() + } + public abstract interface I : R|kotlin/Any| { + } + public final class A : R|kotlin/Comparable|, R|I| { + public constructor(): R|A| { + super() + } + + } + public final class B : R|kotlin/Comparable|, R|I| { + public constructor(): R|B| { + super() + } + + } + public final fun test(): R|kotlin/Unit| { + R|/elemAndList| & I), it(kotlin/Comparable? & I?)>|>(R|/A.A|(), R|/list| & I), it(kotlin/Comparable? & I?)>|>(R|/B.B|())) + } + public final fun list(value: R|T|): R|MyList| { + ^list R|kotlin/TODO|() + } diff --git a/compiler/fir/analysis-tests/tests/org/jetbrains/kotlin/fir/FirDiagnosticsTestGenerated.java b/compiler/fir/analysis-tests/tests/org/jetbrains/kotlin/fir/FirDiagnosticsTestGenerated.java index e04e9e12d75..de6184350ae 100644 --- a/compiler/fir/analysis-tests/tests/org/jetbrains/kotlin/fir/FirDiagnosticsTestGenerated.java +++ b/compiler/fir/analysis-tests/tests/org/jetbrains/kotlin/fir/FirDiagnosticsTestGenerated.java @@ -1351,6 +1351,11 @@ public class FirDiagnosticsTestGenerated extends AbstractFirDiagnosticsTest { runTest("compiler/fir/analysis-tests/testData/resolve/inference/extensionCallableReferences.kt"); } + @TestMetadata("intersectionTypesInConstraints.kt") + public void testIntersectionTypesInConstraints() throws Exception { + runTest("compiler/fir/analysis-tests/testData/resolve/inference/intersectionTypesInConstraints.kt"); + } + @TestMetadata("lambdaAsReturnStatementOfLambda.kt") public void testLambdaAsReturnStatementOfLambda() throws Exception { runTest("compiler/fir/analysis-tests/testData/resolve/inference/lambdaAsReturnStatementOfLambda.kt"); diff --git a/compiler/fir/analysis-tests/tests/org/jetbrains/kotlin/fir/FirDiagnosticsWithLightTreeTestGenerated.java b/compiler/fir/analysis-tests/tests/org/jetbrains/kotlin/fir/FirDiagnosticsWithLightTreeTestGenerated.java index 71b04483f88..f0825c9ee42 100644 --- a/compiler/fir/analysis-tests/tests/org/jetbrains/kotlin/fir/FirDiagnosticsWithLightTreeTestGenerated.java +++ b/compiler/fir/analysis-tests/tests/org/jetbrains/kotlin/fir/FirDiagnosticsWithLightTreeTestGenerated.java @@ -1351,6 +1351,11 @@ public class FirDiagnosticsWithLightTreeTestGenerated extends AbstractFirDiagnos runTest("compiler/fir/analysis-tests/testData/resolve/inference/extensionCallableReferences.kt"); } + @TestMetadata("intersectionTypesInConstraints.kt") + public void testIntersectionTypesInConstraints() throws Exception { + runTest("compiler/fir/analysis-tests/testData/resolve/inference/intersectionTypesInConstraints.kt"); + } + @TestMetadata("lambdaAsReturnStatementOfLambda.kt") public void testLambdaAsReturnStatementOfLambda() throws Exception { runTest("compiler/fir/analysis-tests/testData/resolve/inference/lambdaAsReturnStatementOfLambda.kt"); diff --git a/compiler/fir/cones/src/org/jetbrains/kotlin/fir/types/ConeTypes.kt b/compiler/fir/cones/src/org/jetbrains/kotlin/fir/types/ConeTypes.kt index 98f2393a110..885b7f400c0 100644 --- a/compiler/fir/cones/src/org/jetbrains/kotlin/fir/types/ConeTypes.kt +++ b/compiler/fir/cones/src/org/jetbrains/kotlin/fir/types/ConeTypes.kt @@ -195,6 +195,25 @@ class ConeIntersectionType( override val nullability: ConeNullability get() = ConeNullability.NOT_NULL + + private var hashCode = 0 + + override fun equals(other: Any?): Boolean { + if (this === other) return true + if (javaClass != other?.javaClass) return false + + other as ConeIntersectionType + + if (intersectedTypes != other.intersectedTypes) return false + + return true + } + + override fun hashCode(): Int { + if (hashCode != 0) return hashCode + return intersectedTypes.hashCode().also { hashCode = it } + } + } fun ConeIntersectionType.mapTypes(func: (ConeKotlinType) -> ConeKotlinType): ConeIntersectionType {