From 64c7ab13023e56d6d7d3d51515dc657bf2952867 Mon Sep 17 00:00:00 2001 From: Mikhail Glukhikh Date: Tue, 4 Feb 2020 10:14:34 +0300 Subject: [PATCH] [FIR] Fix lambda resolve in independent context --- .../FirDeclarationsResolveTransformer.kt | 13 +++++----- .../testData/resolve/expresssions/lambda.kt | 5 ++++ .../testData/resolve/expresssions/lambda.txt | 9 +++++++ .../tests/FunctionCalleeExpressions.fir.kt | 12 +++++----- .../blockLevelOnTheSameLineWarning.fir.kt | 2 +- .../tests/controlStructures/emptyIf.fir.kt | 2 +- .../improperElseInExpression.fir.kt | 16 ++++++------- .../controlStructures/redundantLabel.fir.kt | 4 ++-- .../tests/exposed/internalFromLocal.fir.kt | 4 ++-- .../tests/exposed/privateFromLocal.fir.kt | 4 ++-- .../tests/functionLiterals/kt16016.fir.kt | 4 ++-- .../inference/invokeLambdaAsFunction.fir.kt | 8 +++---- .../tests/inference/kt12399.fir.kt | 2 +- .../diagnostics/tests/inline/capture.fir.kt | 24 +++++++++---------- .../nonLocalReturns/noInlineLambda.fir.kt | 8 +++---- .../tests/inline/wrongUsage.fir.kt | 8 +++---- .../tests/smartCasts/lambdaCall.fir.kt | 4 ++-- .../smartCasts/lambdaCallAnnotated.fir.kt | 4 ++-- .../experimental/topLevel.fir.kt | 4 ++-- 19 files changed, 75 insertions(+), 62 deletions(-) diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirDeclarationsResolveTransformer.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirDeclarationsResolveTransformer.kt index 2e45f67c170..257ee59c4d3 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirDeclarationsResolveTransformer.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirDeclarationsResolveTransformer.kt @@ -25,6 +25,7 @@ import org.jetbrains.kotlin.fir.scopes.impl.FirMemberTypeParameterScope import org.jetbrains.kotlin.fir.symbols.impl.FirVariableSymbol import org.jetbrains.kotlin.fir.types.* import org.jetbrains.kotlin.fir.types.impl.FirErrorTypeRefImpl +import org.jetbrains.kotlin.fir.types.impl.FirImplicitTypeRefImpl import org.jetbrains.kotlin.fir.types.impl.FirResolvedTypeRefImpl import org.jetbrains.kotlin.fir.visitors.CompositeTransformResult import org.jetbrains.kotlin.fir.visitors.FirTransformer @@ -410,8 +411,9 @@ class FirDeclarationsResolveTransformer(transformer: FirBodyResolveTransformer) is ResolutionMode.LambdaResolution -> { transformAnonymousFunctionWithLambdaResolution(anonymousFunction, data).compose() } - is ResolutionMode.WithExpectedType -> { - val resolvedLambdaAtom = (data.expectedTypeRef as? FirResolvedTypeRef)?.let { + is ResolutionMode.WithExpectedType, is ResolutionMode.ContextIndependent -> { + val expectedTypeRef = (data as? ResolutionMode.WithExpectedType)?.expectedTypeRef ?: FirImplicitTypeRefImpl(null) + val resolvedLambdaAtom = (expectedTypeRef as? FirResolvedTypeRef)?.let { extractLambdaInfoFromFunctionalType( it.type, it, anonymousFunction ) @@ -467,7 +469,7 @@ class FirDeclarationsResolveTransformer(transformer: FirBodyResolveTransformer) ?: af.returnTypeRef ) af = af.transformValueParameters(ImplicitToErrorTypeTransformer, null) - val bodyExpectedType = returnTypeRefFromResolvedAtom ?: data.expectedTypeRef + val bodyExpectedType = returnTypeRefFromResolvedAtom ?: expectedTypeRef af = transformFunction(af, withExpectedType(bodyExpectedType)).single as FirAnonymousFunction // To separate function and separate commit val writer = FirCallCompletionResultsWriterTransformer( @@ -478,15 +480,12 @@ class FirDeclarationsResolveTransformer(transformer: FirBodyResolveTransformer) integerOperatorsTypeUpdater, integerLiteralTypeApproximator ) - af.transformSingle(writer, data.expectedTypeRef.coneTypeSafe()?.toExpectedType()) + af.transformSingle(writer, expectedTypeRef.coneTypeSafe()?.toExpectedType()) val returnTypes = dataFlowAnalyzer.returnExpressionsOfAnonymousFunction(af).mapNotNull { (it as? FirExpression)?.resultType?.coneTypeUnsafe() } af.replaceReturnTypeRef(af.returnTypeRef.resolvedTypeFromPrototype(inferenceComponents.ctx.commonSuperTypeOrNull(returnTypes) ?: session.builtinTypes.unitType.coneTypeUnsafe())) af.replaceTypeRef(af.constructFunctionalTypeRef(session)) af.compose() } - ResolutionMode.ContextIndependent -> { - transformFunction(anonymousFunction, data) - } is ResolutionMode.WithStatus -> { throw AssertionError("Should not be here in WithStatus mode") } diff --git a/compiler/fir/resolve/testData/resolve/expresssions/lambda.kt b/compiler/fir/resolve/testData/resolve/expresssions/lambda.kt index 71bd7ab4784..ce2a8952974 100644 --- a/compiler/fir/resolve/testData/resolve/expresssions/lambda.kt +++ b/compiler/fir/resolve/testData/resolve/expresssions/lambda.kt @@ -8,5 +8,10 @@ fun main() { bar { "This is also test" } itIs { "this is $it test" } multipleArgs { a, b -> "This is test of $a, $b" } + + val s = { "OK" }() + + val f = { "OK" } + val ss = f.invoke() } diff --git a/compiler/fir/resolve/testData/resolve/expresssions/lambda.txt b/compiler/fir/resolve/testData/resolve/expresssions/lambda.txt index 923c762b823..66cd4b9db63 100644 --- a/compiler/fir/resolve/testData/resolve/expresssions/lambda.txt +++ b/compiler/fir/resolve/testData/resolve/expresssions/lambda.txt @@ -24,4 +24,13 @@ FILE: lambda.kt (String(This is test of ), R|/a|.R|kotlin/Any.toString|(), String(, ), R|/b|.R|kotlin/Any.toString|()) } ) + lval s: R|kotlin/String| = fun (): R|kotlin/String| { + String(OK) + } + .R|FakeOverride|() + lval f: R|() -> kotlin/String| = fun (): R|kotlin/String| { + String(OK) + } + + lval ss: R|kotlin/String| = R|/f|.R|FakeOverride|() } diff --git a/compiler/testData/diagnostics/tests/FunctionCalleeExpressions.fir.kt b/compiler/testData/diagnostics/tests/FunctionCalleeExpressions.fir.kt index ba26cc68507..f0c9784cb3f 100644 --- a/compiler/testData/diagnostics/tests/FunctionCalleeExpressions.fir.kt +++ b/compiler/testData/diagnostics/tests/FunctionCalleeExpressions.fir.kt @@ -56,10 +56,10 @@ fun f() : Int.() -> Unit = {} fun main1() { 1.(fun Int.() = 1)(); - {1}(); - (fun (x : Int) = x)(1) + {1}(); + (fun (x : Int) = x)(1) 1.(fun Int.(x : Int) = x)(1); - l@{1}() + l@{1}() 1.((fun Int.() = 1))() 1.(f())() 1.if(true){f()}else{f()}() @@ -73,12 +73,12 @@ fun main1() { } fun test() { - {x : Int -> 1}(); - (fun Int.() = 1)() + {x : Int -> 1}(); + (fun Int.() = 1)() "sd".(fun Int.() = 1)() val i : Int? = null i.(fun Int.() = 1)(); - {}() + {}() 1?.(fun Int.() = 1)() 1.{}() } diff --git a/compiler/testData/diagnostics/tests/annotations/blockLevelOnTheSameLineWarning.fir.kt b/compiler/testData/diagnostics/tests/annotations/blockLevelOnTheSameLineWarning.fir.kt index 467dbcb69f2..0f3f23c24b9 100644 --- a/compiler/testData/diagnostics/tests/annotations/blockLevelOnTheSameLineWarning.fir.kt +++ b/compiler/testData/diagnostics/tests/annotations/blockLevelOnTheSameLineWarning.fir.kt @@ -34,7 +34,7 @@ fun foo(y: IntArray) { @Ann1 y[0] @Ann1 { x: Int -> x } - @Ann1 { x: Int -> x }(1) + @Ann1 { x: Int -> x }(1) @Ann1 object { fun foo() = 1 } @Ann1 object { fun foo() = 1 }.foo() diff --git a/compiler/testData/diagnostics/tests/controlStructures/emptyIf.fir.kt b/compiler/testData/diagnostics/tests/controlStructures/emptyIf.fir.kt index 761a023dac8..5da2c7adbbe 100644 --- a/compiler/testData/diagnostics/tests/controlStructures/emptyIf.fir.kt +++ b/compiler/testData/diagnostics/tests/controlStructures/emptyIf.fir.kt @@ -10,7 +10,7 @@ fun test() { val y: Unit = if (false); foo(y) - foo({if (1==1);}()) + foo({if (1==1);}()) return if (true); } \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/controlStructures/improperElseInExpression.fir.kt b/compiler/testData/diagnostics/tests/controlStructures/improperElseInExpression.fir.kt index b5d318da51f..37264a2ff93 100644 --- a/compiler/testData/diagnostics/tests/controlStructures/improperElseInExpression.fir.kt +++ b/compiler/testData/diagnostics/tests/controlStructures/improperElseInExpression.fir.kt @@ -9,22 +9,22 @@ fun example() { val e = if (true) {} else false val f = if (true) true else {} - { + { if (true) true - }(); + }(); - { + { if (true) true else false - }(); + }(); - { + { if (true) {} else false - }(); + }(); - { + { if (true) true else {} - }() + }() fun t(): Boolean { return if (true) true diff --git a/compiler/testData/diagnostics/tests/controlStructures/redundantLabel.fir.kt b/compiler/testData/diagnostics/tests/controlStructures/redundantLabel.fir.kt index 84449239afa..1b23784d271 100644 --- a/compiler/testData/diagnostics/tests/controlStructures/redundantLabel.fir.kt +++ b/compiler/testData/diagnostics/tests/controlStructures/redundantLabel.fir.kt @@ -10,9 +10,9 @@ fun testAnnotatedLambdaLabel() = lambda@ @Ann {} fun testParenthesizedLambdaLabel() = lambda@ ( {} ) -fun testLabelBoundToInvokeOperatorExpression() = l@ { 42 }() +fun testLabelBoundToInvokeOperatorExpression() = l@ { 42 }() -fun testLabelBoundToLambda() = (l@ { 42 })() +fun testLabelBoundToLambda() = (l@ { 42 })() fun testWhileLoopLabel() { L@ while (true) {} diff --git a/compiler/testData/diagnostics/tests/exposed/internalFromLocal.fir.kt b/compiler/testData/diagnostics/tests/exposed/internalFromLocal.fir.kt index b1481169882..6becf4d98cb 100644 --- a/compiler/testData/diagnostics/tests/exposed/internalFromLocal.fir.kt +++ b/compiler/testData/diagnostics/tests/exposed/internalFromLocal.fir.kt @@ -3,8 +3,8 @@ interface Your class My { internal val x = object : Your {} - internal fun foo() = { + internal fun foo() = { class Local Local() - }() + }() } \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/exposed/privateFromLocal.fir.kt b/compiler/testData/diagnostics/tests/exposed/privateFromLocal.fir.kt index 418bbfef433..73d344637d5 100644 --- a/compiler/testData/diagnostics/tests/exposed/privateFromLocal.fir.kt +++ b/compiler/testData/diagnostics/tests/exposed/privateFromLocal.fir.kt @@ -5,8 +5,8 @@ class My { private val x = object : Your {} // private from local: ??? - private fun foo() = { + private fun foo() = { class Local Local() - }() + }() } \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/functionLiterals/kt16016.fir.kt b/compiler/testData/diagnostics/tests/functionLiterals/kt16016.fir.kt index 8cf79ac6dfc..356cd30d48e 100644 --- a/compiler/testData/diagnostics/tests/functionLiterals/kt16016.fir.kt +++ b/compiler/testData/diagnostics/tests/functionLiterals/kt16016.fir.kt @@ -2,5 +2,5 @@ val la = { a -> } val las = { a: Int -> } -val larg = { a -> }(123) -val twoarg = { a, b: String, c -> }(123, "asdf", 123) \ No newline at end of file +val larg = { a -> }(123) +val twoarg = { a, b: String, c -> }(123, "asdf", 123) \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/inference/invokeLambdaAsFunction.fir.kt b/compiler/testData/diagnostics/tests/inference/invokeLambdaAsFunction.fir.kt index 5bdbf9a10cb..7d238420de8 100644 --- a/compiler/testData/diagnostics/tests/inference/invokeLambdaAsFunction.fir.kt +++ b/compiler/testData/diagnostics/tests/inference/invokeLambdaAsFunction.fir.kt @@ -1,7 +1,7 @@ -fun test1(i: Int) = { i -> +fun test1(i: Int) = { i -> i -}(i) +}(i) -fun test2() = { i -> i }() +fun test2() = { i -> i }() -fun test3() = { i -> i }(1) \ No newline at end of file +fun test3() = { i -> i }(1) \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/inference/kt12399.fir.kt b/compiler/testData/diagnostics/tests/inference/kt12399.fir.kt index 7bd744df578..216665dfc7e 100644 --- a/compiler/testData/diagnostics/tests/inference/kt12399.fir.kt +++ b/compiler/testData/diagnostics/tests/inference/kt12399.fir.kt @@ -1,3 +1,3 @@ fun foo(a: Any) { - foo({ index -> } { }) + foo({ index -> } { }) } \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/inline/capture.fir.kt b/compiler/testData/diagnostics/tests/inline/capture.fir.kt index 57dbe1cc45f..18680133bd5 100644 --- a/compiler/testData/diagnostics/tests/inline/capture.fir.kt +++ b/compiler/testData/diagnostics/tests/inline/capture.fir.kt @@ -3,49 +3,49 @@ infix fun Function1.noInlineExt(p: Int) {} inline infix fun Function1.inlineExt2(p: Int) { - { + { noInlineExt(11) this.noInlineExt(11) this noInlineExt 11 this - }() + }() } inline fun Function1.inlineExt() { - { + { inlineExt2(1) this.inlineExt2(1) this inlineExt2 1 this(11) - }() + }() } inline fun inlineFunWithInvoke(s: (p: Int) -> Unit) { - { + { s(11) s.invoke(11) s invoke 11 - }() + }() } inline fun inlineFunWithInvokeNonInline(noinline s: (p: Int) -> Unit) { - { + { s(11) s.invoke(11) s invoke 11 - }() + }() } inline fun testExtension(s: (p: Int) -> Unit) { - { + { s.inlineExt() - } () + } () } inline fun inlineFunWrongExtension(s: (p: Int) -> Unit) { - { + { s.noInlineExt(11) - } () + } () } \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/inline/nonLocalReturns/noInlineLambda.fir.kt b/compiler/testData/diagnostics/tests/inline/nonLocalReturns/noInlineLambda.fir.kt index bc5293f974d..24277028a18 100644 --- a/compiler/testData/diagnostics/tests/inline/nonLocalReturns/noInlineLambda.fir.kt +++ b/compiler/testData/diagnostics/tests/inline/nonLocalReturns/noInlineLambda.fir.kt @@ -1,13 +1,13 @@ // !DIAGNOSTICS: -UNUSED_EXPRESSION -UNUSED_PARAMETER -UNUSED_VARIABLE -NOTHING_TO_INLINE inline fun inlineFunOnlyLocal(crossinline p: () -> R) { - { + { p() - }() + }() } inline fun inlineFun(p: () -> R) { - { + { p() - }() + }() } diff --git a/compiler/testData/diagnostics/tests/inline/wrongUsage.fir.kt b/compiler/testData/diagnostics/tests/inline/wrongUsage.fir.kt index c2ca220a4b9..a74451dc5ce 100644 --- a/compiler/testData/diagnostics/tests/inline/wrongUsage.fir.kt +++ b/compiler/testData/diagnostics/tests/inline/wrongUsage.fir.kt @@ -17,23 +17,23 @@ inline fun inlineFunWrongUsageExt(ext: Int.(p: Int) -> Unit) { } inline fun inlineFunWrongUsageInClosure(s: (p: Int) -> Unit) { - { + { s if (true) s else 0 s ?: s - }() + }() } inline fun inlineFunWrongUsageInClosureExt(ext: Int.(p: Int) -> Unit) { - { + { ext if (true) ext else 0 ext ?: ext - }() + }() } inline fun inlineFunNoInline(noinline s: (p: Int) -> Unit) { diff --git a/compiler/testData/diagnostics/tests/smartCasts/lambdaCall.fir.kt b/compiler/testData/diagnostics/tests/smartCasts/lambdaCall.fir.kt index 0f0616ed0e9..144891faa3d 100644 --- a/compiler/testData/diagnostics/tests/smartCasts/lambdaCall.fir.kt +++ b/compiler/testData/diagnostics/tests/smartCasts/lambdaCall.fir.kt @@ -1,6 +1,6 @@ // See KT-9134: smart cast is not provided inside lambda call -fun bar(): Int = { +fun bar(): Int = { var i: Int? i = 42 i -}() \ No newline at end of file +}() \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/smartCasts/lambdaCallAnnotated.fir.kt b/compiler/testData/diagnostics/tests/smartCasts/lambdaCallAnnotated.fir.kt index 14f7ab96fe5..f10ea900537 100644 --- a/compiler/testData/diagnostics/tests/smartCasts/lambdaCallAnnotated.fir.kt +++ b/compiler/testData/diagnostics/tests/smartCasts/lambdaCallAnnotated.fir.kt @@ -4,8 +4,8 @@ @Retention(AnnotationRetention.SOURCE) annotation class My -fun bar(): Int = @My { +fun bar(): Int = @My { var i: Int? i = 42 i -}() \ No newline at end of file +}() \ No newline at end of file diff --git a/compiler/testData/diagnostics/testsWithStdLib/experimental/topLevel.fir.kt b/compiler/testData/diagnostics/testsWithStdLib/experimental/topLevel.fir.kt index cdd4daa6d13..f0c00e916e4 100644 --- a/compiler/testData/diagnostics/testsWithStdLib/experimental/topLevel.fir.kt +++ b/compiler/testData/diagnostics/testsWithStdLib/experimental/topLevel.fir.kt @@ -48,11 +48,11 @@ import api.* fun useAll() { @OptIn(ExperimentalAPI::class) - { + { function() property val s: Typealias = "" - }() + }() } @OptIn(ExperimentalAPI::class)