From e391e68ea388515d52f3d4345df8d5ef2da58ea7 Mon Sep 17 00:00:00 2001 From: Mikhail Glukhikh Date: Thu, 23 Nov 2023 15:11:27 +0100 Subject: [PATCH] K2: drop TypeParameterAsCallable check for reified in ::class Related to KT-63377 --- .../fir/resolver/candidateInfoProviders.kt | 1 + .../jetbrains/kotlin/fir/FirCallResolver.kt | 29 +++++++++---------- .../kotlin/fir/resolve/calls/CallInfo.kt | 1 + .../fir/resolve/calls/ResolutionStages.kt | 5 ++-- .../transformers/FirSyntheticCallGenerator.kt | 1 + .../FirExpressionsResolveTransformer.kt | 18 ++++++++---- ...FirSpecificAnnotationResolveTransformer.kt | 1 + .../memberTypeParameterVsNestedClass2.fir.txt | 2 +- 8 files changed, 34 insertions(+), 24 deletions(-) diff --git a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/resolver/candidateInfoProviders.kt b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/resolver/candidateInfoProviders.kt index 957de1e2c0c..b4e4f1f7e16 100644 --- a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/resolver/candidateInfoProviders.kt +++ b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/resolver/candidateInfoProviders.kt @@ -48,6 +48,7 @@ abstract class AbstractCandidateInfoProvider( containingDeclarations = emptyList(), // TODO - maybe we should pass declarations from context here (no visible differences atm) containingFile = firFile, isImplicitInvoke = false, + isUsedAsGetClassReceiver = false, session = firSession, ) } diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/FirCallResolver.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/FirCallResolver.kt index f830c5052ee..c0a07b5f7da 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/FirCallResolver.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/FirCallResolver.kt @@ -143,8 +143,10 @@ class FirCallResolver( ): List { val collector = AllCandidatesCollector(components, components.resolutionStageRunner) val origin = (qualifiedAccess as? FirFunctionCall)?.origin ?: FirFunctionCallOrigin.Regular - val result = - collectCandidates(qualifiedAccess, name, forceCallKind = null, origin, containingDeclarations, resolutionContext, collector) + val result = collectCandidates( + qualifiedAccess, name, forceCallKind = null, isUsedAsGetClassReceiver = false, + origin, containingDeclarations, resolutionContext, collector + ) return collector.allCandidates.map { OverloadCandidate(it, isInBestCandidates = it in result.candidates) } } @@ -152,6 +154,7 @@ class FirCallResolver( qualifiedAccess: FirQualifiedAccessExpression, name: Name, forceCallKind: CallKind? = null, + isUsedAsGetClassReceiver: Boolean = false, origin: FirFunctionCallOrigin = FirFunctionCallOrigin.Regular, containingDeclarations: List = transformer.components.containingDeclarations, resolutionContext: ResolutionContext = transformer.resolutionContext, @@ -169,6 +172,7 @@ class FirCallResolver( explicitReceiver, argumentList, isImplicitInvoke = qualifiedAccess is FirImplicitInvokeCall, + isUsedAsGetClassReceiver = isUsedAsGetClassReceiver, typeArguments, session, components.file, @@ -222,25 +226,17 @@ class FirCallResolver( fun resolveVariableAccessAndSelectCandidate( qualifiedAccess: FirQualifiedAccessExpression, isUsedAsReceiver: Boolean, + isUsedAsGetClassReceiver: Boolean, callSite: FirElement, ): FirStatement { - return resolveVariableAccessAndSelectCandidateImpl(qualifiedAccess, isUsedAsReceiver, callSite) { true } - } - - fun resolveOnlyEnumOrQualifierAccessAndSelectCandidate( - qualifiedAccess: FirQualifiedAccessExpression, - isUsedAsReceiver: Boolean, - ): FirStatement { - return resolveVariableAccessAndSelectCandidateImpl(qualifiedAccess, isUsedAsReceiver) accept@{ candidates -> - val symbol = candidates.singleOrNull()?.symbol ?: return@accept false - symbol is FirEnumEntrySymbol || symbol is FirRegularClassSymbol - } + return resolveVariableAccessAndSelectCandidateImpl(qualifiedAccess, isUsedAsReceiver, isUsedAsGetClassReceiver, callSite) { true } } private fun resolveVariableAccessAndSelectCandidateImpl( qualifiedAccess: FirQualifiedAccessExpression, isUsedAsReceiver: Boolean, - callSite: FirElement = qualifiedAccess, + isUsedAsGetClassReceiver: Boolean, + callSite: FirElement, acceptCandidates: (Collection) -> Boolean, ): FirStatement { val callee = qualifiedAccess.calleeReference as? FirSimpleNamedReference ?: return qualifiedAccess @@ -250,7 +246,7 @@ class FirCallResolver( val nonFatalDiagnosticFromExpression = (qualifiedAccess as? FirPropertyAccessExpression)?.nonFatalDiagnostics val basicResult by lazy(LazyThreadSafetyMode.NONE) { - collectCandidates(qualifiedAccess, callee.name, callSite = callSite) + collectCandidates(qualifiedAccess, callee.name, isUsedAsGetClassReceiver = isUsedAsGetClassReceiver, callSite = callSite) } // Even if it's not receiver, it makes sense to continue qualifier if resolution is unsuccessful @@ -487,6 +483,7 @@ class FirCallResolver( explicitReceiver = null, delegatedConstructorCall.argumentList, isImplicitInvoke = false, + isUsedAsGetClassReceiver = false, typeArguments = typeArguments, session, components.file, @@ -622,6 +619,7 @@ class FirCallResolver( explicitReceiver = null, annotation.argumentList, isImplicitInvoke = false, + isUsedAsGetClassReceiver = false, typeArguments = annotation.typeArguments, session, components.file, @@ -695,6 +693,7 @@ class FirCallResolver( callableReferenceAccess.explicitReceiver, FirEmptyArgumentList, isImplicitInvoke = false, + isUsedAsGetClassReceiver = false, emptyList(), session, components.file, diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/CallInfo.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/CallInfo.kt index cb8444628cb..68adade4157 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/CallInfo.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/CallInfo.kt @@ -28,6 +28,7 @@ data class CallInfo( override val explicitReceiver: FirExpression?, override val argumentList: FirArgumentList, override val isImplicitInvoke: Boolean, + val isUsedAsGetClassReceiver: Boolean, val typeArguments: List, val session: FirSession, diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/ResolutionStages.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/ResolutionStages.kt index df759d722e9..dab1a1e489a 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/ResolutionStages.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/ResolutionStages.kt @@ -783,8 +783,9 @@ internal object ConstraintSystemForks : ResolutionStage() { internal object TypeParameterAsCallable : ResolutionStage() { override suspend fun check(candidate: Candidate, callInfo: CallInfo, sink: CheckerSink, context: ResolutionContext) { - if (candidate.symbol is FirTypeParameterSymbol) { + val symbol = candidate.symbol + if (symbol is FirTypeParameterSymbol && !(callInfo.isUsedAsGetClassReceiver && symbol.isReified)) { sink.yieldDiagnostic(TypeParameterAsExpression) } } -} \ No newline at end of file +} diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirSyntheticCallGenerator.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirSyntheticCallGenerator.kt index a7a2e543cd0..9cd68a4549d 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirSyntheticCallGenerator.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirSyntheticCallGenerator.kt @@ -374,6 +374,7 @@ class FirSyntheticCallGenerator( explicitReceiver = null, argumentList = argumentList, isImplicitInvoke = false, + isUsedAsGetClassReceiver = false, typeArguments = emptyList(), session = session, containingFile = components.file, 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 10a952a3fb6..95a20f203a8 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 @@ -12,7 +12,6 @@ import org.jetbrains.kotlin.fakeElement import org.jetbrains.kotlin.fir.* import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.declarations.utils.isExternal -import org.jetbrains.kotlin.fir.declarations.utils.isInner import org.jetbrains.kotlin.fir.declarations.utils.isLocal import org.jetbrains.kotlin.fir.diagnostics.* import org.jetbrains.kotlin.fir.expressions.* @@ -91,13 +90,14 @@ open class FirExpressionsResolveTransformer(transformer: FirAbstractBodyResolveT qualifiedAccessExpression: FirQualifiedAccessExpression, data: ResolutionMode, ): FirStatement = whileAnalysing(session, qualifiedAccessExpression) { - transformQualifiedAccessExpression(qualifiedAccessExpression, data, isUsedAsReceiver = false) + transformQualifiedAccessExpression(qualifiedAccessExpression, data, isUsedAsReceiver = false, isUsedAsGetClassReceiver = false) } fun transformQualifiedAccessExpression( qualifiedAccessExpression: FirQualifiedAccessExpression, data: ResolutionMode, isUsedAsReceiver: Boolean, + isUsedAsGetClassReceiver: Boolean, ): FirStatement { if (qualifiedAccessExpression.isResolved && qualifiedAccessExpression.calleeReference !is FirSimpleNamedReference) { return qualifiedAccessExpression @@ -152,6 +152,7 @@ open class FirExpressionsResolveTransformer(transformer: FirAbstractBodyResolveT val transformedCallee = resolveQualifiedAccessAndSelectCandidate( qualifiedAccessExpression, isUsedAsReceiver, + isUsedAsGetClassReceiver, // Set the correct call site. For assignment LHSs, it's the assignment, otherwise it's the qualified access itself. callSite = when (data) { is ResolutionMode.AssignmentLValue -> data.variableAssignment @@ -202,7 +203,7 @@ open class FirExpressionsResolveTransformer(transformer: FirAbstractBodyResolveT if (explicitReceiver is FirPropertyAccessExpression) { qualifiedAccessExpression.replaceExplicitReceiver( transformQualifiedAccessExpression( - explicitReceiver, ResolutionMode.ReceiverResolution, isUsedAsReceiver = true + explicitReceiver, ResolutionMode.ReceiverResolution, isUsedAsReceiver = true, isUsedAsGetClassReceiver = false ) as FirExpression ) return qualifiedAccessExpression @@ -221,9 +222,12 @@ open class FirExpressionsResolveTransformer(transformer: FirAbstractBodyResolveT protected open fun resolveQualifiedAccessAndSelectCandidate( qualifiedAccessExpression: FirQualifiedAccessExpression, isUsedAsReceiver: Boolean, + isUsedAsGetClassReceiver: Boolean, callSite: FirElement, ): FirStatement { - return callResolver.resolveVariableAccessAndSelectCandidate(qualifiedAccessExpression, isUsedAsReceiver, callSite) + return callResolver.resolveVariableAccessAndSelectCandidate( + qualifiedAccessExpression, isUsedAsReceiver, isUsedAsGetClassReceiver, callSite + ) } fun transformSuperReceiver( @@ -1055,7 +1059,7 @@ open class FirExpressionsResolveTransformer(transformer: FirAbstractBodyResolveT val transformedLHS = when (explicitReceiver) { is FirPropertyAccessExpression -> transformQualifiedAccessExpression( - explicitReceiver, ResolutionMode.ContextIndependent, isUsedAsReceiver = true + explicitReceiver, ResolutionMode.ContextIndependent, isUsedAsReceiver = true, isUsedAsGetClassReceiver = false ) as FirExpression else -> explicitReceiver?.transformSingle(this, ResolutionMode.ContextIndependent) @@ -1096,7 +1100,9 @@ open class FirExpressionsResolveTransformer(transformer: FirAbstractBodyResolveT val argument = getClassCall.argument val replacedArgument: FirExpression = if (argument is FirPropertyAccessExpression) - transformQualifiedAccessExpression(argument, dataForLhs, isUsedAsReceiver = true) as FirExpression + transformQualifiedAccessExpression( + argument, dataForLhs, isUsedAsReceiver = true, isUsedAsGetClassReceiver = true + ) as FirExpression else argument.transform(this, dataForLhs) diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/plugin/AbstractFirSpecificAnnotationResolveTransformer.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/plugin/AbstractFirSpecificAnnotationResolveTransformer.kt index 512b2958ad5..df2ac843d85 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/plugin/AbstractFirSpecificAnnotationResolveTransformer.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/plugin/AbstractFirSpecificAnnotationResolveTransformer.kt @@ -189,6 +189,7 @@ abstract class AbstractFirSpecificAnnotationResolveTransformer( override fun resolveQualifiedAccessAndSelectCandidate( qualifiedAccessExpression: FirQualifiedAccessExpression, isUsedAsReceiver: Boolean, + isUsedAsGetClassReceiver: Boolean, callSite: FirElement ): FirStatement { qualifiedAccessExpression.resolveFromImportScope() diff --git a/compiler/testData/diagnostics/tests/typeParameters/memberTypeParameterVsNestedClass2.fir.txt b/compiler/testData/diagnostics/tests/typeParameters/memberTypeParameterVsNestedClass2.fir.txt index b878b2829d7..315bcb8f83b 100644 --- a/compiler/testData/diagnostics/tests/typeParameters/memberTypeParameterVsNestedClass2.fir.txt +++ b/compiler/testData/diagnostics/tests/typeParameters/memberTypeParameterVsNestedClass2.fir.txt @@ -12,7 +12,7 @@ FILE: memberTypeParameterVsNestedClass2.fir.kt } public final inline fun foo(): R|kotlin/Unit| { - (Q|Outer.T|) + (R|T|) lval x: R|T?| = Null(null) lval y: R|T?| = R|/Outer.T.T#|() }