From 383c2d1bff0770b23e4c8a465bcde204b0446b7e Mon Sep 17 00:00:00 2001 From: Mikhail Zarechenskiy Date: Tue, 4 Dec 2018 10:54:41 +0300 Subject: [PATCH] [NI] Take into account captured types for type depth computation It's needed to estimate the count of steps for type approximation algorithm. After the estimated count of steps, we consider such type recursive and this algorithm returns some default value #KT-28598 Fixed --- .../kotlin/types/TypeApproximator.kt | 3 ++ .../generics/capturingOfDeepNestedType.kt | 36 +++++++++++++++++++ .../generics/capturingOfDeepNestedType.txt | 13 +++++++ .../checkers/DiagnosticsTestGenerated.java | 5 +++ .../DiagnosticsUsingJavacTestGenerated.java | 5 +++ 5 files changed, 62 insertions(+) create mode 100644 compiler/testData/diagnostics/tests/generics/capturingOfDeepNestedType.kt create mode 100644 compiler/testData/diagnostics/tests/generics/capturingOfDeepNestedType.txt diff --git a/compiler/resolution/src/org/jetbrains/kotlin/types/TypeApproximator.kt b/compiler/resolution/src/org/jetbrains/kotlin/types/TypeApproximator.kt index 9f82cb0a48a..17412b2ded0 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/types/TypeApproximator.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/types/TypeApproximator.kt @@ -470,6 +470,9 @@ internal fun UnwrappedType.typeDepth() = internal fun SimpleType.typeDepth(): Int { if (this is TypeUtils.SpecialType) return 0 + if (this is NewCapturedType) { + return constructor.projection.type.unwrap().typeDepth() + } val maxInArguments = arguments.asSequence().map { if (it.isStarProjection) 1 else it.type.unwrap().typeDepth() diff --git a/compiler/testData/diagnostics/tests/generics/capturingOfDeepNestedType.kt b/compiler/testData/diagnostics/tests/generics/capturingOfDeepNestedType.kt new file mode 100644 index 00000000000..7088456f9f2 --- /dev/null +++ b/compiler/testData/diagnostics/tests/generics/capturingOfDeepNestedType.kt @@ -0,0 +1,36 @@ +// !LANGUAGE: +NewInference +// !DIAGNOSTICS: -UNUSED_VARIABLE -UNUSED_PARAMETER + +class Inv(val x: T) + +fun case_1(a: Inv?>?>?>?>?>?) { + if (a != null) { + val b: Inv?>?>?>?>? = a.x + } +} + +fun case_2(a: Inv?>?>?>?>?>?) { + if (a != null) { + val b: Inv?>?>?>?>? = a.x + if (b != null) { + val c = b.x + if (c != null) { + val d = c.x + if (d != null) { + val e = d.x + if (e != null) { + val f = e.x + if (f != null) { + val g = f.x + if (g != null) { + takeInt(g) + } + } + } + } + } + } + } +} + +fun takeInt(i: Int) {} \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/generics/capturingOfDeepNestedType.txt b/compiler/testData/diagnostics/tests/generics/capturingOfDeepNestedType.txt new file mode 100644 index 00000000000..662437d13bb --- /dev/null +++ b/compiler/testData/diagnostics/tests/generics/capturingOfDeepNestedType.txt @@ -0,0 +1,13 @@ +package + +public fun case_1(/*0*/ a: Inv?>?>?>?>?>?): kotlin.Unit +public fun case_2(/*0*/ a: Inv?>?>?>?>?>?): kotlin.Unit +public fun takeInt(/*0*/ i: kotlin.Int): kotlin.Unit + +public final class Inv { + public constructor Inv(/*0*/ x: T) + public final val x: T + 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 366c506443a..6ee71c5e2f7 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java @@ -7943,6 +7943,11 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTest { runTest("compiler/testData/diagnostics/tests/generics/argumentsForT.kt"); } + @TestMetadata("capturingOfDeepNestedType.kt") + public void testCapturingOfDeepNestedType() throws Exception { + runTest("compiler/testData/diagnostics/tests/generics/capturingOfDeepNestedType.kt"); + } + @TestMetadata("commonSupertypeContravariant.kt") public void testCommonSupertypeContravariant() throws Exception { runTest("compiler/testData/diagnostics/tests/generics/commonSupertypeContravariant.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsUsingJavacTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsUsingJavacTestGenerated.java index 1ca10062d00..0a95764675d 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsUsingJavacTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsUsingJavacTestGenerated.java @@ -7943,6 +7943,11 @@ public class DiagnosticsUsingJavacTestGenerated extends AbstractDiagnosticsUsing runTest("compiler/testData/diagnostics/tests/generics/argumentsForT.kt"); } + @TestMetadata("capturingOfDeepNestedType.kt") + public void testCapturingOfDeepNestedType() throws Exception { + runTest("compiler/testData/diagnostics/tests/generics/capturingOfDeepNestedType.kt"); + } + @TestMetadata("commonSupertypeContravariant.kt") public void testCommonSupertypeContravariant() throws Exception { runTest("compiler/testData/diagnostics/tests/generics/commonSupertypeContravariant.kt");