FIR: Get rid of replacements map during calls completion
Otherwise, it's complicated to work with nested lambdas: outer/inner ones may be replaced independently and still refer to the old one instances. So in the changed test, if we don't apply the commit, will remain implicit return and receiver types for the nested lambda Anyway, once we decided to leave immutable semantics, replacements are not necessary anymore
This commit is contained in:
-3
@@ -40,7 +40,6 @@ class PostponedArgumentsAnalyzer(
|
|||||||
private val lambdaAnalyzer: LambdaAnalyzer,
|
private val lambdaAnalyzer: LambdaAnalyzer,
|
||||||
private val components: InferenceComponents,
|
private val components: InferenceComponents,
|
||||||
private val candidate: Candidate,
|
private val candidate: Candidate,
|
||||||
private val replacements: MutableMap<FirExpression, FirExpression>,
|
|
||||||
private val callResolver: FirCallResolver
|
private val callResolver: FirCallResolver
|
||||||
) {
|
) {
|
||||||
|
|
||||||
@@ -94,8 +93,6 @@ class PostponedArgumentsAnalyzer(
|
|||||||
replaceTypeRef(FirResolvedTypeRefImpl(null, candidate.resultingTypeForCallableReference!!))
|
replaceTypeRef(FirResolvedTypeRefImpl(null, candidate.resultingTypeForCallableReference!!))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
replacements[callableReferenceAccess] = transformedCalleeReference
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun analyzeLambda(
|
private fun analyzeLambda(
|
||||||
|
|||||||
+19
-25
@@ -5,7 +5,6 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.fir.resolve.inference
|
package org.jetbrains.kotlin.fir.resolve.inference
|
||||||
|
|
||||||
import org.jetbrains.kotlin.fir.copy
|
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirAnonymousFunction
|
import org.jetbrains.kotlin.fir.declarations.FirAnonymousFunction
|
||||||
import org.jetbrains.kotlin.fir.declarations.impl.FirValueParameterImpl
|
import org.jetbrains.kotlin.fir.declarations.impl.FirValueParameterImpl
|
||||||
import org.jetbrains.kotlin.fir.expressions.FirExpression
|
import org.jetbrains.kotlin.fir.expressions.FirExpression
|
||||||
@@ -16,8 +15,8 @@ import org.jetbrains.kotlin.fir.resolve.BodyResolveComponents
|
|||||||
import org.jetbrains.kotlin.fir.resolve.ResolutionMode
|
import org.jetbrains.kotlin.fir.resolve.ResolutionMode
|
||||||
import org.jetbrains.kotlin.fir.resolve.calls.*
|
import org.jetbrains.kotlin.fir.resolve.calls.*
|
||||||
import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor
|
import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor
|
||||||
import org.jetbrains.kotlin.fir.resolve.transformers.*
|
import org.jetbrains.kotlin.fir.resolve.transformers.FirCallCompletionResultsWriterTransformer
|
||||||
import org.jetbrains.kotlin.fir.resolve.transformers.MapArguments
|
import org.jetbrains.kotlin.fir.resolve.transformers.InvocationKindTransformer
|
||||||
import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.FirAbstractBodyResolveTransformer
|
import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.FirAbstractBodyResolveTransformer
|
||||||
import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.FirBodyResolveTransformer
|
import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.FirBodyResolveTransformer
|
||||||
import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.resultType
|
import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.resultType
|
||||||
@@ -75,11 +74,10 @@ class FirCallCompleter(
|
|||||||
}
|
}
|
||||||
|
|
||||||
val completionMode = candidate.computeCompletionMode(inferenceComponents, expectedTypeRef, initialType)
|
val completionMode = candidate.computeCompletionMode(inferenceComponents, expectedTypeRef, initialType)
|
||||||
val replacements = mutableMapOf<FirExpression, FirExpression>()
|
|
||||||
|
|
||||||
val analyzer =
|
val analyzer =
|
||||||
PostponedArgumentsAnalyzer(
|
PostponedArgumentsAnalyzer(
|
||||||
LambdaAnalyzerImpl(replacements), inferenceComponents, candidate, replacements,
|
LambdaAnalyzerImpl(), inferenceComponents, candidate,
|
||||||
transformer.components.callResolver
|
transformer.components.callResolver
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -88,8 +86,6 @@ class FirCallCompleter(
|
|||||||
analyzer.analyze(candidate.system.asPostponedArgumentsAnalyzerContext(), it)
|
analyzer.analyze(candidate.system.asPostponedArgumentsAnalyzerContext(), it)
|
||||||
}
|
}
|
||||||
|
|
||||||
call.transformChildren(MapArguments, replacements.toMap())
|
|
||||||
|
|
||||||
if (completionMode == KotlinConstraintSystemCompleter.ConstraintSystemCompletionMode.FULL) {
|
if (completionMode == KotlinConstraintSystemCompleter.ConstraintSystemCompletionMode.FULL) {
|
||||||
val finalSubstitutor =
|
val finalSubstitutor =
|
||||||
candidate.system.asReadOnlyStorage().buildAbstractResultingSubstitutor(inferenceComponents.ctx) as ConeSubstitutor
|
candidate.system.asReadOnlyStorage().buildAbstractResultingSubstitutor(inferenceComponents.ctx) as ConeSubstitutor
|
||||||
@@ -106,9 +102,7 @@ class FirCallCompleter(
|
|||||||
return call.transformSingle(integerOperatorsTypeUpdater, null)
|
return call.transformSingle(integerOperatorsTypeUpdater, null)
|
||||||
}
|
}
|
||||||
|
|
||||||
private inner class LambdaAnalyzerImpl(
|
private inner class LambdaAnalyzerImpl : LambdaAnalyzer {
|
||||||
val replacements: MutableMap<FirExpression, FirExpression>
|
|
||||||
) : LambdaAnalyzer {
|
|
||||||
override fun analyzeAndGetLambdaReturnArguments(
|
override fun analyzeAndGetLambdaReturnArguments(
|
||||||
lambdaArgument: FirAnonymousFunction,
|
lambdaArgument: FirAnonymousFunction,
|
||||||
isSuspend: Boolean,
|
isSuspend: Boolean,
|
||||||
@@ -142,24 +136,24 @@ class FirCallCompleter(
|
|||||||
|
|
||||||
val expectedReturnTypeRef = expectedReturnType?.let { lambdaArgument.returnTypeRef.resolvedTypeFromPrototype(it) }
|
val expectedReturnTypeRef = expectedReturnType?.let { lambdaArgument.returnTypeRef.resolvedTypeFromPrototype(it) }
|
||||||
|
|
||||||
val newLambdaExpression = lambdaArgument.copy(
|
lambdaArgument.replaceReceiverTypeRef(
|
||||||
receiverTypeRef = receiverType?.let {
|
receiverType?.approximateLambdaInputType()?.let {
|
||||||
lambdaArgument.receiverTypeRef?.resolvedTypeFromPrototype(it.approximateLambdaInputType())
|
lambdaArgument.receiverTypeRef?.resolvedTypeFromPrototype(it)
|
||||||
},
|
}
|
||||||
valueParameters = lambdaArgument.valueParameters.mapIndexed { index, parameter ->
|
|
||||||
parameter.transformReturnTypeRef(
|
|
||||||
StoreType,
|
|
||||||
parameter.returnTypeRef.resolvedTypeFromPrototype(parameters[index].approximateLambdaInputType())
|
|
||||||
)
|
|
||||||
parameter
|
|
||||||
} + listOfNotNull(itParam),
|
|
||||||
returnTypeRef = expectedReturnTypeRef ?: noExpectedType
|
|
||||||
)
|
)
|
||||||
|
|
||||||
replacements[lambdaArgument] =
|
lambdaArgument.valueParameters.forEachIndexed { index, parameter ->
|
||||||
newLambdaExpression.transformSingle(transformer, ResolutionMode.LambdaResolution(expectedReturnTypeRef))
|
parameter.replaceReturnTypeRef(
|
||||||
|
parameter.returnTypeRef.resolvedTypeFromPrototype(parameters[index].approximateLambdaInputType())
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
val returnArguments = dataFlowAnalyzer.returnExpressionsOfAnonymousFunction(newLambdaExpression)
|
lambdaArgument.replaceValueParameters(lambdaArgument.valueParameters + listOfNotNull(itParam))
|
||||||
|
lambdaArgument.replaceReturnTypeRef(expectedReturnTypeRef ?: noExpectedType)
|
||||||
|
|
||||||
|
lambdaArgument.transformSingle(transformer, ResolutionMode.LambdaResolution(expectedReturnTypeRef))
|
||||||
|
|
||||||
|
val returnArguments = dataFlowAnalyzer.returnExpressionsOfAnonymousFunction(lambdaArgument)
|
||||||
return returnArguments to InferenceSession.default
|
return returnArguments to InferenceSession.default
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,8 +2,8 @@ FILE: postponedLambdas.kt
|
|||||||
public final inline fun foo(vararg x: R|kotlin/Array<kotlin/Any>|): R|kotlin/Unit| {
|
public final inline fun foo(vararg x: R|kotlin/Array<kotlin/Any>|): R|kotlin/Unit| {
|
||||||
}
|
}
|
||||||
public final fun test(a: R|kotlin/Any|, b: R|kotlin/Any|, c: R|kotlin/Any|): R|kotlin/Unit| {
|
public final fun test(a: R|kotlin/Any|, b: R|kotlin/Any|, c: R|kotlin/Any|): R|kotlin/Unit| {
|
||||||
R|/foo|(vararg(R|<local>/a|, R|<local>/b|), foo@fun <anonymous>(): R|kotlin/String| <kind=UNKNOWN> {
|
R|/foo|(vararg(R|<local>/a|, foo@fun <anonymous>(): R|kotlin/String| <kind=UNKNOWN> {
|
||||||
String()
|
String()
|
||||||
}
|
}
|
||||||
)
|
, R|<local>/b|))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ interface MyMap<K, V> {
|
|||||||
|
|
||||||
val w: Inv<String> = TODO()
|
val w: Inv<String> = TODO()
|
||||||
|
|
||||||
public fun <X, K> Inv<X>.associateBy1(keySelector: (X) -> K): MyMap<K, String> = TODO()
|
public fun <X, K> Inv<X>.associateBy1(keySelector: (X) -> K): MyMap<K, X> = TODO()
|
||||||
|
|
||||||
val x = myRun {
|
val x = myRun {
|
||||||
w.associateBy1 { f -> f.length }
|
w.associateBy1 { f -> f.length }
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ FILE: nestedLambdas.kt
|
|||||||
}
|
}
|
||||||
public final val w: R|Inv<kotlin/String>| = R|kotlin/TODO|()
|
public final val w: R|Inv<kotlin/String>| = R|kotlin/TODO|()
|
||||||
public get(): R|Inv<kotlin/String>|
|
public get(): R|Inv<kotlin/String>|
|
||||||
public final fun <X, K> R|Inv<X>|.associateBy1(keySelector: R|(X) -> K|): R|MyMap<K, kotlin/String>| {
|
public final fun <X, K> R|Inv<X>|.associateBy1(keySelector: R|(X) -> K|): R|MyMap<K, X>| {
|
||||||
^associateBy1 R|kotlin/TODO|()
|
^associateBy1 R|kotlin/TODO|()
|
||||||
}
|
}
|
||||||
public final val x: R|MyMap<kotlin/Int, kotlin/String>| = R|/myRun|<R|MyMap<kotlin/Int, kotlin/String>|>(<L> = myRun@fun <anonymous>(): R|MyMap<kotlin/Int, kotlin/String>| {
|
public final val x: R|MyMap<kotlin/Int, kotlin/String>| = R|/myRun|<R|MyMap<kotlin/Int, kotlin/String>|>(<L> = myRun@fun <anonymous>(): R|MyMap<kotlin/Int, kotlin/String>| {
|
||||||
|
|||||||
-1
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_BACKEND_FIR: JVM_IR
|
|
||||||
fun <T> block(block: () -> T): T = block()
|
fun <T> block(block: () -> T): T = block()
|
||||||
fun foo() {}
|
fun foo() {}
|
||||||
|
|
||||||
|
|||||||
+24
-24
@@ -22,32 +22,32 @@ FILE fqName:<root> fileName:/samConversionInVarargs.kt
|
|||||||
BLOCK_BODY
|
BLOCK_BODY
|
||||||
FUN name:testLambda visibility:public modality:FINAL <> () returnType:kotlin.Unit
|
FUN name:testLambda visibility:public modality:FINAL <> () returnType:kotlin.Unit
|
||||||
BLOCK_BODY
|
BLOCK_BODY
|
||||||
ERROR_CALL 'Cannot bind 2 arguments to useVararg call with 1 parameters' type=kotlin.Unit
|
CALL 'public final fun useVararg (vararg foos: <root>.IFoo): kotlin.Unit declared in <root>' type=kotlin.Unit origin=null
|
||||||
FUN_EXPR type=kotlin.Function1<kotlin.Int, kotlin.Unit> origin=LAMBDA
|
foos: VARARG type=kotlin.Array<<root>.IFoo> varargElementType=<root>.IFoo
|
||||||
FUN LOCAL_FUNCTION_FOR_LAMBDA name:<anonymous> visibility:local modality:FINAL <> (it:kotlin.Int) returnType:kotlin.Unit
|
FUN_EXPR type=kotlin.Function1<kotlin.Int, kotlin.Unit> origin=LAMBDA
|
||||||
VALUE_PARAMETER name:it index:0 type:kotlin.Int
|
FUN LOCAL_FUNCTION_FOR_LAMBDA name:<anonymous> visibility:local modality:FINAL <> (it:kotlin.Int) returnType:kotlin.Unit
|
||||||
BLOCK_BODY
|
VALUE_PARAMETER name:it index:0 type:kotlin.Int
|
||||||
GET_OBJECT 'CLASS IR_EXTERNAL_DECLARATION_STUB OBJECT name:Unit modality:FINAL visibility:public superTypes:[kotlin.Any]' type=kotlin.Unit
|
BLOCK_BODY
|
||||||
VARARG type=kotlin.Array<<root>.IFoo> varargElementType=<root>.IFoo
|
GET_OBJECT 'CLASS IR_EXTERNAL_DECLARATION_STUB OBJECT name:Unit modality:FINAL visibility:public superTypes:[kotlin.Any]' type=kotlin.Unit
|
||||||
FUN name:testSeveralLambdas visibility:public modality:FINAL <> () returnType:kotlin.Unit
|
FUN name:testSeveralLambdas visibility:public modality:FINAL <> () returnType:kotlin.Unit
|
||||||
BLOCK_BODY
|
BLOCK_BODY
|
||||||
ERROR_CALL 'Cannot bind 4 arguments to useVararg call with 1 parameters' type=kotlin.Unit
|
CALL 'public final fun useVararg (vararg foos: <root>.IFoo): kotlin.Unit declared in <root>' type=kotlin.Unit origin=null
|
||||||
FUN_EXPR type=kotlin.Function1<kotlin.Int, kotlin.Unit> origin=LAMBDA
|
foos: VARARG type=kotlin.Array<<root>.IFoo> varargElementType=<root>.IFoo
|
||||||
FUN LOCAL_FUNCTION_FOR_LAMBDA name:<anonymous> visibility:local modality:FINAL <> (it:kotlin.Int) returnType:kotlin.Unit
|
FUN_EXPR type=kotlin.Function1<kotlin.Int, kotlin.Unit> origin=LAMBDA
|
||||||
VALUE_PARAMETER name:it index:0 type:kotlin.Int
|
FUN LOCAL_FUNCTION_FOR_LAMBDA name:<anonymous> visibility:local modality:FINAL <> (it:kotlin.Int) returnType:kotlin.Unit
|
||||||
BLOCK_BODY
|
VALUE_PARAMETER name:it index:0 type:kotlin.Int
|
||||||
GET_OBJECT 'CLASS IR_EXTERNAL_DECLARATION_STUB OBJECT name:Unit modality:FINAL visibility:public superTypes:[kotlin.Any]' type=kotlin.Unit
|
BLOCK_BODY
|
||||||
FUN_EXPR type=kotlin.Function1<kotlin.Int, kotlin.Unit> origin=LAMBDA
|
GET_OBJECT 'CLASS IR_EXTERNAL_DECLARATION_STUB OBJECT name:Unit modality:FINAL visibility:public superTypes:[kotlin.Any]' type=kotlin.Unit
|
||||||
FUN LOCAL_FUNCTION_FOR_LAMBDA name:<anonymous> visibility:local modality:FINAL <> (it:kotlin.Int) returnType:kotlin.Unit
|
FUN_EXPR type=kotlin.Function1<kotlin.Int, kotlin.Unit> origin=LAMBDA
|
||||||
VALUE_PARAMETER name:it index:0 type:kotlin.Int
|
FUN LOCAL_FUNCTION_FOR_LAMBDA name:<anonymous> visibility:local modality:FINAL <> (it:kotlin.Int) returnType:kotlin.Unit
|
||||||
BLOCK_BODY
|
VALUE_PARAMETER name:it index:0 type:kotlin.Int
|
||||||
GET_OBJECT 'CLASS IR_EXTERNAL_DECLARATION_STUB OBJECT name:Unit modality:FINAL visibility:public superTypes:[kotlin.Any]' type=kotlin.Unit
|
BLOCK_BODY
|
||||||
FUN_EXPR type=kotlin.Function1<kotlin.Int, kotlin.Unit> origin=LAMBDA
|
GET_OBJECT 'CLASS IR_EXTERNAL_DECLARATION_STUB OBJECT name:Unit modality:FINAL visibility:public superTypes:[kotlin.Any]' type=kotlin.Unit
|
||||||
FUN LOCAL_FUNCTION_FOR_LAMBDA name:<anonymous> visibility:local modality:FINAL <> (it:kotlin.Int) returnType:kotlin.Unit
|
FUN_EXPR type=kotlin.Function1<kotlin.Int, kotlin.Unit> origin=LAMBDA
|
||||||
VALUE_PARAMETER name:it index:0 type:kotlin.Int
|
FUN LOCAL_FUNCTION_FOR_LAMBDA name:<anonymous> visibility:local modality:FINAL <> (it:kotlin.Int) returnType:kotlin.Unit
|
||||||
BLOCK_BODY
|
VALUE_PARAMETER name:it index:0 type:kotlin.Int
|
||||||
GET_OBJECT 'CLASS IR_EXTERNAL_DECLARATION_STUB OBJECT name:Unit modality:FINAL visibility:public superTypes:[kotlin.Any]' type=kotlin.Unit
|
BLOCK_BODY
|
||||||
VARARG type=kotlin.Array<<root>.IFoo> varargElementType=<root>.IFoo
|
GET_OBJECT 'CLASS IR_EXTERNAL_DECLARATION_STUB OBJECT name:Unit modality:FINAL visibility:public superTypes:[kotlin.Any]' type=kotlin.Unit
|
||||||
FUN name:withVarargOfInt visibility:public modality:FINAL <> (xs:kotlin.IntArray) returnType:kotlin.String
|
FUN name:withVarargOfInt visibility:public modality:FINAL <> (xs:kotlin.IntArray) returnType:kotlin.String
|
||||||
VALUE_PARAMETER name:xs index:0 type:kotlin.IntArray varargElementType:kotlin.Int [vararg]
|
VALUE_PARAMETER name:xs index:0 type:kotlin.IntArray varargElementType:kotlin.Int [vararg]
|
||||||
BLOCK_BODY
|
BLOCK_BODY
|
||||||
|
|||||||
Reference in New Issue
Block a user