diff --git a/compiler/fir/semantics/src/org/jetbrains/kotlin/fir/resolve/inference/model/FirConstraintPositionAndErrors.kt b/compiler/fir/semantics/src/org/jetbrains/kotlin/fir/resolve/inference/model/FirConstraintPositionAndErrors.kt index f1f68e0831a..18da64d9042 100644 --- a/compiler/fir/semantics/src/org/jetbrains/kotlin/fir/resolve/inference/model/FirConstraintPositionAndErrors.kt +++ b/compiler/fir/semantics/src/org/jetbrains/kotlin/fir/resolve/inference/model/FirConstraintPositionAndErrors.kt @@ -30,6 +30,6 @@ class ConeLambdaArgumentConstraintPosition( class ConeBuilderInferenceSubstitutionConstraintPosition(initialConstraint: InitialConstraint) : - BuilderInferenceSubstitutionConstraintPosition(null, initialConstraint) // TODO + BuilderInferenceSubstitutionConstraintPosition(null, initialConstraint) // TODO class ConeReceiverConstraintPosition(receiver: FirExpression) : ReceiverConstraintPosition(receiver) diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/DiagnosticReporterByTrackingStrategy.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/DiagnosticReporterByTrackingStrategy.kt index 8ea188cf885..5d610683226 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/DiagnosticReporterByTrackingStrategy.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/DiagnosticReporterByTrackingStrategy.kt @@ -451,16 +451,16 @@ class DiagnosticReporterByTrackingStrategy( val argument = when (position) { - is ArgumentConstraintPositionImpl -> position.argument - is ReceiverConstraintPositionImpl -> position.argument - is LambdaArgumentConstraintPositionImpl -> position.lambda.atom + is ArgumentConstraintPosition<*> -> position.argument as KotlinCallArgument + is ReceiverConstraintPosition<*> -> position.argument as KotlinCallArgument + is LambdaArgumentConstraintPosition<*> -> (position.lambda as ResolvedLambdaAtom).atom else -> null } val isWarning = error is NewConstraintWarning val typeMismatchDiagnostic = if (isWarning) TYPE_MISMATCH_WARNING else TYPE_MISMATCH val report = if (isWarning) trace::reportDiagnosticOnce else trace::report - argument?.let { - (it as? LambdaKotlinCallArgument)?.let lambda@{ lambda -> + if (argument != null) { + (argument as? LambdaKotlinCallArgument)?.let lambda@{ lambda -> val parameterTypes = lambda.parametersTypes?.toList() ?: return@lambda val index = parameterTypes.indexOf(error.upperKotlinType.unwrap()) val lambdaExpression = lambda.psiExpression as? KtLambdaExpression ?: return@lambda @@ -471,7 +471,7 @@ class DiagnosticReporterByTrackingStrategy( return } - val expression = it.psiExpression ?: return + val expression = argument.psiExpression ?: return val deparenthesized = KtPsiUtil.safeDeparenthesize(expression) if (reportConstantTypeMismatch(error, deparenthesized)) return @@ -485,46 +485,67 @@ class DiagnosticReporterByTrackingStrategy( } } report(typeMismatchDiagnostic.on(deparenthesized, error.upperKotlinType, error.lowerKotlinType)) + return } - (position as? ExpectedTypeConstraintPositionImpl)?.let { - val call = it.topLevelCall.psiKotlinCall.psiCall.callElement as? KtExpression - val inferredType = - if (!error.lowerKotlinType.isNullableNothing()) error.lowerKotlinType - else error.upperKotlinType.makeNullable() - if (call != null) { - report(typeMismatchDiagnostic.on(call, error.upperKotlinType, inferredType)) + @Suppress("KotlinConstantConditions") + when (position) { + is BuilderInferenceExpectedTypeConstraintPosition -> { + val inferredType = + if (!error.lowerKotlinType.isNullableNothing()) error.lowerKotlinType + else error.upperKotlinType.makeNullable() + trace.report(TYPE_MISMATCH.on(position.topLevelCall, error.upperKotlinType, inferredType)) } - } - - (position as? BuilderInferenceExpectedTypeConstraintPosition)?.let { - val inferredType = - if (!error.lowerKotlinType.isNullableNothing()) error.lowerKotlinType - else error.upperKotlinType.makeNullable() - trace.report(TYPE_MISMATCH.on(it.topLevelCall, error.upperKotlinType, inferredType)) - } - - (position as? BuilderInferenceSubstitutionConstraintPositionImpl)?.let { - reportConstraintErrorByPosition(error, it.initialConstraint.position) - } - - (position as? ExplicitTypeParameterConstraintPositionImpl)?.let { - val typeArgumentReference = (it.typeArgument as SimpleTypeArgumentImpl).typeProjection.typeReference ?: return@let - val diagnosticFactory = if (isWarning) UPPER_BOUND_VIOLATED_WARNING else UPPER_BOUND_VIOLATED - report(diagnosticFactory.on(typeArgumentReference, error.upperKotlinType, error.lowerKotlinType)) - } - - (position as? FixVariableConstraintPositionImpl)?.let { - val morePreciseDiagnosticExists = allDiagnostics.any { other -> - val otherError = other.constraintSystemError ?: return@any false - otherError is NewConstraintError && otherError.position.from !is FixVariableConstraintPositionImpl + is ExpectedTypeConstraintPosition<*> -> { + val call = (position.topLevelCall as? KotlinCall)?.psiKotlinCall?.psiCall?.callElement as? KtExpression + val inferredType = + if (!error.lowerKotlinType.isNullableNothing()) error.lowerKotlinType + else error.upperKotlinType.makeNullable() + if (call != null) { + report(typeMismatchDiagnostic.on(call, error.upperKotlinType, inferredType)) + } } - if (morePreciseDiagnosticExists) return + is BuilderInferenceSubstitutionConstraintPosition<*> -> { + reportConstraintErrorByPosition(error, position.initialConstraint.position) + } + is ExplicitTypeParameterConstraintPosition<*> -> { + val typeArgumentReference = (position.typeArgument as SimpleTypeArgumentImpl).typeProjection.typeReference ?: return + val diagnosticFactory = if (isWarning) UPPER_BOUND_VIOLATED_WARNING else UPPER_BOUND_VIOLATED + report(diagnosticFactory.on(typeArgumentReference, error.upperKotlinType, error.lowerKotlinType)) + } + is FixVariableConstraintPosition<*> -> { + val morePreciseDiagnosticExists = allDiagnostics.any { other -> + val otherError = other.constraintSystemError ?: return@any false + otherError is NewConstraintError && otherError.position.from !is FixVariableConstraintPositionImpl + } + if (morePreciseDiagnosticExists) return - val call = (it.resolvedAtom?.atom as? PSIKotlinCall)?.psiCall ?: call - val expression = call.calleeExpression ?: return + val call = ((position.resolvedAtom as? ResolvedAtom)?.atom as? PSIKotlinCall)?.psiCall ?: call + val expression = call.calleeExpression ?: return - trace.reportDiagnosticOnce(typeMismatchDiagnostic.on(expression, error.upperKotlinType, error.lowerKotlinType)) + trace.reportDiagnosticOnce(typeMismatchDiagnostic.on(expression, error.upperKotlinType, error.lowerKotlinType)) + } + BuilderInferencePosition -> { + // some error reported later? + } + is CallableReferenceConstraintPosition<*> -> TODO() + is DeclaredUpperBoundConstraintPosition<*> -> TODO() + is DelegatedPropertyConstraintPosition<*> -> { + // DELEGATE_SPECIAL_FUNCTION_NONE_APPLICABLE, reported later + } + is IncorporationConstraintPosition -> TODO() + is InjectedAnotherStubTypeConstraintPosition<*> -> TODO() + is KnownTypeParameterConstraintPosition<*> -> { + // UPPER_BOUND_VIOLATED, reported later? + } + is LHSArgumentConstraintPosition<*, *> -> TODO() + SimpleConstraintSystemConstraintPosition -> TODO() + // Never reachable + is ArgumentConstraintPosition<*>, + is LambdaArgumentConstraintPosition<*>, + is ReceiverConstraintPosition<*> -> { + throw AssertionError("Should not be here") + } } } diff --git a/compiler/resolution.common/src/org/jetbrains/kotlin/resolve/calls/inference/model/ConstraintPositionAndErrors.kt b/compiler/resolution.common/src/org/jetbrains/kotlin/resolve/calls/inference/model/ConstraintPositionAndErrors.kt index 585704d6e32..1df25b85be6 100644 --- a/compiler/resolution.common/src/org/jetbrains/kotlin/resolve/calls/inference/model/ConstraintPositionAndErrors.kt +++ b/compiler/resolution.common/src/org/jetbrains/kotlin/resolve/calls/inference/model/ConstraintPositionAndErrors.kt @@ -24,9 +24,9 @@ abstract class InjectedAnotherStubTypeConstraintPosition(private val builderI override fun toString(): String = "Injected from $builderInferenceLambdaOfInjectedStubType builder inference call" } -abstract class BuilderInferenceSubstitutionConstraintPosition( +abstract class BuilderInferenceSubstitutionConstraintPosition( private val builderInferenceLambda: L, - val initialConstraint: I, + val initialConstraint: InitialConstraint, val isFromNotSubstitutedDeclaredUpperBound: Boolean = false ) : ConstraintPosition(), OnlyInputTypeConstraintPosition { override fun toString(): String = "Incorporated builder inference constraint $initialConstraint " + diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/components/KotlinConstraintSystemCompleter.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/components/KotlinConstraintSystemCompleter.kt index 9a9b4f5ff36..2bd3cf0bef2 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/components/KotlinConstraintSystemCompleter.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/components/KotlinConstraintSystemCompleter.kt @@ -458,7 +458,7 @@ class KotlinConstraintSystemCompleter( val position = constraint.position.from.let { basicPosition -> if (basicPosition is IncorporationConstraintPosition) basicPosition.from else basicPosition } - if (position is BuilderInferenceSubstitutionConstraintPosition<*, *> && position.isFromNotSubstitutedDeclaredUpperBound) { + if (position is BuilderInferenceSubstitutionConstraintPosition<*> && position.isFromNotSubstitutedDeclaredUpperBound) { upperBoundType = constraint.type true } else { diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/model/ConstraintPositionAndErrorsImpl.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/model/ConstraintPositionAndErrorsImpl.kt index ec4d70d3898..649f53576e3 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/model/ConstraintPositionAndErrorsImpl.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/model/ConstraintPositionAndErrorsImpl.kt @@ -21,7 +21,7 @@ class BuilderInferenceSubstitutionConstraintPositionImpl( builderInferenceLambda: LambdaKotlinCallArgument, initialConstraint: InitialConstraint, isFromNotSubstitutedDeclaredUpperBound: Boolean = false -) : BuilderInferenceSubstitutionConstraintPosition( +) : BuilderInferenceSubstitutionConstraintPosition( builderInferenceLambda, initialConstraint, isFromNotSubstitutedDeclaredUpperBound )