[FE] Check if type variable is fixed into an empty intersection type and report resolution warnings/errors if needed (completion stage)
^KT-51221 Fixed
This commit is contained in:
committed by
teamcity
parent
8e834fc7bb
commit
9e9e0211eb
+6
-3
@@ -8,9 +8,7 @@ package org.jetbrains.kotlin.resolve.calls.inference.components
|
||||
import org.jetbrains.kotlin.config.LanguageFeature
|
||||
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.ConstraintSystemBuilder
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.model.ConstraintSystemError
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.model.FixVariableConstraintPosition
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.model.VariableWithConstraints
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.model.*
|
||||
import org.jetbrains.kotlin.resolve.calls.model.PostponedAtomWithRevisableExpectedType
|
||||
import org.jetbrains.kotlin.resolve.calls.model.PostponedResolvedAtomMarker
|
||||
import org.jetbrains.kotlin.types.model.KotlinTypeMarker
|
||||
@@ -110,4 +108,9 @@ abstract class ConstraintSystemCompletionContext : VariableFixationFinder.Contex
|
||||
private fun <T : PostponedResolvedAtomMarker> findPostponedArgumentWithFixedInputTypes(
|
||||
postponedArguments: List<T>
|
||||
) = postponedArguments.firstOrNull { argument -> argument.inputTypes.all { containsOnlyFixedVariables(it) } }
|
||||
|
||||
fun List<Constraint>.extractUpperTypes(): List<KotlinTypeMarker> =
|
||||
filter { constraint ->
|
||||
constraint.kind == ConstraintKind.UPPER && !constraint.type.contains { !it.typeConstructor().isClassTypeConstructor() }
|
||||
}.map { it.type }
|
||||
}
|
||||
|
||||
+16
-1
@@ -113,7 +113,7 @@ class NewConstraintWarning(
|
||||
override val lowerType: KotlinTypeMarker,
|
||||
override val upperType: KotlinTypeMarker,
|
||||
override val position: IncorporationConstraintPosition,
|
||||
) : ConstraintSystemError(RESOLVED), NewConstraintMismatch
|
||||
) : ConstraintSystemError(RESOLVED_WITH_WARNING), NewConstraintMismatch
|
||||
|
||||
class CapturedTypeFromSubtyping(
|
||||
val typeVariable: TypeVariableMarker,
|
||||
@@ -135,6 +135,21 @@ class ConstrainingTypeIsError(
|
||||
|
||||
class NoSuccessfulFork(val position: IncorporationConstraintPosition) : ConstraintSystemError(INAPPLICABLE)
|
||||
|
||||
sealed interface InferredEmptyIntersection {
|
||||
val incompatibleTypes: Collection<KotlinTypeMarker>
|
||||
val typeVariable: TypeVariableMarker
|
||||
}
|
||||
|
||||
class InferredEmptyIntersectionWarning(
|
||||
override val incompatibleTypes: Collection<KotlinTypeMarker>,
|
||||
override val typeVariable: TypeVariableMarker
|
||||
) : ConstraintSystemError(RESOLVED_WITH_WARNING), InferredEmptyIntersection
|
||||
|
||||
class InferredEmptyIntersectionError(
|
||||
override val incompatibleTypes: Collection<KotlinTypeMarker>,
|
||||
override val typeVariable: TypeVariableMarker
|
||||
) : ConstraintSystemError(INAPPLICABLE), InferredEmptyIntersection
|
||||
|
||||
class OnlyInputTypesDiagnostic(val typeVariable: TypeVariableMarker) : ConstraintSystemError(INAPPLICABLE)
|
||||
|
||||
object LowerPriorityToPreserveCompatibility : ConstraintSystemError(RESOLVED_NEED_PRESERVE_COMPATIBILITY)
|
||||
|
||||
+19
-2
@@ -5,6 +5,8 @@
|
||||
|
||||
package org.jetbrains.kotlin.resolve.calls.inference.model
|
||||
|
||||
import org.jetbrains.kotlin.config.LanguageFeature
|
||||
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
||||
import org.jetbrains.kotlin.resolve.calls.components.PostponedArgumentsAnalyzerContext
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.*
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.components.*
|
||||
@@ -19,7 +21,8 @@ import kotlin.math.max
|
||||
|
||||
class NewConstraintSystemImpl(
|
||||
private val constraintInjector: ConstraintInjector,
|
||||
val typeSystemContext: TypeSystemInferenceExtensionContext
|
||||
val typeSystemContext: TypeSystemInferenceExtensionContext,
|
||||
private val languageVersionSettings: LanguageVersionSettings,
|
||||
) : ConstraintSystemCompletionContext(),
|
||||
TypeSystemInferenceExtensionContext by typeSystemContext,
|
||||
NewConstraintSystem,
|
||||
@@ -408,6 +411,8 @@ class NewConstraintSystemImpl(
|
||||
) = with(utilContext) {
|
||||
checkState(State.BUILDING, State.COMPLETION)
|
||||
|
||||
checkInferredEmptyIntersection(variable, resultType)
|
||||
|
||||
constraintInjector.addInitialEqualityConstraint(this@NewConstraintSystemImpl, variable.defaultType(), resultType, position)
|
||||
|
||||
/*
|
||||
@@ -434,7 +439,19 @@ class NewConstraintSystemImpl(
|
||||
doPostponedComputationsIfAllVariablesAreFixed()
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalStdlibApi::class)
|
||||
private fun checkInferredEmptyIntersection(variable: TypeVariableMarker, resultType: KotlinTypeMarker) {
|
||||
val intersectionTypeConstructor = resultType.typeConstructor().takeIf { it is IntersectionTypeConstructorMarker } ?: return
|
||||
val isInferredEmptyIntersectionForbidden =
|
||||
languageVersionSettings.supportsFeature(LanguageFeature.ForbidInferringTypeVariablesIntoEmptyIntersection)
|
||||
val intersectionComponents = intersectionTypeConstructor.supertypes()
|
||||
|
||||
if (intersectionComponents.isEmptyIntersection()) {
|
||||
val errorFactory =
|
||||
if (isInferredEmptyIntersectionForbidden) ::InferredEmptyIntersectionError else ::InferredEmptyIntersectionWarning
|
||||
addError(errorFactory(intersectionComponents, variable))
|
||||
}
|
||||
}
|
||||
|
||||
private fun checkMissedConstraints() {
|
||||
val constraintSystem = this@NewConstraintSystemImpl
|
||||
val errorsByMissedConstraints = buildList {
|
||||
|
||||
+1
@@ -29,6 +29,7 @@ enum class CandidateApplicability {
|
||||
PROPERTY_AS_OPERATOR, // using property of functional type as an operator. From resolution perspective, this is considered successful.
|
||||
RESOLVED_NEED_PRESERVE_COMPATIBILITY, // call resolved successfully, but using new features that changes resolve
|
||||
RESOLVED_WITH_ERROR, // call has error, but it is still successful from resolution perspective
|
||||
RESOLVED_WITH_WARNING, // generally call is successful, but there are additional resolution warnings (e.g. for deprecation something)
|
||||
RESOLVED, // call success or has uncompleted inference or in other words possible successful candidate
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user