[NI] Use types and systems from return arguments instead of return type of lambda

This commit is contained in:
Dmitriy Novozhilov
2020-05-26 15:24:41 +03:00
parent f76b57d260
commit 2812ed0a02
15 changed files with 225 additions and 43 deletions
@@ -1815,6 +1815,11 @@ public class FirOldFrontendDiagnosticsTestWithStdlibGenerated extends AbstractFi
runTest("compiler/testData/diagnostics/testsWithStdLib/factoryPattern/multipleOverloads_2.kt");
}
@TestMetadata("multipleOverloads_3.kt")
public void testMultipleOverloads_3() throws Exception {
runTest("compiler/testData/diagnostics/testsWithStdLib/factoryPattern/multipleOverloads_3.kt");
}
@TestMetadata("overloadByLambdaReturnType_disabled.kt")
public void testOverloadByLambdaReturnType_disabled() throws Exception {
runTest("compiler/testData/diagnostics/testsWithStdLib/factoryPattern/overloadByLambdaReturnType_disabled.kt");
@@ -96,7 +96,6 @@ class KotlinResolutionCallbacksImpl(
expectedReturnType: UnwrappedType?,
annotations: Annotations,
stubsForPostponedVariables: Map<NewTypeVariable, StubType>,
shouldRunInIndependentContext: Boolean
): ReturnArgumentsAnalysisResult {
val psiCallArgument = lambdaArgument.psiCallArgument as PSIFunctionKotlinCallArgument
val outerCallContext = psiCallArgument.outerCallContext
@@ -138,7 +137,7 @@ class KotlinResolutionCallbacksImpl(
val lambdaInfo = LambdaInfo(
expectedReturnType ?: TypeUtils.NO_EXPECTED_TYPE,
if (expectedReturnType != null || shouldRunInIndependentContext) ContextDependency.INDEPENDENT else ContextDependency.DEPENDENT
if (expectedReturnType == null) ContextDependency.DEPENDENT else ContextDependency.INDEPENDENT
)
val builtIns = outerCallContext.scope.ownerDescriptor.builtIns
@@ -198,10 +197,8 @@ class KotlinResolutionCallbacksImpl(
val functionTypeInfo = expressionTypingServices.getTypeInfo(psiCallArgument.expression, actualContext)
(temporaryTrace ?: trace).record(BindingContext.NEW_INFERENCE_LAMBDA_INFO, psiCallArgument.ktFunction, LambdaInfo.STUB_EMPTY)
val inferedReturnType = functionTypeInfo.type?.arguments?.last()?.type?.takeIf { functionTypeInfo.type?.isFunctionTypeOrSubtype == true }
if (coroutineSession?.hasInapplicableCall() == true) {
return ReturnArgumentsAnalysisResult(ReturnArgumentsInfo.empty, coroutineSession, inferedReturnType, hasInapplicableCallForBuilderInference = true)
return ReturnArgumentsAnalysisResult(ReturnArgumentsInfo.empty, coroutineSession, hasInapplicableCallForBuilderInference = true)
} else {
temporaryTrace?.commit()
}
@@ -249,7 +246,6 @@ class KotlinResolutionCallbacksImpl(
returnArgumentFound
),
coroutineSession,
inferedReturnType
)
}
@@ -181,6 +181,8 @@ class ResolvedAtomCompleter(
private val ResolvedLambdaAtom.isCoercedToUnit: Boolean
get() {
val resultArgumentsInfo = this.resultArgumentsInfo
?: return (subResolvedAtoms!!.single() as ResolvedLambdaAtom).isCoercedToUnit
val returnTypes =
resultArgumentsInfo.nonErrorArguments.map {
val type = it.safeAs<SimpleKotlinCallArgument>()?.receiver?.receiverValue?.type ?: return@map null
@@ -199,6 +201,8 @@ class ResolvedAtomCompleter(
}
private fun completeLambda(lambda: ResolvedLambdaAtom) {
val lambda = lambda.unwrap()
val resultArgumentsInfo = lambda.resultArgumentsInfo!!
val returnType = if (lambda.isCoercedToUnit) {
builtIns.unitType
} else {
@@ -213,7 +217,7 @@ class ResolvedAtomCompleter(
)
updateTraceForLambda(lambda, topLevelTrace, approximatedReturnType)
for (lambdaResult in lambda.resultArgumentsInfo.nonErrorArguments) {
for (lambdaResult in resultArgumentsInfo.nonErrorArguments) {
val resultValueArgument = lambdaResult as? PSIKotlinCallArgument ?: continue
val newContext =
topLevelCallContext.replaceDataFlowInfo(resultValueArgument.dataFlowInfoAfterThisArgument)
@@ -59,7 +59,6 @@ data class ReturnArgumentsInfo(
data class ReturnArgumentsAnalysisResult(
val returnArgumentsInfo: ReturnArgumentsInfo,
val inferenceSession: InferenceSession?,
val lambdaReturnType: KotlinType? = null,
val hasInapplicableCallForBuilderInference: Boolean = false
)
@@ -73,7 +72,6 @@ interface KotlinResolutionCallbacks {
expectedReturnType: UnwrappedType?, // null means, that return type is not proper i.e. it depends on some type variables
annotations: Annotations,
stubsForPostponedVariables: Map<NewTypeVariable, StubType>,
shouldRunInIndependentContext: Boolean = false
): ReturnArgumentsAnalysisResult
fun bindStubResolvedCallForCandidate(candidate: ResolvedCallAtom)
@@ -105,7 +105,9 @@ class KotlinCallCompleter(
val newAtoms = mutableMapOf<KotlinResolutionCandidate, ResolvedLambdaAtom>()
for ((candidate, atom) in lambdas.entries) {
newAtoms[candidate] = kotlinConstraintSystemCompleter.prepareLambdaAtomForFactoryPattern(atom, candidate, candidate)
val newAtom = kotlinConstraintSystemCompleter.prepareLambdaAtomForFactoryPattern(atom, candidate, candidate)
newAtoms[candidate] = newAtom
candidate.addResolvedKtPrimitive(newAtom)
}
val diagnosticHolderForLambda = KotlinDiagnosticsHolder.SimpleHolder()
@@ -116,18 +118,16 @@ class KotlinCallCompleter(
resolutionCallbacks,
firstAtom,
diagnosticHolderForLambda,
shouldRunInIndependentContext = true
)
val lambdaReturnType = results.lambdaReturnType ?: return candidates
lambdas.getValue(firstCandidate).setAnalyzedResults(results.returnArgumentsInfo, listOf(firstAtom))
firstCandidate.csBuilder.addSubtypeConstraint(lambdaReturnType, firstAtom.returnType, LambdaArgumentConstraintPosition(firstAtom))
while (iterator.hasNext()) {
val (candidate, atom) = iterator.next()
atom.setAnalyzedResults(results.returnArgumentsInfo, firstAtom.subResolvedAtoms!!)
lambdas.getValue(candidate).setAnalyzedResults(results.returnArgumentsInfo, listOf(atom))
candidate.csBuilder.addSubtypeConstraint(lambdaReturnType, atom.returnType, LambdaArgumentConstraintPosition(atom))
postponedArgumentsAnalyzer.applyResultsOfAnalyzedLambdaToCandidateSystem(
candidate.getSystem().asPostponedArgumentsAnalyzerContext(),
atom,
results,
diagnosticHolderForLambda
)
}
val errorCandidates = mutableSetOf<KotlinResolutionCandidate>()
@@ -226,16 +226,16 @@ fun ResolvedLambdaAtom.transformToResolvedLambda(
expectedType: UnwrappedType,
returnTypeVariable: TypeVariableForLambdaReturnType? = null
): ResolvedLambdaAtom {
val resolvedLambdaAtom = preprocessLambdaArgument(
return preprocessLambdaArgument(
csBuilder,
atom,
expectedType,
diagnosticsHolder,
forceResolution = true,
returnTypeVariable = returnTypeVariable
) as ResolvedLambdaAtom
return resolvedLambdaAtom
).also {
this.setAnalyzedResults(null, listOf(it))
} as ResolvedLambdaAtom
}
private fun preprocessCallableReference(
@@ -66,23 +66,33 @@ class PostponedArgumentsAnalyzer(
}
}
data class SubstitutorAndStubsForLambdaAnalysis(
val stubsForPostponedVariables: Map<TypeVariableMarker, StubTypeMarker>,
val substitute: (KotlinType) -> UnwrappedType
)
fun Context.createSubstituteFunctorForLambdaAnalysis(): SubstitutorAndStubsForLambdaAnalysis {
val stubsForPostponedVariables = bindingStubsForPostponedVariables()
val currentSubstitutor = buildCurrentSubstitutor(stubsForPostponedVariables.mapKeys { it.key.freshTypeConstructor(this) })
return SubstitutorAndStubsForLambdaAnalysis(stubsForPostponedVariables) {
currentSubstitutor.safeSubstitute(this, it) as UnwrappedType
}
}
fun analyzeLambda(
c: Context,
resolutionCallbacks: KotlinResolutionCallbacks,
lambda: ResolvedLambdaAtom,
diagnosticHolder: KotlinDiagnosticsHolder,
shouldRunInIndependentContext: Boolean = false
): ReturnArgumentsAnalysisResult {
val stubsForPostponedVariables = c.bindingStubsForPostponedVariables()
val currentSubstitutor = c.buildCurrentSubstitutor(stubsForPostponedVariables.mapKeys { it.key.freshTypeConstructor(c) })
fun substitute(type: UnwrappedType) = currentSubstitutor.safeSubstitute(c, type) as UnwrappedType
val substitutorAndStubsForLambdaAnalysis = c.createSubstituteFunctorForLambdaAnalysis()
val substitute = substitutorAndStubsForLambdaAnalysis.substitute
// Expected type has a higher priority against which lambda should be analyzed
// Mostly, this is needed to report more specific diagnostics on lambda parameters
fun expectedOrActualType(expected: UnwrappedType?, actual: UnwrappedType?): UnwrappedType? {
val expectedSubstituted = expected?.let(::substitute)
return if (expectedSubstituted != null && c.canBeProper(expectedSubstituted)) expectedSubstituted else actual?.let(::substitute)
val expectedSubstituted = expected?.let(substitute)
return if (expectedSubstituted != null && c.canBeProper(expectedSubstituted)) expectedSubstituted else actual?.let(substitute)
}
val builtIns = c.getBuilder().builtIns
@@ -104,7 +114,7 @@ class PostponedArgumentsAnalyzer(
val parameters =
expectedParametersToMatchAgainst?.mapIndexed { index, expected ->
expectedOrActualType(expected, lambda.parameters.getOrNull(index)) ?: builtIns.nothingType
} ?: lambda.parameters.map(::substitute)
} ?: lambda.parameters.map(substitute)
val rawReturnType = lambda.returnType
@@ -129,15 +139,25 @@ class PostponedArgumentsAnalyzer(
parameters,
expectedTypeForReturnArguments,
convertedAnnotations ?: Annotations.EMPTY,
stubsForPostponedVariables.cast(),
shouldRunInIndependentContext
substitutorAndStubsForLambdaAnalysis.stubsForPostponedVariables.cast(),
)
val (returnArgumentsInfo, inferenceSession, inferedReturnType, hasInapplicableCallForBuilderInference) =
applyResultsOfAnalyzedLambdaToCandidateSystem(c, lambda, returnArgumentsAnalysisResult, diagnosticHolder, substitute)
return returnArgumentsAnalysisResult
}
fun applyResultsOfAnalyzedLambdaToCandidateSystem(
c: Context,
lambda: ResolvedLambdaAtom,
returnArgumentsAnalysisResult: ReturnArgumentsAnalysisResult,
diagnosticHolder: KotlinDiagnosticsHolder,
substitute: (KotlinType) -> UnwrappedType = c.createSubstituteFunctorForLambdaAnalysis().substitute
) {
val (returnArgumentsInfo, inferenceSession, hasInapplicableCallForBuilderInference) =
returnArgumentsAnalysisResult
if (hasInapplicableCallForBuilderInference) {
c.getBuilder().removePostponedVariables()
return returnArgumentsAnalysisResult
return
}
val returnArguments = returnArgumentsInfo.nonErrorArguments
@@ -153,7 +173,7 @@ class PostponedArgumentsAnalyzer(
val subResolvedKtPrimitives = allReturnArguments.map {
resolveKtPrimitive(
c.getBuilder(), it, lambda.returnType.let(::substitute),
c.getBuilder(), it, lambda.returnType.let(substitute),
diagnosticHolder, ReceiverInfo.notReceiver, convertedType = null,
inferenceSession
)
@@ -161,7 +181,7 @@ class PostponedArgumentsAnalyzer(
if (!returnArgumentsInfo.returnArgumentsExist) {
val unitType = lambda.returnType.builtIns.unitType
val lambdaReturnType = lambda.returnType.let(::substitute)
val lambdaReturnType = lambda.returnType.let(substitute)
c.getBuilder().addSubtypeConstraint(unitType, lambdaReturnType, LambdaArgumentConstraintPosition(lambda))
}
@@ -173,7 +193,7 @@ class PostponedArgumentsAnalyzer(
val postponedVariables = inferenceSession.inferPostponedVariables(lambda, storageSnapshot, diagnosticHolder)
if (postponedVariables == null) {
c.getBuilder().removePostponedVariables()
return returnArgumentsAnalysisResult
return
}
for ((constructor, resultType) in postponedVariables) {
@@ -184,8 +204,6 @@ class PostponedArgumentsAnalyzer(
c.getBuilder().addEqualityConstraint(variable.defaultType(c), resultType, CoroutinePosition())
}
}
return returnArgumentsAnalysisResult
}
private fun UnwrappedType?.receiver(): UnwrappedType? {
@@ -135,11 +135,17 @@ class ResolvedLambdaAtom(
val typeVariableForLambdaReturnType: TypeVariableForLambdaReturnType?,
override val expectedType: UnwrappedType?
) : PostponedResolvedAtom() {
lateinit var resultArgumentsInfo: ReturnArgumentsInfo
/**
* [resultArgumentsInfo] can be null only if lambda was analyzed in process of resolve
* ambiguity by lambda return type
* There is a contract that [resultArgumentsInfo] will be not null for unwrapped lambda atom
* (see [unwrap])
*/
var resultArgumentsInfo: ReturnArgumentsInfo? = null
private set
fun setAnalyzedResults(
resultArguments: ReturnArgumentsInfo,
resultArguments: ReturnArgumentsInfo?,
subResolvedAtoms: List<ResolvedAtom>
) {
this.resultArgumentsInfo = resultArguments
@@ -150,6 +156,10 @@ class ResolvedLambdaAtom(
override val outputType: UnwrappedType get() = returnType
}
fun ResolvedLambdaAtom.unwrap(): ResolvedLambdaAtom {
return if (resultArgumentsInfo != null) this else subResolvedAtoms!!.single() as ResolvedLambdaAtom
}
abstract class ResolvedCallableReferenceAtom(
override val atom: CallableReferenceKotlinCallArgument,
override val expectedType: UnwrappedType?
@@ -0,0 +1,54 @@
// !LANGUAGE: +NewInference +FactoryPatternResolution
// !DIAGNOSTICS: -UNUSED_PARAMETER -UNUSED_VARIABLE -UNUSED_EXPRESSION -EXPERIMENTAL_API_USAGE -EXPERIMENTAL_UNSIGNED_LITERALS
// ISSUE: KT-11265
// FILE: OverloadResolutionByLambdaReturnType.kt
package kotlin
annotation class OverloadResolutionByLambdaReturnType
// FILE: main.kt
import kotlin.OverloadResolutionByLambdaReturnType
public inline fun <T, R> Iterable<T>.myFlatMap(transform: (T) -> Iterable<R>): List<R> {
TODO()
}
@OverloadResolutionByLambdaReturnType
@kotlin.jvm.JvmName("myFlatMapSequence")
public inline fun <T, R> Iterable<T>.myFlatMap(transform: (T) -> Sequence<R>): List<R> {
TODO()
}
interface Name
interface DeclarationDescriptor {
val nextCandidates: List<DeclarationDescriptor>?
val nextCandidatesSeq: Sequence<DeclarationDescriptor>?
val name: Name
}
fun test_1(name: Name, toplevelDescriptors: List<DeclarationDescriptor>): List<DeclarationDescriptor> {
val candidates = toplevelDescriptors.<!AMBIGUITY!>myFlatMap<!> { container ->
val nextCandidates = container.<!UNRESOLVED_REFERENCE!>nextCandidates<!> ?: return@myFlatMap emptyList()
nextCandidates
}
return candidates
}
fun test_2(name: Name, toplevelDescriptors: List<DeclarationDescriptor>): List<DeclarationDescriptor> {
val candidates = toplevelDescriptors.<!AMBIGUITY!>myFlatMap<!> { container ->
val nextCandidates = container.<!UNRESOLVED_REFERENCE!>nextCandidatesSeq<!> ?: return@myFlatMap sequenceOf()
nextCandidates
}
return candidates
}
fun test_3(name: Name, toplevelDescriptors: List<DeclarationDescriptor>): List<DeclarationDescriptor> {
val candidates = toplevelDescriptors.<!AMBIGUITY!>myFlatMap<!> { container ->
val nextCandidates = container.<!UNRESOLVED_REFERENCE!>nextCandidatesSeq<!>!!
nextCandidates
}
return candidates
}
@@ -0,0 +1,54 @@
// !LANGUAGE: +NewInference +FactoryPatternResolution
// !DIAGNOSTICS: -UNUSED_PARAMETER -UNUSED_VARIABLE -UNUSED_EXPRESSION -EXPERIMENTAL_API_USAGE -EXPERIMENTAL_UNSIGNED_LITERALS
// ISSUE: KT-11265
// FILE: OverloadResolutionByLambdaReturnType.kt
package kotlin
annotation class OverloadResolutionByLambdaReturnType
// FILE: main.kt
import kotlin.OverloadResolutionByLambdaReturnType
public inline fun <T, R> Iterable<T>.myFlatMap(transform: (T) -> Iterable<R>): List<R> {
TODO()
}
@OverloadResolutionByLambdaReturnType
@kotlin.jvm.JvmName("myFlatMapSequence")
public inline fun <T, R> Iterable<T>.myFlatMap(transform: (T) -> Sequence<R>): List<R> {
TODO()
}
interface Name
interface DeclarationDescriptor {
val nextCandidates: List<DeclarationDescriptor>?
val nextCandidatesSeq: Sequence<DeclarationDescriptor>?
val name: Name
}
fun test_1(name: Name, toplevelDescriptors: List<DeclarationDescriptor>): List<DeclarationDescriptor> {
val candidates = toplevelDescriptors.myFlatMap { container ->
val nextCandidates = container.nextCandidates ?: return@myFlatMap emptyList()
nextCandidates
}
return candidates
}
fun test_2(name: Name, toplevelDescriptors: List<DeclarationDescriptor>): List<DeclarationDescriptor> {
val candidates = toplevelDescriptors.myFlatMap { container ->
val nextCandidates = container.nextCandidatesSeq ?: return@myFlatMap sequenceOf()
nextCandidates
}
return candidates
}
fun test_3(name: Name, toplevelDescriptors: List<DeclarationDescriptor>): List<DeclarationDescriptor> {
val candidates = toplevelDescriptors.myFlatMap { container ->
val nextCandidates = container.nextCandidatesSeq!!
nextCandidates
}
return candidates
}
@@ -0,0 +1,32 @@
package
public fun test_1(/*0*/ name: Name, /*1*/ toplevelDescriptors: kotlin.collections.List<DeclarationDescriptor>): kotlin.collections.List<DeclarationDescriptor>
public fun test_2(/*0*/ name: Name, /*1*/ toplevelDescriptors: kotlin.collections.List<DeclarationDescriptor>): kotlin.collections.List<DeclarationDescriptor>
public fun test_3(/*0*/ name: Name, /*1*/ toplevelDescriptors: kotlin.collections.List<DeclarationDescriptor>): kotlin.collections.List<DeclarationDescriptor>
public inline fun </*0*/ T, /*1*/ R> kotlin.collections.Iterable<T>.myFlatMap(/*0*/ transform: (T) -> kotlin.collections.Iterable<R>): kotlin.collections.List<R>
@kotlin.OverloadResolutionByLambdaReturnType @kotlin.jvm.JvmName(name = "myFlatMapSequence") public inline fun </*0*/ T, /*1*/ R> kotlin.collections.Iterable<T>.myFlatMap(/*0*/ transform: (T) -> kotlin.sequences.Sequence<R>): kotlin.collections.List<R>
public interface DeclarationDescriptor {
public abstract val name: Name
public abstract val nextCandidates: kotlin.collections.List<DeclarationDescriptor>?
public abstract val nextCandidatesSeq: kotlin.sequences.Sequence<DeclarationDescriptor>?
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
public interface Name {
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
package kotlin {
public final annotation class OverloadResolutionByLambdaReturnType : kotlin.Annotation {
public constructor OverloadResolutionByLambdaReturnType()
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
}
@@ -30,7 +30,7 @@ fun test_2() {
}
fun test_3() {
val x = <!CANDIDATE_CHOSEN_USING_OVERLOAD_RESOLUTION_BY_LAMBDA_ANNOTATION!>create <!TYPE_MISMATCH!>{ <!CONSTANT_EXPECTED_TYPE_MISMATCH!>1.0<!> }<!><!>
val x = <!CANDIDATE_CHOSEN_USING_OVERLOAD_RESOLUTION_BY_LAMBDA_ANNOTATION!>create { <!CONSTANT_EXPECTED_TYPE_MISMATCH!>1.0<!> }<!>
}
@OverloadResolutionByLambdaReturnType
@@ -2830,6 +2830,11 @@ public class DiagnosticsTestWithStdLibGenerated extends AbstractDiagnosticsTestW
runTest("compiler/testData/diagnostics/testsWithStdLib/factoryPattern/multipleOverloads_2.kt");
}
@TestMetadata("multipleOverloads_3.kt")
public void testMultipleOverloads_3() throws Exception {
runTest("compiler/testData/diagnostics/testsWithStdLib/factoryPattern/multipleOverloads_3.kt");
}
@TestMetadata("overloadByLambdaReturnType_disabled.kt")
public void testOverloadByLambdaReturnType_disabled() throws Exception {
runTest("compiler/testData/diagnostics/testsWithStdLib/factoryPattern/overloadByLambdaReturnType_disabled.kt");
@@ -2830,6 +2830,11 @@ public class DiagnosticsTestWithStdLibUsingJavacGenerated extends AbstractDiagno
runTest("compiler/testData/diagnostics/testsWithStdLib/factoryPattern/multipleOverloads_2.kt");
}
@TestMetadata("multipleOverloads_3.kt")
public void testMultipleOverloads_3() throws Exception {
runTest("compiler/testData/diagnostics/testsWithStdLib/factoryPattern/multipleOverloads_3.kt");
}
@TestMetadata("overloadByLambdaReturnType_disabled.kt")
public void testOverloadByLambdaReturnType_disabled() throws Exception {
runTest("compiler/testData/diagnostics/testsWithStdLib/factoryPattern/overloadByLambdaReturnType_disabled.kt");
@@ -30,6 +30,7 @@ import org.jetbrains.kotlin.resolve.calls.callUtil.getType
import org.jetbrains.kotlin.resolve.calls.model.ReceiverKotlinCallArgument
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
import org.jetbrains.kotlin.resolve.calls.model.ResolvedLambdaAtom
import org.jetbrains.kotlin.resolve.calls.model.unwrap
import org.jetbrains.kotlin.resolve.calls.resolvedCallUtil.getImplicitReceiverValue
import org.jetbrains.kotlin.resolve.calls.tower.NewResolvedCallImpl
import org.jetbrains.kotlin.resolve.calls.tower.receiverValue
@@ -76,7 +77,7 @@ fun ResolvedCall<*>.hasLastFunctionalParameterWithResult(context: BindingContext
if (this is NewResolvedCallImpl<*>) {
// TODO: looks like hack
resolvedCallAtom.subResolvedAtoms?.firstOrNull { it is ResolvedLambdaAtom }.safeAs<ResolvedLambdaAtom>()?.let { lambdaAtom ->
return lambdaAtom.resultArgumentsInfo.nonErrorArguments.filterIsInstance<ReceiverKotlinCallArgument>().all {
return lambdaAtom.unwrap().resultArgumentsInfo!!.nonErrorArguments.filterIsInstance<ReceiverKotlinCallArgument>().all {
val type = it.receiverValue?.type ?: return@all false
predicate(type)
}