[FIR] Resolve return expressions in independent context
This commit is contained in:
+9
-3
@@ -174,10 +174,16 @@ class FirControlFlowStatementsResolveTransformer(transformer: FirBodyResolveTran
|
|||||||
// ------------------------------- Jumps -------------------------------
|
// ------------------------------- Jumps -------------------------------
|
||||||
|
|
||||||
override fun <E : FirTargetElement> transformJump(jump: FirJump<E>, data: ResolutionMode): CompositeTransformResult<FirStatement> {
|
override fun <E : FirTargetElement> transformJump(jump: FirJump<E>, data: ResolutionMode): CompositeTransformResult<FirStatement> {
|
||||||
var result = transformer.transformExpression(jump, data).single
|
val expectedTypeRef = (jump as? FirReturnExpression)?.target?.labeledElement?.returnTypeRef
|
||||||
|
|
||||||
|
val mode = if (expectedTypeRef != null) {
|
||||||
|
ResolutionMode.WithExpectedType(expectedTypeRef)
|
||||||
|
} else {
|
||||||
|
ResolutionMode.ContextIndependent
|
||||||
|
}
|
||||||
|
var result = transformer.transformExpression(jump, mode).single
|
||||||
if (result is FirReturnExpression) {
|
if (result is FirReturnExpression) {
|
||||||
val expectedType = result.target.labeledElement.returnTypeRef.coneTypeSafe<ConeKotlinType>()
|
result = result.transformResult(integerLiteralTypeApproximator, expectedTypeRef!!.coneTypeSafe())
|
||||||
result = result.transformResult(integerLiteralTypeApproximator, expectedType)
|
|
||||||
}
|
}
|
||||||
dataFlowAnalyzer.exitJump(jump)
|
dataFlowAnalyzer.exitJump(jump)
|
||||||
return result.compose()
|
return result.compose()
|
||||||
|
|||||||
@@ -0,0 +1,11 @@
|
|||||||
|
interface Box<T>
|
||||||
|
|
||||||
|
public fun <T> foo(nextFunction: (T) -> T): Box<T> = null!!
|
||||||
|
|
||||||
|
fun leaves(value: String, forward: Boolean): Box<String> {
|
||||||
|
if (forward) {
|
||||||
|
return foo { "" }
|
||||||
|
} else {
|
||||||
|
return foo { "" }
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
FILE: untouchedReturnInIf.kt
|
||||||
|
public abstract interface Box<T> : R|kotlin/Any| {
|
||||||
|
}
|
||||||
|
public final fun <T> foo(nextFunction: R|(T) -> T|): R|Box<T>| {
|
||||||
|
^foo Null(null)!!
|
||||||
|
}
|
||||||
|
public final fun leaves(value: R|kotlin/String|, forward: R|kotlin/Boolean|): R|Box<kotlin/String>| {
|
||||||
|
when () {
|
||||||
|
R|<local>/forward| -> {
|
||||||
|
^leaves R|/foo|<R|kotlin/String|>(<L> = foo@fun <anonymous>(it: R|kotlin/String|): R|kotlin/String| {
|
||||||
|
^ String()
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
else -> {
|
||||||
|
^leaves R|/foo|<R|kotlin/String|>(<L> = foo@fun <anonymous>(it: R|kotlin/String|): R|kotlin/String| {
|
||||||
|
^ String()
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
+5
-5
@@ -9,9 +9,9 @@ FILE: typesInLocalFunctions.kt
|
|||||||
lval s: R|Some| = R|/Some.Some|()
|
lval s: R|Some| = R|/Some.Some|()
|
||||||
when () {
|
when () {
|
||||||
Boolean(true) -> {
|
Boolean(true) -> {
|
||||||
^foo fun <implicit>.<anonymous>(): <implicit> {
|
^foo fun <anonymous>(): R|kotlin/Boolean| {
|
||||||
when () {
|
^ when () {
|
||||||
(s# is Some) -> {
|
(R|<local>/s| is R|Some|) -> {
|
||||||
Boolean(true)
|
Boolean(true)
|
||||||
}
|
}
|
||||||
else -> {
|
else -> {
|
||||||
@@ -23,8 +23,8 @@ FILE: typesInLocalFunctions.kt
|
|||||||
|
|
||||||
}
|
}
|
||||||
else -> {
|
else -> {
|
||||||
^foo fun <implicit>.<anonymous>(): <implicit> {
|
^foo fun <anonymous>(): R|kotlin/Boolean| {
|
||||||
Boolean(true)
|
^ Boolean(true)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
+10
-5
@@ -338,6 +338,11 @@ public class FirDiagnosticsTestGenerated extends AbstractFirDiagnosticsTest {
|
|||||||
runTest("compiler/fir/resolve/testData/resolve/typeParameterVsNested.kt");
|
runTest("compiler/fir/resolve/testData/resolve/typeParameterVsNested.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("typesInLocalFunctions.kt")
|
||||||
|
public void testTypesInLocalFunctions() throws Exception {
|
||||||
|
runTest("compiler/fir/resolve/testData/resolve/typesInLocalFunctions.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("varargInPrimaryConstructor.kt")
|
@TestMetadata("varargInPrimaryConstructor.kt")
|
||||||
public void testVarargInPrimaryConstructor() throws Exception {
|
public void testVarargInPrimaryConstructor() throws Exception {
|
||||||
runTest("compiler/fir/resolve/testData/resolve/varargInPrimaryConstructor.kt");
|
runTest("compiler/fir/resolve/testData/resolve/varargInPrimaryConstructor.kt");
|
||||||
@@ -460,6 +465,11 @@ public class FirDiagnosticsTestGenerated extends AbstractFirDiagnosticsTest {
|
|||||||
runTest("compiler/fir/resolve/testData/resolve/arguments/tryInLambda.kt");
|
runTest("compiler/fir/resolve/testData/resolve/arguments/tryInLambda.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("untouchedReturnInIf.kt")
|
||||||
|
public void testUntouchedReturnInIf() throws Exception {
|
||||||
|
runTest("compiler/fir/resolve/testData/resolve/arguments/untouchedReturnInIf.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("vararg.kt")
|
@TestMetadata("vararg.kt")
|
||||||
public void testVararg() throws Exception {
|
public void testVararg() throws Exception {
|
||||||
runTest("compiler/fir/resolve/testData/resolve/arguments/vararg.kt");
|
runTest("compiler/fir/resolve/testData/resolve/arguments/vararg.kt");
|
||||||
@@ -1361,11 +1371,6 @@ public class FirDiagnosticsTestGenerated extends AbstractFirDiagnosticsTest {
|
|||||||
public void testJavaAccessorConversion() throws Exception {
|
public void testJavaAccessorConversion() throws Exception {
|
||||||
runTest("compiler/fir/resolve/testData/resolve/problems/javaAccessorConversion.kt");
|
runTest("compiler/fir/resolve/testData/resolve/problems/javaAccessorConversion.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
@TestMetadata("typesInLocalFunctions.kt")
|
|
||||||
public void testTypesInLocalFunctions() throws Exception {
|
|
||||||
runTest("compiler/fir/resolve/testData/resolve/problems/typesInLocalFunctions.kt");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@TestMetadata("compiler/fir/resolve/testData/resolve/references")
|
@TestMetadata("compiler/fir/resolve/testData/resolve/references")
|
||||||
|
|||||||
Generated
+10
-5
@@ -338,6 +338,11 @@ public class FirDiagnosticsWithLightTreeTestGenerated extends AbstractFirDiagnos
|
|||||||
runTest("compiler/fir/resolve/testData/resolve/typeParameterVsNested.kt");
|
runTest("compiler/fir/resolve/testData/resolve/typeParameterVsNested.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("typesInLocalFunctions.kt")
|
||||||
|
public void testTypesInLocalFunctions() throws Exception {
|
||||||
|
runTest("compiler/fir/resolve/testData/resolve/typesInLocalFunctions.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("varargInPrimaryConstructor.kt")
|
@TestMetadata("varargInPrimaryConstructor.kt")
|
||||||
public void testVarargInPrimaryConstructor() throws Exception {
|
public void testVarargInPrimaryConstructor() throws Exception {
|
||||||
runTest("compiler/fir/resolve/testData/resolve/varargInPrimaryConstructor.kt");
|
runTest("compiler/fir/resolve/testData/resolve/varargInPrimaryConstructor.kt");
|
||||||
@@ -460,6 +465,11 @@ public class FirDiagnosticsWithLightTreeTestGenerated extends AbstractFirDiagnos
|
|||||||
runTest("compiler/fir/resolve/testData/resolve/arguments/tryInLambda.kt");
|
runTest("compiler/fir/resolve/testData/resolve/arguments/tryInLambda.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("untouchedReturnInIf.kt")
|
||||||
|
public void testUntouchedReturnInIf() throws Exception {
|
||||||
|
runTest("compiler/fir/resolve/testData/resolve/arguments/untouchedReturnInIf.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("vararg.kt")
|
@TestMetadata("vararg.kt")
|
||||||
public void testVararg() throws Exception {
|
public void testVararg() throws Exception {
|
||||||
runTest("compiler/fir/resolve/testData/resolve/arguments/vararg.kt");
|
runTest("compiler/fir/resolve/testData/resolve/arguments/vararg.kt");
|
||||||
@@ -1361,11 +1371,6 @@ public class FirDiagnosticsWithLightTreeTestGenerated extends AbstractFirDiagnos
|
|||||||
public void testJavaAccessorConversion() throws Exception {
|
public void testJavaAccessorConversion() throws Exception {
|
||||||
runTest("compiler/fir/resolve/testData/resolve/problems/javaAccessorConversion.kt");
|
runTest("compiler/fir/resolve/testData/resolve/problems/javaAccessorConversion.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
@TestMetadata("typesInLocalFunctions.kt")
|
|
||||||
public void testTypesInLocalFunctions() throws Exception {
|
|
||||||
runTest("compiler/fir/resolve/testData/resolve/problems/typesInLocalFunctions.kt");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@TestMetadata("compiler/fir/resolve/testData/resolve/references")
|
@TestMetadata("compiler/fir/resolve/testData/resolve/references")
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ fun main(x: Inv<Int>) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
foo1 {
|
foo1 {
|
||||||
if (x.hashCode() == 0) return@foo1 <!UNRESOLVED_REFERENCE!>::bar<!>
|
if (x.hashCode() == 0) return@foo1 ::bar
|
||||||
|
|
||||||
::bar
|
::bar
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user