From 3964ee38be7393861b00a2ca8e657e906138bf26 Mon Sep 17 00:00:00 2001 From: Mikhail Glukhikh Date: Fri, 28 Apr 2023 09:21:36 +0200 Subject: [PATCH] K2: fix handling of synthetic calls in delegate inference This commit is intended to avoid the second resolve of delegate when we need to consider provideDelegate() possibility in inference. Also here we provide correct completion of synthetic calls during delegate inference. #KT-58013 Fixed --- ...CompilerTestFE10TestdataTestGenerated.java | 36 +++++++++++++++++++ ...sticCompilerFE10TestDataTestGenerated.java | 36 +++++++++++++++++++ ...eeOldFrontendDiagnosticsTestGenerated.java | 36 +++++++++++++++++++ ...siOldFrontendDiagnosticsTestGenerated.java | 36 +++++++++++++++++++ .../FirDeclarationsResolveTransformer.kt | 7 ++-- .../FirExpressionsResolveTransformer.kt | 16 ++++++++- .../inference/elvisInDelegated.fir.txt | 23 ++++++++++++ .../inference/elvisInDelegated.kt | 16 +++++++++ .../inference/ifInDelegated.fir.txt | 31 ++++++++++++++++ .../inference/ifInDelegated.kt | 16 +++++++++ .../notNullAssertionInLocalDelegated.fir.txt | 23 ++++++++++++ .../notNullAssertionInLocalDelegated.kt | 16 +++++++++ .../inference/tryInGenerated.fir.txt | 28 +++++++++++++++ .../inference/tryInGenerated.kt | 16 +++++++++ .../notNullAssertionInLocalDelegated.fir.kt | 21 +++++++++++ .../notNullAssertionInLocalDelegated.fir.txt | 36 +++++++++++++++++++ .../notNullAssertionInLocalDelegated.kt | 21 +++++++++++ .../provideDelegate/onObject.kt | 10 ++++++ .../test/runners/DiagnosticTestGenerated.java | 36 +++++++++++++++++++ 19 files changed, 457 insertions(+), 3 deletions(-) create mode 100644 compiler/testData/diagnostics/tests/delegatedProperty/inference/elvisInDelegated.fir.txt create mode 100644 compiler/testData/diagnostics/tests/delegatedProperty/inference/elvisInDelegated.kt create mode 100644 compiler/testData/diagnostics/tests/delegatedProperty/inference/ifInDelegated.fir.txt create mode 100644 compiler/testData/diagnostics/tests/delegatedProperty/inference/ifInDelegated.kt create mode 100644 compiler/testData/diagnostics/tests/delegatedProperty/inference/notNullAssertionInLocalDelegated.fir.txt create mode 100644 compiler/testData/diagnostics/tests/delegatedProperty/inference/notNullAssertionInLocalDelegated.kt create mode 100644 compiler/testData/diagnostics/tests/delegatedProperty/inference/tryInGenerated.fir.txt create mode 100644 compiler/testData/diagnostics/tests/delegatedProperty/inference/tryInGenerated.kt create mode 100644 compiler/testData/diagnostics/tests/delegatedProperty/provideDelegate/notNullAssertionInLocalDelegated.fir.kt create mode 100644 compiler/testData/diagnostics/tests/delegatedProperty/provideDelegate/notNullAssertionInLocalDelegated.fir.txt create mode 100644 compiler/testData/diagnostics/tests/delegatedProperty/provideDelegate/notNullAssertionInLocalDelegated.kt create mode 100644 compiler/testData/diagnostics/tests/delegatedProperty/provideDelegate/onObject.kt diff --git a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosticCompilerTestFE10TestdataTestGenerated.java b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosticCompilerTestFE10TestdataTestGenerated.java index 64cebfe3747..1173b3759df 100644 --- a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosticCompilerTestFE10TestdataTestGenerated.java +++ b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosticCompilerTestFE10TestdataTestGenerated.java @@ -8889,6 +8889,12 @@ public class DiagnosticCompilerTestFE10TestdataTestGenerated extends AbstractDia runTest("compiler/testData/diagnostics/tests/delegatedProperty/inference/differentDelegatedExpressions.kt"); } + @Test + @TestMetadata("elvisInDelegated.kt") + public void testElvisInDelegated() throws Exception { + runTest("compiler/testData/diagnostics/tests/delegatedProperty/inference/elvisInDelegated.kt"); + } + @Test @TestMetadata("extensionGet.kt") public void testExtensionGet() throws Exception { @@ -8913,6 +8919,12 @@ public class DiagnosticCompilerTestFE10TestdataTestGenerated extends AbstractDia runTest("compiler/testData/diagnostics/tests/delegatedProperty/inference/genericMethods.kt"); } + @Test + @TestMetadata("ifInDelegated.kt") + public void testIfInDelegated() throws Exception { + runTest("compiler/testData/diagnostics/tests/delegatedProperty/inference/ifInDelegated.kt"); + } + @Test @TestMetadata("kt41952.kt") public void testKt41952() throws Exception { @@ -8955,12 +8967,24 @@ public class DiagnosticCompilerTestFE10TestdataTestGenerated extends AbstractDia runTest("compiler/testData/diagnostics/tests/delegatedProperty/inference/noExpectedTypeForSupertypeConstraint.kt"); } + @Test + @TestMetadata("notNullAssertionInLocalDelegated.kt") + public void testNotNullAssertionInLocalDelegated() throws Exception { + runTest("compiler/testData/diagnostics/tests/delegatedProperty/inference/notNullAssertionInLocalDelegated.kt"); + } + @Test @TestMetadata("resultTypeOfLambdaForConventionMethods.kt") public void testResultTypeOfLambdaForConventionMethods() throws Exception { runTest("compiler/testData/diagnostics/tests/delegatedProperty/inference/resultTypeOfLambdaForConventionMethods.kt"); } + @Test + @TestMetadata("tryInGenerated.kt") + public void testTryInGenerated() throws Exception { + runTest("compiler/testData/diagnostics/tests/delegatedProperty/inference/tryInGenerated.kt"); + } + @Test @TestMetadata("typeOfLazyDelegatedPropertyWithObject.kt") public void testTypeOfLazyDelegatedPropertyWithObject() throws Exception { @@ -9055,6 +9079,18 @@ public class DiagnosticCompilerTestFE10TestdataTestGenerated extends AbstractDia runTest("compiler/testData/diagnostics/tests/delegatedProperty/provideDelegate/noOperatorModifierOnProvideDelegate.kt"); } + @Test + @TestMetadata("notNullAssertionInLocalDelegated.kt") + public void testNotNullAssertionInLocalDelegated() throws Exception { + runTest("compiler/testData/diagnostics/tests/delegatedProperty/provideDelegate/notNullAssertionInLocalDelegated.kt"); + } + + @Test + @TestMetadata("onObject.kt") + public void testOnObject() throws Exception { + runTest("compiler/testData/diagnostics/tests/delegatedProperty/provideDelegate/onObject.kt"); + } + @Test @TestMetadata("overloadResolutionForSeveralProvideDelegates.kt") public void testOverloadResolutionForSeveralProvideDelegates() throws Exception { diff --git a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/LLFirPreresolvedReversedDiagnosticCompilerFE10TestDataTestGenerated.java b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/LLFirPreresolvedReversedDiagnosticCompilerFE10TestDataTestGenerated.java index 5480cd7baba..a1c90efee80 100644 --- a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/LLFirPreresolvedReversedDiagnosticCompilerFE10TestDataTestGenerated.java +++ b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/LLFirPreresolvedReversedDiagnosticCompilerFE10TestDataTestGenerated.java @@ -8889,6 +8889,12 @@ public class LLFirPreresolvedReversedDiagnosticCompilerFE10TestDataTestGenerated runTest("compiler/testData/diagnostics/tests/delegatedProperty/inference/differentDelegatedExpressions.kt"); } + @Test + @TestMetadata("elvisInDelegated.kt") + public void testElvisInDelegated() throws Exception { + runTest("compiler/testData/diagnostics/tests/delegatedProperty/inference/elvisInDelegated.kt"); + } + @Test @TestMetadata("extensionGet.kt") public void testExtensionGet() throws Exception { @@ -8913,6 +8919,12 @@ public class LLFirPreresolvedReversedDiagnosticCompilerFE10TestDataTestGenerated runTest("compiler/testData/diagnostics/tests/delegatedProperty/inference/genericMethods.kt"); } + @Test + @TestMetadata("ifInDelegated.kt") + public void testIfInDelegated() throws Exception { + runTest("compiler/testData/diagnostics/tests/delegatedProperty/inference/ifInDelegated.kt"); + } + @Test @TestMetadata("kt41952.kt") public void testKt41952() throws Exception { @@ -8955,12 +8967,24 @@ public class LLFirPreresolvedReversedDiagnosticCompilerFE10TestDataTestGenerated runTest("compiler/testData/diagnostics/tests/delegatedProperty/inference/noExpectedTypeForSupertypeConstraint.kt"); } + @Test + @TestMetadata("notNullAssertionInLocalDelegated.kt") + public void testNotNullAssertionInLocalDelegated() throws Exception { + runTest("compiler/testData/diagnostics/tests/delegatedProperty/inference/notNullAssertionInLocalDelegated.kt"); + } + @Test @TestMetadata("resultTypeOfLambdaForConventionMethods.kt") public void testResultTypeOfLambdaForConventionMethods() throws Exception { runTest("compiler/testData/diagnostics/tests/delegatedProperty/inference/resultTypeOfLambdaForConventionMethods.kt"); } + @Test + @TestMetadata("tryInGenerated.kt") + public void testTryInGenerated() throws Exception { + runTest("compiler/testData/diagnostics/tests/delegatedProperty/inference/tryInGenerated.kt"); + } + @Test @TestMetadata("typeOfLazyDelegatedPropertyWithObject.kt") public void testTypeOfLazyDelegatedPropertyWithObject() throws Exception { @@ -9055,6 +9079,18 @@ public class LLFirPreresolvedReversedDiagnosticCompilerFE10TestDataTestGenerated runTest("compiler/testData/diagnostics/tests/delegatedProperty/provideDelegate/noOperatorModifierOnProvideDelegate.kt"); } + @Test + @TestMetadata("notNullAssertionInLocalDelegated.kt") + public void testNotNullAssertionInLocalDelegated() throws Exception { + runTest("compiler/testData/diagnostics/tests/delegatedProperty/provideDelegate/notNullAssertionInLocalDelegated.kt"); + } + + @Test + @TestMetadata("onObject.kt") + public void testOnObject() throws Exception { + runTest("compiler/testData/diagnostics/tests/delegatedProperty/provideDelegate/onObject.kt"); + } + @Test @TestMetadata("overloadResolutionForSeveralProvideDelegates.kt") public void testOverloadResolutionForSeveralProvideDelegates() throws Exception { diff --git a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirLightTreeOldFrontendDiagnosticsTestGenerated.java b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirLightTreeOldFrontendDiagnosticsTestGenerated.java index de28efb7378..89be1368d04 100644 --- a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirLightTreeOldFrontendDiagnosticsTestGenerated.java +++ b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirLightTreeOldFrontendDiagnosticsTestGenerated.java @@ -8889,6 +8889,12 @@ public class FirLightTreeOldFrontendDiagnosticsTestGenerated extends AbstractFir runTest("compiler/testData/diagnostics/tests/delegatedProperty/inference/differentDelegatedExpressions.kt"); } + @Test + @TestMetadata("elvisInDelegated.kt") + public void testElvisInDelegated() throws Exception { + runTest("compiler/testData/diagnostics/tests/delegatedProperty/inference/elvisInDelegated.kt"); + } + @Test @TestMetadata("extensionGet.kt") public void testExtensionGet() throws Exception { @@ -8913,6 +8919,12 @@ public class FirLightTreeOldFrontendDiagnosticsTestGenerated extends AbstractFir runTest("compiler/testData/diagnostics/tests/delegatedProperty/inference/genericMethods.kt"); } + @Test + @TestMetadata("ifInDelegated.kt") + public void testIfInDelegated() throws Exception { + runTest("compiler/testData/diagnostics/tests/delegatedProperty/inference/ifInDelegated.kt"); + } + @Test @TestMetadata("kt41952.kt") public void testKt41952() throws Exception { @@ -8955,12 +8967,24 @@ public class FirLightTreeOldFrontendDiagnosticsTestGenerated extends AbstractFir runTest("compiler/testData/diagnostics/tests/delegatedProperty/inference/noExpectedTypeForSupertypeConstraint.kt"); } + @Test + @TestMetadata("notNullAssertionInLocalDelegated.kt") + public void testNotNullAssertionInLocalDelegated() throws Exception { + runTest("compiler/testData/diagnostics/tests/delegatedProperty/inference/notNullAssertionInLocalDelegated.kt"); + } + @Test @TestMetadata("resultTypeOfLambdaForConventionMethods.kt") public void testResultTypeOfLambdaForConventionMethods() throws Exception { runTest("compiler/testData/diagnostics/tests/delegatedProperty/inference/resultTypeOfLambdaForConventionMethods.kt"); } + @Test + @TestMetadata("tryInGenerated.kt") + public void testTryInGenerated() throws Exception { + runTest("compiler/testData/diagnostics/tests/delegatedProperty/inference/tryInGenerated.kt"); + } + @Test @TestMetadata("typeOfLazyDelegatedPropertyWithObject.kt") public void testTypeOfLazyDelegatedPropertyWithObject() throws Exception { @@ -9055,6 +9079,18 @@ public class FirLightTreeOldFrontendDiagnosticsTestGenerated extends AbstractFir runTest("compiler/testData/diagnostics/tests/delegatedProperty/provideDelegate/noOperatorModifierOnProvideDelegate.kt"); } + @Test + @TestMetadata("notNullAssertionInLocalDelegated.kt") + public void testNotNullAssertionInLocalDelegated() throws Exception { + runTest("compiler/testData/diagnostics/tests/delegatedProperty/provideDelegate/notNullAssertionInLocalDelegated.kt"); + } + + @Test + @TestMetadata("onObject.kt") + public void testOnObject() throws Exception { + runTest("compiler/testData/diagnostics/tests/delegatedProperty/provideDelegate/onObject.kt"); + } + @Test @TestMetadata("overloadResolutionForSeveralProvideDelegates.kt") public void testOverloadResolutionForSeveralProvideDelegates() throws Exception { diff --git a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirPsiOldFrontendDiagnosticsTestGenerated.java b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirPsiOldFrontendDiagnosticsTestGenerated.java index 2a9f015cd00..8424dbfcdfa 100644 --- a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirPsiOldFrontendDiagnosticsTestGenerated.java +++ b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirPsiOldFrontendDiagnosticsTestGenerated.java @@ -8895,6 +8895,12 @@ public class FirPsiOldFrontendDiagnosticsTestGenerated extends AbstractFirPsiDia runTest("compiler/testData/diagnostics/tests/delegatedProperty/inference/differentDelegatedExpressions.kt"); } + @Test + @TestMetadata("elvisInDelegated.kt") + public void testElvisInDelegated() throws Exception { + runTest("compiler/testData/diagnostics/tests/delegatedProperty/inference/elvisInDelegated.kt"); + } + @Test @TestMetadata("extensionGet.kt") public void testExtensionGet() throws Exception { @@ -8919,6 +8925,12 @@ public class FirPsiOldFrontendDiagnosticsTestGenerated extends AbstractFirPsiDia runTest("compiler/testData/diagnostics/tests/delegatedProperty/inference/genericMethods.kt"); } + @Test + @TestMetadata("ifInDelegated.kt") + public void testIfInDelegated() throws Exception { + runTest("compiler/testData/diagnostics/tests/delegatedProperty/inference/ifInDelegated.kt"); + } + @Test @TestMetadata("kt41952.kt") public void testKt41952() throws Exception { @@ -8961,12 +8973,24 @@ public class FirPsiOldFrontendDiagnosticsTestGenerated extends AbstractFirPsiDia runTest("compiler/testData/diagnostics/tests/delegatedProperty/inference/noExpectedTypeForSupertypeConstraint.kt"); } + @Test + @TestMetadata("notNullAssertionInLocalDelegated.kt") + public void testNotNullAssertionInLocalDelegated() throws Exception { + runTest("compiler/testData/diagnostics/tests/delegatedProperty/inference/notNullAssertionInLocalDelegated.kt"); + } + @Test @TestMetadata("resultTypeOfLambdaForConventionMethods.kt") public void testResultTypeOfLambdaForConventionMethods() throws Exception { runTest("compiler/testData/diagnostics/tests/delegatedProperty/inference/resultTypeOfLambdaForConventionMethods.kt"); } + @Test + @TestMetadata("tryInGenerated.kt") + public void testTryInGenerated() throws Exception { + runTest("compiler/testData/diagnostics/tests/delegatedProperty/inference/tryInGenerated.kt"); + } + @Test @TestMetadata("typeOfLazyDelegatedPropertyWithObject.kt") public void testTypeOfLazyDelegatedPropertyWithObject() throws Exception { @@ -9061,6 +9085,18 @@ public class FirPsiOldFrontendDiagnosticsTestGenerated extends AbstractFirPsiDia runTest("compiler/testData/diagnostics/tests/delegatedProperty/provideDelegate/noOperatorModifierOnProvideDelegate.kt"); } + @Test + @TestMetadata("notNullAssertionInLocalDelegated.kt") + public void testNotNullAssertionInLocalDelegated() throws Exception { + runTest("compiler/testData/diagnostics/tests/delegatedProperty/provideDelegate/notNullAssertionInLocalDelegated.kt"); + } + + @Test + @TestMetadata("onObject.kt") + public void testOnObject() throws Exception { + runTest("compiler/testData/diagnostics/tests/delegatedProperty/provideDelegate/onObject.kt"); + } + @Test @TestMetadata("overloadResolutionForSeveralProvideDelegates.kt") public void testOverloadResolutionForSeveralProvideDelegates() throws Exception { diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirDeclarationsResolveTransformer.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirDeclarationsResolveTransformer.kt index 854d3b39976..ee5b28d3730 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirDeclarationsResolveTransformer.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirDeclarationsResolveTransformer.kt @@ -324,7 +324,7 @@ open class FirDeclarationsResolveTransformer( .transformSingle(components.integerLiteralAndOperatorApproximationTransformer, null) // Second, replace result type of delegate expression with stub type if delegate not yet resolved - if (delegateExpression is FirQualifiedAccessExpression) { + if (delegateExpression is FirResolvable) { val calleeReference = delegateExpression.calleeReference if (calleeReference is FirNamedReferenceWithCandidate) { val system = calleeReference.candidate.system @@ -343,11 +343,14 @@ open class FirDeclarationsResolveTransformer( } val provideDelegateCall = wrappedDelegateExpression.delegateProvider as FirFunctionCall + provideDelegateCall.replaceExplicitReceiver(delegateExpression) // Resolve call for provideDelegate, without completion // TODO: this generates some nodes in the control flow graph which we don't want if we // end up not selecting this option. - provideDelegateCall.transformSingle(this, ResolutionMode.ContextIndependent) + transformer.expressionsTransformer.transformFunctionCallInternal( + provideDelegateCall, ResolutionMode.ContextIndependent, provideDelegate = true + ) // If we got successful candidate for provideDelegate, let's select it val provideDelegateCandidate = provideDelegateCall.candidate() diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirExpressionsResolveTransformer.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirExpressionsResolveTransformer.kt index df2a15f6fa6..2412b94f481 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirExpressionsResolveTransformer.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirExpressionsResolveTransformer.kt @@ -391,6 +391,13 @@ open class FirExpressionsResolveTransformer(transformer: FirAbstractBodyResolveT } override fun transformFunctionCall(functionCall: FirFunctionCall, data: ResolutionMode): FirStatement = + transformFunctionCallInternal(functionCall, data, provideDelegate = false) + + internal fun transformFunctionCallInternal( + functionCall: FirFunctionCall, + data: ResolutionMode, + provideDelegate: Boolean, + ): FirStatement = whileAnalysing(session, functionCall) { val calleeReference = functionCall.calleeReference if ( @@ -416,7 +423,14 @@ open class FirExpressionsResolveTransformer(transformer: FirAbstractBodyResolveT val initialExplicitReceiver = functionCall.explicitReceiver val withTransformedArguments = if (!resolvingAugmentedAssignment) { dataFlowAnalyzer.enterCallArguments(functionCall, functionCall.arguments) - transformExplicitReceiver(functionCall).also { + // In provideDelegate mode the explicitReceiver is already resolved + // E.g. we have val some by someDelegate + // At 1st stage of delegate inference we resolve someDelegate itself, + // at 2nd stage in provideDelegate mode we are trying to resolve someDelegate.provideDelegate(), + // and 'someDelegate' explicit receiver is resolved at 1st stage + // See also FirDeclarationsResolveTransformer.transformWrappedDelegateExpression + val withResolvedExplicitReceiver = if (provideDelegate) functionCall else transformExplicitReceiver(functionCall) + withResolvedExplicitReceiver.also { it.replaceArgumentList(it.argumentList.transform(this, ResolutionMode.ContextDependent)) dataFlowAnalyzer.exitCallArguments() } diff --git a/compiler/testData/diagnostics/tests/delegatedProperty/inference/elvisInDelegated.fir.txt b/compiler/testData/diagnostics/tests/delegatedProperty/inference/elvisInDelegated.fir.txt new file mode 100644 index 00000000000..d8f3766b0f2 --- /dev/null +++ b/compiler/testData/diagnostics/tests/delegatedProperty/inference/elvisInDelegated.fir.txt @@ -0,0 +1,23 @@ +FILE: elvisInDelegated.kt + public final data class Ref : R|kotlin/Any| { + public constructor(t: R|D|): R|Ref| { + super() + } + + public final val t: R|D| = R|/t| + public get(): R|D| + + public final operator fun component1(): R|D| + + public final fun copy(t: R|D| = this@R|/Ref|.R|/Ref.t|): R|Ref| + + } + public final operator fun R|Ref|.getValue(hisRef: R|kotlin/Any?|, property: R|kotlin/reflect/KProperty<*>|): R|V| { + ^getValue this@R|/getValue|.R|SubstitutionOverride| + } + public final fun R|kotlin/collections/List>|.getElement(i: R|kotlin/Int|): R|Ref| { + ^getElement (this@R|/getElement|.R|SubstitutionOverride|>|(R|/i|) as R|Ref|) + } + public final fun test(list: R|kotlin/collections/List>|): R|kotlin/Unit| { + lval data: R|kotlin/String|by R|/list|.R|/getElement|(Int(0)) ?: R|kotlin/error|(String()) + } diff --git a/compiler/testData/diagnostics/tests/delegatedProperty/inference/elvisInDelegated.kt b/compiler/testData/diagnostics/tests/delegatedProperty/inference/elvisInDelegated.kt new file mode 100644 index 00000000000..f25a2bd7fdd --- /dev/null +++ b/compiler/testData/diagnostics/tests/delegatedProperty/inference/elvisInDelegated.kt @@ -0,0 +1,16 @@ +// FIR_IDENTICAL +// ISSUE: KT-58013 (related) +// WITH_REFLECT +// FIR_DUMP + +import kotlin.reflect.KProperty + +data class Ref(val t: D) + +operator fun Ref.getValue(hisRef: Any?, property: KProperty<*>): V = this.t + +fun List>.getElement(i: Int): Ref = this[i] as Ref + +fun test(list: List>) { + val data: String by list.getElement(0) ?: error("") +} diff --git a/compiler/testData/diagnostics/tests/delegatedProperty/inference/ifInDelegated.fir.txt b/compiler/testData/diagnostics/tests/delegatedProperty/inference/ifInDelegated.fir.txt new file mode 100644 index 00000000000..06400fccc56 --- /dev/null +++ b/compiler/testData/diagnostics/tests/delegatedProperty/inference/ifInDelegated.fir.txt @@ -0,0 +1,31 @@ +FILE: ifInDelegated.kt + public final data class Ref : R|kotlin/Any| { + public constructor(t: R|D|): R|Ref| { + super() + } + + public final val t: R|D| = R|/t| + public get(): R|D| + + public final operator fun component1(): R|D| + + public final fun copy(t: R|D| = this@R|/Ref|.R|/Ref.t|): R|Ref| + + } + public final operator fun R|Ref|.getValue(hisRef: R|kotlin/Any?|, property: R|kotlin/reflect/KProperty<*>|): R|V| { + ^getValue this@R|/getValue|.R|SubstitutionOverride| + } + public final fun R|kotlin/collections/List>|.getElement(i: R|kotlin/Int|): R|Ref| { + ^getElement (this@R|/getElement|.R|SubstitutionOverride|>|(R|/i|) as R|Ref|) + } + public final fun test(list: R|kotlin/collections/List>|, arg: R|kotlin/Boolean|): R|kotlin/Unit| { + lval data: R|kotlin/String|by when () { + R|/arg| -> { + R|/list|.R|/getElement|(Int(0)) + } + else -> { + R|/list|.R|/getElement|(Int(1)) + } + } + + } diff --git a/compiler/testData/diagnostics/tests/delegatedProperty/inference/ifInDelegated.kt b/compiler/testData/diagnostics/tests/delegatedProperty/inference/ifInDelegated.kt new file mode 100644 index 00000000000..724b2b11a1f --- /dev/null +++ b/compiler/testData/diagnostics/tests/delegatedProperty/inference/ifInDelegated.kt @@ -0,0 +1,16 @@ +// FIR_IDENTICAL +// ISSUE: KT-58013 (related) +// WITH_REFLECT +// FIR_DUMP + +import kotlin.reflect.KProperty + +data class Ref(val t: D) + +operator fun Ref.getValue(hisRef: Any?, property: KProperty<*>): V = this.t + +fun List>.getElement(i: Int): Ref = this[i] as Ref + +fun test(list: List>, arg: Boolean) { + val data: String by if (arg) list.getElement(0) else list.getElement(1) +} diff --git a/compiler/testData/diagnostics/tests/delegatedProperty/inference/notNullAssertionInLocalDelegated.fir.txt b/compiler/testData/diagnostics/tests/delegatedProperty/inference/notNullAssertionInLocalDelegated.fir.txt new file mode 100644 index 00000000000..02ef49e1949 --- /dev/null +++ b/compiler/testData/diagnostics/tests/delegatedProperty/inference/notNullAssertionInLocalDelegated.fir.txt @@ -0,0 +1,23 @@ +FILE: notNullAssertionInLocalDelegated.kt + public final data class Ref : R|kotlin/Any| { + public constructor(t: R|D|): R|Ref| { + super() + } + + public final val t: R|D| = R|/t| + public get(): R|D| + + public final operator fun component1(): R|D| + + public final fun copy(t: R|D| = this@R|/Ref|.R|/Ref.t|): R|Ref| + + } + public final operator fun R|Ref|.getValue(hisRef: R|kotlin/Any?|, property: R|kotlin/reflect/KProperty<*>|): R|V| { + ^getValue this@R|/getValue|.R|SubstitutionOverride| + } + public final fun R|kotlin/collections/List>|.getElement(i: R|kotlin/Int|): R|Ref| { + ^getElement (this@R|/getElement|.R|SubstitutionOverride|>|(R|/i|) as R|Ref|) + } + public final fun test(list: R|kotlin/collections/List>|): R|kotlin/Unit| { + lval data: R|kotlin/String|by R|/list|.R|/getElement|(Int(0))!! + } diff --git a/compiler/testData/diagnostics/tests/delegatedProperty/inference/notNullAssertionInLocalDelegated.kt b/compiler/testData/diagnostics/tests/delegatedProperty/inference/notNullAssertionInLocalDelegated.kt new file mode 100644 index 00000000000..415de4ef916 --- /dev/null +++ b/compiler/testData/diagnostics/tests/delegatedProperty/inference/notNullAssertionInLocalDelegated.kt @@ -0,0 +1,16 @@ +// FIR_IDENTICAL +// ISSUE: KT-58013 +// WITH_REFLECT +// FIR_DUMP + +import kotlin.reflect.KProperty + +data class Ref(val t: D) + +operator fun Ref.getValue(hisRef: Any?, property: KProperty<*>): V = this.t + +fun List>.getElement(i: Int): Ref = this[i] as Ref + +fun test(list: List>) { + val data: String by list.getElement(0)!! +} diff --git a/compiler/testData/diagnostics/tests/delegatedProperty/inference/tryInGenerated.fir.txt b/compiler/testData/diagnostics/tests/delegatedProperty/inference/tryInGenerated.fir.txt new file mode 100644 index 00000000000..73d36a32416 --- /dev/null +++ b/compiler/testData/diagnostics/tests/delegatedProperty/inference/tryInGenerated.fir.txt @@ -0,0 +1,28 @@ +FILE: tryInGenerated.kt + public final data class Ref : R|kotlin/Any| { + public constructor(t: R|D|): R|Ref| { + super() + } + + public final val t: R|D| = R|/t| + public get(): R|D| + + public final operator fun component1(): R|D| + + public final fun copy(t: R|D| = this@R|/Ref|.R|/Ref.t|): R|Ref| + + } + public final operator fun R|Ref|.getValue(hisRef: R|kotlin/Any?|, property: R|kotlin/reflect/KProperty<*>|): R|V| { + ^getValue this@R|/getValue|.R|SubstitutionOverride| + } + public final fun R|kotlin/collections/List>|.getElement(i: R|kotlin/Int|): R|Ref| { + ^getElement (this@R|/getElement|.R|SubstitutionOverride|>|(R|/i|) as R|Ref|) + } + public final fun test(list: R|kotlin/collections/List>|): R|kotlin/Unit| { + lval data: R|kotlin/String|by try { + R|/list|.R|/getElement|(Int(0)) + } + finally { + } + + } diff --git a/compiler/testData/diagnostics/tests/delegatedProperty/inference/tryInGenerated.kt b/compiler/testData/diagnostics/tests/delegatedProperty/inference/tryInGenerated.kt new file mode 100644 index 00000000000..23fb1b371a0 --- /dev/null +++ b/compiler/testData/diagnostics/tests/delegatedProperty/inference/tryInGenerated.kt @@ -0,0 +1,16 @@ +// FIR_IDENTICAL +// ISSUE: KT-58013 (related) +// WITH_REFLECT +// FIR_DUMP + +import kotlin.reflect.KProperty + +data class Ref(val t: D) + +operator fun Ref.getValue(hisRef: Any?, property: KProperty<*>): V = this.t + +fun List>.getElement(i: Int): Ref = this[i] as Ref + +fun test(list: List>) { + val data: String by try { list.getElement(0) } finally {} +} diff --git a/compiler/testData/diagnostics/tests/delegatedProperty/provideDelegate/notNullAssertionInLocalDelegated.fir.kt b/compiler/testData/diagnostics/tests/delegatedProperty/provideDelegate/notNullAssertionInLocalDelegated.fir.kt new file mode 100644 index 00000000000..33186979160 --- /dev/null +++ b/compiler/testData/diagnostics/tests/delegatedProperty/provideDelegate/notNullAssertionInLocalDelegated.fir.kt @@ -0,0 +1,21 @@ +// ISSUE: KT-58013 +// WITH_REFLECT +// FIR_DUMP + +import kotlin.reflect.KProperty + +data class Ref(val t: D) + +class GenericDelegate(val value: G) + +operator fun Ref.provideDelegate(a: Any?, p: KProperty<*>): GenericDelegate = GenericDelegate(this.t) + +operator fun GenericDelegate.getValue(a: Any?, p: KProperty<*>): W = this.value + +fun List>.getElement(i: Int): Ref = this[i] as Ref + +fun test(list: List>) { + val data: String by list.getElement(0)!! + + val data2: String by list.getElement(0) +} diff --git a/compiler/testData/diagnostics/tests/delegatedProperty/provideDelegate/notNullAssertionInLocalDelegated.fir.txt b/compiler/testData/diagnostics/tests/delegatedProperty/provideDelegate/notNullAssertionInLocalDelegated.fir.txt new file mode 100644 index 00000000000..9ea20207799 --- /dev/null +++ b/compiler/testData/diagnostics/tests/delegatedProperty/provideDelegate/notNullAssertionInLocalDelegated.fir.txt @@ -0,0 +1,36 @@ +FILE: notNullAssertionInLocalDelegated.fir.kt + public final data class Ref : R|kotlin/Any| { + public constructor(t: R|D|): R|Ref| { + super() + } + + public final val t: R|D| = R|/t| + public get(): R|D| + + public final operator fun component1(): R|D| + + public final fun copy(t: R|D| = this@R|/Ref|.R|/Ref.t|): R|Ref| + + } + public final class GenericDelegate : R|kotlin/Any| { + public constructor(value: R|G|): R|GenericDelegate| { + super() + } + + public final val value: R|G| = R|/value| + public get(): R|G| + + } + public final operator fun R|Ref|.provideDelegate(a: R|kotlin/Any?|, p: R|kotlin/reflect/KProperty<*>|): R|GenericDelegate| { + ^provideDelegate R|/GenericDelegate.GenericDelegate|(this@R|/provideDelegate|.R|SubstitutionOverride|) + } + public final operator fun R|GenericDelegate|.getValue(a: R|kotlin/Any?|, p: R|kotlin/reflect/KProperty<*>|): R|W| { + ^getValue this@R|/getValue|.R|SubstitutionOverride| + } + public final fun R|kotlin/collections/List>|.getElement(i: R|kotlin/Int|): R|Ref| { + ^getElement (this@R|/getElement|.R|SubstitutionOverride|>|(R|/i|) as R|Ref|) + } + public final fun test(list: R|kotlin/collections/List>|): R|kotlin/Unit| { + lval data: R|kotlin/String|by R|/list|.R|/getElement|(Int(0))!!.R|/provideDelegate|(Null(null), ::R|/data|) + lval data2: R|kotlin/String|by R|/list|.R|/getElement|(Int(0)).R|/provideDelegate|(Null(null), ::R|/data2|) + } diff --git a/compiler/testData/diagnostics/tests/delegatedProperty/provideDelegate/notNullAssertionInLocalDelegated.kt b/compiler/testData/diagnostics/tests/delegatedProperty/provideDelegate/notNullAssertionInLocalDelegated.kt new file mode 100644 index 00000000000..8bd4e067314 --- /dev/null +++ b/compiler/testData/diagnostics/tests/delegatedProperty/provideDelegate/notNullAssertionInLocalDelegated.kt @@ -0,0 +1,21 @@ +// ISSUE: KT-58013 +// WITH_REFLECT +// FIR_DUMP + +import kotlin.reflect.KProperty + +data class Ref(val t: D) + +class GenericDelegate(val value: G) + +operator fun Ref.provideDelegate(a: Any?, p: KProperty<*>): GenericDelegate = GenericDelegate(this.t) + +operator fun GenericDelegate.getValue(a: Any?, p: KProperty<*>): W = this.value + +fun List>.getElement(i: Int): Ref = this[i] as Ref + +fun test(list: List>) { + val data: String by list.getElement(0)!! + + val data2: String by list.getElement(0) +} diff --git a/compiler/testData/diagnostics/tests/delegatedProperty/provideDelegate/onObject.kt b/compiler/testData/diagnostics/tests/delegatedProperty/provideDelegate/onObject.kt new file mode 100644 index 00000000000..1b5ace1d3ef --- /dev/null +++ b/compiler/testData/diagnostics/tests/delegatedProperty/provideDelegate/onObject.kt @@ -0,0 +1,10 @@ +// FIR_IDENTICAL +class C { + operator fun getValue(x: Any?, y: Any?): String = "" +} + +object O { + operator fun provideDelegate(x: Any?, y: Any?): C = C() +} + +val x: String by O 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 9033b120715..819bd96ddc5 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 @@ -8895,6 +8895,12 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest { runTest("compiler/testData/diagnostics/tests/delegatedProperty/inference/differentDelegatedExpressions.kt"); } + @Test + @TestMetadata("elvisInDelegated.kt") + public void testElvisInDelegated() throws Exception { + runTest("compiler/testData/diagnostics/tests/delegatedProperty/inference/elvisInDelegated.kt"); + } + @Test @TestMetadata("extensionGet.kt") public void testExtensionGet() throws Exception { @@ -8919,6 +8925,12 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest { runTest("compiler/testData/diagnostics/tests/delegatedProperty/inference/genericMethods.kt"); } + @Test + @TestMetadata("ifInDelegated.kt") + public void testIfInDelegated() throws Exception { + runTest("compiler/testData/diagnostics/tests/delegatedProperty/inference/ifInDelegated.kt"); + } + @Test @TestMetadata("kt41952.kt") public void testKt41952() throws Exception { @@ -8961,12 +8973,24 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest { runTest("compiler/testData/diagnostics/tests/delegatedProperty/inference/noExpectedTypeForSupertypeConstraint.kt"); } + @Test + @TestMetadata("notNullAssertionInLocalDelegated.kt") + public void testNotNullAssertionInLocalDelegated() throws Exception { + runTest("compiler/testData/diagnostics/tests/delegatedProperty/inference/notNullAssertionInLocalDelegated.kt"); + } + @Test @TestMetadata("resultTypeOfLambdaForConventionMethods.kt") public void testResultTypeOfLambdaForConventionMethods() throws Exception { runTest("compiler/testData/diagnostics/tests/delegatedProperty/inference/resultTypeOfLambdaForConventionMethods.kt"); } + @Test + @TestMetadata("tryInGenerated.kt") + public void testTryInGenerated() throws Exception { + runTest("compiler/testData/diagnostics/tests/delegatedProperty/inference/tryInGenerated.kt"); + } + @Test @TestMetadata("typeOfLazyDelegatedPropertyWithObject.kt") public void testTypeOfLazyDelegatedPropertyWithObject() throws Exception { @@ -9061,6 +9085,18 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest { runTest("compiler/testData/diagnostics/tests/delegatedProperty/provideDelegate/noOperatorModifierOnProvideDelegate.kt"); } + @Test + @TestMetadata("notNullAssertionInLocalDelegated.kt") + public void testNotNullAssertionInLocalDelegated() throws Exception { + runTest("compiler/testData/diagnostics/tests/delegatedProperty/provideDelegate/notNullAssertionInLocalDelegated.kt"); + } + + @Test + @TestMetadata("onObject.kt") + public void testOnObject() throws Exception { + runTest("compiler/testData/diagnostics/tests/delegatedProperty/provideDelegate/onObject.kt"); + } + @Test @TestMetadata("overloadResolutionForSeveralProvideDelegates.kt") public void testOverloadResolutionForSeveralProvideDelegates() throws Exception {