K2: drop TypeParameterAsCallable check for reified in ::class

Related to KT-63377
This commit is contained in:
Mikhail Glukhikh
2023-11-23 15:11:27 +01:00
committed by Space Team
parent 83cfcc30c6
commit e391e68ea3
8 changed files with 34 additions and 24 deletions
@@ -48,6 +48,7 @@ abstract class AbstractCandidateInfoProvider(
containingDeclarations = emptyList(), // TODO - maybe we should pass declarations from context here (no visible differences atm) containingDeclarations = emptyList(), // TODO - maybe we should pass declarations from context here (no visible differences atm)
containingFile = firFile, containingFile = firFile,
isImplicitInvoke = false, isImplicitInvoke = false,
isUsedAsGetClassReceiver = false,
session = firSession, session = firSession,
) )
} }
@@ -143,8 +143,10 @@ class FirCallResolver(
): List<OverloadCandidate> { ): List<OverloadCandidate> {
val collector = AllCandidatesCollector(components, components.resolutionStageRunner) val collector = AllCandidatesCollector(components, components.resolutionStageRunner)
val origin = (qualifiedAccess as? FirFunctionCall)?.origin ?: FirFunctionCallOrigin.Regular val origin = (qualifiedAccess as? FirFunctionCall)?.origin ?: FirFunctionCallOrigin.Regular
val result = val result = collectCandidates(
collectCandidates(qualifiedAccess, name, forceCallKind = null, origin, containingDeclarations, resolutionContext, collector) qualifiedAccess, name, forceCallKind = null, isUsedAsGetClassReceiver = false,
origin, containingDeclarations, resolutionContext, collector
)
return collector.allCandidates.map { OverloadCandidate(it, isInBestCandidates = it in result.candidates) } return collector.allCandidates.map { OverloadCandidate(it, isInBestCandidates = it in result.candidates) }
} }
@@ -152,6 +154,7 @@ class FirCallResolver(
qualifiedAccess: FirQualifiedAccessExpression, qualifiedAccess: FirQualifiedAccessExpression,
name: Name, name: Name,
forceCallKind: CallKind? = null, forceCallKind: CallKind? = null,
isUsedAsGetClassReceiver: Boolean = false,
origin: FirFunctionCallOrigin = FirFunctionCallOrigin.Regular, origin: FirFunctionCallOrigin = FirFunctionCallOrigin.Regular,
containingDeclarations: List<FirDeclaration> = transformer.components.containingDeclarations, containingDeclarations: List<FirDeclaration> = transformer.components.containingDeclarations,
resolutionContext: ResolutionContext = transformer.resolutionContext, resolutionContext: ResolutionContext = transformer.resolutionContext,
@@ -169,6 +172,7 @@ class FirCallResolver(
explicitReceiver, explicitReceiver,
argumentList, argumentList,
isImplicitInvoke = qualifiedAccess is FirImplicitInvokeCall, isImplicitInvoke = qualifiedAccess is FirImplicitInvokeCall,
isUsedAsGetClassReceiver = isUsedAsGetClassReceiver,
typeArguments, typeArguments,
session, session,
components.file, components.file,
@@ -222,25 +226,17 @@ class FirCallResolver(
fun resolveVariableAccessAndSelectCandidate( fun resolveVariableAccessAndSelectCandidate(
qualifiedAccess: FirQualifiedAccessExpression, qualifiedAccess: FirQualifiedAccessExpression,
isUsedAsReceiver: Boolean, isUsedAsReceiver: Boolean,
isUsedAsGetClassReceiver: Boolean,
callSite: FirElement, callSite: FirElement,
): FirStatement { ): FirStatement {
return resolveVariableAccessAndSelectCandidateImpl(qualifiedAccess, isUsedAsReceiver, callSite) { true } return resolveVariableAccessAndSelectCandidateImpl(qualifiedAccess, isUsedAsReceiver, isUsedAsGetClassReceiver, 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
}
} }
private fun resolveVariableAccessAndSelectCandidateImpl( private fun resolveVariableAccessAndSelectCandidateImpl(
qualifiedAccess: FirQualifiedAccessExpression, qualifiedAccess: FirQualifiedAccessExpression,
isUsedAsReceiver: Boolean, isUsedAsReceiver: Boolean,
callSite: FirElement = qualifiedAccess, isUsedAsGetClassReceiver: Boolean,
callSite: FirElement,
acceptCandidates: (Collection<Candidate>) -> Boolean, acceptCandidates: (Collection<Candidate>) -> Boolean,
): FirStatement { ): FirStatement {
val callee = qualifiedAccess.calleeReference as? FirSimpleNamedReference ?: return qualifiedAccess val callee = qualifiedAccess.calleeReference as? FirSimpleNamedReference ?: return qualifiedAccess
@@ -250,7 +246,7 @@ class FirCallResolver(
val nonFatalDiagnosticFromExpression = (qualifiedAccess as? FirPropertyAccessExpression)?.nonFatalDiagnostics val nonFatalDiagnosticFromExpression = (qualifiedAccess as? FirPropertyAccessExpression)?.nonFatalDiagnostics
val basicResult by lazy(LazyThreadSafetyMode.NONE) { 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 // Even if it's not receiver, it makes sense to continue qualifier if resolution is unsuccessful
@@ -487,6 +483,7 @@ class FirCallResolver(
explicitReceiver = null, explicitReceiver = null,
delegatedConstructorCall.argumentList, delegatedConstructorCall.argumentList,
isImplicitInvoke = false, isImplicitInvoke = false,
isUsedAsGetClassReceiver = false,
typeArguments = typeArguments, typeArguments = typeArguments,
session, session,
components.file, components.file,
@@ -622,6 +619,7 @@ class FirCallResolver(
explicitReceiver = null, explicitReceiver = null,
annotation.argumentList, annotation.argumentList,
isImplicitInvoke = false, isImplicitInvoke = false,
isUsedAsGetClassReceiver = false,
typeArguments = annotation.typeArguments, typeArguments = annotation.typeArguments,
session, session,
components.file, components.file,
@@ -695,6 +693,7 @@ class FirCallResolver(
callableReferenceAccess.explicitReceiver, callableReferenceAccess.explicitReceiver,
FirEmptyArgumentList, FirEmptyArgumentList,
isImplicitInvoke = false, isImplicitInvoke = false,
isUsedAsGetClassReceiver = false,
emptyList(), emptyList(),
session, session,
components.file, components.file,
@@ -28,6 +28,7 @@ data class CallInfo(
override val explicitReceiver: FirExpression?, override val explicitReceiver: FirExpression?,
override val argumentList: FirArgumentList, override val argumentList: FirArgumentList,
override val isImplicitInvoke: Boolean, override val isImplicitInvoke: Boolean,
val isUsedAsGetClassReceiver: Boolean,
val typeArguments: List<FirTypeProjection>, val typeArguments: List<FirTypeProjection>,
val session: FirSession, val session: FirSession,
@@ -783,8 +783,9 @@ internal object ConstraintSystemForks : ResolutionStage() {
internal object TypeParameterAsCallable : ResolutionStage() { internal object TypeParameterAsCallable : ResolutionStage() {
override suspend fun check(candidate: Candidate, callInfo: CallInfo, sink: CheckerSink, context: ResolutionContext) { 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) sink.yieldDiagnostic(TypeParameterAsExpression)
} }
} }
} }
@@ -374,6 +374,7 @@ class FirSyntheticCallGenerator(
explicitReceiver = null, explicitReceiver = null,
argumentList = argumentList, argumentList = argumentList,
isImplicitInvoke = false, isImplicitInvoke = false,
isUsedAsGetClassReceiver = false,
typeArguments = emptyList(), typeArguments = emptyList(),
session = session, session = session,
containingFile = components.file, containingFile = components.file,
@@ -12,7 +12,6 @@ import org.jetbrains.kotlin.fakeElement
import org.jetbrains.kotlin.fir.* import org.jetbrains.kotlin.fir.*
import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.declarations.utils.isExternal 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.declarations.utils.isLocal
import org.jetbrains.kotlin.fir.diagnostics.* import org.jetbrains.kotlin.fir.diagnostics.*
import org.jetbrains.kotlin.fir.expressions.* import org.jetbrains.kotlin.fir.expressions.*
@@ -91,13 +90,14 @@ open class FirExpressionsResolveTransformer(transformer: FirAbstractBodyResolveT
qualifiedAccessExpression: FirQualifiedAccessExpression, qualifiedAccessExpression: FirQualifiedAccessExpression,
data: ResolutionMode, data: ResolutionMode,
): FirStatement = whileAnalysing(session, qualifiedAccessExpression) { ): FirStatement = whileAnalysing(session, qualifiedAccessExpression) {
transformQualifiedAccessExpression(qualifiedAccessExpression, data, isUsedAsReceiver = false) transformQualifiedAccessExpression(qualifiedAccessExpression, data, isUsedAsReceiver = false, isUsedAsGetClassReceiver = false)
} }
fun transformQualifiedAccessExpression( fun transformQualifiedAccessExpression(
qualifiedAccessExpression: FirQualifiedAccessExpression, qualifiedAccessExpression: FirQualifiedAccessExpression,
data: ResolutionMode, data: ResolutionMode,
isUsedAsReceiver: Boolean, isUsedAsReceiver: Boolean,
isUsedAsGetClassReceiver: Boolean,
): FirStatement { ): FirStatement {
if (qualifiedAccessExpression.isResolved && qualifiedAccessExpression.calleeReference !is FirSimpleNamedReference) { if (qualifiedAccessExpression.isResolved && qualifiedAccessExpression.calleeReference !is FirSimpleNamedReference) {
return qualifiedAccessExpression return qualifiedAccessExpression
@@ -152,6 +152,7 @@ open class FirExpressionsResolveTransformer(transformer: FirAbstractBodyResolveT
val transformedCallee = resolveQualifiedAccessAndSelectCandidate( val transformedCallee = resolveQualifiedAccessAndSelectCandidate(
qualifiedAccessExpression, qualifiedAccessExpression,
isUsedAsReceiver, isUsedAsReceiver,
isUsedAsGetClassReceiver,
// Set the correct call site. For assignment LHSs, it's the assignment, otherwise it's the qualified access itself. // Set the correct call site. For assignment LHSs, it's the assignment, otherwise it's the qualified access itself.
callSite = when (data) { callSite = when (data) {
is ResolutionMode.AssignmentLValue -> data.variableAssignment is ResolutionMode.AssignmentLValue -> data.variableAssignment
@@ -202,7 +203,7 @@ open class FirExpressionsResolveTransformer(transformer: FirAbstractBodyResolveT
if (explicitReceiver is FirPropertyAccessExpression) { if (explicitReceiver is FirPropertyAccessExpression) {
qualifiedAccessExpression.replaceExplicitReceiver( qualifiedAccessExpression.replaceExplicitReceiver(
transformQualifiedAccessExpression( transformQualifiedAccessExpression(
explicitReceiver, ResolutionMode.ReceiverResolution, isUsedAsReceiver = true explicitReceiver, ResolutionMode.ReceiverResolution, isUsedAsReceiver = true, isUsedAsGetClassReceiver = false
) as FirExpression ) as FirExpression
) )
return qualifiedAccessExpression return qualifiedAccessExpression
@@ -221,9 +222,12 @@ open class FirExpressionsResolveTransformer(transformer: FirAbstractBodyResolveT
protected open fun resolveQualifiedAccessAndSelectCandidate( protected open fun resolveQualifiedAccessAndSelectCandidate(
qualifiedAccessExpression: FirQualifiedAccessExpression, qualifiedAccessExpression: FirQualifiedAccessExpression,
isUsedAsReceiver: Boolean, isUsedAsReceiver: Boolean,
isUsedAsGetClassReceiver: Boolean,
callSite: FirElement, callSite: FirElement,
): FirStatement { ): FirStatement {
return callResolver.resolveVariableAccessAndSelectCandidate(qualifiedAccessExpression, isUsedAsReceiver, callSite) return callResolver.resolveVariableAccessAndSelectCandidate(
qualifiedAccessExpression, isUsedAsReceiver, isUsedAsGetClassReceiver, callSite
)
} }
fun transformSuperReceiver( fun transformSuperReceiver(
@@ -1055,7 +1059,7 @@ open class FirExpressionsResolveTransformer(transformer: FirAbstractBodyResolveT
val transformedLHS = when (explicitReceiver) { val transformedLHS = when (explicitReceiver) {
is FirPropertyAccessExpression -> is FirPropertyAccessExpression ->
transformQualifiedAccessExpression( transformQualifiedAccessExpression(
explicitReceiver, ResolutionMode.ContextIndependent, isUsedAsReceiver = true explicitReceiver, ResolutionMode.ContextIndependent, isUsedAsReceiver = true, isUsedAsGetClassReceiver = false
) as FirExpression ) as FirExpression
else -> else ->
explicitReceiver?.transformSingle(this, ResolutionMode.ContextIndependent) explicitReceiver?.transformSingle(this, ResolutionMode.ContextIndependent)
@@ -1096,7 +1100,9 @@ open class FirExpressionsResolveTransformer(transformer: FirAbstractBodyResolveT
val argument = getClassCall.argument val argument = getClassCall.argument
val replacedArgument: FirExpression = val replacedArgument: FirExpression =
if (argument is FirPropertyAccessExpression) if (argument is FirPropertyAccessExpression)
transformQualifiedAccessExpression(argument, dataForLhs, isUsedAsReceiver = true) as FirExpression transformQualifiedAccessExpression(
argument, dataForLhs, isUsedAsReceiver = true, isUsedAsGetClassReceiver = true
) as FirExpression
else else
argument.transform(this, dataForLhs) argument.transform(this, dataForLhs)
@@ -189,6 +189,7 @@ abstract class AbstractFirSpecificAnnotationResolveTransformer(
override fun resolveQualifiedAccessAndSelectCandidate( override fun resolveQualifiedAccessAndSelectCandidate(
qualifiedAccessExpression: FirQualifiedAccessExpression, qualifiedAccessExpression: FirQualifiedAccessExpression,
isUsedAsReceiver: Boolean, isUsedAsReceiver: Boolean,
isUsedAsGetClassReceiver: Boolean,
callSite: FirElement callSite: FirElement
): FirStatement { ): FirStatement {
qualifiedAccessExpression.resolveFromImportScope() qualifiedAccessExpression.resolveFromImportScope()
@@ -12,7 +12,7 @@ FILE: memberTypeParameterVsNestedClass2.fir.kt
} }
public final inline fun <reified T> foo(): R|kotlin/Unit| { public final inline fun <reified T> foo(): R|kotlin/Unit| {
<getClass>(Q|Outer.T|) <getClass>(R|T|)
lval x: R|T?| = Null(null) lval x: R|T?| = Null(null)
lval y: R|T?| = R|/Outer.T.T<CS errors: /Outer.T.T>#|() lval y: R|T?| = R|/Outer.T.T<CS errors: /Outer.T.T>#|()
} }