[FIR] Fix local variable tests.

- Mangle names for extension receivers in lambdas
 - Correctly mark anonymous variables and variables for arguments
   for destructuring declaration.

There is one failure remaining which is cause by lambda
type inference differences that leads to FIR having an explicit
return from the lambda whereas old frontend leads to an implicit
return. This difference is visible in debug stepping that the
local variables tests do because the implicit return has the line
number of the closing brace of the lambda. This change adds an
IrText test to make the difference clear.
This commit is contained in:
Mads Ager
2021-10-28 13:49:57 +02:00
committed by Mikhail Glukhikh
parent 99293de6e9
commit e1f6c19c83
31 changed files with 186 additions and 60 deletions
@@ -140,7 +140,7 @@ FILE fqName:<root> fileName:/destructuringInLambda.kt
EXPRESSION_BODY
FUN_EXPR type=kotlin.Function1<<root>.A, kotlin.Int> origin=LAMBDA
FUN LOCAL_FUNCTION_FOR_LAMBDA name:<anonymous> visibility:local modality:FINAL <> (<destruct>:<root>.A) returnType:kotlin.Int
VALUE_PARAMETER name:<destruct> index:0 type:<root>.A
VALUE_PARAMETER DESTRUCTURED_OBJECT_PARAMETER name:<destruct> index:0 type:<root>.A
BLOCK_BODY
VAR name:y type:kotlin.Int [val]
CALL 'public final fun component2 (): kotlin.Int [operator] declared in <root>.A' type=kotlin.Int origin=COMPONENT_N(index=2)
@@ -8,8 +8,8 @@ FILE fqName:<root> fileName:/extensionLambda.kt
$receiver: CONST String type=kotlin.String value="42"
block: FUN_EXPR type=kotlin.Function1<kotlin.String, kotlin.Int> origin=LAMBDA
FUN LOCAL_FUNCTION_FOR_LAMBDA name:<anonymous> visibility:local modality:FINAL <> ($receiver:kotlin.String) returnType:kotlin.Int
$receiver: VALUE_PARAMETER name:<this> type:kotlin.String
$receiver: VALUE_PARAMETER name:$this$run type:kotlin.String
BLOCK_BODY
RETURN type=kotlin.Nothing from='local final fun <anonymous> (): kotlin.Int declared in <root>.test1'
CALL 'public open fun <get-length> (): kotlin.Int declared in kotlin.String' type=kotlin.Int origin=GET_PROPERTY
$this: GET_VAR '<this>: kotlin.String declared in <root>.test1.<anonymous>' type=kotlin.String origin=null
$this: GET_VAR '$this$run: kotlin.String declared in <root>.test1.<anonymous>' type=kotlin.String origin=null
@@ -1,6 +1,7 @@
fun test1(): Int {
return "42".run<String, Int>(block = local fun String.<anonymous>(): Int {
return <this>.<get-length>()
return $this$run.<get-length>()
}
)
}
@@ -0,0 +1,15 @@
FILE fqName:<root> fileName:/lambdaReturningUnit.kt
FUN name:flaf visibility:public modality:FINAL <> (block:kotlin.Function0<kotlin.Any?>) returnType:kotlin.Unit [inline]
VALUE_PARAMETER name:block index:0 type:kotlin.Function0<kotlin.Any?>
BLOCK_BODY
TYPE_OP type=kotlin.Unit origin=IMPLICIT_COERCION_TO_UNIT typeOperand=kotlin.Unit
CALL 'public abstract fun invoke (): R of kotlin.Function0 [operator] declared in kotlin.Function0' type=kotlin.Any? origin=INVOKE
$this: GET_VAR 'block: kotlin.Function0<kotlin.Any?> declared in <root>.flaf' type=kotlin.Function0<kotlin.Any?> origin=VARIABLE_AS_FUNCTION
FUN name:box visibility:public modality:FINAL <> () returnType:kotlin.Unit [suspend]
BLOCK_BODY
CALL 'public final fun flaf (block: kotlin.Function0<kotlin.Any?>): kotlin.Unit [inline] declared in <root>' type=kotlin.Unit origin=null
block: FUN_EXPR type=kotlin.Function0<kotlin.Any?> origin=LAMBDA
FUN LOCAL_FUNCTION_FOR_LAMBDA name:<anonymous> visibility:local modality:FINAL <> () returnType:kotlin.Any?
BLOCK_BODY
RETURN type=kotlin.Nothing from='local final fun <anonymous> (): kotlin.Any? declared in <root>.box'
GET_OBJECT 'CLASS IR_EXTERNAL_DECLARATION_STUB OBJECT name:Unit modality:FINAL visibility:public superTypes:[kotlin.Any]' type=kotlin.Unit
@@ -0,0 +1,10 @@
inline fun flaf(block: Function0<Any?>) {
block.invoke() /*~> Unit */
}
suspend fun box() {
flaf(block = local fun <anonymous>(): Any? {
return Unit
}
)
}
@@ -0,0 +1,14 @@
FILE fqName:<root> fileName:/lambdaReturningUnit.kt
FUN name:flaf visibility:public modality:FINAL <> (block:kotlin.Function0<kotlin.Any?>) returnType:kotlin.Unit [inline]
VALUE_PARAMETER name:block index:0 type:kotlin.Function0<kotlin.Any?>
BLOCK_BODY
TYPE_OP type=kotlin.Unit origin=IMPLICIT_COERCION_TO_UNIT typeOperand=kotlin.Unit
CALL 'public abstract fun invoke (): R of kotlin.Function0 [operator] declared in kotlin.Function0' type=kotlin.Any? origin=INVOKE
$this: GET_VAR 'block: kotlin.Function0<kotlin.Any?> declared in <root>.flaf' type=kotlin.Function0<kotlin.Any?> origin=VARIABLE_AS_FUNCTION
FUN name:box visibility:public modality:FINAL <> () returnType:kotlin.Unit [suspend]
BLOCK_BODY
CALL 'public final fun flaf (block: kotlin.Function0<kotlin.Any?>): kotlin.Unit [inline] declared in <root>' type=kotlin.Unit origin=null
block: FUN_EXPR type=kotlin.Function0<kotlin.Unit> origin=LAMBDA
FUN LOCAL_FUNCTION_FOR_LAMBDA name:<anonymous> visibility:local modality:FINAL <> () returnType:kotlin.Unit
BLOCK_BODY
GET_OBJECT 'CLASS IR_EXTERNAL_DECLARATION_STUB OBJECT name:Unit modality:FINAL visibility:public superTypes:[kotlin.Any]' type=kotlin.Unit
@@ -0,0 +1,12 @@
// With FIR the type of the lambda in box is () -> Any?
// With old frontend the type of the lambda is () -> Unit
inline fun flaf(block: () -> Any?) {
block()
}
suspend fun box() {
flaf {
Unit
}
}
@@ -0,0 +1,11 @@
inline fun flaf(block: Function0<Any?>) {
block.invoke() /*~> Unit */
}
suspend fun box() {
flaf(block = local fun <anonymous>() {
Unit
}
)
}
@@ -92,7 +92,7 @@ FILE fqName:<root> fileName:/multipleImplicitReceivers.kt
receiver: GET_OBJECT 'CLASS OBJECT name:A modality:FINAL visibility:public superTypes:[kotlin.Any]' type=<root>.A
block: FUN_EXPR type=kotlin.Function1<<root>.A, kotlin.Int> origin=LAMBDA
FUN LOCAL_FUNCTION_FOR_LAMBDA name:<anonymous> visibility:local modality:FINAL <> ($receiver:<root>.A) returnType:kotlin.Int
$receiver: VALUE_PARAMETER name:<this> type:<root>.A
$receiver: VALUE_PARAMETER name:$this$with type:<root>.A
BLOCK_BODY
RETURN type=kotlin.Nothing from='local final fun <anonymous> (): kotlin.Int declared in <root>.test'
CALL 'public final fun with <T, R> (receiver: T of kotlin.StandardKt.with, block: @[ExtensionFunctionType] kotlin.Function1<T of kotlin.StandardKt.with, R of kotlin.StandardKt.with>): R of kotlin.StandardKt.with [inline] declared in kotlin.StandardKt' type=kotlin.Int origin=null
@@ -101,7 +101,7 @@ FILE fqName:<root> fileName:/multipleImplicitReceivers.kt
receiver: GET_VAR 'fooImpl: <root>.IFoo declared in <root>.test' type=<root>.IFoo origin=null
block: FUN_EXPR type=kotlin.Function1<<root>.IFoo, kotlin.Int> origin=LAMBDA
FUN LOCAL_FUNCTION_FOR_LAMBDA name:<anonymous> visibility:local modality:FINAL <> ($receiver:<root>.IFoo) returnType:kotlin.Int
$receiver: VALUE_PARAMETER name:<this> type:<root>.IFoo
$receiver: VALUE_PARAMETER name:$this$with type:<root>.IFoo
BLOCK_BODY
RETURN type=kotlin.Nothing from='local final fun <anonymous> (): kotlin.Int declared in <root>.test.<anonymous>'
CALL 'public final fun with <T, R> (receiver: T of kotlin.StandardKt.with, block: @[ExtensionFunctionType] kotlin.Function1<T of kotlin.StandardKt.with, R of kotlin.StandardKt.with>): R of kotlin.StandardKt.with [inline] declared in kotlin.StandardKt' type=kotlin.Int origin=null
@@ -110,11 +110,11 @@ FILE fqName:<root> fileName:/multipleImplicitReceivers.kt
receiver: GET_VAR 'invokeImpl: <root>.IInvoke declared in <root>.test' type=<root>.IInvoke origin=null
block: FUN_EXPR type=kotlin.Function1<<root>.IInvoke, kotlin.Int> origin=LAMBDA
FUN LOCAL_FUNCTION_FOR_LAMBDA name:<anonymous> visibility:local modality:FINAL <> ($receiver:<root>.IInvoke) returnType:kotlin.Int
$receiver: VALUE_PARAMETER name:<this> type:<root>.IInvoke
$receiver: VALUE_PARAMETER name:$this$with type:<root>.IInvoke
BLOCK_BODY
RETURN type=kotlin.Nothing from='local final fun <anonymous> (): kotlin.Int declared in <root>.test.<anonymous>.<anonymous>'
CALL 'public open fun invoke (): kotlin.Int [operator] declared in <root>.IInvoke' type=kotlin.Int origin=null
$this: GET_VAR '<this>: <root>.IInvoke declared in <root>.test.<anonymous>.<anonymous>.<anonymous>' type=<root>.IInvoke origin=null
$this: GET_VAR '$this$with: <root>.IInvoke declared in <root>.test.<anonymous>.<anonymous>.<anonymous>' type=<root>.IInvoke origin=null
$receiver: CALL 'public open fun <get-foo> (): <root>.B declared in <root>.IFoo' type=<root>.B origin=GET_PROPERTY
$this: GET_VAR '<this>: <root>.IFoo declared in <root>.test.<anonymous>.<anonymous>' type=<root>.IFoo origin=null
$receiver: GET_VAR '<this>: <root>.A declared in <root>.test.<anonymous>' type=<root>.A origin=null
$this: GET_VAR '$this$with: <root>.IFoo declared in <root>.test.<anonymous>.<anonymous>' type=<root>.IFoo origin=null
$receiver: GET_VAR '$this$with: <root>.A declared in <root>.test.<anonymous>' type=<root>.A origin=null
@@ -35,7 +35,7 @@ fun test(fooImpl: IFoo, invokeImpl: IInvoke) {
with<A, Int>(receiver = A, block = local fun A.<anonymous>(): Int {
return with<IFoo, Int>(receiver = fooImpl, block = local fun IFoo.<anonymous>(): Int {
return with<IInvoke, Int>(receiver = invokeImpl, block = local fun IInvoke.<anonymous>(): Int {
return (<this>, (<this>, <this>).<get-foo>()).invoke()
return ($this$with, ($this$with, $this$with).<get-foo>()).invoke()
}
)
}
@@ -43,3 +43,4 @@ fun test(fooImpl: IFoo, invokeImpl: IInvoke) {
}
) /*~> Unit */
}