[FE 1.0] Don't lose diagnostics during lambda analysis at the overload resolution by return type stage
^KT-49658 Fixed
This commit is contained in:
committed by
teamcity
parent
7820b268fb
commit
37d163d417
+23
-1
@@ -7,6 +7,7 @@ package org.jetbrains.kotlin.resolve.calls.components
|
||||
|
||||
import org.jetbrains.kotlin.builtins.isFunctionTypeOrSubtype
|
||||
import org.jetbrains.kotlin.config.LanguageFeature
|
||||
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.synthetic.SyntheticMemberDescriptor
|
||||
import org.jetbrains.kotlin.resolve.calls.components.candidate.ResolutionCandidate
|
||||
@@ -31,7 +32,8 @@ import org.jetbrains.kotlin.utils.addToStdlib.same
|
||||
class KotlinCallCompleter(
|
||||
private val postponedArgumentsAnalyzer: PostponedArgumentsAnalyzer,
|
||||
private val kotlinConstraintSystemCompleter: KotlinConstraintSystemCompleter,
|
||||
private val trivialConstraintTypeInferenceOracle: TrivialConstraintTypeInferenceOracle
|
||||
private val trivialConstraintTypeInferenceOracle: TrivialConstraintTypeInferenceOracle,
|
||||
private val languageVersionSettings: LanguageVersionSettings
|
||||
) {
|
||||
|
||||
fun runCompletion(
|
||||
@@ -127,6 +129,7 @@ class KotlinCallCompleter(
|
||||
ConstraintSystemCompletionMode.FULL,
|
||||
diagnosticHolderForLambda,
|
||||
)
|
||||
propagateLambdaAnalysisDiagnostics(diagnosticHolderForLambda, firstCandidate)
|
||||
|
||||
while (iterator.hasNext()) {
|
||||
val (candidate, atom) = iterator.next()
|
||||
@@ -137,6 +140,7 @@ class KotlinCallCompleter(
|
||||
ConstraintSystemCompletionMode.FULL,
|
||||
diagnosticHolderForLambda
|
||||
)
|
||||
propagateLambdaAnalysisDiagnostics(diagnosticHolderForLambda, candidate)
|
||||
}
|
||||
|
||||
val errorCandidates = mutableSetOf<SimpleResolutionCandidate>()
|
||||
@@ -155,6 +159,24 @@ class KotlinCallCompleter(
|
||||
}
|
||||
}
|
||||
|
||||
private fun propagateLambdaAnalysisDiagnostics(
|
||||
diagnosticHolder: KotlinDiagnosticsHolder.SimpleHolder,
|
||||
candidate: SimpleResolutionCandidate
|
||||
) {
|
||||
val dontLoseDiagnosticsDuringOverloadResolutionByReturnType =
|
||||
languageVersionSettings.supportsFeature(LanguageFeature.DontLoseDiagnosticsDuringOverloadResolutionByReturnType)
|
||||
|
||||
for (diagnostic in diagnosticHolder.getDiagnostics()) {
|
||||
if (diagnostic is TransformableToWarning<*>) {
|
||||
val transformedDiagnostic =
|
||||
if (dontLoseDiagnosticsDuringOverloadResolutionByReturnType) diagnostic else diagnostic.transformToWarning()
|
||||
if (transformedDiagnostic != null) {
|
||||
candidate.addDiagnostic(transformedDiagnostic)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun SimpleResolutionCandidate.getInputTypesOfLambdaAtom(atom: ResolvedLambdaAtom): List<UnwrappedType> {
|
||||
val result = mutableListOf<UnwrappedType>()
|
||||
val substitutor = getSystem().getBuilder().buildCurrentSubstitutor()
|
||||
|
||||
+2
-2
@@ -85,7 +85,7 @@ private fun checkExpressionArgument(
|
||||
if (argumentType.isMarkedNullable) {
|
||||
if (csBuilder.addSubtypeConstraintIfCompatible(argumentType, actualExpectedType, position)) return null
|
||||
if (csBuilder.addSubtypeConstraintIfCompatible(argumentType.makeNotNullable(), actualExpectedType, position)) {
|
||||
return ArgumentNullabilityMismatchDiagnostic(actualExpectedType, argumentType, expressionArgument)
|
||||
return ArgumentNullabilityErrorDiagnostic(actualExpectedType, argumentType, expressionArgument)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -97,7 +97,7 @@ private fun checkExpressionArgument(
|
||||
|
||||
// Used only for arguments with @NotNull annotation
|
||||
if (expectedType is NotNullTypeParameter && argumentType.isMarkedNullable) {
|
||||
diagnosticsHolder.addDiagnostic(ArgumentNullabilityMismatchDiagnostic(expectedType, argumentType, expressionArgument))
|
||||
diagnosticsHolder.addDiagnostic(ArgumentNullabilityErrorDiagnostic(expectedType, argumentType, expressionArgument))
|
||||
}
|
||||
|
||||
if (expressionArgument.isSafeCall) {
|
||||
|
||||
+32
-5
@@ -23,12 +23,18 @@ import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor
|
||||
import org.jetbrains.kotlin.resolve.calls.components.candidate.ResolutionCandidate
|
||||
import org.jetbrains.kotlin.resolve.calls.components.candidate.CallableReferenceResolutionCandidate
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.model.ConstraintSystemError
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.model.NewConstraintError
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.model.NewConstraintWarning
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.model.transformToWarning
|
||||
import org.jetbrains.kotlin.resolve.calls.tower.CandidateApplicability
|
||||
import org.jetbrains.kotlin.resolve.calls.tower.CandidateApplicability.*
|
||||
import org.jetbrains.kotlin.types.TypeConstructor
|
||||
import org.jetbrains.kotlin.types.UnwrappedType
|
||||
|
||||
interface TransformableToWarning<T : KotlinCallDiagnostic> {
|
||||
fun transformToWarning(): T?
|
||||
}
|
||||
|
||||
abstract class InapplicableArgumentDiagnostic : KotlinCallDiagnostic(INAPPLICABLE) {
|
||||
abstract val argument: KotlinCallArgument
|
||||
|
||||
@@ -227,11 +233,29 @@ class NonApplicableCallForBuilderInferenceDiagnostic(val kotlinCall: KotlinCall)
|
||||
}
|
||||
}
|
||||
|
||||
class ArgumentNullabilityMismatchDiagnostic(
|
||||
val expectedType: UnwrappedType,
|
||||
val actualType: UnwrappedType,
|
||||
sealed interface ArgumentNullabilityMismatchDiagnostic {
|
||||
val expectedType: UnwrappedType
|
||||
val actualType: UnwrappedType
|
||||
val expressionArgument: ExpressionKotlinCallArgument
|
||||
) : KotlinCallDiagnostic(UNSAFE_CALL) {
|
||||
}
|
||||
|
||||
class ArgumentNullabilityErrorDiagnostic(
|
||||
override val expectedType: UnwrappedType,
|
||||
override val actualType: UnwrappedType,
|
||||
override val expressionArgument: ExpressionKotlinCallArgument
|
||||
) : KotlinCallDiagnostic(UNSAFE_CALL), TransformableToWarning<ArgumentNullabilityWarningDiagnostic>, ArgumentNullabilityMismatchDiagnostic {
|
||||
override fun report(reporter: DiagnosticReporter) {
|
||||
reporter.onCallArgument(expressionArgument, this)
|
||||
}
|
||||
|
||||
override fun transformToWarning() = ArgumentNullabilityWarningDiagnostic(expectedType, actualType, expressionArgument)
|
||||
}
|
||||
|
||||
class ArgumentNullabilityWarningDiagnostic(
|
||||
override val expectedType: UnwrappedType,
|
||||
override val actualType: UnwrappedType,
|
||||
override val expressionArgument: ExpressionKotlinCallArgument
|
||||
) : KotlinCallDiagnostic(RESOLVED), ArgumentNullabilityMismatchDiagnostic {
|
||||
override fun report(reporter: DiagnosticReporter) {
|
||||
reporter.onCallArgument(expressionArgument, this)
|
||||
}
|
||||
@@ -287,8 +311,11 @@ class MultipleArgumentsApplicableForContextReceiver(val receiverDescriptor: Rece
|
||||
|
||||
class KotlinConstraintSystemDiagnostic(
|
||||
val error: ConstraintSystemError
|
||||
) : KotlinCallDiagnostic(error.applicability) {
|
||||
) : KotlinCallDiagnostic(error.applicability), TransformableToWarning<KotlinConstraintSystemDiagnostic> {
|
||||
override fun report(reporter: DiagnosticReporter) = reporter.constraintError(error)
|
||||
|
||||
override fun transformToWarning(): KotlinConstraintSystemDiagnostic? =
|
||||
if (error is NewConstraintError) KotlinConstraintSystemDiagnostic(error.transformToWarning()) else null
|
||||
}
|
||||
|
||||
val KotlinCallDiagnostic.constraintSystemError: ConstraintSystemError?
|
||||
|
||||
Reference in New Issue
Block a user