diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/collectors/SimpleDiagnosticsCollector.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/collectors/SimpleDiagnosticsCollector.kt index d4e1d341ead..e59742480cc 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/collectors/SimpleDiagnosticsCollector.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/collectors/SimpleDiagnosticsCollector.kt @@ -5,10 +5,9 @@ package org.jetbrains.kotlin.fir.analysis.collectors +import org.jetbrains.kotlin.diagnostics.DiagnosticReporter import org.jetbrains.kotlin.fir.FirSession import org.jetbrains.kotlin.fir.analysis.checkers.context.MutableCheckerContext -import org.jetbrains.kotlin.fir.analysis.collectors.components.AbstractDiagnosticCollectorComponent -import org.jetbrains.kotlin.diagnostics.DiagnosticReporter import org.jetbrains.kotlin.fir.resolve.ScopeSession import org.jetbrains.kotlin.fir.resolve.transformers.ReturnTypeCalculatorForFullBodyResolve @@ -21,7 +20,7 @@ class SimpleDiagnosticsCollector( return CheckerRunningDiagnosticCollectorVisitor( MutableCheckerContext( this, - ReturnTypeCalculatorForFullBodyResolve + ReturnTypeCalculatorForFullBodyResolve.Default ), components ) diff --git a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/AdapterGenerator.kt b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/AdapterGenerator.kt index e8848451938..cf735ee9a9d 100644 --- a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/AdapterGenerator.kt +++ b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/AdapterGenerator.kt @@ -567,7 +567,7 @@ internal class AdapterGenerator( } // On the other hand, the actual type should be either a functional type or a subtype of a class that has a contributed `invoke`. val expectedFunctionType = getFunctionTypeForPossibleSamType(parameter.returnTypeRef.coneType) - return argument.isFunctional(session, scopeSession, expectedFunctionType, ReturnTypeCalculatorForFullBodyResolve) + return argument.isFunctional(session, scopeSession, expectedFunctionType, ReturnTypeCalculatorForFullBodyResolve.Default) } internal fun getFunctionTypeForPossibleSamType(parameterType: ConeKotlinType): ConeKotlinType? { diff --git a/compiler/fir/providers/src/org/jetbrains/kotlin/fir/resolve/transformers/ReturnTypeCalculatorForFullBodyResolve.kt b/compiler/fir/providers/src/org/jetbrains/kotlin/fir/resolve/transformers/ReturnTypeCalculatorForFullBodyResolve.kt index d85c3856b6a..99aa6ec1d3b 100644 --- a/compiler/fir/providers/src/org/jetbrains/kotlin/fir/resolve/transformers/ReturnTypeCalculatorForFullBodyResolve.kt +++ b/compiler/fir/providers/src/org/jetbrains/kotlin/fir/resolve/transformers/ReturnTypeCalculatorForFullBodyResolve.kt @@ -13,7 +13,23 @@ import org.jetbrains.kotlin.fir.scopes.FakeOverrideTypeCalculator import org.jetbrains.kotlin.fir.types.FirResolvedTypeRef import org.jetbrains.kotlin.fir.types.builder.buildErrorTypeRef -object ReturnTypeCalculatorForFullBodyResolve : ReturnTypeCalculator() { +class ReturnTypeCalculatorForFullBodyResolve private constructor( + private val diagnosticKind: DiagnosticKind, + private val reason: String, +) : ReturnTypeCalculator() { + companion object { + // It's actual only for local functions because simple members are being resolved at another phase. + // Local properties are just unresolved if they are used recursively. + val Default = ReturnTypeCalculatorForFullBodyResolve( + DiagnosticKind.RecursionInImplicitTypes, + "Recursion with local function" + ) + val Contract = ReturnTypeCalculatorForFullBodyResolve( + DiagnosticKind.InferenceError, + "Cannot calculate return type during full-body resolution (local class/object?)" + ) + } + override val fakeOverrideTypeCalculator: FakeOverrideTypeCalculator get() = FakeOverrideTypeCalculator.Forced @@ -24,11 +40,6 @@ object ReturnTypeCalculatorForFullBodyResolve : ReturnTypeCalculator() { return FakeOverrideTypeCalculator.Forced.computeReturnType(declaration) } - return buildErrorTypeRef { - diagnostic = ConeSimpleDiagnostic( - "Cannot calculate return type during full-body resolution (local class/object?): ${declaration.render()}", - DiagnosticKind.InferenceError - ) - } + return buildErrorTypeRef { diagnostic = ConeSimpleDiagnostic("$reason: ${declaration.render()}", diagnosticKind) } } } diff --git a/compiler/fir/providers/src/org/jetbrains/kotlin/fir/scopes/impl/FirTypeIntersectionScopeContext.kt b/compiler/fir/providers/src/org/jetbrains/kotlin/fir/scopes/impl/FirTypeIntersectionScopeContext.kt index c257da18c56..d5bd84e5ca3 100644 --- a/compiler/fir/providers/src/org/jetbrains/kotlin/fir/scopes/impl/FirTypeIntersectionScopeContext.kt +++ b/compiler/fir/providers/src/org/jetbrains/kotlin/fir/scopes/impl/FirTypeIntersectionScopeContext.kt @@ -154,7 +154,7 @@ class FirTypeIntersectionScopeContext( overrideService.extractBothWaysOverridable(allMembersWithScope.maxByVisibility(), allMembersWithScope, overrideChecker) val group = groupWithPrivate.filter { !Visibilities.isPrivate(it.member.fir.visibility) }.ifEmpty { groupWithPrivate } val nonSubsumed = if (forClassUseSiteScope) group.nonSubsumed() else group - val mostSpecific = overrideService.selectMostSpecificMembers(nonSubsumed, ReturnTypeCalculatorForFullBodyResolve) + val mostSpecific = overrideService.selectMostSpecificMembers(nonSubsumed, ReturnTypeCalculatorForFullBodyResolve.Default) val nonTrivial = if (forClassUseSiteScope) { // Create a non-trivial intersection override when the base methods come from different scopes, // even if one of them is more specific than the others, i.e. when there is more than one method that is not subsumed. diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirAbstractBodyResolveTransformerDispatcher.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirAbstractBodyResolveTransformerDispatcher.kt index 51b4c51b7f1..32262f46256 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirAbstractBodyResolveTransformerDispatcher.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirAbstractBodyResolveTransformerDispatcher.kt @@ -24,7 +24,7 @@ abstract class FirAbstractBodyResolveTransformerDispatcher( phase: FirResolvePhase, override var implicitTypeOnly: Boolean, scopeSession: ScopeSession, - val returnTypeCalculator: ReturnTypeCalculator = ReturnTypeCalculatorForFullBodyResolve, + val returnTypeCalculator: ReturnTypeCalculator = ReturnTypeCalculatorForFullBodyResolve.Default, outerBodyResolveContext: BodyResolveContext? = null, val firResolveContextCollector: FirResolveContextCollector? = null, ) : FirAbstractBodyResolveTransformer(phase) { diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirBodyResolveTransformer.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirBodyResolveTransformer.kt index 545d11dfccc..9eb00cbc85c 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirBodyResolveTransformer.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirBodyResolveTransformer.kt @@ -6,7 +6,7 @@ package org.jetbrains.kotlin.fir.resolve.transformers.body.resolve import org.jetbrains.kotlin.fir.FirSession -import org.jetbrains.kotlin.fir.declarations.* +import org.jetbrains.kotlin.fir.declarations.FirResolvePhase import org.jetbrains.kotlin.fir.resolve.ScopeSession import org.jetbrains.kotlin.fir.resolve.transformers.ReturnTypeCalculator import org.jetbrains.kotlin.fir.resolve.transformers.ReturnTypeCalculatorForFullBodyResolve @@ -16,7 +16,7 @@ open class FirBodyResolveTransformer( phase: FirResolvePhase, implicitTypeOnly: Boolean, scopeSession: ScopeSession, - returnTypeCalculator: ReturnTypeCalculator = ReturnTypeCalculatorForFullBodyResolve, + returnTypeCalculator: ReturnTypeCalculator = ReturnTypeCalculatorForFullBodyResolve.Default, outerBodyResolveContext: BodyResolveContext? = null, firResolveContextCollector: FirResolveContextCollector? = null ) : FirAbstractBodyResolveTransformerDispatcher( diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirImplicitBodyResolve.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirImplicitBodyResolve.kt index 95cb830eb5d..f353bd54bc9 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirImplicitBodyResolve.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirImplicitBodyResolve.kt @@ -24,7 +24,6 @@ import org.jetbrains.kotlin.fir.resolve.transformers.ReturnTypeCalculatorForFull import org.jetbrains.kotlin.fir.resolve.transformers.contracts.runContractResolveForLocalClass import org.jetbrains.kotlin.fir.scopes.FakeOverrideTypeCalculator import org.jetbrains.kotlin.fir.scopes.fakeOverrideSubstitution -import org.jetbrains.kotlin.fir.delegatedWrapperData import org.jetbrains.kotlin.fir.scopes.impl.originalForWrappedIntegerOperator import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirSyntheticPropertySymbol @@ -193,7 +192,7 @@ open class ReturnTypeCalculatorWithJump( override fun tryCalculateReturnTypeOrNull(declaration: FirCallableDeclaration): FirResolvedTypeRef { // Local declarations must be handled by `ReturnTypeCalculatorForFullBodyResolve` to avoid resolution cycles in LL FIR. if (declaration.visibility == Visibilities.Local) { - return ReturnTypeCalculatorForFullBodyResolve.tryCalculateReturnType(declaration) + return ReturnTypeCalculatorForFullBodyResolve.Default.tryCalculateReturnType(declaration) } if (declaration is FirValueParameter && declaration.returnTypeRef is FirImplicitTypeRef) { diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/contracts/FirAbstractContractResolveTransformerDispatcher.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/contracts/FirAbstractContractResolveTransformerDispatcher.kt index 1bc653850ce..77f3ad425aa 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/contracts/FirAbstractContractResolveTransformerDispatcher.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/contracts/FirAbstractContractResolveTransformerDispatcher.kt @@ -25,6 +25,7 @@ import org.jetbrains.kotlin.fir.moduleData import org.jetbrains.kotlin.fir.references.builder.buildSimpleNamedReference import org.jetbrains.kotlin.fir.resolve.ResolutionMode import org.jetbrains.kotlin.fir.resolve.ScopeSession +import org.jetbrains.kotlin.fir.resolve.transformers.ReturnTypeCalculatorForFullBodyResolve import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.BodyResolveContext import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.FirAbstractBodyResolveTransformerDispatcher import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.FirDeclarationsResolveTransformer @@ -45,6 +46,7 @@ abstract class FirAbstractContractResolveTransformerDispatcher( FirResolvePhase.CONTRACTS, implicitTypeOnly = false, scopeSession, + returnTypeCalculator = ReturnTypeCalculatorForFullBodyResolve.Contract, outerBodyResolveContext = outerBodyResolveContext ) { final override val expressionsTransformer: FirExpressionsResolveTransformer = diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/contracts/FirContractResolveTransformerAdapter.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/contracts/FirContractResolveTransformerAdapter.kt index 11d6a2bc45a..e66f1d5aee7 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/contracts/FirContractResolveTransformerAdapter.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/contracts/FirContractResolveTransformerAdapter.kt @@ -49,7 +49,7 @@ fun F.runContractResolveForLocalClass( targetedClasses: Set ): F { val newContext = outerBodyResolveContext.createSnapshotForLocalClasses( - ReturnTypeCalculatorForFullBodyResolve, + ReturnTypeCalculatorForFullBodyResolve.Contract, targetedClasses ) val transformer = FirContractResolveTransformer(session, scopeSession, newContext) diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/plugin/FirAnnotationArgumentsMappingTransformer.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/plugin/FirAnnotationArgumentsMappingTransformer.kt index 0d13a22fe7c..a9b4e88f45d 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/plugin/FirAnnotationArgumentsMappingTransformer.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/plugin/FirAnnotationArgumentsMappingTransformer.kt @@ -15,11 +15,7 @@ import org.jetbrains.kotlin.fir.resolve.ResolutionMode import org.jetbrains.kotlin.fir.resolve.ScopeSession import org.jetbrains.kotlin.fir.resolve.transformers.ReturnTypeCalculator import org.jetbrains.kotlin.fir.resolve.transformers.ReturnTypeCalculatorForFullBodyResolve -import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.BodyResolveContext -import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.FirAbstractBodyResolveTransformerDispatcher -import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.FirDeclarationsResolveTransformer -import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.FirExpressionsResolveTransformer -import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.FirResolveContextCollector +import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.* import org.jetbrains.kotlin.fir.visitors.transformSingle open class FirAnnotationArgumentsMappingTransformer( @@ -27,7 +23,7 @@ open class FirAnnotationArgumentsMappingTransformer( scopeSession: ScopeSession, resolvePhase: FirResolvePhase, outerBodyResolveContext: BodyResolveContext? = null, - returnTypeCalculator: ReturnTypeCalculator = ReturnTypeCalculatorForFullBodyResolve, + returnTypeCalculator: ReturnTypeCalculator = ReturnTypeCalculatorForFullBodyResolve.Default, firResolveContextCollector: FirResolveContextCollector? = null, ) : FirAbstractBodyResolveTransformerDispatcher( session, diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/plugin/FirAnnotationArgumentsResolveTransformer.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/plugin/FirAnnotationArgumentsResolveTransformer.kt index 782b0f0bb47..4bee3df4c65 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/plugin/FirAnnotationArgumentsResolveTransformer.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/plugin/FirAnnotationArgumentsResolveTransformer.kt @@ -34,7 +34,7 @@ open class FirAnnotationArgumentsResolveTransformer( scopeSession: ScopeSession, resolvePhase: FirResolvePhase, outerBodyResolveContext: BodyResolveContext? = null, - returnTypeCalculator: ReturnTypeCalculator = ReturnTypeCalculatorForFullBodyResolve, + returnTypeCalculator: ReturnTypeCalculator = ReturnTypeCalculatorForFullBodyResolve.Default, firResolveContextCollector: FirResolveContextCollector? = null, ) : FirAbstractBodyResolveTransformerDispatcher( session, diff --git a/compiler/testData/diagnostics/tests/inference/recursiveLocalFuns/localFactorial.fir.kt b/compiler/testData/diagnostics/tests/inference/recursiveLocalFuns/localFactorial.fir.kt index fc52c00306a..b1ab33fd53f 100644 --- a/compiler/testData/diagnostics/tests/inference/recursiveLocalFuns/localFactorial.fir.kt +++ b/compiler/testData/diagnostics/tests/inference/recursiveLocalFuns/localFactorial.fir.kt @@ -2,7 +2,7 @@ fun foo() { fun fact(n: Int) = { if (n > 0) { - fact(n - 1) * n + fact(n - 1) * n } else { 1 diff --git a/compiler/testData/diagnostics/tests/inference/recursiveLocalFuns/recursiveFun.fir.kt b/compiler/testData/diagnostics/tests/inference/recursiveLocalFuns/recursiveFun.fir.kt index a4b6e0861eb..bd777a778b3 100644 --- a/compiler/testData/diagnostics/tests/inference/recursiveLocalFuns/recursiveFun.fir.kt +++ b/compiler/testData/diagnostics/tests/inference/recursiveLocalFuns/recursiveFun.fir.kt @@ -1,3 +1,3 @@ fun foo() { - fun bar() = (fun() = bar()) + fun bar() = (fun() = bar()) } diff --git a/compiler/testData/diagnostics/tests/inference/recursiveLocalFuns/recursiveLambda.fir.kt b/compiler/testData/diagnostics/tests/inference/recursiveLocalFuns/recursiveLambda.fir.kt index 962d4b4eadb..8b0aeb2a0a4 100644 --- a/compiler/testData/diagnostics/tests/inference/recursiveLocalFuns/recursiveLambda.fir.kt +++ b/compiler/testData/diagnostics/tests/inference/recursiveLocalFuns/recursiveLambda.fir.kt @@ -1,5 +1,5 @@ fun foo() { fun bar() = { - bar() + bar() } -} \ No newline at end of file +} diff --git a/compiler/testData/diagnostics/tests/inference/recursiveLocalFuns/selfCall.fir.kt b/compiler/testData/diagnostics/tests/inference/recursiveLocalFuns/selfCall.fir.kt index 903e4dcceca..54381ac4650 100644 --- a/compiler/testData/diagnostics/tests/inference/recursiveLocalFuns/selfCall.fir.kt +++ b/compiler/testData/diagnostics/tests/inference/recursiveLocalFuns/selfCall.fir.kt @@ -1,8 +1,8 @@ fun foo() { - fun bar1() = bar1() + fun bar1() = bar1() - fun bar2() = 1 + bar2() - fun bar3() = id(bar3()) + fun bar2() = 1 + bar2() + fun bar3() = id(bar3()) } fun id(x: T) = x diff --git a/compiler/testData/diagnostics/tests/regressions/kt9384.fir.kt b/compiler/testData/diagnostics/tests/regressions/kt9384.fir.kt index 239a81e2aad..14130092f04 100644 --- a/compiler/testData/diagnostics/tests/regressions/kt9384.fir.kt +++ b/compiler/testData/diagnostics/tests/regressions/kt9384.fir.kt @@ -3,10 +3,10 @@ fun main(args: Array) { fun f() = run { private class C { private fun foo() { - f().foo(); + f().foo(); } } C() } -} \ No newline at end of file +}