FIR: fix label stealling and crash with multiple labels
Consider the code below
```
fun test() {
a@ b@ {
{}
}
}
```
Currently when the code is converted to FIR, label `b` is bound to the
outer lambda and `a` gets bound to the inner lambda because it's not
consumed. This is wrong and also leads transfromation to fail with
exceptions because of the unexpected consumption of `a`.
This change fixes the above issue by designating a specific node in the
AST as the allowed user of a label when the label is added.
This commit is contained in:
committed by
TeamCityServer
parent
5c716ea979
commit
fadde98a86
+9
@@ -0,0 +1,9 @@
|
||||
// FIR_IDENTICAL
|
||||
fun test() {
|
||||
a@ b@ while(true) {
|
||||
val f = {
|
||||
<!NOT_A_FUNCTION_LABEL!>return@a<!>
|
||||
}
|
||||
break@b
|
||||
}
|
||||
}
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
package
|
||||
|
||||
public fun test(): kotlin.Unit
|
||||
+11
-2
@@ -51,12 +51,21 @@ fun testLoopLabelInReturn(xs: List<Int>) {
|
||||
}
|
||||
|
||||
fun testValLabelInReturn() {
|
||||
L@ val fn = { return@L }
|
||||
L@ val fn = { <!NOT_A_FUNCTION_LABEL!>return@L<!> }
|
||||
fn()
|
||||
}
|
||||
|
||||
fun testHighOrderFunctionCallLabelInReturn() {
|
||||
L@ run {
|
||||
return@L
|
||||
<!NOT_A_FUNCTION_LABEL!>return@L<!>
|
||||
}
|
||||
}
|
||||
|
||||
fun testMultipleLabelsWithNestedLambda() {
|
||||
l1@ l2@{
|
||||
{
|
||||
<!NOT_A_FUNCTION_LABEL!>return@l1<!>
|
||||
}
|
||||
return@l2
|
||||
}
|
||||
}
|
||||
|
||||
+10
-1
@@ -59,4 +59,13 @@ fun testHighOrderFunctionCallLabelInReturn() {
|
||||
<!REDUNDANT_LABEL_WARNING!>L@<!> run {
|
||||
<!NOT_A_FUNCTION_LABEL!>return@L<!>
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun testMultipleLabelsWithNestedLambda() {
|
||||
l1@ l2@{
|
||||
{
|
||||
<!RETURN_NOT_ALLOWED!>return@l1<!>
|
||||
}
|
||||
return@l2
|
||||
}
|
||||
}
|
||||
|
||||
+2
@@ -9,6 +9,7 @@ public fun testLambdaLabel(): () -> kotlin.Unit
|
||||
public fun testLambdaMultipleLabels1(): () -> kotlin.Unit
|
||||
public fun testLambdaMultipleLabels2(): () -> kotlin.Unit
|
||||
public fun testLoopLabelInReturn(/*0*/ xs: kotlin.collections.List<kotlin.Int>): kotlin.Unit
|
||||
public fun testMultipleLabelsWithNestedLambda(): kotlin.Unit
|
||||
public fun testParenthesizedLambdaLabel(): () -> kotlin.Unit
|
||||
public fun testValLabelInReturn(): kotlin.Unit
|
||||
|
||||
@@ -18,3 +19,4 @@ public fun testValLabelInReturn(): kotlin.Unit
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
|
||||
+11
-2
@@ -51,12 +51,21 @@ fun testLoopLabelInReturn(xs: List<Int>) {
|
||||
}
|
||||
|
||||
fun testValLabelInReturn() {
|
||||
L@ val fn = { return@L }
|
||||
L@ val fn = { <!NOT_A_FUNCTION_LABEL!>return@L<!> }
|
||||
fn()
|
||||
}
|
||||
|
||||
fun testHighOrderFunctionCallLabelInReturn() {
|
||||
L@ run {
|
||||
return@L
|
||||
<!NOT_A_FUNCTION_LABEL!>return@L<!>
|
||||
}
|
||||
}
|
||||
|
||||
fun testMultipleLabelsWithNestedLambda() {
|
||||
l1@ l2@{
|
||||
{
|
||||
<!NOT_A_FUNCTION_LABEL!>return@l1<!>
|
||||
}
|
||||
return@l2
|
||||
}
|
||||
}
|
||||
|
||||
+10
-1
@@ -59,4 +59,13 @@ fun testHighOrderFunctionCallLabelInReturn() {
|
||||
<!REDUNDANT_LABEL_WARNING!>L@<!> run {
|
||||
<!NOT_A_FUNCTION_LABEL_WARNING!>return@L<!>
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun testMultipleLabelsWithNestedLambda() {
|
||||
l1@ l2@{
|
||||
{
|
||||
<!RETURN_NOT_ALLOWED!>return@l1<!>
|
||||
}
|
||||
return@l2
|
||||
}
|
||||
}
|
||||
|
||||
+2
@@ -9,6 +9,7 @@ public fun testLambdaLabel(): () -> kotlin.Unit
|
||||
public fun testLambdaMultipleLabels1(): () -> kotlin.Unit
|
||||
public fun testLambdaMultipleLabels2(): () -> kotlin.Unit
|
||||
public fun testLoopLabelInReturn(/*0*/ xs: kotlin.collections.List<kotlin.Int>): kotlin.Unit
|
||||
public fun testMultipleLabelsWithNestedLambda(): kotlin.Unit
|
||||
public fun testParenthesizedLambdaLabel(): () -> kotlin.Unit
|
||||
public fun testValLabelInReturn(): kotlin.Unit
|
||||
|
||||
@@ -18,3 +19,4 @@ public fun testValLabelInReturn(): kotlin.Unit
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user