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:
Denis Zharkov
2020-11-15 13:10:54 +03:00
parent e2099a0307
commit f97cc0b62d
40 changed files with 194 additions and 213 deletions
@@ -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("")
}
}
@@ -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())))
}
)
}
@@ -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
@@ -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 {
@@ -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
@@ -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,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)
@@ -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<!>
@@ -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>>() }
}
@@ -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> {
@@ -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> {
@@ -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) {
@@ -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" }
}
@@ -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!>{ } { }<!>
@@ -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,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
@@ -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()
}
}
}
@@ -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) {
@@ -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())
@@ -30,7 +30,7 @@ fun A.test2() {
}
fun A?.test3() {
foo() // error
<!INAPPLICABLE_CANDIDATE!>foo<!>() // error
<!INAPPLICABLE_CANDIDATE!>bar<!>() // error
buzz()
@@ -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<!>()
}
@@ -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<!>
}
}
}
}
@@ -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<!>
}
}
}
}
@@ -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
@@ -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,
)