FIR: substitute the whole lambda body after builder inference
This commit is contained in:
committed by
teamcityserver
parent
f737d8002e
commit
0026560bd7
+5
-6
@@ -7,6 +7,7 @@ package org.jetbrains.kotlin.fir.resolve.inference
|
|||||||
|
|
||||||
import org.jetbrains.kotlin.fir.FirElement
|
import org.jetbrains.kotlin.fir.FirElement
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirAnnotatedDeclaration
|
import org.jetbrains.kotlin.fir.declarations.FirAnnotatedDeclaration
|
||||||
|
import org.jetbrains.kotlin.fir.declarations.FirAnonymousFunction
|
||||||
import org.jetbrains.kotlin.fir.declarations.hasAnnotation
|
import org.jetbrains.kotlin.fir.declarations.hasAnnotation
|
||||||
import org.jetbrains.kotlin.fir.expressions.FirArgumentList
|
import org.jetbrains.kotlin.fir.expressions.FirArgumentList
|
||||||
import org.jetbrains.kotlin.fir.expressions.FirResolvable
|
import org.jetbrains.kotlin.fir.expressions.FirResolvable
|
||||||
@@ -28,6 +29,7 @@ import org.jetbrains.kotlin.resolve.descriptorUtil.BUILDER_INFERENCE_ANNOTATION_
|
|||||||
import org.jetbrains.kotlin.types.model.TypeConstructorMarker
|
import org.jetbrains.kotlin.types.model.TypeConstructorMarker
|
||||||
|
|
||||||
class FirBuilderInferenceSession(
|
class FirBuilderInferenceSession(
|
||||||
|
private val lambda: FirAnonymousFunction,
|
||||||
resolutionContext: ResolutionContext,
|
resolutionContext: ResolutionContext,
|
||||||
private val stubsForPostponedVariables: Map<ConeTypeVariable, ConeStubType>,
|
private val stubsForPostponedVariables: Map<ConeTypeVariable, ConeStubType>,
|
||||||
) : AbstractManyCandidatesInferenceSession(resolutionContext) {
|
) : AbstractManyCandidatesInferenceSession(resolutionContext) {
|
||||||
@@ -225,19 +227,16 @@ class FirBuilderInferenceSession(
|
|||||||
return introducedConstraint
|
return introducedConstraint
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: besides calls, perhaps use the stub type substitutor for all top-level expressions inside the lambda
|
|
||||||
private fun updateCalls(commonSystem: NewConstraintSystemImpl) {
|
private fun updateCalls(commonSystem: NewConstraintSystemImpl) {
|
||||||
val nonFixedToVariablesSubstitutor = createNonFixedTypeToVariableSubstitutor()
|
val nonFixedToVariablesSubstitutor = createNonFixedTypeToVariableSubstitutor()
|
||||||
val commonSystemSubstitutor = commonSystem.buildCurrentSubstitutor() as ConeSubstitutor
|
val commonSystemSubstitutor = commonSystem.buildCurrentSubstitutor() as ConeSubstitutor
|
||||||
val nonFixedTypesToResultSubstitutor = ConeComposedSubstitutor(commonSystemSubstitutor, nonFixedToVariablesSubstitutor)
|
val nonFixedTypesToResultSubstitutor = ConeComposedSubstitutor(commonSystemSubstitutor, nonFixedToVariablesSubstitutor)
|
||||||
val completionResultsWriter = components.callCompleter.createCompletionResultsWriter(nonFixedTypesToResultSubstitutor)
|
|
||||||
|
|
||||||
val stubTypeSubstitutor = FirStubTypeTransformer(nonFixedTypesToResultSubstitutor)
|
val stubTypeSubstitutor = FirStubTypeTransformer(nonFixedTypesToResultSubstitutor)
|
||||||
for ((completedCall, _) in commonCalls) {
|
lambda.transformSingle(stubTypeSubstitutor, null)
|
||||||
completedCall.transformSingle(stubTypeSubstitutor, null)
|
// TODO: support diagnostics, see [CoroutineInferenceSession#updateCalls]
|
||||||
// TODO: support diagnostics, see [CoroutineInferenceSession#updateCalls]
|
|
||||||
}
|
|
||||||
|
|
||||||
|
val completionResultsWriter = components.callCompleter.createCompletionResultsWriter(nonFixedTypesToResultSubstitutor)
|
||||||
for ((call, _) in partiallyResolvedCalls) {
|
for ((call, _) in partiallyResolvedCalls) {
|
||||||
call.transformSingle(completionResultsWriter, null)
|
call.transformSingle(completionResultsWriter, null)
|
||||||
// TODO: support diagnostics, see [CoroutineInferenceSession#updateCalls]
|
// TODO: support diagnostics, see [CoroutineInferenceSession#updateCalls]
|
||||||
|
|||||||
+5
-1
@@ -272,7 +272,11 @@ class FirCallCompleter(
|
|||||||
|
|
||||||
val builderInferenceSession = runIf(stubsForPostponedVariables.isNotEmpty()) {
|
val builderInferenceSession = runIf(stubsForPostponedVariables.isNotEmpty()) {
|
||||||
@Suppress("UNCHECKED_CAST")
|
@Suppress("UNCHECKED_CAST")
|
||||||
FirBuilderInferenceSession(transformer.resolutionContext, stubsForPostponedVariables as Map<ConeTypeVariable, ConeStubType>)
|
FirBuilderInferenceSession(
|
||||||
|
lambdaArgument,
|
||||||
|
transformer.resolutionContext,
|
||||||
|
stubsForPostponedVariables as Map<ConeTypeVariable, ConeStubType>
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
transformer.context.withAnonymousFunctionTowerDataContext(lambdaArgument.symbol) {
|
transformer.context.withAnonymousFunctionTowerDataContext(lambdaArgument.symbol) {
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
// !LANGUAGE: +UnrestrictedBuilderInference
|
// !LANGUAGE: +UnrestrictedBuilderInference
|
||||||
// !DIAGNOSTICS: -DEPRECATION -EXPERIMENTAL_IS_NOT_ENABLED
|
// !DIAGNOSTICS: -DEPRECATION -EXPERIMENTAL_IS_NOT_ENABLED
|
||||||
// WITH_RUNTIME
|
// WITH_RUNTIME
|
||||||
// IGNORE_BACKEND_FIR: JVM_IR
|
|
||||||
// DONT_TARGET_EXACT_BACKEND: WASM
|
// DONT_TARGET_EXACT_BACKEND: WASM
|
||||||
|
|
||||||
// FILE: main.kt
|
// FILE: main.kt
|
||||||
|
|||||||
Vendored
+3
-3
@@ -10,7 +10,7 @@ fun main() {
|
|||||||
buildList {
|
buildList {
|
||||||
add(3)
|
add(3)
|
||||||
object : A {
|
object : A {
|
||||||
override fun foo(): MutableList<String> = this@buildList
|
override fun foo(): MutableList<String> = <!RETURN_TYPE_MISMATCH!>this@buildList<!>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
buildList {
|
buildList {
|
||||||
@@ -19,12 +19,12 @@ fun main() {
|
|||||||
}
|
}
|
||||||
buildList {
|
buildList {
|
||||||
add("3")
|
add("3")
|
||||||
val x: MutableList<Int> = this@buildList
|
val x: MutableList<Int> = <!INITIALIZER_TYPE_MISMATCH!>this@buildList<!>
|
||||||
}
|
}
|
||||||
buildList {
|
buildList {
|
||||||
val y: CharSequence = ""
|
val y: CharSequence = ""
|
||||||
add(y)
|
add(y)
|
||||||
val x: MutableList<String> = this@buildList
|
val x: MutableList<String> = <!INITIALIZER_TYPE_MISMATCH!>this@buildList<!>
|
||||||
}
|
}
|
||||||
buildList {
|
buildList {
|
||||||
add("")
|
add("")
|
||||||
|
|||||||
Vendored
+11
-11
@@ -37,8 +37,8 @@ fun test() {
|
|||||||
get()?.hashCode()
|
get()?.hashCode()
|
||||||
get()?.<!NONE_APPLICABLE!>equals<!>(1)
|
get()?.<!NONE_APPLICABLE!>equals<!>(1)
|
||||||
val x = get()
|
val x = get()
|
||||||
x<!UNNECESSARY_SAFE_CALL!>?.<!>hashCode()
|
x?.hashCode()
|
||||||
x<!UNNECESSARY_SAFE_CALL!>?.<!><!NONE_APPLICABLE!>equals<!>(1)
|
x?.<!NONE_APPLICABLE!>equals<!>(1)
|
||||||
x.equals("")
|
x.equals("")
|
||||||
}
|
}
|
||||||
val ret3 = build {
|
val ret3 = build {
|
||||||
@@ -50,20 +50,20 @@ fun test() {
|
|||||||
get()?.hashCode()
|
get()?.hashCode()
|
||||||
get()?.<!NONE_APPLICABLE!>equals<!>(1)
|
get()?.<!NONE_APPLICABLE!>equals<!>(1)
|
||||||
val x = get()
|
val x = get()
|
||||||
x<!UNNECESSARY_SAFE_CALL!>?.<!>hashCode()
|
x?.hashCode()
|
||||||
x<!UNNECESSARY_SAFE_CALL!>?.<!><!NONE_APPLICABLE!>equals<!>(1)
|
x?.<!NONE_APPLICABLE!>equals<!>(1)
|
||||||
|
|
||||||
if (get() == null) {}
|
if (get() == null) {}
|
||||||
if (get() === null) {}
|
if (get() === null) {}
|
||||||
|
|
||||||
if (x != null) {
|
if (x != null) {
|
||||||
x<!UNNECESSARY_SAFE_CALL!>?.<!>hashCode()
|
x?.hashCode()
|
||||||
x<!UNNECESSARY_SAFE_CALL!>?.<!><!NONE_APPLICABLE!>equals<!>(1)
|
x?.<!NONE_APPLICABLE!>equals<!>(1)
|
||||||
x.equals("")
|
x.equals("")
|
||||||
x.hashCode()
|
x.hashCode()
|
||||||
x.toString()
|
x.toString()
|
||||||
x.test()
|
x.test()
|
||||||
x<!UNNECESSARY_SAFE_CALL!>?.<!>test2()
|
x?.test2()
|
||||||
x.test2()
|
x.test2()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -166,8 +166,8 @@ fun test() {
|
|||||||
get()?.hashCode()
|
get()?.hashCode()
|
||||||
get()?.<!NONE_APPLICABLE!>equals<!>(1)
|
get()?.<!NONE_APPLICABLE!>equals<!>(1)
|
||||||
val x = get()
|
val x = get()
|
||||||
x<!UNNECESSARY_SAFE_CALL!>?.<!>hashCode()
|
x?.hashCode()
|
||||||
x<!UNNECESSARY_SAFE_CALL!>?.<!><!NONE_APPLICABLE!>equals<!>(1)
|
x?.<!NONE_APPLICABLE!>equals<!>(1)
|
||||||
|
|
||||||
if (get() == null) {}
|
if (get() == null) {}
|
||||||
if (get() === null) {}
|
if (get() === null) {}
|
||||||
@@ -296,8 +296,8 @@ fun test() {
|
|||||||
get()?.hashCode()
|
get()?.hashCode()
|
||||||
get()?.<!NONE_APPLICABLE!>equals<!>(1)
|
get()?.<!NONE_APPLICABLE!>equals<!>(1)
|
||||||
val x = get()
|
val x = get()
|
||||||
x<!UNNECESSARY_SAFE_CALL!>?.<!>hashCode()
|
x?.hashCode()
|
||||||
x<!UNNECESSARY_SAFE_CALL!>?.<!><!NONE_APPLICABLE!>equals<!>(1)
|
x?.<!NONE_APPLICABLE!>equals<!>(1)
|
||||||
|
|
||||||
if (get() == null) {}
|
if (get() == null) {}
|
||||||
if (get() === null) {}
|
if (get() === null) {}
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ fun <E : Any?, C : Base<E>> Receiver<E>.toChannel(destination: C): C {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun <R : Any?> foo(r: Receiver<R>): R {
|
fun <R : Any?> foo(r: Receiver<R>): R {
|
||||||
return produce<R>(block = local fun Derived<R>.<anonymous>() {
|
return produce<R>(block = local fun Derived<ErrorType>.<anonymous>() {
|
||||||
r.toChannel<R, Derived<ErrorType>>(destination = <this>) /*~> Unit */
|
r.toChannel<R, Derived<ErrorType>>(destination = <this>) /*~> Unit */
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
@@ -28,3 +28,4 @@ fun <R : Any?> foo(r: Receiver<R>): R {
|
|||||||
fun box(): String {
|
fun box(): String {
|
||||||
return "OK"
|
return "OK"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+4
-4
@@ -72,16 +72,16 @@ FILE fqName:<root> fileName:/kt47082.kt
|
|||||||
RETURN type=kotlin.Nothing from='public final fun foo <R> (r: <root>.Receiver<R of <root>.foo>): R of <root>.foo declared in <root>'
|
RETURN type=kotlin.Nothing from='public final fun foo <R> (r: <root>.Receiver<R of <root>.foo>): R of <root>.foo declared in <root>'
|
||||||
CALL 'public final fun produce <E> (block: @[ExtensionFunctionType] kotlin.Function1<<root>.Derived<E of <root>.produce>, kotlin.Unit>): E of <root>.produce declared in <root>' type=R of <root>.foo origin=null
|
CALL 'public final fun produce <E> (block: @[ExtensionFunctionType] kotlin.Function1<<root>.Derived<E of <root>.produce>, kotlin.Unit>): E of <root>.produce declared in <root>' type=R of <root>.foo origin=null
|
||||||
<E>: R of <root>.foo
|
<E>: R of <root>.foo
|
||||||
block: FUN_EXPR type=kotlin.Function1<<root>.Derived<R of <root>.foo>, kotlin.Unit> origin=LAMBDA
|
block: FUN_EXPR type=kotlin.Function1<<root>.Derived<IrErrorType(null)>, kotlin.Unit> origin=LAMBDA
|
||||||
FUN LOCAL_FUNCTION_FOR_LAMBDA name:<anonymous> visibility:local modality:FINAL <> ($receiver:<root>.Derived<R of <root>.foo>) returnType:kotlin.Unit
|
FUN LOCAL_FUNCTION_FOR_LAMBDA name:<anonymous> visibility:local modality:FINAL <> ($receiver:<root>.Derived<IrErrorType(null)>) returnType:kotlin.Unit
|
||||||
$receiver: VALUE_PARAMETER name:<this> type:<root>.Derived<R of <root>.foo>
|
$receiver: VALUE_PARAMETER name:<this> type:<root>.Derived<IrErrorType(null)>
|
||||||
BLOCK_BODY
|
BLOCK_BODY
|
||||||
TYPE_OP type=kotlin.Unit origin=IMPLICIT_COERCION_TO_UNIT typeOperand=kotlin.Unit
|
TYPE_OP type=kotlin.Unit origin=IMPLICIT_COERCION_TO_UNIT typeOperand=kotlin.Unit
|
||||||
CALL 'public final fun toChannel <E, C> (destination: C of <root>.toChannel): C of <root>.toChannel declared in <root>' type=<root>.Derived<IrErrorType(null)> origin=null
|
CALL 'public final fun toChannel <E, C> (destination: C of <root>.toChannel): C of <root>.toChannel declared in <root>' type=<root>.Derived<IrErrorType(null)> origin=null
|
||||||
<E>: R of <root>.foo
|
<E>: R of <root>.foo
|
||||||
<C>: <root>.Derived<IrErrorType(null)>
|
<C>: <root>.Derived<IrErrorType(null)>
|
||||||
$receiver: GET_VAR 'r: <root>.Receiver<R of <root>.foo> declared in <root>.foo' type=<root>.Receiver<R of <root>.foo> origin=null
|
$receiver: GET_VAR 'r: <root>.Receiver<R of <root>.foo> declared in <root>.foo' type=<root>.Receiver<R of <root>.foo> origin=null
|
||||||
destination: GET_VAR '<this>: <root>.Derived<R of <root>.foo> declared in <root>.foo.<anonymous>' type=<root>.Derived<IrErrorType(null)> origin=null
|
destination: GET_VAR '<this>: <root>.Derived<IrErrorType(null)> declared in <root>.foo.<anonymous>' type=<root>.Derived<IrErrorType(null)> origin=null
|
||||||
FUN name:box visibility:public modality:FINAL <> () returnType:kotlin.String
|
FUN name:box visibility:public modality:FINAL <> () returnType:kotlin.String
|
||||||
BLOCK_BODY
|
BLOCK_BODY
|
||||||
RETURN type=kotlin.Nothing from='public final fun box (): kotlin.String declared in <root>'
|
RETURN type=kotlin.Nothing from='public final fun box (): kotlin.String declared in <root>'
|
||||||
|
|||||||
Reference in New Issue
Block a user