WIP
diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/collectors/components/ErrorNodeDiagnosticCollectorComponent.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/collectors/components/ErrorNodeDiagnosticCollectorComponent.kt
index 591b9a4..ea70bda 100644
--- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/collectors/components/ErrorNodeDiagnosticCollectorComponent.kt
+++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/collectors/components/ErrorNodeDiagnosticCollectorComponent.kt
@@ -181,6 +181,16 @@
         reportFirDiagnostic(diagnostic, source, data)
     }
 
+    override fun visitAnonymousFunction(
+        anonymousFunction: FirAnonymousFunction,
+        data: CheckerContext,
+    ) {
+        val diagnostic = anonymousFunction.diagnostic ?: return
+        val source = anonymousFunction.source
+
+        reportFirDiagnostic(diagnostic, source, data)
+    }
+
     private fun reportFirDiagnostic(
         diagnostic: ConeDiagnostic,
         source: KtSourceElement?,
diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/coneDiagnosticToFirDiagnostic.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/coneDiagnosticToFirDiagnostic.kt
index 600c25a..4fe0c3f 100644
--- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/coneDiagnosticToFirDiagnostic.kt
+++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/coneDiagnosticToFirDiagnostic.kt
@@ -17,6 +17,7 @@
 import org.jetbrains.kotlin.fir.analysis.checkers.projectionKindAsString
 import org.jetbrains.kotlin.fir.analysis.getChild
 import org.jetbrains.kotlin.fir.builder.FirSyntaxErrors
+import org.jetbrains.kotlin.fir.declarations.FirAnonymousFunction
 import org.jetbrains.kotlin.fir.declarations.utils.*
 import org.jetbrains.kotlin.fir.diagnostics.*
 import org.jetbrains.kotlin.fir.expressions.*
@@ -168,7 +169,10 @@
 
     is ConeDestructuringDeclarationsOnTopLevel -> null // TODO Currently a parsing error. Would be better to report here instead KT-58563
     is ConeCannotInferTypeParameterType -> FirErrors.CANNOT_INFER_PARAMETER_TYPE.createOn(source)
-    is ConeCannotInferValueParameterType -> FirErrors.CANNOT_INFER_PARAMETER_TYPE.createOn(source)
+    is ConeCannotInferValueParameterType -> when {
+        isTopLevelLambda -> FirErrors.VALUE_PARAMETER_WITHOUT_EXPLICIT_TYPE.createOn(source)
+        else -> FirErrors.CANNOT_INFER_PARAMETER_TYPE.createOn(source)
+    }
     is ConeCannotInferReceiverParameterType -> FirErrors.CANNOT_INFER_PARAMETER_TYPE.createOn(source)
     is ConeTypeVariableTypeIsNotInferred -> FirErrors.INFERENCE_ERROR.createOn(callOrAssignmentSource ?: source)
     is ConeInstanceAccessBeforeSuperCall -> FirErrors.INSTANCE_ACCESS_BEFORE_SUPER_CALL.createOn(source, this.target)
@@ -316,7 +320,8 @@
                         rootCause.actualType.removeTypeVariableTypes(typeContext)
                     },
                     isMismatchDueToNullability = rootCause.isMismatchDueToNullability,
-                    candidate = diagnostic.candidate
+                    candidate = diagnostic.candidate,
+                    rootCause.returnExpressionForLambda,
                 )
             }
 
@@ -450,30 +455,38 @@
     actualType: ConeKotlinType,
     isMismatchDueToNullability: Boolean,
     candidate: AbstractCallCandidate<*>,
+    returnExpressionForLambda: FirAnonymousFunction?,
 ): KtDiagnostic {
     val symbol = candidate.symbol as FirCallableSymbol
     val receiverType = (candidate.chosenExtensionReceiver ?: candidate.dispatchReceiver)?.expression?.resolvedType
 
-    return if (expectedType is ConeCapturedType &&
-        expectedType.constructor.projection.kind.let { it == ProjectionKind.OUT || it == ProjectionKind.STAR } &&
-        receiverType != null &&
-        // Ensure we report an actual argument type mismatch of the candidate and not a lambda return expression
-        candidate.argumentMapping.keys.any { it.expression.source == source }
-    ) {
-        FirErrors.MEMBER_PROJECTED_OUT.createOn(
-            source,
-            receiverType,
-            expectedType.projectionKindAsString(),
-            symbol.originalOrSelf(),
-        )
-    } else {
-        FirErrors.ARGUMENT_TYPE_MISMATCH.createOn(
-            source,
-            expectedType,
-            // For lambda expressions, use their resolved type because `rootCause.actualType` can contain unresolved types
-            actualType,
-            isMismatchDueToNullability
-        )
+    return when {
+        returnExpressionForLambda != null ->
+            FirErrors.RETURN_TYPE_MISMATCH.createOn(
+                source, expectedType, actualType, returnExpressionForLambda, isMismatchDueToNullability
+            )
+        expectedType is ConeCapturedType &&
+                expectedType.constructor.projection.kind.let { it == ProjectionKind.OUT || it == ProjectionKind.STAR } &&
+                receiverType != null &&
+                // Ensure we report an actual argument type mismatch of the candidate and not a lambda return expression
+                candidate.argumentMapping.keys.any { it.expression.source == source }
+            -> {
+            FirErrors.MEMBER_PROJECTED_OUT.createOn(
+                source,
+                receiverType,
+                expectedType.projectionKindAsString(),
+                symbol.originalOrSelf(),
+            )
+        }
+        else -> {
+            FirErrors.ARGUMENT_TYPE_MISMATCH.createOn(
+                source,
+                expectedType,
+                // For lambda expressions, use their resolved type because `rootCause.actualType` can contain unresolved types
+                actualType,
+                isMismatchDueToNullability
+            )
+        }
     }
 }
 
@@ -564,7 +577,8 @@
                     expectedType = lowerConeType.removeTypeVariableTypes(typeContext),
                     actualType = upperConeType.removeTypeVariableTypes(typeContext),
                     isMismatchDueToNullability = typeMismatchDueToNullability,
-                    candidate = candidate
+                    candidate = candidate,
+                    (position as? ConeLambdaArgumentConstraintPosition)?.lambda,
                 )
             }
 
diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/stages/ArgumentCheckingProcessor.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/stages/ArgumentCheckingProcessor.kt
index e8b132e..8f73e60 100644
--- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/stages/ArgumentCheckingProcessor.kt
+++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/stages/ArgumentCheckingProcessor.kt
@@ -9,6 +9,7 @@
 import org.jetbrains.kotlin.builtins.functions.FunctionTypeKind
 import org.jetbrains.kotlin.builtins.functions.isBasicFunctionOrKFunction
 import org.jetbrains.kotlin.fir.FirSession
+import org.jetbrains.kotlin.fir.declarations.FirAnonymousFunction
 import org.jetbrains.kotlin.fir.declarations.FirDeclarationOrigin
 import org.jetbrains.kotlin.fir.expressions.*
 import org.jetbrains.kotlin.fir.resolve.calls.*
@@ -44,6 +45,7 @@
         val context: ResolutionContext,
         val isReceiver: Boolean,
         val isDispatch: Boolean,
+        val returnExpressionForLambda: FirAnonymousFunction? = null,
     ) {
         val session: FirSession
             get() = context.session
@@ -62,9 +64,13 @@
         sink: CheckerSink,
         context: ResolutionContext,
         isReceiver: Boolean,
-        isDispatch: Boolean
+        isDispatch: Boolean,
+        returnExpressionForLambda: FirAnonymousFunction? = null,
     ) {
-        val argumentContext = ArgumentContext(candidate, candidate.csBuilder, expectedType, sink, context, isReceiver, isDispatch)
+        val argumentContext = ArgumentContext(
+            candidate, candidate.csBuilder, expectedType, sink, context, isReceiver, isDispatch,
+            returnExpressionForLambda,
+        )
         argumentContext.resolveArgumentExpression(atom)
     }
 
@@ -241,7 +247,8 @@
                 expression,
                 // Reaching here means argument types mismatch, and we want to record whether it's due to the nullability by checking a subtype
                 // relation with nullable expected type.
-                session.typeContext.isTypeMismatchDueToNullability(argumentType, actualExpectedType)
+                session.typeContext.isTypeMismatchDueToNullability(argumentType, actualExpectedType),
+                returnExpressionForLambda,
             )
         }
 
@@ -377,7 +384,8 @@
                     reportDiagnostic(
                         ArgumentTypeMismatch(
                             expectedType, lambdaType, expression,
-                            context.session.typeContext.isTypeMismatchDueToNullability(lambdaType, expectedType)
+                            context.session.typeContext.isTypeMismatchDueToNullability(lambdaType, expectedType),
+                            returnExpressionForLambda
                         )
                     )
                 }
diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/stages/ResolutionStages.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/stages/ResolutionStages.kt
index b6f904d..2efcc00 100644
--- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/stages/ResolutionStages.kt
+++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/stages/ResolutionStages.kt
@@ -1013,7 +1013,8 @@
                     expectedType,
                     lambdaType,
                     expression,
-                    context.session.typeContext.isTypeMismatchDueToNullability(lambdaType, expectedType)
+                    context.session.typeContext.isTypeMismatchDueToNullability(lambdaType, expectedType),
+                    returnExpressionForLambda = null,
                 )
             )
         }
diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/FirCallCompleter.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/FirCallCompleter.kt
index b4b115e..cfbbdc2 100644
--- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/FirCallCompleter.kt
+++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/FirCallCompleter.kt
@@ -44,6 +44,7 @@
 import org.jetbrains.kotlin.resolve.calls.inference.addEqualityConstraintIfCompatible
 import org.jetbrains.kotlin.resolve.calls.inference.addSubtypeConstraintIfCompatible
 import org.jetbrains.kotlin.resolve.calls.inference.buildAbstractResultingSubstitutor
+import org.jetbrains.kotlin.resolve.calls.inference.buildCurrentSubstitutor
 import org.jetbrains.kotlin.resolve.calls.inference.components.ConstraintSystemCompletionMode
 import org.jetbrains.kotlin.resolve.calls.inference.model.ConstraintStorage
 import org.jetbrains.kotlin.types.TypeApproximatorConfiguration
@@ -116,15 +117,7 @@
                 val finalSubstitutor = readOnlyConstraintStorage
                     .buildAbstractResultingSubstitutor(session.typeContext) as ConeSubstitutor
                 call.transformSingle(
-                    FirCallCompletionResultsWriterTransformer(
-                        session, components.scopeSession, finalSubstitutor,
-                        components.returnTypeCalculator,
-                        session.typeApproximator,
-                        components.dataFlowAnalyzer,
-                        components.integerLiteralAndOperatorApproximationTransformer,
-                        components.samResolver,
-                        components.context,
-                    ),
+                    createCompletionResultsWriter(finalSubstitutor),
                     null
                 )
             }
@@ -134,13 +127,24 @@
 
                 inferenceSession.processPartiallyResolvedCall(call, resolutionMode, completionMode)
 
-                call
+                if (candidate.isSyntheticCallForTopLevelLambda()) {
+                    val finalSubstitutor = candidate.system.currentStorage()
+                        .buildCurrentSubstitutor(session.typeContext, emptyMap()) as ConeSubstitutor
+                    call.transformSingle(
+                        createCompletionResultsWriter(finalSubstitutor),
+                        null
+                    )
+                } else {
+                    call
+                }
             }
 
             ConstraintSystemCompletionMode.UNTIL_FIRST_LAMBDA -> throw IllegalStateException()
         }
     }
 
+    private fun Candidate.isSyntheticCallForTopLevelLambda(): Boolean = callInfo.callSite is FirAnonymousFunctionExpression
+
     private fun checkStorageConstraintsAfterFullCompletion(storage: ConstraintStorage) {
         // Fast path for sake of optimization
         if (storage.notFixedTypeVariables.isEmpty()) return
@@ -359,7 +363,7 @@
                         this.name = name
                         symbol = FirValueParameterSymbol(name)
                         returnTypeRef =
-                            itType.approximateLambdaInputType(symbol, withPCLASession).toFirResolvedTypeRef(
+                            itType.approximateLambdaInputType(symbol, withPCLASession, candidate).toFirResolvedTypeRef(
                                 lambdaAtom.anonymousFunction.source?.fakeElement(KtFakeSourceElementKind.ItLambdaParameter)
                             )
                         defaultValue = null
@@ -379,7 +383,7 @@
                 receiverType == null -> lambda.replaceReceiverParameter(null)
                 !lambdaAtom.coerceFirstParameterToExtensionReceiver -> {
                     lambda.receiverParameter?.apply {
-                        val type = receiverType.approximateLambdaInputType(valueParameter = null, withPCLASession)
+                        val type = receiverType.approximateLambdaInputType(valueParameter = null, withPCLASession, candidate)
                         val source =
                             source?.fakeElement(KtFakeSourceElementKind.LambdaReceiver)
                                 ?: lambda.source?.fakeElement(KtFakeSourceElementKind.LambdaReceiver)
@@ -402,7 +406,7 @@
                             symbol = FirValueParameterSymbol(name)
                             returnTypeRef = contextParameterType
                                 // TODO(KT-73150) investigate/test the need for approximation
-                                .approximateLambdaInputType(symbol, withPCLASession)
+                                .approximateLambdaInputType(symbol, withPCLASession, candidate)
                                 .toFirResolvedTypeRef(lambdaAtom.anonymousFunction.source?.fakeElement(KtFakeSourceElementKind.LambdaContextParameter))
                             valueParameterKind = if (session.languageVersionSettings.supportsFeature(LanguageFeature.ContextParameters)) {
                                 FirValueParameterKind.ContextParameter
@@ -437,7 +441,7 @@
                     )
                     return@forEachIndexed
                 }
-                val newReturnType = theParameters[index].approximateLambdaInputType(parameter.symbol, withPCLASession)
+                val newReturnType = theParameters[index].approximateLambdaInputType(parameter.symbol, withPCLASession, candidate)
                 val newReturnTypeRef = if (parameter.returnTypeRef is FirImplicitTypeRef) {
                     newReturnType.toFirResolvedTypeRef(parameter.source?.fakeElement(KtFakeSourceElementKind.ImplicitReturnTypeOfLambdaValueParameter))
                 } else parameter.returnTypeRef.resolvedTypeFromPrototype(newReturnType)
@@ -524,12 +528,15 @@
     private fun ConeKotlinType.approximateLambdaInputType(
         valueParameter: FirValueParameterSymbol?,
         isRootLambdaForPCLASession: Boolean,
+        containingCandidate: Candidate,
     ): ConeKotlinType {
         // We only run lambda completion from ConstraintSystemCompletionContext.analyzeRemainingNotAnalyzedPostponedArgument when they are
         // left uninferred.
         // Currently, we use stub types for builder inference, so CANNOT_INFER_PARAMETER_TYPE is the only possible result here.
         if (useErrorTypeInsteadOfTypeVariableForParameterType(isReceiver = valueParameter == null, isRootLambdaForPCLASession)) {
-            val diagnostic = valueParameter?.let(::ConeCannotInferValueParameterType) ?: ConeCannotInferReceiverParameterType()
+            val diagnostic = valueParameter?.let {
+                ConeCannotInferValueParameterType(it, isTopLevelLambda = containingCandidate.isSyntheticCallForTopLevelLambda())
+            } ?: ConeCannotInferReceiverParameterType()
             return ConeErrorType(diagnostic)
         }
 
diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/FirPCLAInferenceSession.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/FirPCLAInferenceSession.kt
index 8026e83..7908e58 100644
--- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/FirPCLAInferenceSession.kt
+++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/FirPCLAInferenceSession.kt
@@ -71,8 +71,15 @@
 
         currentCommonSystem.replaceContentWith(candidate.system.currentStorage())
 
-        if (completionMode == ConstraintSystemCompletionMode.PCLA_POSTPONED_CALL) {
-            outerCandidate.postponedPCLACalls += ConeAtomWithCandidate(call, candidate)
+        when (completionMode) {
+            ConstraintSystemCompletionMode.PCLA_POSTPONED_CALL -> {
+                outerCandidate.postponedPCLACalls += ConeAtomWithCandidate(call, candidate)
+            }
+//            ConstraintSystemCompletionMode.PCLA_COMPLETED_NESTED_CALL -> {
+//                outerCandidate.postponedPCLACalls += candidate.postponedPCLACalls
+//                outerCandidate.lambdasAnalyzedWithPCLA += candidate.lambdasAnalyzedWithPCLA
+//            }
+            else -> {}
         }
     }
 
diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/PostponedArgumentsAnalyzer.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/PostponedArgumentsAnalyzer.kt
index 5b62b7e..732b507 100644
--- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/PostponedArgumentsAnalyzer.kt
+++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/PostponedArgumentsAnalyzer.kt
@@ -278,7 +278,8 @@
                     checkerSink,
                     context = resolutionContext,
                     isReceiver = false,
-                    isDispatch = false
+                    isDispatch = false,
+                    returnExpressionForLambda = lambda.anonymousFunction,
                 )
             }
         }
diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirSyntheticCallGenerator.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirSyntheticCallGenerator.kt
index 6c688d8b..b310cfd 100644
--- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirSyntheticCallGenerator.kt
+++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirSyntheticCallGenerator.kt
@@ -29,6 +29,7 @@
 import org.jetbrains.kotlin.fir.references.FirErrorNamedReference
 import org.jetbrains.kotlin.fir.references.FirReference
 import org.jetbrains.kotlin.fir.references.FirResolvedCallableReference
+import org.jetbrains.kotlin.fir.references.FirResolvedErrorReference
 import org.jetbrains.kotlin.fir.references.builder.buildErrorNamedReference
 import org.jetbrains.kotlin.fir.references.builder.buildResolvedErrorReference
 import org.jetbrains.kotlin.fir.references.impl.FirSimpleNamedReference
@@ -245,6 +246,34 @@
             .firstOrNull() // TODO: it should be single() after KTIJ-26465 is fixed
     }
 
+    fun resolveAnonymousFunctionExpressionWithSyntheticOuterCall(
+        anonymousFunctionExpression: FirAnonymousFunctionExpression,
+        expectedType: ConeKotlinType?,
+        context: ResolutionContext,
+    ): FirExpression {
+        val argumentList = buildUnaryArgumentList(anonymousFunctionExpression)
+
+        val reference = generateCalleeReferenceToFunctionWithExpectedTypeForArgument(
+            anonymousFunctionExpression,
+            argumentList,
+            expectedType,
+            context,
+        )
+
+        val fakeCall = buildFunctionCall {
+            calleeReference = reference
+            this.argumentList = argumentList
+        }
+
+        val resultingCall = components.callCompleter.completeCall(fakeCall, ResolutionMode.ContextIndependent)
+
+        (resultingCall.calleeReference as? FirResolvedErrorReference)?.let {
+            anonymousFunctionExpression.anonymousFunction.replaceDiagnostic(it.diagnostic)
+        }
+
+        return resultingCall.arguments[0]
+    }
+
     fun resolveCallableReferenceWithSyntheticOuterCall(
         callableReferenceAccess: FirCallableReferenceAccess,
         expectedType: ConeKotlinType?,
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 8dc6614..4592477 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
@@ -1157,10 +1157,21 @@
     private fun transformTopLevelAnonymousFunctionExpression(
         anonymousFunctionExpression: FirAnonymousFunctionExpression,
         expectedType: ConeKotlinType?,
-    ): FirStatement = anonymousFunctionExpression.also {
-        it.replaceAnonymousFunction(transformTopLevelAnonymousFunctionInObsoleteWay(anonymousFunctionExpression, expectedType))
+    ): FirStatement = when {
+        session.languageVersionSettings.supportsFeature(LanguageFeature.ResolveTopLevelLambdasAsSyntheticCallArgument) ->
+            components.syntheticCallGenerator.resolveAnonymousFunctionExpressionWithSyntheticOuterCall(
+                anonymousFunctionExpression, expectedType, resolutionContext
+            )
+        else -> {
+            @OptIn(OnlyForDefaultLanguageFeatureDisabled::class) // ResolveTopLevelLambdasAsSyntheticCallArgument
+            val updatedAnonymousFunction = transformTopLevelAnonymousFunctionInObsoleteWay(anonymousFunctionExpression, expectedType)
+            anonymousFunctionExpression.replaceAnonymousFunction(updatedAnonymousFunction)
+
+            anonymousFunctionExpression
+        }
     }
 
+    @OnlyForDefaultLanguageFeatureDisabled(LanguageFeature.ResolveTopLevelLambdasAsSyntheticCallArgument)
     private fun transformTopLevelAnonymousFunctionInObsoleteWay(
         anonymousFunctionExpression: FirAnonymousFunctionExpression,
         expectedType: ConeKotlinType?
@@ -1235,6 +1246,7 @@
         return lambda
     }
 
+    @OnlyForDefaultLanguageFeatureDisabled(LanguageFeature.ResolveTopLevelLambdasAsSyntheticCallArgument)
     private fun FirAnonymousFunction.computeReturnTypeRef(expected: FirResolvedTypeRef?): FirResolvedTypeRef {
         val returnType = computeReturnType(
             session,
@@ -1253,6 +1265,37 @@
         )
     }
 
+    @OnlyForDefaultLanguageFeatureDisabled(LanguageFeature.ResolveTopLevelLambdasAsSyntheticCallArgument)
+    private object ImplicitToErrorTypeTransformer : FirTransformer<Any?>() {
+        override fun <E : FirElement> transformElement(element: E, data: Any?): E {
+            return element
+        }
+
+        override fun transformValueParameter(
+            valueParameter: FirValueParameter,
+            data: Any?
+        ): FirStatement =
+            whileAnalysing(valueParameter.moduleData.session, valueParameter) {
+                if (valueParameter.returnTypeRef is FirImplicitTypeRef) {
+                    valueParameter.replaceReturnTypeRef(
+                        valueParameter.returnTypeRef.resolvedTypeFromPrototype(
+                            ConeErrorType(
+                                ConeSimpleDiagnostic(
+                                    "No type for parameter",
+                                    DiagnosticKind.ValueParameterWithNoTypeAnnotation
+                                )
+                            ),
+                            fallbackSource = valueParameter.source?.fakeElement(
+                                KtFakeSourceElementKind.ImplicitReturnTypeOfLambdaValueParameter,
+                            ),
+                        )
+                    )
+                }
+                return valueParameter
+            }
+    }
+
+    @OnlyForDefaultLanguageFeatureDisabled(LanguageFeature.ResolveTopLevelLambdasAsSyntheticCallArgument)
     private fun obtainValueParametersFromResolvedLambdaAtom(
         resolvedLambdaAtom: ConeResolvedLambdaAtom,
         lambda: FirAnonymousFunction,
@@ -1290,6 +1333,7 @@
         }
     }
 
+    @OnlyForDefaultLanguageFeatureDisabled(LanguageFeature.ResolveTopLevelLambdasAsSyntheticCallArgument)
     private fun obtainValueParametersFromExpectedType(
         expectedType: ConeKotlinType?,
         lambda: FirAnonymousFunction
@@ -1305,6 +1349,7 @@
         return obtainValueParametersFromExpectedParameterTypes(parameterTypes, lambda)
     }
 
+    @OnlyForDefaultLanguageFeatureDisabled(LanguageFeature.ResolveTopLevelLambdasAsSyntheticCallArgument)
     private fun obtainValueParametersFromExpectedParameterTypes(
         expectedTypeParameterTypes: List<ConeKotlinType>,
         lambda: FirAnonymousFunction
@@ -1476,34 +1521,6 @@
         }
     }
 
-    private object ImplicitToErrorTypeTransformer : FirTransformer<Any?>() {
-        override fun <E : FirElement> transformElement(element: E, data: Any?): E {
-            return element
-        }
-
-        override fun transformValueParameter(
-            valueParameter: FirValueParameter,
-            data: Any?
-        ): FirStatement =
-            whileAnalysing(valueParameter.moduleData.session, valueParameter) {
-                if (valueParameter.returnTypeRef is FirImplicitTypeRef) {
-                    valueParameter.replaceReturnTypeRef(
-                        valueParameter.returnTypeRef.resolvedTypeFromPrototype(
-                            ConeErrorType(
-                                ConeSimpleDiagnostic(
-                                    "No type for parameter",
-                                    DiagnosticKind.ValueParameterWithNoTypeAnnotation
-                                )
-                            ),
-                            fallbackSource = valueParameter.source?.fakeElement(
-                                KtFakeSourceElementKind.ImplicitReturnTypeOfLambdaValueParameter,
-                            ),
-                        )
-                    )
-                }
-                return valueParameter
-            }
-    }
 
     private val FirVariable.initializerResolved: Boolean
         get() {
diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirExpressionsResolveTransformer.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirExpressionsResolveTransformer.kt
index 88a51d6..7bd16ed 100644
--- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirExpressionsResolveTransformer.kt
+++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirExpressionsResolveTransformer.kt
@@ -1234,7 +1234,7 @@
             callableReferenceAccess
         } else {
             components.syntheticCallGenerator.resolveCallableReferenceWithSyntheticOuterCall(
-                callableReferenceAccess, data.expectedType, resolutionContext, data
+                callableReferenceAccess, data.expectedType, resolutionContext
             )
         }.also {
             dataFlowAnalyzer.exitCallableReference(it)
diff --git a/compiler/fir/semantics/src/org/jetbrains/kotlin/fir/resolve/calls/ResolutionDiagnostic.kt b/compiler/fir/semantics/src/org/jetbrains/kotlin/fir/resolve/calls/ResolutionDiagnostic.kt
index d23e591..e0b44da 100644
--- a/compiler/fir/semantics/src/org/jetbrains/kotlin/fir/resolve/calls/ResolutionDiagnostic.kt
+++ b/compiler/fir/semantics/src/org/jetbrains/kotlin/fir/resolve/calls/ResolutionDiagnostic.kt
@@ -135,6 +135,7 @@
     val actualType: ConeKotlinType,
     val argument: FirExpression,
     val isMismatchDueToNullability: Boolean,
+    val returnExpressionForLambda: FirAnonymousFunction? = null,
 ) : ResolutionDiagnostic(if (isMismatchDueToNullability) UNSAFE_CALL else INAPPLICABLE)
 
 class UnitReturnTypeLambdaContradictsExpectedType(
diff --git a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/FirAnonymousFunction.kt b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/FirAnonymousFunction.kt
index d23f3c2..adc2f39 100644
--- a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/FirAnonymousFunction.kt
+++ b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/FirAnonymousFunction.kt
@@ -14,6 +14,7 @@
 import org.jetbrains.kotlin.fir.FirLabel
 import org.jetbrains.kotlin.fir.FirModuleData
 import org.jetbrains.kotlin.fir.contracts.FirContractDescription
+import org.jetbrains.kotlin.fir.diagnostics.ConeDiagnostic
 import org.jetbrains.kotlin.fir.expressions.FirAnnotation
 import org.jetbrains.kotlin.fir.expressions.FirBlock
 import org.jetbrains.kotlin.fir.references.FirControlFlowGraphReference
@@ -52,6 +53,7 @@
     abstract val hasExplicitParameterList: Boolean
     abstract override val typeParameters: List<FirTypeParameter>
     abstract val typeRef: FirTypeRef
+    abstract val diagnostic: ConeDiagnostic?
 
     override fun <R, D> accept(visitor: FirVisitor<R, D>, data: D): R =
         visitor.visitAnonymousFunction(this, data)
@@ -86,6 +88,8 @@
 
     abstract fun replaceTypeRef(newTypeRef: FirTypeRef)
 
+    abstract fun replaceDiagnostic(newDiagnostic: ConeDiagnostic?)
+
     abstract override fun <D> transformAnnotations(transformer: FirTransformer<D>, data: D): FirAnonymousFunction
 
     abstract override fun <D> transformStatus(transformer: FirTransformer<D>, data: D): FirAnonymousFunction
diff --git a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/builder/FirAnonymousFunctionBuilder.kt b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/builder/FirAnonymousFunctionBuilder.kt
index 4afd99e..63f4920 100644
--- a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/builder/FirAnonymousFunctionBuilder.kt
+++ b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/builder/FirAnonymousFunctionBuilder.kt
@@ -22,6 +22,7 @@
 import org.jetbrains.kotlin.fir.declarations.*
 import org.jetbrains.kotlin.fir.declarations.impl.FirAnonymousFunctionImpl
 import org.jetbrains.kotlin.fir.declarations.impl.FirResolvedDeclarationStatusImpl
+import org.jetbrains.kotlin.fir.diagnostics.ConeDiagnostic
 import org.jetbrains.kotlin.fir.expressions.FirAnnotation
 import org.jetbrains.kotlin.fir.expressions.FirBlock
 import org.jetbrains.kotlin.fir.references.FirControlFlowGraphReference
@@ -57,6 +58,7 @@
     var hasExplicitParameterList: Boolean by kotlin.properties.Delegates.notNull<Boolean>()
     val typeParameters: MutableList<FirTypeParameter> = mutableListOf()
     var typeRef: FirTypeRef = FirImplicitTypeRefImplWithoutSource
+    var diagnostic: ConeDiagnostic? = null
 
     override fun build(): FirAnonymousFunction {
         return FirAnonymousFunctionImpl(
@@ -84,6 +86,7 @@
             hasExplicitParameterList,
             typeParameters,
             typeRef,
+            diagnostic,
         )
     }
 
diff --git a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/impl/FirAnonymousFunctionImpl.kt b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/impl/FirAnonymousFunctionImpl.kt
index 63a68e3..2c3e424 100644
--- a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/impl/FirAnonymousFunctionImpl.kt
+++ b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/impl/FirAnonymousFunctionImpl.kt
@@ -19,6 +19,7 @@
 import org.jetbrains.kotlin.fir.builder.toMutableOrEmpty
 import org.jetbrains.kotlin.fir.contracts.FirContractDescription
 import org.jetbrains.kotlin.fir.declarations.*
+import org.jetbrains.kotlin.fir.diagnostics.ConeDiagnostic
 import org.jetbrains.kotlin.fir.expressions.FirAnnotation
 import org.jetbrains.kotlin.fir.expressions.FirBlock
 import org.jetbrains.kotlin.fir.references.FirControlFlowGraphReference
@@ -56,6 +57,7 @@
     override val hasExplicitParameterList: Boolean,
     override val typeParameters: MutableList<FirTypeParameter>,
     override var typeRef: FirTypeRef,
+    override var diagnostic: ConeDiagnostic?,
 ) : FirAnonymousFunction() {
     override val containerSource: DeserializedContainerSource?
         get() = null
@@ -194,4 +196,8 @@
     override fun replaceTypeRef(newTypeRef: FirTypeRef) {
         typeRef = newTypeRef
     }
+
+    override fun replaceDiagnostic(newDiagnostic: ConeDiagnostic?) {
+        diagnostic = newDiagnostic
+    }
 }
diff --git a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/annotations.kt b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/annotations.kt
index 812cbee..6de4e20 100644
--- a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/annotations.kt
+++ b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/annotations.kt
@@ -5,6 +5,8 @@
 
 package org.jetbrains.kotlin.fir
 
+import org.jetbrains.kotlin.config.LanguageFeature
+
 /**
  * [NoMutableState] annotation means that annotated class has no mutable state
  *   and it's safe to use it concurrent environment (e.g. as session component)
@@ -36,3 +38,11 @@
 @RequiresOptIn
 annotation class SessionConfiguration
 
+/**
+ * Declarations that are only being used in case some default language features are disabled: mostly likely due to using not the latest
+ * language version.
+ *
+ * Let's try to have a convention to use a relevant language feature name as a side comment.
+ */
+@RequiresOptIn
+annotation class OnlyForDefaultLanguageFeatureDisabled(val languageFeature: LanguageFeature)
diff --git a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/diagnostics/ConeSimpleDiagnostic.kt b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/diagnostics/ConeSimpleDiagnostic.kt
index 9d24ed5..fa403bc 100644
--- a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/diagnostics/ConeSimpleDiagnostic.kt
+++ b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/diagnostics/ConeSimpleDiagnostic.kt
@@ -40,7 +40,8 @@
 
 class ConeCannotInferValueParameterType(
     val valueParameter: FirValueParameterSymbol,
-    override val reason: String = "Cannot infer type for parameter ${valueParameter.name}"
+    override val reason: String = "Cannot infer type for parameter ${valueParameter.name}",
+    val isTopLevelLambda: Boolean = false,
 ) : ConeCannotInferType()
 
 class ConeCannotInferReceiverParameterType(
diff --git a/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/FirTree.kt b/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/FirTree.kt
index 984c192..2cb38f9 100644
--- a/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/FirTree.kt
+++ b/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/FirTree.kt
@@ -463,6 +463,7 @@
         +field("hasExplicitParameterList", boolean)
         +typeParameters
         +field(typeRef, withReplace = true)
+        +field("diagnostic", coneDiagnosticType, nullable = true, withReplace = true)
     }
 
     val anonymousFunctionExpression: Element by element(Expression) {
diff --git a/compiler/util/src/org/jetbrains/kotlin/config/LanguageVersionSettings.kt b/compiler/util/src/org/jetbrains/kotlin/config/LanguageVersionSettings.kt
index 7581874..576b2dd 100644
--- a/compiler/util/src/org/jetbrains/kotlin/config/LanguageVersionSettings.kt
+++ b/compiler/util/src/org/jetbrains/kotlin/config/LanguageVersionSettings.kt
@@ -377,6 +377,8 @@
     ForbidSyntheticPropertiesWithoutBaseJavaGetter(KOTLIN_2_2, kind = BUG_FIX), // KT-72305, KT-64358
     AnnotationDefaultTargetMigrationWarning(KOTLIN_2_2, kind = BUG_FIX), // KT-73255, KT-73494
 
+    ResolveTopLevelLambdasAsSyntheticCallArgument(KOTLIN_2_1), // KT-67869
+
     // 2.3
 
     ForbidCompanionInLocalInnerClass(KOTLIN_2_3, kind = BUG_FIX),