FIR: Rework receivers processing in resolution
- Put extensionReceiver to candidate even if it's explicit (for sake of clarity) - Split CheckReceiver (dispatch part should only check nullability)
This commit is contained in:
@@ -0,0 +1,16 @@
|
||||
interface A {
|
||||
val list: List<String>
|
||||
}
|
||||
|
||||
interface B {
|
||||
val list: MutableList<String>
|
||||
}
|
||||
|
||||
fun B.foo(a: A?) {
|
||||
list.plusAssign(mutableListOf(""))
|
||||
with(a) {
|
||||
list.plusAssign(mutableListOf(""))
|
||||
list += mutableListOf("")
|
||||
}
|
||||
}
|
||||
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
FILE: plusAssignNullable.kt
|
||||
public abstract interface A : R|kotlin/Any| {
|
||||
public abstract val list: R|kotlin/collections/List<kotlin/String>|
|
||||
public get(): R|kotlin/collections/List<kotlin/String>|
|
||||
|
||||
}
|
||||
public abstract interface B : R|kotlin/Any| {
|
||||
public abstract val list: R|kotlin/collections/MutableList<kotlin/String>|
|
||||
public get(): R|kotlin/collections/MutableList<kotlin/String>|
|
||||
|
||||
}
|
||||
public final fun R|B|.foo(a: R|A?|): R|kotlin/Unit| {
|
||||
this@R|/foo|.R|/B.list|.R|kotlin/collections/plusAssign|<R|kotlin/String|>(R|kotlin/collections/mutableListOf|<R|kotlin/String|>(vararg(String())))
|
||||
R|kotlin/with|<R|A?|, R|kotlin/Unit|>(R|<local>/a|, <L> = with@fun R|A?|.<anonymous>(): R|kotlin/Unit| <kind=EXACTLY_ONCE> {
|
||||
this@R|/foo|.R|/B.list|.R|kotlin/collections/plusAssign|<R|kotlin/String|>(R|kotlin/collections/mutableListOf|<R|kotlin/String|>(vararg(String())))
|
||||
this@R|/foo|.R|/B.list|.R|kotlin/collections/plusAssign|<R|kotlin/String|>(R|kotlin/collections/mutableListOf|<R|kotlin/String|>(vararg(String())))
|
||||
}
|
||||
)
|
||||
}
|
||||
+5
@@ -208,6 +208,11 @@ public class FirDiagnosticsWithStdlibTestGenerated extends AbstractFirDiagnostic
|
||||
runTest("compiler/fir/analysis-tests/testData/resolveWithStdlib/nullableTypeParameter.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("plusAssignNullable.kt")
|
||||
public void testPlusAssignNullable() throws Exception {
|
||||
runTest("compiler/fir/analysis-tests/testData/resolveWithStdlib/plusAssignNullable.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("problems.kt")
|
||||
public void testProblems() throws Exception {
|
||||
runTest("compiler/fir/analysis-tests/testData/resolveWithStdlib/problems.kt");
|
||||
|
||||
@@ -12,8 +12,8 @@ sealed class CallKind(vararg resolutionSequence: ResolutionStage) {
|
||||
CheckExplicitReceiverConsistency,
|
||||
NoTypeArguments,
|
||||
CreateFreshTypeVariableSubstitutorStage,
|
||||
CheckReceivers.Dispatch,
|
||||
CheckReceivers.Extension,
|
||||
CheckDispatchReceiver,
|
||||
CheckExtensionReceiver,
|
||||
CheckLowPriorityInOverloadResolution,
|
||||
PostponedVariablesInitializerResolutionStage
|
||||
)
|
||||
@@ -33,8 +33,8 @@ sealed class CallKind(vararg resolutionSequence: ResolutionStage) {
|
||||
CheckExplicitReceiverConsistency,
|
||||
MapTypeArguments,
|
||||
CreateFreshTypeVariableSubstitutorStage,
|
||||
CheckReceivers.Dispatch,
|
||||
CheckReceivers.Extension,
|
||||
CheckDispatchReceiver,
|
||||
CheckExtensionReceiver,
|
||||
CheckArguments,
|
||||
EagerResolveOfCallableReferences,
|
||||
CheckLowPriorityInOverloadResolution,
|
||||
@@ -47,8 +47,8 @@ sealed class CallKind(vararg resolutionSequence: ResolutionStage) {
|
||||
CheckExplicitReceiverConsistency,
|
||||
MapTypeArguments,
|
||||
CreateFreshTypeVariableSubstitutorStage,
|
||||
CheckReceivers.Dispatch,
|
||||
CheckReceivers.Extension,
|
||||
CheckDispatchReceiver,
|
||||
CheckExtensionReceiver,
|
||||
CheckArguments,
|
||||
EagerResolveOfCallableReferences
|
||||
)
|
||||
@@ -58,8 +58,8 @@ sealed class CallKind(vararg resolutionSequence: ResolutionStage) {
|
||||
DiscriminateSynthetics,
|
||||
NoTypeArguments,
|
||||
CreateFreshTypeVariableSubstitutorStage,
|
||||
CheckReceivers.Dispatch,
|
||||
CheckReceivers.Extension,
|
||||
CheckDispatchReceiver,
|
||||
CheckExtensionReceiver,
|
||||
CheckCallableReferenceExpectedType,
|
||||
CheckLowPriorityInOverloadResolution
|
||||
)
|
||||
@@ -102,8 +102,8 @@ class ResolutionSequenceBuilder(
|
||||
if (checkExplicitReceiverConsistency) add(CheckExplicitReceiverConsistency)
|
||||
if (mapTypeArguments) add(MapTypeArguments) else add(NoTypeArguments)
|
||||
if (checkArguments || checkDispatchReceiver || checkExtensionReceiver) add(CreateFreshTypeVariableSubstitutorStage)
|
||||
if (checkDispatchReceiver) add(CheckReceivers.Dispatch)
|
||||
if (checkExtensionReceiver) add(CheckReceivers.Extension)
|
||||
if (checkDispatchReceiver) add(CheckDispatchReceiver)
|
||||
if (checkExtensionReceiver) add(CheckExtensionReceiver)
|
||||
if (checkArguments) add(CheckArguments)
|
||||
if (resolveCallableReferenceArguments) add(EagerResolveOfCallableReferences)
|
||||
if (checkLowPriorityInOverloadResolution) add(CheckLowPriorityInOverloadResolution)
|
||||
|
||||
@@ -15,7 +15,6 @@ import org.jetbrains.kotlin.fir.expressions.FirExpression
|
||||
import org.jetbrains.kotlin.fir.expressions.builder.buildArgumentList
|
||||
import org.jetbrains.kotlin.fir.expressions.impl.FirExpressionStub
|
||||
import org.jetbrains.kotlin.fir.expressions.impl.FirNoReceiverExpression
|
||||
import org.jetbrains.kotlin.fir.resolve.BodyResolveComponents
|
||||
import org.jetbrains.kotlin.fir.resolve.DoubleColonLHS
|
||||
import org.jetbrains.kotlin.fir.resolve.inference.InferenceComponents
|
||||
import org.jetbrains.kotlin.fir.resolve.inference.PostponedResolvedAtom
|
||||
@@ -81,7 +80,7 @@ data class CallInfo(
|
||||
class Candidate(
|
||||
val symbol: AbstractFirBasedSymbol<*>,
|
||||
val dispatchReceiverValue: ReceiverValue?,
|
||||
val implicitExtensionReceiverValue: ImplicitReceiverValue<*>?,
|
||||
val extensionReceiverValue: ReceiverValue?,
|
||||
val explicitReceiverKind: ExplicitReceiverKind,
|
||||
val constraintSystemFactory: InferenceComponents.ConstraintSystemFactory,
|
||||
private val baseSystem: ConstraintStorage,
|
||||
@@ -128,18 +127,11 @@ class Candidate(
|
||||
|
||||
var passedStages: Int = 0
|
||||
|
||||
fun dispatchReceiverExpression(): FirExpression = when (explicitReceiverKind) {
|
||||
ExplicitReceiverKind.DISPATCH_RECEIVER, ExplicitReceiverKind.BOTH_RECEIVERS ->
|
||||
callInfo.explicitReceiver?.takeIf { it !is FirExpressionStub } ?: FirNoReceiverExpression
|
||||
else -> dispatchReceiverValue?.receiverExpression ?: FirNoReceiverExpression
|
||||
}
|
||||
fun dispatchReceiverExpression(): FirExpression =
|
||||
dispatchReceiverValue?.receiverExpression?.takeIf { it !is FirExpressionStub } ?: FirNoReceiverExpression
|
||||
|
||||
fun extensionReceiverExpression(): FirExpression = when (explicitReceiverKind) {
|
||||
ExplicitReceiverKind.EXTENSION_RECEIVER, ExplicitReceiverKind.BOTH_RECEIVERS ->
|
||||
callInfo.explicitReceiver?.takeIf { it !is FirExpressionStub } ?: FirNoReceiverExpression
|
||||
else ->
|
||||
implicitExtensionReceiverValue?.receiverExpression ?: FirNoReceiverExpression
|
||||
}
|
||||
fun extensionReceiverExpression(): FirExpression =
|
||||
extensionReceiverValue?.receiverExpression?.takeIf { it !is FirExpressionStub } ?: FirNoReceiverExpression
|
||||
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (this === other) return true
|
||||
|
||||
@@ -52,11 +52,11 @@ class CandidateFactory private constructor(
|
||||
explicitReceiverKind: ExplicitReceiverKind,
|
||||
scope: FirScope?,
|
||||
dispatchReceiverValue: ReceiverValue? = null,
|
||||
implicitExtensionReceiverValue: ImplicitReceiverValue<*>? = null,
|
||||
extensionReceiverValue: ReceiverValue? = null,
|
||||
builtInExtensionFunctionReceiverValue: ReceiverValue? = null
|
||||
): Candidate {
|
||||
return Candidate(
|
||||
symbol, dispatchReceiverValue, implicitExtensionReceiverValue,
|
||||
symbol, dispatchReceiverValue, extensionReceiverValue,
|
||||
explicitReceiverKind, context.inferenceComponents.constraintSystemFactory, baseSystem,
|
||||
builtInExtensionFunctionReceiverValue?.receiverExpression?.let {
|
||||
callInfo.withReceiverAsArgument(it)
|
||||
@@ -78,7 +78,7 @@ class CandidateFactory private constructor(
|
||||
return Candidate(
|
||||
symbol,
|
||||
dispatchReceiverValue = null,
|
||||
implicitExtensionReceiverValue = null,
|
||||
extensionReceiverValue = null,
|
||||
explicitReceiverKind = ExplicitReceiverKind.NO_EXPLICIT_RECEIVER,
|
||||
context.inferenceComponents.constraintSystemFactory,
|
||||
baseSystem,
|
||||
|
||||
@@ -22,8 +22,11 @@ import org.jetbrains.kotlin.fir.scopes.FirTypeScope
|
||||
import org.jetbrains.kotlin.fir.symbols.AbstractFirBasedSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirClassSymbol
|
||||
import org.jetbrains.kotlin.fir.types.*
|
||||
import org.jetbrains.kotlin.fir.types.ConeKotlinErrorType
|
||||
import org.jetbrains.kotlin.fir.types.ConeKotlinType
|
||||
import org.jetbrains.kotlin.fir.types.builder.buildResolvedTypeRef
|
||||
import org.jetbrains.kotlin.fir.types.coneType
|
||||
import org.jetbrains.kotlin.fir.types.coneTypeSafe
|
||||
|
||||
interface Receiver
|
||||
|
||||
@@ -51,7 +54,7 @@ abstract class AbstractExplicitReceiverValue<E : FirExpression> : AbstractExplic
|
||||
get() = explicitReceiver
|
||||
}
|
||||
|
||||
internal class ExpressionReceiverValue(
|
||||
class ExpressionReceiverValue(
|
||||
override val explicitReceiver: FirExpression
|
||||
) : AbstractExplicitReceiverValue<FirExpression>(), ReceiverValue
|
||||
|
||||
|
||||
+45
-85
@@ -22,8 +22,8 @@ import org.jetbrains.kotlin.fir.types.*
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.resolve.calls.tasks.ExplicitReceiverKind
|
||||
import org.jetbrains.kotlin.resolve.calls.tasks.ExplicitReceiverKind.*
|
||||
import org.jetbrains.kotlin.types.AbstractNullabilityChecker
|
||||
|
||||
abstract class ResolutionStage {
|
||||
abstract suspend fun check(candidate: Candidate, callInfo: CallInfo, sink: CheckerSink, context: ResolutionContext)
|
||||
@@ -57,52 +57,44 @@ internal object CheckExplicitReceiverConsistency : ResolutionStage() {
|
||||
}
|
||||
}
|
||||
|
||||
internal sealed class CheckReceivers : ResolutionStage() {
|
||||
object Dispatch : CheckReceivers() {
|
||||
override fun ExplicitReceiverKind.shouldBeCheckedAgainstImplicit(): Boolean {
|
||||
return this == EXTENSION_RECEIVER // For NO_EXPLICIT_RECEIVER we can check extension receiver only
|
||||
}
|
||||
|
||||
override fun ExplicitReceiverKind.shouldBeCheckedAgainstExplicit(): Boolean {
|
||||
return this == DISPATCH_RECEIVER || this == BOTH_RECEIVERS
|
||||
}
|
||||
|
||||
override fun Candidate.getReceiverType(context: ResolutionContext): ConeKotlinType? {
|
||||
return dispatchReceiverValue?.type
|
||||
}
|
||||
}
|
||||
|
||||
object Extension : CheckReceivers() {
|
||||
override fun ExplicitReceiverKind.shouldBeCheckedAgainstImplicit(): Boolean {
|
||||
return this == DISPATCH_RECEIVER || this == NO_EXPLICIT_RECEIVER
|
||||
}
|
||||
|
||||
override fun ExplicitReceiverKind.shouldBeCheckedAgainstExplicit(): Boolean {
|
||||
return this == EXTENSION_RECEIVER || this == BOTH_RECEIVERS
|
||||
}
|
||||
|
||||
override fun Candidate.getReceiverType(context: ResolutionContext): ConeKotlinType? {
|
||||
val callableSymbol = symbol as? FirCallableSymbol<*> ?: return null
|
||||
val callable = callableSymbol.fir
|
||||
val receiverType = callable.receiverTypeRef?.coneType
|
||||
if (receiverType != null) return receiverType
|
||||
val returnTypeRef = callable.returnTypeRef as? FirResolvedTypeRef ?: return null
|
||||
if (!returnTypeRef.type.isExtensionFunctionType(context.session)) return null
|
||||
return (returnTypeRef.type.typeArguments.firstOrNull() as? ConeKotlinTypeProjection)?.type
|
||||
}
|
||||
}
|
||||
|
||||
abstract fun Candidate.getReceiverType(context: ResolutionContext): ConeKotlinType?
|
||||
|
||||
abstract fun ExplicitReceiverKind.shouldBeCheckedAgainstExplicit(): Boolean
|
||||
|
||||
abstract fun ExplicitReceiverKind.shouldBeCheckedAgainstImplicit(): Boolean
|
||||
|
||||
object CheckExtensionReceiver : ResolutionStage() {
|
||||
override suspend fun check(candidate: Candidate, callInfo: CallInfo, sink: CheckerSink, context: ResolutionContext) {
|
||||
val expectedReceiverType = candidate.getReceiverType(context)
|
||||
val explicitReceiverExpression = callInfo.explicitReceiver
|
||||
val explicitReceiverKind = candidate.explicitReceiverKind
|
||||
val expectedReceiverType = candidate.getReceiverType(context) ?: return
|
||||
|
||||
val argumentExtensionReceiverValue = candidate.extensionReceiverValue ?: return
|
||||
val expectedType = candidate.substitutor.substituteOrSelf(expectedReceiverType.type)
|
||||
val argumentType = captureFromTypeParameterUpperBoundIfNeeded(
|
||||
argumentType = argumentExtensionReceiverValue.type,
|
||||
expectedType = expectedType,
|
||||
session = context.session
|
||||
)
|
||||
candidate.resolvePlainArgumentType(
|
||||
candidate.csBuilder,
|
||||
argumentType = argumentType,
|
||||
expectedType = expectedType,
|
||||
sink = sink,
|
||||
context = context,
|
||||
isReceiver = true,
|
||||
isDispatch = false,
|
||||
)
|
||||
|
||||
sink.yieldIfNeed()
|
||||
}
|
||||
|
||||
private fun Candidate.getReceiverType(context: ResolutionContext): ConeKotlinType? {
|
||||
val callableSymbol = symbol as? FirCallableSymbol<*> ?: return null
|
||||
val callable = callableSymbol.fir
|
||||
val receiverType = callable.receiverTypeRef?.coneType
|
||||
if (receiverType != null) return receiverType
|
||||
val returnTypeRef = callable.returnTypeRef as? FirResolvedTypeRef ?: return null
|
||||
if (!returnTypeRef.type.isExtensionFunctionType(context.session)) return null
|
||||
return (returnTypeRef.type.typeArguments.firstOrNull() as? ConeKotlinTypeProjection)?.type
|
||||
}
|
||||
}
|
||||
|
||||
object CheckDispatchReceiver : ResolutionStage() {
|
||||
override suspend fun check(candidate: Candidate, callInfo: CallInfo, sink: CheckerSink, context: ResolutionContext) {
|
||||
val explicitReceiverExpression = callInfo.explicitReceiver
|
||||
if (explicitReceiverExpression.isSuperCall()) {
|
||||
val status = candidate.symbol.fir as? FirMemberDeclaration
|
||||
if (status?.modality == Modality.ABSTRACT) {
|
||||
@@ -110,49 +102,17 @@ internal sealed class CheckReceivers : ResolutionStage() {
|
||||
}
|
||||
}
|
||||
|
||||
if (expectedReceiverType != null) {
|
||||
if (explicitReceiverExpression != null &&
|
||||
explicitReceiverKind.shouldBeCheckedAgainstExplicit() &&
|
||||
!explicitReceiverExpression.isSuperReferenceExpression()
|
||||
) {
|
||||
candidate.resolvePlainExpressionArgument(
|
||||
candidate.csBuilder,
|
||||
argument = explicitReceiverExpression,
|
||||
expectedType = candidate.substitutor.substituteOrSelf(expectedReceiverType),
|
||||
sink = sink,
|
||||
context = context,
|
||||
isReceiver = true,
|
||||
isDispatch = this is Dispatch
|
||||
)
|
||||
sink.yieldIfNeed()
|
||||
} else {
|
||||
val argumentExtensionReceiverValue = candidate.implicitExtensionReceiverValue
|
||||
if (argumentExtensionReceiverValue != null && explicitReceiverKind.shouldBeCheckedAgainstImplicit()) {
|
||||
val expectedType = candidate.substitutor.substituteOrSelf(expectedReceiverType.type)
|
||||
val argumentType = captureFromTypeParameterUpperBoundIfNeeded(
|
||||
argumentType = argumentExtensionReceiverValue.type,
|
||||
expectedType = expectedType,
|
||||
session = context.session
|
||||
)
|
||||
candidate.resolvePlainArgumentType(
|
||||
candidate.csBuilder,
|
||||
argumentType = argumentType,
|
||||
expectedType = expectedType,
|
||||
sink = sink,
|
||||
context = context,
|
||||
isReceiver = true,
|
||||
isDispatch = this is Dispatch
|
||||
)
|
||||
sink.yieldIfNeed()
|
||||
}
|
||||
}
|
||||
val dispatchReceiverValueType = candidate.dispatchReceiverValue?.type ?: return
|
||||
|
||||
if (!AbstractNullabilityChecker.isSubtypeOfAny(context.session.typeContext, dispatchReceiverValueType)) {
|
||||
sink.yieldDiagnostic(InapplicableWrongReceiver)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun FirExpression?.isSuperCall(): Boolean {
|
||||
if (this !is FirQualifiedAccessExpression) return false
|
||||
return calleeReference is FirSuperReference
|
||||
}
|
||||
private fun FirExpression?.isSuperCall(): Boolean {
|
||||
if (this !is FirQualifiedAccessExpression) return false
|
||||
return calleeReference is FirSuperReference
|
||||
}
|
||||
|
||||
private fun FirExpression.isSuperReferenceExpression(): Boolean {
|
||||
|
||||
+3
-4
@@ -65,9 +65,8 @@ class FirTowerResolver(
|
||||
}
|
||||
else -> {
|
||||
if (receiver is FirQualifiedAccessExpression) {
|
||||
val calleeReference = receiver.calleeReference
|
||||
if (calleeReference is FirSuperReference) {
|
||||
manager.enqueueResolverTask { mainTask.runResolverForSuperReceiver(info, receiver.typeRef) }
|
||||
if (receiver.calleeReference is FirSuperReference) {
|
||||
manager.enqueueResolverTask { mainTask.runResolverForSuperReceiver(info, receiver) }
|
||||
return
|
||||
}
|
||||
}
|
||||
@@ -108,7 +107,7 @@ class FirTowerResolver(
|
||||
ExplicitReceiverKind.NO_EXPLICIT_RECEIVER,
|
||||
scope,
|
||||
dispatchReceiver,
|
||||
implicitExtensionReceiverValue = null,
|
||||
extensionReceiverValue = null,
|
||||
builtInExtensionFunctionReceiverValue = null
|
||||
),
|
||||
context
|
||||
|
||||
+10
-14
@@ -14,7 +14,10 @@ import org.jetbrains.kotlin.fir.symbols.AbstractFirBasedSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirNamedFunctionSymbol
|
||||
import org.jetbrains.kotlin.fir.typeContext
|
||||
import org.jetbrains.kotlin.fir.types.*
|
||||
import org.jetbrains.kotlin.fir.types.ConeClassLikeType
|
||||
import org.jetbrains.kotlin.fir.types.ConeStarProjection
|
||||
import org.jetbrains.kotlin.fir.types.coneType
|
||||
import org.jetbrains.kotlin.fir.types.constructClassType
|
||||
import org.jetbrains.kotlin.fir.types.impl.FirImplicitBuiltinTypeRef
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.resolve.calls.tasks.ExplicitReceiverKind
|
||||
@@ -68,19 +71,13 @@ internal class TowerLevelHandler {
|
||||
CallKind.CallableReference -> {
|
||||
val stubReceiver = info.stubReceiver
|
||||
if (stubReceiver != null) {
|
||||
val stubReceiverValue = ExpressionReceiverValue(stubReceiver)
|
||||
val stubProcessor = TowerScopeLevelProcessor(
|
||||
info.explicitReceiver,
|
||||
if (towerLevel is MemberScopeTowerLevel && towerLevel.dispatchReceiver is AbstractExplicitReceiver<*>) {
|
||||
ExplicitReceiverKind.DISPATCH_RECEIVER
|
||||
} else {
|
||||
ExplicitReceiverKind.EXTENSION_RECEIVER
|
||||
},
|
||||
explicitReceiverKind,
|
||||
collector,
|
||||
stubReceiverCandidateFactory!!, group
|
||||
)
|
||||
val towerLevelWithStubReceiver = towerLevel.replaceReceiverValue(stubReceiverValue)
|
||||
towerLevelWithStubReceiver.processFunctionsAndProperties(info.name, stubProcessor)
|
||||
towerLevel.processFunctionsAndProperties(info.name, stubProcessor)
|
||||
// NB: we don't perform this for implicit Unit
|
||||
if (!collector.isSuccess() && info.explicitReceiver?.typeRef !is FirImplicitBuiltinTypeRef) {
|
||||
towerLevel.processFunctionsAndProperties(info.name, processor)
|
||||
@@ -147,18 +144,17 @@ private class TowerScopeLevelProcessor(
|
||||
override fun consumeCandidate(
|
||||
symbol: AbstractFirBasedSymbol<*>,
|
||||
dispatchReceiverValue: ReceiverValue?,
|
||||
implicitExtensionReceiverValue: ImplicitReceiverValue<*>?,
|
||||
extensionReceiverValue: ReceiverValue?,
|
||||
scope: FirScope,
|
||||
builtInExtensionFunctionReceiverValue: ReceiverValue?
|
||||
) {
|
||||
// Check explicit extension receiver for default package members
|
||||
if (symbol is FirNamedFunctionSymbol && dispatchReceiverValue == null &&
|
||||
(implicitExtensionReceiverValue == null) != (explicitReceiver == null) &&
|
||||
extensionReceiverValue != null &&
|
||||
explicitReceiver !is FirResolvedQualifier &&
|
||||
symbol.callableId.packageName.startsWith(defaultPackage)
|
||||
) {
|
||||
val extensionReceiverType = explicitReceiver?.typeRef?.coneTypeSafe()
|
||||
?: implicitExtensionReceiverValue?.type as? ConeClassLikeType
|
||||
val extensionReceiverType = extensionReceiverValue.type as? ConeClassLikeType
|
||||
if (extensionReceiverType != null) {
|
||||
val declarationReceiverType = (symbol as? FirCallableSymbol<*>)?.fir?.receiverTypeRef?.coneType
|
||||
if (declarationReceiverType is ConeClassLikeType) {
|
||||
@@ -183,7 +179,7 @@ private class TowerScopeLevelProcessor(
|
||||
explicitReceiverKind,
|
||||
scope,
|
||||
dispatchReceiverValue,
|
||||
implicitExtensionReceiverValue,
|
||||
extensionReceiverValue,
|
||||
builtInExtensionFunctionReceiverValue
|
||||
), candidateFactory.context
|
||||
)
|
||||
|
||||
+9
-21
@@ -9,7 +9,6 @@ import org.jetbrains.kotlin.fir.FirSession
|
||||
import org.jetbrains.kotlin.fir.declarations.FirConstructor
|
||||
import org.jetbrains.kotlin.fir.declarations.isInner
|
||||
import org.jetbrains.kotlin.fir.dispatchReceiverClassOrNull
|
||||
import org.jetbrains.kotlin.fir.expressions.FirExpression
|
||||
import org.jetbrains.kotlin.fir.expressions.builder.buildResolvedQualifier
|
||||
import org.jetbrains.kotlin.fir.resolve.*
|
||||
import org.jetbrains.kotlin.fir.resolve.calls.*
|
||||
@@ -21,9 +20,6 @@ import org.jetbrains.kotlin.fir.scopes.processClassifiersByName
|
||||
import org.jetbrains.kotlin.fir.symbols.AbstractFirBasedSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.*
|
||||
import org.jetbrains.kotlin.fir.types.ConeClassLikeType
|
||||
import org.jetbrains.kotlin.fir.types.ConeKotlinType
|
||||
import org.jetbrains.kotlin.fir.types.ConeNullability
|
||||
import org.jetbrains.kotlin.fir.types.withNullability
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.util.OperatorNameConventions
|
||||
|
||||
@@ -45,7 +41,7 @@ interface TowerScopeLevel {
|
||||
fun consumeCandidate(
|
||||
symbol: T,
|
||||
dispatchReceiverValue: ReceiverValue?,
|
||||
implicitExtensionReceiverValue: ImplicitReceiverValue<*>?,
|
||||
extensionReceiverValue: ReceiverValue?,
|
||||
scope: FirScope,
|
||||
builtInExtensionFunctionReceiverValue: ReceiverValue? = null
|
||||
)
|
||||
@@ -69,7 +65,7 @@ abstract class SessionBasedTowerLevel(val session: FirSession) : TowerScopeLevel
|
||||
class MemberScopeTowerLevel(
|
||||
session: FirSession,
|
||||
private val bodyResolveComponents: BodyResolveComponents,
|
||||
val dispatchReceiver: ReceiverValue,
|
||||
val dispatchReceiverValue: ReceiverValue,
|
||||
private val extensionReceiver: ReceiverValue? = null,
|
||||
private val implicitExtensionInvokeMode: Boolean = false,
|
||||
private val scopeSession: ScopeSession
|
||||
@@ -79,7 +75,7 @@ class MemberScopeTowerLevel(
|
||||
processScopeMembers: FirScope.(processor: (T) -> Unit) -> Unit
|
||||
): ProcessorAction {
|
||||
var empty = true
|
||||
val scope = dispatchReceiver.scope(session, scopeSession) ?: return ProcessorAction.NONE
|
||||
val scope = dispatchReceiverValue.scope(session, scopeSession) ?: return ProcessorAction.NONE
|
||||
scope.processScopeMembers { candidate ->
|
||||
empty = false
|
||||
if (candidate is FirCallableSymbol<*> &&
|
||||
@@ -89,24 +85,23 @@ class MemberScopeTowerLevel(
|
||||
if ((fir as? FirConstructor)?.isInner == false) {
|
||||
return@processScopeMembers
|
||||
}
|
||||
val dispatchReceiverValue = NotNullableReceiverValue(dispatchReceiver)
|
||||
|
||||
output.consumeCandidate(
|
||||
candidate, dispatchReceiverValue,
|
||||
implicitExtensionReceiverValue = extensionReceiver as? ImplicitReceiverValue<*>,
|
||||
extensionReceiverValue = extensionReceiver,
|
||||
scope
|
||||
)
|
||||
|
||||
if (implicitExtensionInvokeMode) {
|
||||
output.consumeCandidate(
|
||||
candidate, dispatchReceiverValue,
|
||||
implicitExtensionReceiverValue = null,
|
||||
extensionReceiverValue = null,
|
||||
scope,
|
||||
builtInExtensionFunctionReceiverValue = this.extensionReceiver
|
||||
)
|
||||
}
|
||||
} else if (candidate is FirClassLikeSymbol<*>) {
|
||||
output.consumeCandidate(candidate, null, extensionReceiver as? ImplicitReceiverValue<*>, scope)
|
||||
output.consumeCandidate(candidate, null, extensionReceiver, scope)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -114,7 +109,7 @@ class MemberScopeTowerLevel(
|
||||
val withSynthetic = FirSyntheticPropertiesScope(session, scope)
|
||||
withSynthetic.processScopeMembers { symbol ->
|
||||
empty = false
|
||||
output.consumeCandidate(symbol, NotNullableReceiverValue(dispatchReceiver), null, scope)
|
||||
output.consumeCandidate(symbol, dispatchReceiverValue, null, scope)
|
||||
}
|
||||
}
|
||||
return if (empty) ProcessorAction.NONE else ProcessorAction.NEXT
|
||||
@@ -221,7 +216,7 @@ class ScopeTowerLevel(
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
processor.consumeCandidate(
|
||||
unwrappedCandidate as T, dispatchReceiverValue,
|
||||
implicitExtensionReceiverValue = extensionReceiver as? ImplicitReceiverValue<*>,
|
||||
extensionReceiverValue = extensionReceiver,
|
||||
scope
|
||||
)
|
||||
}
|
||||
@@ -252,7 +247,7 @@ class ScopeTowerLevel(
|
||||
empty = false
|
||||
processor.consumeCandidate(
|
||||
it as T, dispatchReceiverValue = null,
|
||||
implicitExtensionReceiverValue = null,
|
||||
extensionReceiverValue = null,
|
||||
scope = scope
|
||||
)
|
||||
}
|
||||
@@ -261,13 +256,6 @@ class ScopeTowerLevel(
|
||||
}
|
||||
}
|
||||
|
||||
class NotNullableReceiverValue(val value: ReceiverValue) : ReceiverValue {
|
||||
override val type: ConeKotlinType
|
||||
get() = value.type.withNullability(ConeNullability.NOT_NULL)
|
||||
override val receiverExpression: FirExpression
|
||||
get() = value.receiverExpression
|
||||
}
|
||||
|
||||
private fun FirCallableSymbol<*>.hasExtensionReceiver(): Boolean {
|
||||
return fir.receiverTypeRef != null
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
// !LANGUAGE: +InlineClasses
|
||||
// IGNORE_BACKEND: JVM
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
// IGNORE_LIGHT_ANALYSIS
|
||||
inline class IC(val x: String)
|
||||
|
||||
|
||||
Vendored
+2
-2
@@ -7,8 +7,8 @@ public interface J {
|
||||
// FILE: test.kt
|
||||
|
||||
fun f1(x: Int?): Any = <!UNRESOLVED_REFERENCE!>x::hashCode<!>
|
||||
fun <T> f2(t: T): Any = t::hashCode
|
||||
fun <S : String?> f3(s: S): Any = s::hashCode
|
||||
fun <T> f2(t: T): Any = <!UNRESOLVED_REFERENCE!>t::hashCode<!>
|
||||
fun <S : String?> f3(s: S): Any = <!UNRESOLVED_REFERENCE!>s::hashCode<!>
|
||||
fun <U : Any> f4(u: U?): Any = <!UNRESOLVED_REFERENCE!>u::hashCode<!>
|
||||
fun f5(c: List<*>): Any = <!UNRESOLVED_REFERENCE!>c[0]::hashCode<!>
|
||||
|
||||
|
||||
+5
-5
@@ -14,11 +14,11 @@ fun test() {
|
||||
}
|
||||
|
||||
fun check() {
|
||||
[1, 2] checkType { <!INAPPLICABLE_CANDIDATE!>_<!><Array<Int>>() }
|
||||
[""] checkType { <!INAPPLICABLE_CANDIDATE!>_<!><Array<String>>() }
|
||||
[1, 2] <!INAPPLICABLE_CANDIDATE!>checkType<!> { <!INAPPLICABLE_CANDIDATE!>_<!><Array<Int>>() }
|
||||
[""] <!INAPPLICABLE_CANDIDATE!>checkType<!> { <!INAPPLICABLE_CANDIDATE!>_<!><Array<String>>() }
|
||||
|
||||
val f: IntArray = [1]
|
||||
[f] checkType { <!INAPPLICABLE_CANDIDATE!>_<!><Array<IntArray>>() }
|
||||
[f] <!INAPPLICABLE_CANDIDATE!>checkType<!> { <!INAPPLICABLE_CANDIDATE!>_<!><Array<IntArray>>() }
|
||||
|
||||
[1, ""] checkType { <!INAPPLICABLE_CANDIDATE!>_<!><Array<Any>>() }
|
||||
}
|
||||
[1, ""] <!INAPPLICABLE_CANDIDATE!>checkType<!> { <!INAPPLICABLE_CANDIDATE!>_<!><Array<Any>>() }
|
||||
}
|
||||
|
||||
Vendored
+1
-1
@@ -11,7 +11,7 @@ fun test() {
|
||||
const val <T> a3 = 0
|
||||
<!INAPPLICABLE_LATEINIT_MODIFIER!>lateinit val <T> a4 = 0<!>
|
||||
val <T> a5 by Delegate<Int>()
|
||||
val <T> a6 by Delegate<<!UNRESOLVED_REFERENCE!>T<!>>()
|
||||
val <T> a6 by <!INAPPLICABLE_CANDIDATE!>Delegate<<!UNRESOLVED_REFERENCE!>T<!>>()<!>
|
||||
}
|
||||
|
||||
class Delegate<F> {
|
||||
|
||||
Vendored
+1
-1
@@ -11,7 +11,7 @@ fun test() {
|
||||
const val <T> a3 = 0
|
||||
<!INAPPLICABLE_LATEINIT_MODIFIER!>lateinit val <T> a4 = 0<!>
|
||||
val <T> a5 by Delegate<Int>()
|
||||
val <T> a6 by Delegate<<!UNRESOLVED_REFERENCE!>T<!>>()
|
||||
val <T> a6 by <!INAPPLICABLE_CANDIDATE!>Delegate<<!UNRESOLVED_REFERENCE!>T<!>>()<!>
|
||||
}
|
||||
|
||||
class Delegate<F> {
|
||||
|
||||
+1
-1
@@ -5,7 +5,7 @@
|
||||
import kotlin.reflect.KProperty
|
||||
|
||||
class B {
|
||||
val c by <!INAPPLICABLE_CANDIDATE!>Delegate<!>(<!UNRESOLVED_REFERENCE!>ag<!>)
|
||||
val c by <!INAPPLICABLE_CANDIDATE!><!INAPPLICABLE_CANDIDATE!>Delegate<!>(<!UNRESOLVED_REFERENCE!>ag<!>)<!>
|
||||
}
|
||||
|
||||
class Delegate<T: Any>(val init: T) {
|
||||
|
||||
+1
-1
@@ -5,5 +5,5 @@ fun interface Bar {
|
||||
operator fun Bar.plus(b: Bar): String = invoke() + b.invoke()
|
||||
|
||||
fun box(): String {
|
||||
return { "O" } + { "K" }
|
||||
return { "O" } <!INAPPLICABLE_CANDIDATE!>+<!> { "K" }
|
||||
}
|
||||
|
||||
Vendored
+1
-1
@@ -7,4 +7,4 @@ object Z {
|
||||
infix fun add(b : Foo.() -> Unit) : Z = Z
|
||||
}
|
||||
|
||||
val t2 = Z <!INAPPLICABLE_CANDIDATE!>add<!> { } { }
|
||||
val t2 = Z <!INAPPLICABLE_CANDIDATE!>add<!> <!INAPPLICABLE_CANDIDATE!>{ } { }<!>
|
||||
|
||||
+2
-2
@@ -1,6 +1,6 @@
|
||||
fun <E : String?, T : ((CharSequence) -> Unit)?> foo(x: E, y: T) {
|
||||
if (x != null) {
|
||||
y(x)
|
||||
<!INAPPLICABLE_CANDIDATE!>y<!>(x)
|
||||
}
|
||||
|
||||
if (y != null) {
|
||||
@@ -10,4 +10,4 @@ fun <E : String?, T : ((CharSequence) -> Unit)?> foo(x: E, y: T) {
|
||||
if (x != null && y != null) {
|
||||
y(x)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
fun <T : Any?> foo(x: T) {
|
||||
if (x is String?) {
|
||||
x.length
|
||||
x.<!INAPPLICABLE_CANDIDATE!>length<!>
|
||||
|
||||
if (x != null) {
|
||||
x.length
|
||||
|
||||
@@ -24,7 +24,7 @@ fun <T : CharSequence?> foo(x: T) {
|
||||
x?.bar1()
|
||||
}
|
||||
|
||||
x.length
|
||||
x.<!INAPPLICABLE_CANDIDATE!>length<!>
|
||||
|
||||
if (x is String) {
|
||||
x.length
|
||||
|
||||
+2
-2
@@ -23,7 +23,7 @@ fun <T : String?> T.foo() {
|
||||
this?.bar1()
|
||||
}
|
||||
|
||||
length
|
||||
<!INAPPLICABLE_CANDIDATE!>length<!>
|
||||
|
||||
if (this is String) {
|
||||
length
|
||||
@@ -33,4 +33,4 @@ fun <T : String?> T.foo() {
|
||||
bar2()
|
||||
bar3()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -7,7 +7,7 @@ fun CharSequence?.bar2() {}
|
||||
fun <T : CharSequence> T.bar3() {}
|
||||
|
||||
fun <T : String?> foo(x: T) {
|
||||
x.length
|
||||
x.<!INAPPLICABLE_CANDIDATE!>length<!>
|
||||
x?.length
|
||||
|
||||
if (1 == 1) {
|
||||
|
||||
+4
-4
@@ -14,14 +14,14 @@ class A<T> {
|
||||
|
||||
fun foo2(a: A<out CharSequence>, b: A<in CharSequence>) {
|
||||
a.<!INAPPLICABLE_CANDIDATE!>foo1<!>(Out<CharSequence>())
|
||||
a.foo1<<!UPPER_BOUND_VIOLATED!>Out<CharSequence><!>>(Out())
|
||||
a.<!INAPPLICABLE_CANDIDATE!>foo1<!><Out<CharSequence>>(Out())
|
||||
|
||||
a.foo1(Out())
|
||||
a.foo1(Out<Nothing>())
|
||||
|
||||
a.foo2(Inv())
|
||||
a.<!INAPPLICABLE_CANDIDATE!>foo2<!>(Inv<CharSequence>())
|
||||
a.foo2<<!UPPER_BOUND_VIOLATED!>Inv<CharSequence><!>>(Inv())
|
||||
a.<!INAPPLICABLE_CANDIDATE!>foo2<!><Inv<CharSequence>>(Inv())
|
||||
|
||||
a.foo3(In())
|
||||
a.foo3(In<CharSequence>())
|
||||
@@ -33,11 +33,11 @@ fun foo2(a: A<out CharSequence>, b: A<in CharSequence>) {
|
||||
|
||||
b.foo2(Inv())
|
||||
b.<!INAPPLICABLE_CANDIDATE!>foo2<!>(Inv<CharSequence>())
|
||||
b.foo2<<!UPPER_BOUND_VIOLATED!>Inv<CharSequence><!>>(Inv())
|
||||
b.<!INAPPLICABLE_CANDIDATE!>foo2<!><Inv<CharSequence>>(Inv())
|
||||
|
||||
|
||||
b.<!INAPPLICABLE_CANDIDATE!>foo3<!>(In<CharSequence>())
|
||||
b.foo3<<!UPPER_BOUND_VIOLATED!>In<CharSequence><!>>(In())
|
||||
b.<!INAPPLICABLE_CANDIDATE!>foo3<!><In<CharSequence>>(In())
|
||||
|
||||
b.foo3(In<Any?>())
|
||||
b.foo3(In())
|
||||
|
||||
+1
-1
@@ -30,7 +30,7 @@ fun A.test2() {
|
||||
}
|
||||
|
||||
fun A?.test3() {
|
||||
foo() // error
|
||||
<!INAPPLICABLE_CANDIDATE!>foo<!>() // error
|
||||
<!INAPPLICABLE_CANDIDATE!>bar<!>() // error
|
||||
buzz()
|
||||
|
||||
|
||||
Vendored
+1
-1
@@ -32,7 +32,7 @@ fun test() {
|
||||
foo()
|
||||
}
|
||||
with(platformN) {
|
||||
foo()
|
||||
<!INAPPLICABLE_CANDIDATE!>foo<!>()
|
||||
}
|
||||
with(platformJ) {
|
||||
foo()
|
||||
|
||||
@@ -15,5 +15,5 @@ val test5: List<TNString?> = TODO()
|
||||
val test6: () -> List<TNString> = TODO()
|
||||
|
||||
fun test(x: TNString) {
|
||||
x.hashCode()
|
||||
x.<!INAPPLICABLE_CANDIDATE!>hashCode<!>()
|
||||
}
|
||||
|
||||
Vendored
+3
-3
@@ -17,7 +17,7 @@ fun CharSequence?.isNullOrEmpty(): Boolean {
|
||||
fun smartcastOnReceiver(s: String?) {
|
||||
with(s) {
|
||||
if (isNullOrEmpty()) {
|
||||
length
|
||||
<!INAPPLICABLE_CANDIDATE!>length<!>
|
||||
}
|
||||
else {
|
||||
length
|
||||
@@ -32,7 +32,7 @@ fun mixedReceiver(s: String?) {
|
||||
}
|
||||
} else {
|
||||
with(s) {
|
||||
length
|
||||
<!INAPPLICABLE_CANDIDATE!>length<!>
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Vendored
+3
-3
@@ -17,7 +17,7 @@ fun CharSequence?.isNullOrEmpty(): Boolean {
|
||||
fun smartcastOnReceiver(s: String?) {
|
||||
with(s) {
|
||||
if (isNullOrEmpty()) {
|
||||
length
|
||||
<!INAPPLICABLE_CANDIDATE!>length<!>
|
||||
}
|
||||
else {
|
||||
length
|
||||
@@ -32,7 +32,7 @@ fun mixedReceiver(s: String?) {
|
||||
}
|
||||
} else {
|
||||
with(s) {
|
||||
length
|
||||
<!INAPPLICABLE_CANDIDATE!>length<!>
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+6
-6
@@ -9,17 +9,17 @@ package testPackCase1
|
||||
|
||||
fun case1(a: A, c: C) {
|
||||
|
||||
<!DEBUG_INFO_CALL("fqName: fqName is unknown; typeCall: unresolved"), INAPPLICABLE_CANDIDATE!>a?.b += c<!>
|
||||
a?.b .<!DEBUG_INFO_CALL("fqName: fqName is unknown; typeCall: unresolved")!><!INAPPLICABLE_CANDIDATE!>plusAssign<!>(c)<!>
|
||||
<!DEBUG_INFO_CALL("fqName: testPackCase1.B.plusAssign; typeCall: operator function")!>a?.b += c<!>
|
||||
a?.b .<!DEBUG_INFO_CALL("fqName: testPackCase1.B.plusAssign; typeCall: operator function")!>plusAssign(c)<!>
|
||||
|
||||
val x = {
|
||||
<!DEBUG_INFO_CALL("fqName: fqName is unknown; typeCall: unresolved"), INAPPLICABLE_CANDIDATE!>a?.b += c<!>
|
||||
a?.b.<!DEBUG_INFO_CALL("fqName: fqName is unknown; typeCall: unresolved")!><!INAPPLICABLE_CANDIDATE!>plusAssign<!>(c)<!>
|
||||
<!DEBUG_INFO_CALL("fqName: testPackCase1.B.plusAssign; typeCall: operator function")!>a?.b += c<!>
|
||||
a?.b.<!DEBUG_INFO_CALL("fqName: testPackCase1.B.plusAssign; typeCall: operator function")!>plusAssign(c)<!>
|
||||
}()
|
||||
|
||||
<!DEBUG_INFO_CALL("fqName: fqName is unknown; typeCall: unresolved"), INAPPLICABLE_CANDIDATE!>a?.b += { c }()<!>
|
||||
<!DEBUG_INFO_CALL("fqName: testPackCase1.B.plusAssign; typeCall: operator function")!>a?.b += { c }()<!>
|
||||
|
||||
a?.b.<!DEBUG_INFO_CALL("fqName: fqName is unknown; typeCall: unresolved")!><!INAPPLICABLE_CANDIDATE!>plusAssign<!>({ c }())<!>
|
||||
a?.b.<!DEBUG_INFO_CALL("fqName: testPackCase1.B.plusAssign; typeCall: operator function")!>plusAssign({ c }())<!>
|
||||
}
|
||||
|
||||
class A(val b: B)
|
||||
|
||||
@@ -103,8 +103,8 @@ fun case_7() {
|
||||
|
||||
// TESTCASE NUMBER: 8
|
||||
fun case_8(x: TypealiasNullableString) {
|
||||
if (x !== null === null && <!DEBUG_INFO_EXPRESSION_TYPE("TypealiasNullableString")!>x<!> != null != null) <!DEBUG_INFO_EXPRESSION_TYPE("TypealiasNullableString")!>x<!>.get(0)
|
||||
if (x !== null != null && <!DEBUG_INFO_EXPRESSION_TYPE("TypealiasNullableString")!>x<!> != null === null) <!DEBUG_INFO_EXPRESSION_TYPE("TypealiasNullableString")!>x<!>.get(0)
|
||||
if (x !== null === null && <!DEBUG_INFO_EXPRESSION_TYPE("TypealiasNullableString")!>x<!> != null != null) <!DEBUG_INFO_EXPRESSION_TYPE("TypealiasNullableString")!>x<!>.<!INAPPLICABLE_CANDIDATE!>get<!>(0)
|
||||
if (x !== null != null && <!DEBUG_INFO_EXPRESSION_TYPE("TypealiasNullableString")!>x<!> != null === null) <!DEBUG_INFO_EXPRESSION_TYPE("TypealiasNullableString")!>x<!>.<!INAPPLICABLE_CANDIDATE!>get<!>(0)
|
||||
}
|
||||
|
||||
// TESTCASE NUMBER: 9
|
||||
|
||||
@@ -20,7 +20,7 @@ inline fun <reified T, reified K> case_1(x: T) {
|
||||
inline fun <reified T, reified K> case_2(x: T) {
|
||||
x as K
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("K & T & T")!>x<!>
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("K & T & T")!>x<!>.equals(x)
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("K & T & T")!>x<!>.<!INAPPLICABLE_CANDIDATE!>equals<!>(x)
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -49,7 +49,7 @@ inline fun <reified T, reified K> case_4(x: T?) {
|
||||
inline fun <reified T, reified K> case_5(x: T) {
|
||||
if (x is K?) {
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("K? & T & T")!>x<!>
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("K? & T & T")!>x<!>.equals(x)
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("K? & T & T")!>x<!>.<!INAPPLICABLE_CANDIDATE!>equals<!>(x)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -22,8 +22,8 @@ fun case_2(a: Any?) {
|
||||
}
|
||||
})()
|
||||
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Any & kotlin.Any?")!>a<!>
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Any & kotlin.Any?")!>a<!>.equals(10)
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Any?")!>a<!>
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Any?")!>a<!>.<!INAPPLICABLE_CANDIDATE!>equals<!>(10)
|
||||
}
|
||||
|
||||
// TESTCASE NUMBER: 3
|
||||
|
||||
@@ -75,7 +75,7 @@ fun <T> case_6(x: T) {
|
||||
fun <T> case_7(x: T) {
|
||||
if (x is Int? || x is Float?) {
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Number? & kotlin.Comparable<kotlin.Int & kotlin.Float>? & T & T")!>x<!>
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Number? & kotlin.Comparable<kotlin.Int & kotlin.Float>? & T & T")!>x<!>.toByte()
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Number? & kotlin.Comparable<kotlin.Int & kotlin.Float>? & T & T")!>x<!>.<!INAPPLICABLE_CANDIDATE!>toByte<!>()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -86,7 +86,7 @@ fun <T> case_7(x: T) {
|
||||
inline fun <reified T> case_8(x: T) {
|
||||
if (x is Int? || x is Float?) {
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Number? & kotlin.Comparable<kotlin.Int & kotlin.Float>? & T & T")!>x<!>
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Number? & kotlin.Comparable<kotlin.Int & kotlin.Float>? & T & T")!>x<!>.toByte()
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Number? & kotlin.Comparable<kotlin.Int & kotlin.Float>? & T & T")!>x<!>.<!INAPPLICABLE_CANDIDATE!>toByte<!>()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ fun <T, K> case_1(x: T?, y: K?) {
|
||||
y as K
|
||||
val z = <!DEBUG_INFO_EXPRESSION_TYPE("T & T?")!>x<!> ?: <!DEBUG_INFO_EXPRESSION_TYPE("K & K?")!>y<!>
|
||||
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("T & T?")!>x<!>.equals(10)
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("T & T?")!>x<!>.<!INAPPLICABLE_CANDIDATE!>equals<!>(10)
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Any?")!>z<!>
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Any?")!>z<!>.<!INAPPLICABLE_CANDIDATE!>equals<!>(10)
|
||||
}
|
||||
@@ -18,5 +18,5 @@ inline fun <reified T: Any, reified K: T?> case_2(y: K?) {
|
||||
y as K
|
||||
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("K & K?")!>y<!>
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("K & K?")!>y<!>.equals(10)
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("K & K?")!>y<!>.<!INAPPLICABLE_CANDIDATE!>equals<!>(10)
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@ fun <T> case_1(x: T) {
|
||||
|
||||
if (y != x) {
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("T")!>x<!>
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("T")!>x<!>.equals(null)
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("T")!>x<!>.<!INAPPLICABLE_CANDIDATE!>equals<!>(null)
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("T")!>x<!>.propT
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("T")!>x<!>.<!INAPPLICABLE_CANDIDATE!>propAny<!>
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("T")!>x<!>.propNullableT
|
||||
@@ -17,7 +17,7 @@ fun <T> case_1(x: T) {
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("T")!>x<!>.<!INAPPLICABLE_CANDIDATE!>funAny<!>()
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("T")!>x<!>.funNullableT()
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("T")!>x<!>.funNullableAny()
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("T")!>x<!>.apply { equals(null) }
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("T")!>x<!>.apply { <!INAPPLICABLE_CANDIDATE!>equals<!>(null) }
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("T")!>x<!>.apply { propT }
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("T")!>x<!>.apply { <!INAPPLICABLE_CANDIDATE!>propAny<!> }
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("T")!>x<!>.apply { propNullableT }
|
||||
@@ -25,8 +25,8 @@ fun <T> case_1(x: T) {
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("T")!>x<!>.apply { funT() }
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("T")!>x<!>.apply { <!INAPPLICABLE_CANDIDATE!>funAny<!>() }
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("T")!>x<!>.apply { funNullableT() }
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("T")!>x<!>.apply { funNullableAny(); <!DEBUG_INFO_EXPRESSION_TYPE("T")!>x<!>.equals(null) }
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("T")!>x<!>.also { <!DEBUG_INFO_EXPRESSION_TYPE("T")!>it<!>.equals(null) }
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("T")!>x<!>.apply { funNullableAny(); <!DEBUG_INFO_EXPRESSION_TYPE("T")!>x<!>.<!INAPPLICABLE_CANDIDATE!>equals<!>(null) }
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("T")!>x<!>.also { <!DEBUG_INFO_EXPRESSION_TYPE("T")!>it<!>.<!INAPPLICABLE_CANDIDATE!>equals<!>(null) }
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("T")!>x<!>.also { <!DEBUG_INFO_EXPRESSION_TYPE("T")!>it<!>.propT }
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("T")!>x<!>.also { <!DEBUG_INFO_EXPRESSION_TYPE("T")!>it<!>.<!INAPPLICABLE_CANDIDATE!>propAny<!> }
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("T")!>x<!>.also { <!DEBUG_INFO_EXPRESSION_TYPE("T")!>it<!>.propNullableT }
|
||||
@@ -51,7 +51,7 @@ fun <T> case_2(x: T?, y: Nothing?) {
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("T?")!>x<!>.<!INAPPLICABLE_CANDIDATE!>funAny<!>()
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("T?")!>x<!>.funNullableT()
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("T?")!>x<!>.funNullableAny()
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("T?")!>x<!>.apply { equals(null) }
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("T?")!>x<!>.apply { <!INAPPLICABLE_CANDIDATE!>equals<!>(null) }
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("T?")!>x<!>.apply { propT }
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("T?")!>x<!>.apply { <!INAPPLICABLE_CANDIDATE!>propAny<!> }
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("T?")!>x<!>.apply { propNullableT }
|
||||
|
||||
@@ -334,7 +334,7 @@ fun <T> case_24(x: Inv<out T?>?, y: Nothing?) {
|
||||
fun case_25(x: Int?) {
|
||||
val x = (l@ {
|
||||
if (x == null) return@l
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Int & kotlin.Int")!>x<!>
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Int & kotlin.Int?")!>x<!>
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Int & kotlin.Int?")!>x<!>.inv()
|
||||
})()
|
||||
}
|
||||
@@ -660,7 +660,7 @@ fun case_44(x: Inv<out Inv<out Inv<out Inv<out Inv<out Inv<out Inv<out Number>>>
|
||||
fun <T> case_45(x: T) {
|
||||
val y = (l@ {
|
||||
if (x == null) return@l
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("T!! & T!!")!>x<!>
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("T!! & T")!>x<!>
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("T!! & T")!>x<!>.equals(null)
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("T!! & T")!>x<!>.propT
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("T!! & T")!>x<!>.propAny
|
||||
@@ -677,7 +677,7 @@ fun <T> case_45(x: T) {
|
||||
fun <T> case_46(x: T?) {
|
||||
(l@ {
|
||||
if (x === null) return@l
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("T?!! & T?!!")!>x<!>
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("T?!! & T?")!>x<!>
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("T?!! & T?")!>x<!>.equals(null)
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("T?!! & T?")!>x<!>.propT
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("T?!! & T?")!>x<!>.propAny
|
||||
|
||||
@@ -244,7 +244,7 @@ fun <T>case_18(x: T, f: Boolean) {
|
||||
while (f) {
|
||||
if (false || false || false || x == nullableNothingProperty) break
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("T")!>x<!>
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("T")!>x<!>.equals(null)
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("T")!>x<!>.<!INAPPLICABLE_CANDIDATE!>equals<!>(null)
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("T")!>x<!>.propT
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("T")!>x<!>.<!INAPPLICABLE_CANDIDATE!>propAny<!>
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("T")!>x<!>.propNullableT
|
||||
@@ -261,7 +261,7 @@ fun <K, V>case_19(map: MutableMap<K, V>, y: Nothing?) {
|
||||
for ((k, v) in map) {
|
||||
if (k !== implicitNullableNothingProperty && true && v != y) else { break }
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("K")!>k<!>
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("K")!>k<!>.equals(null)
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("K")!>k<!>.<!INAPPLICABLE_CANDIDATE!>equals<!>(null)
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("K")!>k<!>.propT
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("K")!>k<!>.<!INAPPLICABLE_CANDIDATE!>propAny<!>
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("K")!>k<!>.propNullableT
|
||||
@@ -271,7 +271,7 @@ fun <K, V>case_19(map: MutableMap<K, V>, y: Nothing?) {
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("K")!>k<!>.funNullableT()
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("K")!>k<!>.funNullableAny()
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("V")!>v<!>
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("V")!>v<!>.equals(null)
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("V")!>v<!>.<!INAPPLICABLE_CANDIDATE!>equals<!>(null)
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("V")!>v<!>.propT
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("V")!>v<!>.<!INAPPLICABLE_CANDIDATE!>propAny<!>
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("V")!>v<!>.propNullableT
|
||||
|
||||
+5
-1
@@ -68,7 +68,11 @@ class SingleCandidateResolver(
|
||||
resolutionParameters.callableSymbol,
|
||||
explicitReceiverKind = explicitReceiverKind,
|
||||
dispatchReceiverValue = dispatchReceiverValue,
|
||||
implicitExtensionReceiverValue = implicitExtensionReceiverValue,
|
||||
extensionReceiverValue =
|
||||
if (explicitReceiverKind.isExtensionReceiver)
|
||||
callInfo.explicitReceiver?.let { ExpressionReceiverValue(it) }
|
||||
else
|
||||
implicitExtensionReceiverValue,
|
||||
scope = null,
|
||||
)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user