[NI] Remove lambda coersion to Unit in case of error return type(s)

Coersion to Unit from error type leads to misleading type mismatches:
"expected <expected lambda return type> found Unit", despite no user-provided Unit / empty lambda.
These diagnostics were collected, but not reported before, and that had been disguising the issue for a while.

KT-34729 Fixed
This commit is contained in:
Pavel Kirpichenkov
2020-01-20 19:25:35 +03:00
parent 3a98c84105
commit c5893913f3
39 changed files with 263 additions and 46 deletions
@@ -12,7 +12,6 @@ import org.jetbrains.kotlin.descriptors.CallableDescriptor
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor
import org.jetbrains.kotlin.descriptors.annotations.Annotations
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.resolve.calls.inference.components.ConstraintInjector
import org.jetbrains.kotlin.resolve.calls.inference.model.NewTypeVariable
import org.jetbrains.kotlin.resolve.calls.model.*
@@ -42,6 +41,16 @@ interface KotlinResolutionStatelessCallbacks {
): SimpleConstraintSystem
}
data class ReturnArgumentsInfo(
val nonErrorArguments: List<KotlinCallArgument>,
val returnArgumentsExist: Boolean
)
data class ReturnArgumentsAnalysisResult(
val returnArgumentsInfo: ReturnArgumentsInfo,
val inferenceSession: InferenceSession?
)
// This components hold state (trace). Work with this carefully.
interface KotlinResolutionCallbacks {
fun analyzeAndGetLambdaReturnArguments(
@@ -52,7 +61,7 @@ interface KotlinResolutionCallbacks {
expectedReturnType: UnwrappedType?, // null means, that return type is not proper i.e. it depends on some type variables
annotations: Annotations,
stubsForPostponedVariables: Map<NewTypeVariable, StubType>
): Pair<List<KotlinCallArgument>, InferenceSession?>
): ReturnArgumentsAnalysisResult
fun bindStubResolvedCallForCandidate(candidate: ResolvedCallAtom)
@@ -118,7 +118,7 @@ class PostponedArgumentsAnalyzer(
else FilteredAnnotations(annotations, true) { it != KotlinBuiltIns.FQ_NAMES.extensionFunctionType }
}
val (returnArguments, inferenceSession) = resolutionCallbacks.analyzeAndGetLambdaReturnArguments(
val (returnArgumentsInfo, inferenceSession) = resolutionCallbacks.analyzeAndGetLambdaReturnArguments(
lambda.atom,
lambda.isSuspend,
receiver,
@@ -128,21 +128,21 @@ class PostponedArgumentsAnalyzer(
stubsForPostponedVariables.cast()
)
returnArguments.forEach { c.addSubsystemFromArgument(it) }
returnArgumentsInfo.nonErrorArguments.forEach { c.addSubsystemFromArgument(it) }
val subResolvedKtPrimitives = returnArguments.map {
val subResolvedKtPrimitives = returnArgumentsInfo.nonErrorArguments.map {
resolveKtPrimitive(
c.getBuilder(), it, lambda.returnType.let(::substitute), diagnosticHolder, isReceiver = false
)
}
if (returnArguments.isEmpty()) {
if (!returnArgumentsInfo.returnArgumentsExist) {
val unitType = lambda.returnType.builtIns.unitType
val lambdaReturnType = lambda.returnType.let(::substitute)
c.getBuilder().addSubtypeConstraint(unitType, lambdaReturnType, LambdaArgumentConstraintPosition(lambda))
}
lambda.setAnalyzedResults(returnArguments, subResolvedKtPrimitives)
lambda.setAnalyzedResults(returnArgumentsInfo, subResolvedKtPrimitives)
if (inferenceSession != null) {
val storageSnapshot = c.getBuilder().currentStorage()
@@ -8,6 +8,7 @@ package org.jetbrains.kotlin.resolve.calls.model
import org.jetbrains.kotlin.descriptors.CallableDescriptor
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor
import org.jetbrains.kotlin.resolve.calls.components.CallableReferenceCandidate
import org.jetbrains.kotlin.resolve.calls.components.ReturnArgumentsInfo
import org.jetbrains.kotlin.resolve.calls.components.TypeArgumentsToParametersMapper
import org.jetbrains.kotlin.resolve.calls.components.extractInputOutputTypesFromCallableReferenceExpectedType
import org.jetbrains.kotlin.resolve.calls.inference.components.FreshVariableNewTypeSubstitutor
@@ -115,14 +116,14 @@ class ResolvedLambdaAtom(
val typeVariableForLambdaReturnType: TypeVariableForLambdaReturnType?,
override val expectedType: UnwrappedType?
) : PostponedResolvedAtom() {
lateinit var resultArguments: List<KotlinCallArgument>
lateinit var resultArgumentsInfo: ReturnArgumentsInfo
private set
fun setAnalyzedResults(
resultArguments: List<KotlinCallArgument>,
resultArguments: ReturnArgumentsInfo,
subResolvedAtoms: List<ResolvedAtom>
) {
this.resultArguments = resultArguments
this.resultArgumentsInfo = resultArguments
setAnalyzedResults(subResolvedAtoms)
}