Skip to content

Commit

Permalink
[FIR] Unwrap blocks in the list of return expression of lambdas
Browse files Browse the repository at this point in the history
If lambda contains destructuring parameters we generate the body of lambda
  in the separate block as the last statement of lambda body. This block
  should not be considered as actual return expression of the lambda

^KT-67185 Fixed
  • Loading branch information
demiurg906 committed Apr 7, 2024
1 parent 96a6e53 commit 84eb2dd
Show file tree
Hide file tree
Showing 24 changed files with 158 additions and 2 deletions.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Expand Up @@ -101,7 +101,7 @@ class ControlFlowGraphBuilder {
// lambda@{ x } -> x
// lambda@{ class C } -> Unit-returning stub
function.isLambda -> {
val lastStatement = fir.statements.lastOrNull()
val lastStatement = function.lastStatement()

when {
// Skip last return statement because otherwise it add Nothing constraint on the lambda return type.
Expand Down Expand Up @@ -1619,3 +1619,18 @@ val FirControlFlowGraphOwner.isUsedInControlFlowGraphBuilderForScript: Boolean
@OptIn(UnresolvedExpressionTypeAccess::class)
private val FirExpression.hasNothingType: Boolean
get() = coneTypeOrNull?.isNothing == true

fun FirAnonymousFunction.lastStatement(): FirStatement? {
val last = this.body?.statements?.lastOrNull() ?: return null

fun FirStatement.unwrapBlocks(): FirStatement {
return when (this) {
is FirBlock -> statements.lastOrNull()?.unwrapBlocks() ?: this
else -> this
}
}

return last.unwrapBlocks()
}


Expand Up @@ -11,6 +11,7 @@ import org.jetbrains.kotlin.fir.lookupTracker
import org.jetbrains.kotlin.fir.recordTypeResolveAsLookup
import org.jetbrains.kotlin.fir.references.builder.buildErrorNamedReference
import org.jetbrains.kotlin.fir.resolve.calls.*
import org.jetbrains.kotlin.fir.resolve.dfa.cfg.lastStatement
import org.jetbrains.kotlin.fir.resolve.diagnostics.ConeUnresolvedReferenceError
import org.jetbrains.kotlin.fir.resolve.inference.model.ConeLambdaArgumentConstraintPosition
import org.jetbrains.kotlin.fir.resolve.shouldReturnUnit
Expand Down Expand Up @@ -180,7 +181,7 @@ class PostponedArgumentsAnalyzer(
val checkerSink: CheckerSink = CheckerSinkImpl(candidate)
val builder = c.getBuilder()

val lastExpression = lambda.atom.body?.statements?.lastOrNull() as? FirExpression
val lastExpression = lambda.atom.lastStatement() as? FirExpression
var hasExpressionInReturnArguments = false
val returnTypeRef = lambda.atom.returnTypeRef.let {
it as? FirResolvedTypeRef ?: it.resolvedTypeFromPrototype(substitute(lambda.returnType))
Expand Down
@@ -0,0 +1,15 @@
// ISSUE: KT-67185
// WITH_STDLIB

fun noop() {}

fun foo(list: List<Pair<String, String>>) {
list.map { (a, b) -> { noop() } }
.forEach { it() }
}

fun box(): String {
val list = listOf("a" to "b", "c" to "")
foo(list)
return "OK"
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 84eb2dd

Please sign in to comment.