From 3f052af517b1d7e8d12bab8036dc2031fb660bf8 Mon Sep 17 00:00:00 2001 From: "Denis.Zharkov" Date: Mon, 20 Feb 2023 16:53:33 +0100 Subject: [PATCH] K2: Propagate explicit getter type to the property without initializer In K1, we have the rules like: - if there's explicit type of a property, then use it - if there's an initializer, obtain its expression-type - Otherwise, use getter's return type The case when getter's type is implicit is handled at FirDeclarationsResolveTransformer.transformProperty ^KT-56707 Fixed --- ...CompilerTestFE10TestdataTestGenerated.java | 12 ++++++++++++ ...irOldFrontendDiagnosticsTestGenerated.java | 12 ++++++++++++ ...DiagnosticsWithLightTreeTestGenerated.java | 12 ++++++++++++ .../transformers/FirTypeResolveTransformer.kt | 14 ++++++++++++-- .../org/jetbrains/kotlin/KtSourceElement.kt | 3 +++ .../properties/inferPropertyTypeFromGetter.kt | 19 +++++++++++++++++++ .../explicitGetterType.fir.kt | 18 ------------------ .../explicitGetterType.kt | 1 + .../diagnostics/tests/properties/kt56707.kt | 13 +++++++++++++ .../test/runners/DiagnosticTestGenerated.java | 12 ++++++++++++ 10 files changed, 96 insertions(+), 20 deletions(-) create mode 100644 compiler/testData/diagnostics/tests/properties/inferPropertyTypeFromGetter.kt delete mode 100644 compiler/testData/diagnostics/tests/properties/inferenceFromGetters/explicitGetterType.fir.kt create mode 100644 compiler/testData/diagnostics/tests/properties/kt56707.kt diff --git a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosisCompilerTestFE10TestdataTestGenerated.java b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosisCompilerTestFE10TestdataTestGenerated.java index 0cd37e048f3..0dae05b60ad 100644 --- a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosisCompilerTestFE10TestdataTestGenerated.java +++ b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosisCompilerTestFE10TestdataTestGenerated.java @@ -25056,12 +25056,24 @@ public class DiagnosisCompilerTestFE10TestdataTestGenerated extends AbstractDiag runTest("compiler/testData/diagnostics/tests/properties/extensionPropertyMustHaveAccessorsOrBeAbstract.kt"); } + @Test + @TestMetadata("inferPropertyTypeFromGetter.kt") + public void testInferPropertyTypeFromGetter() throws Exception { + runTest("compiler/testData/diagnostics/tests/properties/inferPropertyTypeFromGetter.kt"); + } + @Test @TestMetadata("kt47621.kt") public void testKt47621() throws Exception { runTest("compiler/testData/diagnostics/tests/properties/kt47621.kt"); } + @Test + @TestMetadata("kt56707.kt") + public void testKt56707() throws Exception { + runTest("compiler/testData/diagnostics/tests/properties/kt56707.kt"); + } + @Test @TestMetadata("lateinitOnTopLevel.kt") public void testLateinitOnTopLevel() throws Exception { diff --git a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsTestGenerated.java b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsTestGenerated.java index cf75b759237..414738a21b3 100644 --- a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsTestGenerated.java +++ b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsTestGenerated.java @@ -25062,12 +25062,24 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirDiagnosti runTest("compiler/testData/diagnostics/tests/properties/extensionPropertyMustHaveAccessorsOrBeAbstract.kt"); } + @Test + @TestMetadata("inferPropertyTypeFromGetter.kt") + public void testInferPropertyTypeFromGetter() throws Exception { + runTest("compiler/testData/diagnostics/tests/properties/inferPropertyTypeFromGetter.kt"); + } + @Test @TestMetadata("kt47621.kt") public void testKt47621() throws Exception { runTest("compiler/testData/diagnostics/tests/properties/kt47621.kt"); } + @Test + @TestMetadata("kt56707.kt") + public void testKt56707() throws Exception { + runTest("compiler/testData/diagnostics/tests/properties/kt56707.kt"); + } + @Test @TestMetadata("lateinitOnTopLevel.kt") public void testLateinitOnTopLevel() throws Exception { diff --git a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsWithLightTreeTestGenerated.java b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsWithLightTreeTestGenerated.java index dbec21849df..40c5d941bff 100644 --- a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsWithLightTreeTestGenerated.java +++ b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsWithLightTreeTestGenerated.java @@ -25056,12 +25056,24 @@ public class FirOldFrontendDiagnosticsWithLightTreeTestGenerated extends Abstrac runTest("compiler/testData/diagnostics/tests/properties/extensionPropertyMustHaveAccessorsOrBeAbstract.kt"); } + @Test + @TestMetadata("inferPropertyTypeFromGetter.kt") + public void testInferPropertyTypeFromGetter() throws Exception { + runTest("compiler/testData/diagnostics/tests/properties/inferPropertyTypeFromGetter.kt"); + } + @Test @TestMetadata("kt47621.kt") public void testKt47621() throws Exception { runTest("compiler/testData/diagnostics/tests/properties/kt47621.kt"); } + @Test + @TestMetadata("kt56707.kt") + public void testKt56707() throws Exception { + runTest("compiler/testData/diagnostics/tests/properties/kt56707.kt"); + } + @Test @TestMetadata("lateinitOnTopLevel.kt") public void testLateinitOnTopLevel() throws Exception { diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirTypeResolveTransformer.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirTypeResolveTransformer.kt index 657b46c861c..34f0d4659f5 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirTypeResolveTransformer.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirTypeResolveTransformer.kt @@ -6,7 +6,9 @@ package org.jetbrains.kotlin.fir.resolve.transformers import kotlinx.collections.immutable.toImmutableList +import org.jetbrains.kotlin.KtFakeSourceElementKind import org.jetbrains.kotlin.fir.FirSession +import org.jetbrains.kotlin.fir.copyWithNewSourceKind import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.declarations.utils.isFromVararg import org.jetbrains.kotlin.fir.expressions.* @@ -154,8 +156,16 @@ open class FirTypeResolveTransformer( setAccessorTypesByPropertyType(property) } - if (property.returnTypeRef is FirResolvedTypeRef && property.delegate != null) { - setAccessorTypesByPropertyType(property) + when { + property.returnTypeRef is FirResolvedTypeRef && property.delegate != null -> { + setAccessorTypesByPropertyType(property) + } + property.returnTypeRef !is FirResolvedTypeRef && property.initializer == null && + property.getter?.returnTypeRef is FirResolvedTypeRef -> { + property.replaceReturnTypeRef( + property.getter!!.returnTypeRef.copyWithNewSourceKind(KtFakeSourceElementKind.PropertyTypeFromGetterReturnType) + ) + } } unboundCyclesInTypeParametersSupertypes(property) diff --git a/compiler/frontend.common/src/org/jetbrains/kotlin/KtSourceElement.kt b/compiler/frontend.common/src/org/jetbrains/kotlin/KtSourceElement.kt index 2d917aab85e..8329e9920fa 100644 --- a/compiler/frontend.common/src/org/jetbrains/kotlin/KtSourceElement.kt +++ b/compiler/frontend.common/src/org/jetbrains/kotlin/KtSourceElement.kt @@ -262,6 +262,9 @@ sealed class KtFakeSourceElementKind(final override val shouldSkipErrorTypeRepor // Synthetic calls for if/when/try/etc. object SyntheticCall : KtFakeSourceElementKind() + + // When property doesn't have an initializer and explicit return type, but its getter's return type is specified + object PropertyTypeFromGetterReturnType : KtFakeSourceElementKind() } sealed class AbstractKtSourceElement { diff --git a/compiler/testData/diagnostics/tests/properties/inferPropertyTypeFromGetter.kt b/compiler/testData/diagnostics/tests/properties/inferPropertyTypeFromGetter.kt new file mode 100644 index 00000000000..534c907dc8c --- /dev/null +++ b/compiler/testData/diagnostics/tests/properties/inferPropertyTypeFromGetter.kt @@ -0,0 +1,19 @@ +// FIR_IDENTICAL +// ISSUE: KT-56707 + +class Foo0 { + val child = 1 + val allChildren + get(): Int = child + allChildren // Should not be TYPECHECKER_HAS_RUN_INTO_RECURSIVE_PROBLEM on `allChildren` reference +} + +class Foo1 { + val child = 1 + val allChildren + get() = child + 1 +} + +fun use() { + Foo0().allChildren + Foo1().allChildren +} diff --git a/compiler/testData/diagnostics/tests/properties/inferenceFromGetters/explicitGetterType.fir.kt b/compiler/testData/diagnostics/tests/properties/inferenceFromGetters/explicitGetterType.fir.kt deleted file mode 100644 index 138dc1ded67..00000000000 --- a/compiler/testData/diagnostics/tests/properties/inferenceFromGetters/explicitGetterType.fir.kt +++ /dev/null @@ -1,18 +0,0 @@ -// !CHECK_TYPE -val x get(): String = foo() -val y get(): List = bar() -val z get(): List { - return bar() -} - -val u get(): String = field - -fun foo(): E = null!! -fun bar(): List = null!! - - -fun baz() { - x checkType { _() } - y checkType { _>() } - z checkType { _>() } -} diff --git a/compiler/testData/diagnostics/tests/properties/inferenceFromGetters/explicitGetterType.kt b/compiler/testData/diagnostics/tests/properties/inferenceFromGetters/explicitGetterType.kt index 9f83d3d8b3d..71ab1aac963 100644 --- a/compiler/testData/diagnostics/tests/properties/inferenceFromGetters/explicitGetterType.kt +++ b/compiler/testData/diagnostics/tests/properties/inferenceFromGetters/explicitGetterType.kt @@ -1,3 +1,4 @@ +// FIR_IDENTICAL // !CHECK_TYPE val x get(): String = foo() val y get(): List = bar() diff --git a/compiler/testData/diagnostics/tests/properties/kt56707.kt b/compiler/testData/diagnostics/tests/properties/kt56707.kt new file mode 100644 index 00000000000..28a796133ed --- /dev/null +++ b/compiler/testData/diagnostics/tests/properties/kt56707.kt @@ -0,0 +1,13 @@ +// FIR_IDENTICAL +// WITH_STDLIB +// ISSUE: KT-56707 + +class Foo { + val children = mutableSetOf() + val allChildren + get() : Set = (children + children.flatMap { it.allChildren }).toSet() // Should not be TYPECHECKER_HAS_RUN_INTO_RECURSIVE_PROBLEM on `allChildren` reference +} + +fun use() { + ")!>Foo().allChildren +} diff --git a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticTestGenerated.java b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticTestGenerated.java index 6fb615720b2..32430804958 100644 --- a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticTestGenerated.java +++ b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticTestGenerated.java @@ -25062,12 +25062,24 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest { runTest("compiler/testData/diagnostics/tests/properties/extensionPropertyMustHaveAccessorsOrBeAbstract.kt"); } + @Test + @TestMetadata("inferPropertyTypeFromGetter.kt") + public void testInferPropertyTypeFromGetter() throws Exception { + runTest("compiler/testData/diagnostics/tests/properties/inferPropertyTypeFromGetter.kt"); + } + @Test @TestMetadata("kt47621.kt") public void testKt47621() throws Exception { runTest("compiler/testData/diagnostics/tests/properties/kt47621.kt"); } + @Test + @TestMetadata("kt56707.kt") + public void testKt56707() throws Exception { + runTest("compiler/testData/diagnostics/tests/properties/kt56707.kt"); + } + @Test @TestMetadata("lateinitOnTopLevel.kt") public void testLateinitOnTopLevel() throws Exception {