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 67310be021c..05c1566b41c 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 @@ -10687,6 +10687,12 @@ public class DiagnosticCompilerTestFE10TestdataTestGenerated extends AbstractDia runTest("compiler/testData/diagnostics/tests/delegatedProperty/inference/labeledDelegatedExpression.kt"); } + @Test + @TestMetadata("lambdaDelegate.kt") + public void testLambdaDelegate() throws Exception { + runTest("compiler/testData/diagnostics/tests/delegatedProperty/inference/lambdaDelegate.kt"); + } + @Test @TestMetadata("lambdaWithMultipleReturns.kt") public void testLambdaWithMultipleReturns() 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 62b8417071b..ee74e1a4ea4 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 @@ -10687,6 +10687,12 @@ public class LLFirPreresolvedReversedDiagnosticCompilerFE10TestDataTestGenerated runTest("compiler/testData/diagnostics/tests/delegatedProperty/inference/labeledDelegatedExpression.kt"); } + @Test + @TestMetadata("lambdaDelegate.kt") + public void testLambdaDelegate() throws Exception { + runTest("compiler/testData/diagnostics/tests/delegatedProperty/inference/lambdaDelegate.kt"); + } + @Test @TestMetadata("lambdaWithMultipleReturns.kt") public void testLambdaWithMultipleReturns() 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 0ecae3f0b0b..ed7febe0aa5 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 @@ -10681,6 +10681,12 @@ public class FirLightTreeOldFrontendDiagnosticsTestGenerated extends AbstractFir runTest("compiler/testData/diagnostics/tests/delegatedProperty/inference/labeledDelegatedExpression.kt"); } + @Test + @TestMetadata("lambdaDelegate.kt") + public void testLambdaDelegate() throws Exception { + runTest("compiler/testData/diagnostics/tests/delegatedProperty/inference/lambdaDelegate.kt"); + } + @Test @TestMetadata("lambdaWithMultipleReturns.kt") public void testLambdaWithMultipleReturns() 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 349ddb386f2..24abf027a04 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 @@ -10687,6 +10687,12 @@ public class FirPsiOldFrontendDiagnosticsTestGenerated extends AbstractFirPsiDia runTest("compiler/testData/diagnostics/tests/delegatedProperty/inference/labeledDelegatedExpression.kt"); } + @Test + @TestMetadata("lambdaDelegate.kt") + public void testLambdaDelegate() throws Exception { + runTest("compiler/testData/diagnostics/tests/delegatedProperty/inference/lambdaDelegate.kt"); + } + @Test @TestMetadata("lambdaWithMultipleReturns.kt") public void testLambdaWithMultipleReturns() throws Exception { diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/ResolutionMode.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/ResolutionMode.kt index 723dc4c3ba8..b0a99e44931 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/ResolutionMode.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/ResolutionMode.kt @@ -23,10 +23,11 @@ sealed class ResolutionMode( override fun toString(): String = "ContextDependent" } - data object Delegate : ContextDependent() data object AugmentedAssignmentCallOption : ContextDependent(skipCompletion = true) } + data object Delegate : ResolutionMode(forceFullCompletion = false) + data object ContextIndependent : ResolutionMode(forceFullCompletion = true) sealed class ReceiverResolution(val forCallableReference: Boolean) : ResolutionMode(forceFullCompletion = true) { diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/FirPCLAInferenceSession.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/FirPCLAInferenceSession.kt index 9f781620b70..94f0e80fc21 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/FirPCLAInferenceSession.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/FirPCLAInferenceSession.kt @@ -63,7 +63,7 @@ class FirPCLAInferenceSession( // Integrating back would happen at FirDelegatedPropertyInferenceSession.completeSessionOrPostponeIfNonRoot // after all other delegation-related calls are being analyzed - if (resolutionMode == ResolutionMode.ContextDependent.Delegate) return + if (resolutionMode == ResolutionMode.Delegate) return currentCommonSystem.replaceContentWith(candidate.system.currentStorage()) @@ -211,7 +211,7 @@ class FirPCLAInferenceSession( } if (callInfo.arguments.any { it.isQualifiedAccessContainingTypeVariables() || it.doesArgumentUseOuterCS() }) return true - if (callInfo.resolutionMode is ResolutionMode.ContextDependent.Delegate) return true + if (callInfo.resolutionMode is ResolutionMode.Delegate) return true // For assignments like myVarContainingTV = SomeCallWithNonTrivialInference(...) // We should integrate the call into the PCLA tree, too 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 25c84b4d617..576f03acdae 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 @@ -440,7 +440,7 @@ open class FirDeclarationsResolveTransformer( } private fun transformDelegateExpression(delegate: FirWrappedDelegateExpression): FirExpression = - delegate.expression.transformSingle(transformer, ResolutionMode.ContextDependent.Delegate) + delegate.expression.transformSingle(transformer, ResolutionMode.Delegate) .transformSingle(components.integerLiteralAndOperatorApproximationTransformer, null) /** @@ -1024,7 +1024,12 @@ open class FirDeclarationsResolveTransformer( } is ResolutionMode.WithExpectedType -> transformAnonymousFunctionWithExpectedType(anonymousFunction, data.expectedTypeRef, data) - is ResolutionMode.ContextIndependent, is ResolutionMode.AssignmentLValue, is ResolutionMode.ReceiverResolution -> + + is ResolutionMode.ContextIndependent, + is ResolutionMode.AssignmentLValue, + is ResolutionMode.ReceiverResolution, + is ResolutionMode.Delegate, + -> transformAnonymousFunctionWithExpectedType(anonymousFunction, FirImplicitTypeRefImplWithoutSource, data) is ResolutionMode.WithStatus -> throw AssertionError("Should not be here in WithStatus/WithExpectedTypeFromCast mode") 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 4ee67c3ac88..04a58a59c53 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 @@ -491,10 +491,7 @@ open class FirExpressionsResolveTransformer(transformer: FirAbstractBodyResolveT ) val approximationIsNeeded = - resolutionMode !is ResolutionMode.ReceiverResolution && - (resolutionMode !is ResolutionMode.ContextDependent || - // TODO check why we need a special case for ContextDependent.Delegate - resolutionMode is ResolutionMode.ContextDependent.Delegate) + resolutionMode !is ResolutionMode.ReceiverResolution && resolutionMode !is ResolutionMode.ContextDependent val integerOperatorCall = buildIntegerLiteralOperatorCall { source = originalCall.source @@ -1070,8 +1067,7 @@ open class FirExpressionsResolveTransformer(transformer: FirAbstractBodyResolveT transformedLHS?.let { callableReferenceAccess.replaceExplicitReceiver(transformedLHS) } - // TODO check why we need a special case for ContextDependent.Delegate - return if (data is ResolutionMode.ContextDependent && data !is ResolutionMode.ContextDependent.Delegate) { + return if (data is ResolutionMode.ContextDependent) { context.storeCallableReferenceContext(callableReferenceAccess) callableReferenceAccess } else { diff --git a/compiler/testData/diagnostics/tests/delegatedProperty/inference/lambdaDelegate.kt b/compiler/testData/diagnostics/tests/delegatedProperty/inference/lambdaDelegate.kt new file mode 100644 index 00000000000..2c27e0e62a6 --- /dev/null +++ b/compiler/testData/diagnostics/tests/delegatedProperty/inference/lambdaDelegate.kt @@ -0,0 +1,38 @@ +// ISSUE: KT-64635 +// FIR_IDENTICAL +import kotlin.reflect.KProperty + +class Context + +interface MyReadOnlyProperty { + operator fun getValue(thisRef: T, property: KProperty<*>): V +} + +open class NodeHolder { + operator fun ((Context).() -> Unit).provideDelegate( + thisRef: Any?, + prop: KProperty<*> + ): MyReadOnlyProperty = TODO() +} + +class SubClass1 : NodeHolder() { + val foo: (Context).() -> Unit = {} + val x by foo +} + +class SubClass2 : NodeHolder() { + val x by {} +} + +fun main() { + val my_holder_works = + object : NodeHolder() { + val foo: (Context).() -> Unit = {} + val x by foo + } + + val my_holder_bad = + object : NodeHolder() { + val x by {} + } +} 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 11208a1f32e..a288d485931 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 @@ -10687,6 +10687,12 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest { runTest("compiler/testData/diagnostics/tests/delegatedProperty/inference/labeledDelegatedExpression.kt"); } + @Test + @TestMetadata("lambdaDelegate.kt") + public void testLambdaDelegate() throws Exception { + runTest("compiler/testData/diagnostics/tests/delegatedProperty/inference/lambdaDelegate.kt"); + } + @Test @TestMetadata("lambdaWithMultipleReturns.kt") public void testLambdaWithMultipleReturns() throws Exception {