diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/InferenceUtils.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/InferenceUtils.kt index c95a158e7d5..afe9c783316 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/InferenceUtils.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/InferenceUtils.kt @@ -12,6 +12,7 @@ import org.jetbrains.kotlin.fir.declarations.FirClass import org.jetbrains.kotlin.fir.diagnostics.ConeSimpleDiagnostic import org.jetbrains.kotlin.fir.diagnostics.DiagnosticKind import org.jetbrains.kotlin.fir.expressions.FirReturnExpression +import org.jetbrains.kotlin.fir.expressions.impl.FirUnitExpression import org.jetbrains.kotlin.fir.resolve.* import org.jetbrains.kotlin.fir.resolve.calls.Candidate import org.jetbrains.kotlin.fir.scopes.FakeOverrideTypeCalculator @@ -249,15 +250,15 @@ fun extractLambdaInfoFromFunctionalType( } if (!expectedType.isBuiltinFunctionalType(session)) return null - val lastStatement = argument.body?.statements?.singleOrNull() - val returnType = + val singleStatement = argument.body?.statements?.singleOrNull() as? FirReturnExpression + if (argument.returnType == null && singleStatement != null && + singleStatement.target.labeledElement == argument && singleStatement.result is FirUnitExpression + ) { // Simply { }, i.e., function literals without body. Raw FIR added an implicit return with an implicit unit type ref. - if (lastStatement?.source?.kind is FirFakeSourceElementKind.ImplicitReturn && - (lastStatement as? FirReturnExpression)?.result?.source?.kind is FirFakeSourceElementKind.ImplicitUnit - ) - session.builtinTypes.unitType.type - else - argument.returnType ?: expectedType.returnType(session) + argument.replaceReturnTypeRef(session.builtinTypes.unitType) + } + val returnType = argument.returnType ?: expectedType.returnType(session) + // `fun (x: T) = ...` and `fun T.() = ...` are both instances of `T.() -> V` and `(T) -> V`; `fun () = ...` is not. // For lambdas, the existence of the receiver is always implied by the expected type, and a value parameter // can never fill its role. @@ -269,8 +270,11 @@ fun extractLambdaInfoFromFunctionalType( expectedParameters // Infer existence of a parameter named `it` of an appropriate type. } else { argument.valueParameters.mapIndexed { index, parameter -> - parameter.returnTypeRef.coneTypeSafe() ?: expectedParameters.getOrNull(index) - ?: ConeClassErrorType(ConeSimpleDiagnostic("Cannot infer type for parameter ${parameter.name}", DiagnosticKind.CannotInferParameterType)) + parameter.returnTypeRef.coneTypeSafe() + ?: expectedParameters.getOrNull(index) + ?: ConeClassErrorType( + ConeSimpleDiagnostic("Cannot infer type for parameter ${parameter.name}", DiagnosticKind.CannotInferParameterType) + ) } } diff --git a/compiler/testData/diagnostics/tests/regressions/kt32792.fir.kt b/compiler/testData/diagnostics/tests/regressions/kt32792.fir.kt index bac2704f7c3..25f2174d30d 100644 --- a/compiler/testData/diagnostics/tests/regressions/kt32792.fir.kt +++ b/compiler/testData/diagnostics/tests/regressions/kt32792.fir.kt @@ -4,7 +4,7 @@ inline fun tryLambdas(lamb : () -> T) : T{ return lamb.invoke() } fun main() { - tryLambdas { + tryLambdas { return@tryLambdas } } \ No newline at end of file