[FIR] Report missing TYPECHECKER_HAS_RUN_INTO_RECURSIVE_PROBLEM for local functions

^KT-59376
^KT-55221 Fixed
This commit is contained in:
Ivan Kochurkin
2023-07-12 15:29:55 +02:00
committed by Space Team
parent d9736ec88c
commit dac8688a29
16 changed files with 41 additions and 34 deletions
@@ -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
)
@@ -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? {
@@ -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) }
}
}
@@ -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.
@@ -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) {
@@ -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(
@@ -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) {
@@ -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 =
@@ -49,7 +49,7 @@ fun <F : FirClassLikeDeclaration> F.runContractResolveForLocalClass(
targetedClasses: Set<FirClassLikeDeclaration>
): F {
val newContext = outerBodyResolveContext.createSnapshotForLocalClasses(
ReturnTypeCalculatorForFullBodyResolve,
ReturnTypeCalculatorForFullBodyResolve.Contract,
targetedClasses
)
val transformer = FirContractResolveTransformer(session, scopeSession, newContext)
@@ -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,
@@ -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,
@@ -2,7 +2,7 @@
fun foo() {
fun fact(n: Int) = {
if (n > 0) {
fact(n - 1) <!UNRESOLVED_REFERENCE!>*<!> n
<!TYPECHECKER_HAS_RUN_INTO_RECURSIVE_PROBLEM!>fact(n - 1)<!> <!UNRESOLVED_REFERENCE!>*<!> n
}
else {
1
@@ -1,3 +1,3 @@
fun foo() {
fun bar() = (fun() = bar())
fun bar() = (fun() = <!TYPECHECKER_HAS_RUN_INTO_RECURSIVE_PROBLEM!>bar()<!>)
}
@@ -1,5 +1,5 @@
fun foo() {
fun bar() = {
bar()
<!TYPECHECKER_HAS_RUN_INTO_RECURSIVE_PROBLEM, TYPECHECKER_HAS_RUN_INTO_RECURSIVE_PROBLEM!>bar()<!>
}
}
}
@@ -1,8 +1,8 @@
fun foo() {
fun bar1() = bar1()
fun bar1() = <!TYPECHECKER_HAS_RUN_INTO_RECURSIVE_PROBLEM!>bar1()<!>
fun bar2() = 1 <!OVERLOAD_RESOLUTION_AMBIGUITY!>+<!> bar2()
fun bar3() = id(bar3())
fun bar2() = 1 <!OVERLOAD_RESOLUTION_AMBIGUITY!>+<!> <!TYPECHECKER_HAS_RUN_INTO_RECURSIVE_PROBLEM!>bar2()<!>
fun bar3() = id(<!TYPECHECKER_HAS_RUN_INTO_RECURSIVE_PROBLEM!>bar3()<!>)
}
fun <T> id(x: T) = x
@@ -3,10 +3,10 @@ fun main(args: Array<String>) {
fun f() = run {
<!WRONG_MODIFIER_TARGET!>private<!> class C {
private fun foo() {
f().<!UNRESOLVED_REFERENCE!>foo<!>();
<!TYPECHECKER_HAS_RUN_INTO_RECURSIVE_PROBLEM!>f()<!>.<!UNRESOLVED_REFERENCE!>foo<!>();
}
}
C()
}
}
}