Skip to content

Commit 300e0ac

Browse files
committed
Report RETURN_NOT_ALLOWED and RETURN_IN_FUNCTION_WITH_EXPRESSION_BODY only on the return with label (KT-13340)
#KT-13340 Fixed
1 parent 95ea191 commit 300e0ac

File tree

21 files changed

+70
-32
lines changed

21 files changed

+70
-32
lines changed

compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -774,8 +774,8 @@ enum BadNamedArgumentsTarget {
774774

775775
DiagnosticFactory0<KtSimpleNameExpression> EXPRESSION_EXPECTED_PACKAGE_FOUND = DiagnosticFactory0.create(ERROR);
776776

777-
DiagnosticFactory0<KtReturnExpression> RETURN_NOT_ALLOWED = DiagnosticFactory0.create(ERROR);
778-
DiagnosticFactory0<KtReturnExpression> RETURN_IN_FUNCTION_WITH_EXPRESSION_BODY = DiagnosticFactory0.create(ERROR);
777+
DiagnosticFactory0<KtReturnExpression> RETURN_NOT_ALLOWED = DiagnosticFactory0.create(ERROR, PositioningStrategies.RETURN_WITH_LABEL);
778+
DiagnosticFactory0<KtReturnExpression> RETURN_IN_FUNCTION_WITH_EXPRESSION_BODY = DiagnosticFactory0.create(ERROR, PositioningStrategies.RETURN_WITH_LABEL);
779779
DiagnosticFactory0<KtDeclarationWithBody>
780780
NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY = DiagnosticFactory0.create(ERROR, DECLARATION_WITH_BODY);
781781

compiler/frontend/src/org/jetbrains/kotlin/diagnostics/PositioningStrategies.kt

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -477,4 +477,14 @@ object PositioningStrategies {
477477
}
478478
}
479479

480+
@JvmField val RETURN_WITH_LABEL: PositioningStrategy<KtReturnExpression> = object: PositioningStrategy<KtReturnExpression>() {
481+
override fun mark(element: KtReturnExpression): List<TextRange> {
482+
val labeledExpression = element.labeledExpression
483+
if (labeledExpression != null) {
484+
return markRange(element, labeledExpression)
485+
}
486+
487+
return markElement(element.returnKeyword)
488+
}
489+
}
480490
}

compiler/frontend/src/org/jetbrains/kotlin/psi/KtReturnExpression.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,11 @@
1717
package org.jetbrains.kotlin.psi;
1818

1919
import com.intellij.lang.ASTNode;
20+
import com.intellij.psi.PsiElement;
2021
import org.jetbrains.annotations.NotNull;
2122
import org.jetbrains.annotations.Nullable;
23+
import org.jetbrains.kotlin.KtNodeTypes;
24+
import org.jetbrains.kotlin.lexer.KtTokens;
2225

2326
public class KtReturnExpression extends KtExpressionWithLabel implements KtStatementExpression {
2427
public KtReturnExpression(@NotNull ASTNode node) {
@@ -34,4 +37,15 @@ public <R, D> R accept(@NotNull KtVisitor<R, D> visitor, D data) {
3437
public KtExpression getReturnedExpression() {
3538
return findChildByClass(KtExpression.class);
3639
}
40+
41+
@NotNull
42+
public PsiElement getReturnKeyword() {
43+
//noinspection ConstantConditions
44+
return findChildByType(KtTokens.RETURN_KEYWORD);
45+
}
46+
47+
@Nullable
48+
public PsiElement getLabeledExpression() {
49+
return findChildByType(KtNodeTypes.LABEL_QUALIFIER);
50+
}
3751
}

compiler/testData/diagnostics/tests/FunctionReturnTypes.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ fun test2() : Any = a@ {return@a 1}
1212
fun test3() : Any { <!RETURN_TYPE_MISMATCH!>return<!> }
1313
fun test4(): ()-> Unit = { <!RETURN_NOT_ALLOWED, RETURN_TYPE_MISMATCH!>return@test4<!> }
1414
fun test5(): Any = l@{ return@l }
15-
fun test6(): Any = {<!RETURN_NOT_ALLOWED!>return 1<!>}
15+
fun test6(): Any = {<!RETURN_NOT_ALLOWED!>return<!> 1}
1616

1717
fun bbb() {
1818
return <!CONSTANT_EXPECTED_TYPE_MISMATCH!>1<!>
@@ -136,7 +136,7 @@ fun blockNoReturnIfUnitInOneBranch(): Int {
136136
fun nonBlockReturnIfEmptyIf(): Int = if (1 < 2) <!TYPE_MISMATCH!>{}<!> else <!TYPE_MISMATCH!>{}<!>
137137
fun nonBlockNoReturnIfUnitInOneBranch(): Int = if (1 < 2) <!TYPE_MISMATCH!>{}<!> else 2
138138

139-
val a = <!RETURN_NOT_ALLOWED!>return 1<!>
139+
val a = <!RETURN_NOT_ALLOWED!>return<!> 1
140140

141141
class A() {
142142
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
fun foo1(): () -> String = <!RETURN_IN_FUNCTION_WITH_EXPRESSION_BODY!>return<!> { "some long expression "}
2+
fun foo2(): () -> String = <!RETURN_IN_FUNCTION_WITH_EXPRESSION_BODY!>return<!UNRESOLVED_REFERENCE!>@label<!><!> { "some long expression "}
3+
fun foo3(): () -> String = <!RETURN_IN_FUNCTION_WITH_EXPRESSION_BODY!>return<!><!SYNTAX!>@<!> { "some long expression "}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
package
2+
3+
public fun foo1(): () -> kotlin.String
4+
public fun foo2(): () -> kotlin.String
5+
public fun foo3(): () -> kotlin.String

compiler/testData/diagnostics/tests/controlFlowAnalysis/kt10823.kt

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
fun find2(): Any? {
22
fun visit(element: Any) {
3-
<!RETURN_NOT_ALLOWED!>return@find2 element<!>
3+
<!RETURN_NOT_ALLOWED!>return@find2<!> element
44
}
55
return null
66
}
@@ -10,23 +10,23 @@ fun find2(): Any? {
1010
fun find(): Any? {
1111
object : Any() {
1212
fun visit(element: Any) {
13-
<!RETURN_NOT_ALLOWED!>return@find element<!>
13+
<!RETURN_NOT_ALLOWED!>return@find<!> element
1414
}
1515
}
1616
return null
1717
}
1818

1919
fun find4(): Any? {
2020
<!NOT_YET_SUPPORTED_IN_INLINE!>inline fun visit(element: Any) {
21-
<!RETURN_NOT_ALLOWED!>return@find4 element<!>
21+
<!RETURN_NOT_ALLOWED!>return@find4<!> element
2222
}<!>
2323
return null
2424
}
2525

2626
fun find3(): Any? {
2727
object : Any() {
2828
<!NOTHING_TO_INLINE!>inline<!> fun visit(element: Any) {
29-
<!RETURN_NOT_ALLOWED!>return@find3 element<!>
29+
<!RETURN_NOT_ALLOWED!>return@find3<!> element
3030
}
3131
}
3232
return null

compiler/testData/diagnostics/tests/controlStructures/kt799.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,9 @@ fun test() {
1212
doSmth(if (true) 3 else return, <!TOO_MANY_ARGUMENTS!>1<!>)
1313
}
1414

15-
val a : Nothing = <!RETURN_NOT_ALLOWED!>return 1<!>
15+
val a : Nothing = <!RETURN_NOT_ALLOWED!>return<!> 1
1616

17-
val b = <!RETURN_NOT_ALLOWED!>return 1<!>
17+
val b = <!RETURN_NOT_ALLOWED!>return<!> 1
1818

1919
val c = doSmth(if (true) 3 else <!RETURN_NOT_ALLOWED!>return<!>)
2020

compiler/testData/diagnostics/tests/declarationChecks/ScalaLikeNamedFun.kt

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,34 @@
11
// !DIAGNOSTICS: -UNUSED_PARAMETER -UNUSED_VARIABLE
22
// KT-5068 Add special error for scala-like syntax 'fun foo(): Int = { 1 }'
33

4-
fun test1(): Int = <!TYPE_MISMATCH_DUE_TO_EQUALS_LAMBDA_IN_FUN!>{ <!RETURN_NOT_ALLOWED!>return 1<!> }<!>
4+
fun test1(): Int = <!TYPE_MISMATCH_DUE_TO_EQUALS_LAMBDA_IN_FUN!>{ <!RETURN_NOT_ALLOWED!>return<!> 1 }<!>
55
fun test2(): Int = <!TYPE_MISMATCH_DUE_TO_EQUALS_LAMBDA_IN_FUN!>{ 1 }<!>
6-
val test3: () -> Int = fun (): Int = <!TYPE_MISMATCH_DUE_TO_EQUALS_LAMBDA_IN_FUN!>{ <!RETURN_NOT_ALLOWED!>return 1<!> }<!>
6+
val test3: () -> Int = fun (): Int = <!TYPE_MISMATCH_DUE_TO_EQUALS_LAMBDA_IN_FUN!>{ <!RETURN_NOT_ALLOWED!>return<!> 1 }<!>
77
val test4: () -> Int = fun (): Int = <!TYPE_MISMATCH_DUE_TO_EQUALS_LAMBDA_IN_FUN!>{ 1 }<!>
88
fun test5(): Int { return <!TYPE_MISMATCH!>{ 1 }<!> }
99
fun test6(): Int = <!TYPE_MISMATCH!>fun (): Int = 1<!>
1010

1111
fun outer() {
12-
fun test1(): Int = <!TYPE_MISMATCH_DUE_TO_EQUALS_LAMBDA_IN_FUN!>{ <!RETURN_NOT_ALLOWED!>return 1<!> }<!>
12+
fun test1(): Int = <!TYPE_MISMATCH_DUE_TO_EQUALS_LAMBDA_IN_FUN!>{ <!RETURN_NOT_ALLOWED!>return<!> 1 }<!>
1313
fun test2(): Int = <!TYPE_MISMATCH_DUE_TO_EQUALS_LAMBDA_IN_FUN!>{ 1 }<!>
14-
val test3: () -> Int = fun (): Int = <!TYPE_MISMATCH_DUE_TO_EQUALS_LAMBDA_IN_FUN!>{ <!RETURN_NOT_ALLOWED!>return 1<!> }<!>
14+
val test3: () -> Int = fun (): Int = <!TYPE_MISMATCH_DUE_TO_EQUALS_LAMBDA_IN_FUN!>{ <!RETURN_NOT_ALLOWED!>return<!> 1 }<!>
1515
val test4: () -> Int = fun (): Int = <!TYPE_MISMATCH_DUE_TO_EQUALS_LAMBDA_IN_FUN!>{ 1 }<!>
1616
fun test5(): Int { return <!TYPE_MISMATCH!>{ 1 }<!> }
1717
fun test6(): Int = <!TYPE_MISMATCH!>fun (): Int = 1<!>
1818
}
1919

2020
class Outer {
21-
fun test1(): Int = <!TYPE_MISMATCH_DUE_TO_EQUALS_LAMBDA_IN_FUN!>{ <!RETURN_NOT_ALLOWED!>return 1<!> }<!>
21+
fun test1(): Int = <!TYPE_MISMATCH_DUE_TO_EQUALS_LAMBDA_IN_FUN!>{ <!RETURN_NOT_ALLOWED!>return<!> 1 }<!>
2222
fun test2(): Int = <!TYPE_MISMATCH_DUE_TO_EQUALS_LAMBDA_IN_FUN!>{ 1 }<!>
23-
val test3: () -> Int = fun (): Int = <!TYPE_MISMATCH_DUE_TO_EQUALS_LAMBDA_IN_FUN!>{ <!RETURN_NOT_ALLOWED!>return 1<!> }<!>
23+
val test3: () -> Int = fun (): Int = <!TYPE_MISMATCH_DUE_TO_EQUALS_LAMBDA_IN_FUN!>{ <!RETURN_NOT_ALLOWED!>return<!> 1 }<!>
2424
val test4: () -> Int = fun (): Int = <!TYPE_MISMATCH_DUE_TO_EQUALS_LAMBDA_IN_FUN!>{ 1 }<!>
2525
fun test5(): Int { return <!TYPE_MISMATCH!>{ 1 }<!> }
2626
fun test6(): Int = <!TYPE_MISMATCH!>fun (): Int = 1<!>
2727

2828
class Nested {
29-
fun test1(): Int = <!TYPE_MISMATCH_DUE_TO_EQUALS_LAMBDA_IN_FUN!>{ <!RETURN_NOT_ALLOWED!>return 1<!> }<!>
29+
fun test1(): Int = <!TYPE_MISMATCH_DUE_TO_EQUALS_LAMBDA_IN_FUN!>{ <!RETURN_NOT_ALLOWED!>return<!> 1 }<!>
3030
fun test2(): Int = <!TYPE_MISMATCH_DUE_TO_EQUALS_LAMBDA_IN_FUN!>{ 1 }<!>
31-
val test3: () -> Int = fun (): Int = <!TYPE_MISMATCH_DUE_TO_EQUALS_LAMBDA_IN_FUN!>{ <!RETURN_NOT_ALLOWED!>return 1<!> }<!>
31+
val test3: () -> Int = fun (): Int = <!TYPE_MISMATCH_DUE_TO_EQUALS_LAMBDA_IN_FUN!>{ <!RETURN_NOT_ALLOWED!>return<!> 1 }<!>
3232
val test4: () -> Int = fun (): Int = <!TYPE_MISMATCH_DUE_TO_EQUALS_LAMBDA_IN_FUN!>{ 1 }<!>
3333
fun test5(): Int { return <!TYPE_MISMATCH!>{ 1 }<!> }
3434
fun test6(): Int = <!TYPE_MISMATCH!>fun (): Int = 1<!>

compiler/testData/diagnostics/tests/functionLiterals/return/AutoLabelsNonLocal.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
fun f() {
22
foo {
33
bar {
4-
<!RETURN_NOT_ALLOWED!>return@foo 1<!>
4+
<!RETURN_NOT_ALLOWED!>return@foo<!> 1
55
}
66
return@foo 1
77
}

compiler/testData/diagnostics/tests/inline/nonLocalReturns/labeledReturn.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ inline fun inlineFun(s: ()->Int) {
1717
fun noInlineCall(): String {
1818
noInline {
1919
if (true) {
20-
<!RETURN_NOT_ALLOWED!>return@noInlineCall ""<!>
20+
<!RETURN_NOT_ALLOWED!>return@noInlineCall<!> ""
2121
}
2222
1
2323
}

compiler/testData/diagnostics/tests/inline/nonLocalReturns/lambdaAsGeneric.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
fun box() : String {
22
test {
3-
<!RETURN_NOT_ALLOWED!>return@box "123"<!>
3+
<!RETURN_NOT_ALLOWED!>return@box<!> "123"
44
}
55

66
return "OK"

compiler/testData/diagnostics/tests/inline/nonLocalReturns/lambdaAsNonFunction.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
fun box() : String {
22
test {
3-
<!RETURN_NOT_ALLOWED!>return@box "123"<!>
3+
<!RETURN_NOT_ALLOWED!>return@box<!> "123"
44
}
55

66
return "OK"

compiler/testData/diagnostics/tests/inline/nonLocalReturns/propertyAccessorsAndConstructor.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ inline fun <R> doCallInt(p: () -> R): R {
77
}
88

99
class A {
10-
var result: Int = doCallInt { <!RETURN_NOT_ALLOWED!>return this<!> };
10+
var result: Int = doCallInt { <!RETURN_NOT_ALLOWED!>return<!> this };
1111

1212
var field: Int
1313
get() {

compiler/testData/diagnostics/tests/labels/kt361.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ fun nonlocals(b : Boolean) {
22
a@<!UNUSED_LAMBDA_EXPRESSION!>{
33
fun foo() {
44
if (b) {
5-
<!RETURN_NOT_ALLOWED!>return@a 1<!> // The label must be resolved, but an error should be reported for a non-local return
5+
<!RETURN_NOT_ALLOWED!>return@a<!> 1 // The label must be resolved, but an error should be reported for a non-local return
66
}
77
}
88

compiler/testData/diagnostics/tests/regressions/kt411.kt

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ fun t2() : String {
2323
if (true) {
2424
return@l 1
2525
}
26-
<!RETURN_NOT_ALLOWED!>return "s"<!>
26+
<!RETURN_NOT_ALLOWED!>return<!> "s"
2727
}
2828
return "s"
2929
}
@@ -32,10 +32,10 @@ fun t3() : String {
3232
invoker(
3333
l@{
3434
if (true) {
35-
<!RETURN_NOT_ALLOWED!>return@t3 "1"<!>
35+
<!RETURN_NOT_ALLOWED!>return@t3<!> "1"
3636
}
3737
else {
38-
<!RETURN_NOT_ALLOWED!>return <!CONSTANT_EXPECTED_TYPE_MISMATCH!>2<!><!>
38+
<!RETURN_NOT_ALLOWED!>return<!> <!CONSTANT_EXPECTED_TYPE_MISMATCH!>2<!>
3939
}
4040
<!UNREACHABLE_CODE!>return@l 0<!>
4141
}
@@ -47,7 +47,7 @@ fun t3() : String {
4747
)
4848
invoker(
4949
{
50-
<!RETURN_NOT_ALLOWED!>return "0"<!>
50+
<!RETURN_NOT_ALLOWED!>return<!> "0"
5151
}
5252
)
5353
return "2"

compiler/testData/diagnostics/tests/secondaryConstructors/return.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
class A {
22
init {
33
<!RETURN_NOT_ALLOWED!>return<!>
4-
<!RETURN_NOT_ALLOWED, UNREACHABLE_CODE!>return 1<!>
4+
<!UNREACHABLE_CODE!><!RETURN_NOT_ALLOWED!>return<!> 1<!>
55
}
66
constructor() <!UNREACHABLE_CODE!>{
77
if (1 == 1) {

compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -589,6 +589,12 @@ public void testReturn() throws Exception {
589589
doTest(fileName);
590590
}
591591

592+
@TestMetadata("ReturnInFunctionWithoutBody.kt")
593+
public void testReturnInFunctionWithoutBody() throws Exception {
594+
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/ReturnInFunctionWithoutBody.kt");
595+
doTest(fileName);
596+
}
597+
592598
@TestMetadata("SafeCallInvoke.kt")
593599
public void testSafeCallInvoke() throws Exception {
594600
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/SafeCallInvoke.kt");

idea/testData/checker/FunctionReturnTypes.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@ fun blockNoReturnIfUnitInOneBranch(): Int {
131131
fun nonBlockReturnIfEmptyIf(): Int = if (1 < 2) <error>{}</error> else <error>{}</error>
132132
fun nonBlockNoReturnIfUnitInOneBranch(): Int = if (1 < 2) <error>{}</error> else 2
133133

134-
val a = <error>return 1</error>
134+
val a = <error>return</error> 1
135135

136136
class A() {
137137
}
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
<error descr="[RETURN_NOT_ALLOWED] 'return' is not allowed here">return a</error>
1+
<error descr="[RETURN_NOT_ALLOWED] 'return' is not allowed here">return</error> a
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
@file:<error descr="[UNRESOLVED_REFERENCE] Unresolved reference: suppress">suppress</error>(<error descr="[RETURN_NOT_ALLOWED] 'return' is not allowed here"><error descr="[RETURN_NOT_ALLOWED] 'return' is not allowed here">return <error descr="[UNRESOLVED_REFERENCE] Unresolved reference: a"><error descr="[UNRESOLVED_REFERENCE] Unresolved reference: a">a</error></error></error></error>)
1+
@file:<error descr="[UNRESOLVED_REFERENCE] Unresolved reference: suppress">suppress</error>(<error descr="[RETURN_NOT_ALLOWED] 'return' is not allowed here"><error descr="[RETURN_NOT_ALLOWED] 'return' is not allowed here">return</error></error> <error descr="[UNRESOLVED_REFERENCE] Unresolved reference: a"><error descr="[UNRESOLVED_REFERENCE] Unresolved reference: a">a</error></error>)

0 commit comments

Comments
 (0)