Add compatibility resolve when variable has "bad" intersection type

#KT-39468 Fixed
This commit is contained in:
Mikhail Zarechenskiy
2020-07-02 16:10:57 +03:00
parent 92a51b9794
commit d51bb2c053
13 changed files with 238 additions and 0 deletions
@@ -17,6 +17,7 @@ import org.jetbrains.kotlin.resolve.calls.model.*
import org.jetbrains.kotlin.resolve.calls.results.SimpleConstraintSystem
import org.jetbrains.kotlin.resolve.calls.tower.ImplicitScopeTower
import org.jetbrains.kotlin.resolve.constants.IntegerValueTypeConstant
import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.types.StubType
import org.jetbrains.kotlin.types.UnwrappedType
@@ -36,6 +37,8 @@ interface KotlinResolutionStatelessCallbacks {
fun isCoroutineCall(argument: KotlinCallArgument, parameter: ValueParameterDescriptor): Boolean
fun isApplicableCallForBuilderInference(descriptor: CallableDescriptor, languageVersionSettings: LanguageVersionSettings): Boolean
fun isOldIntersectionIsEmpty(types: Collection<KotlinType>): Boolean
fun createConstraintSystemForOverloadResolution(
constraintInjector: ConstraintInjector, builtIns: KotlinBuiltIns
): SimpleConstraintSystem
@@ -29,6 +29,7 @@ import org.jetbrains.kotlin.types.typeUtil.contains
import org.jetbrains.kotlin.types.typeUtil.makeNotNullable
import org.jetbrains.kotlin.types.typeUtil.makeNullable
import org.jetbrains.kotlin.utils.SmartList
import org.jetbrains.kotlin.utils.addToStdlib.cast
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
internal object CheckVisibility : ResolutionPart() {
@@ -250,6 +251,24 @@ internal object PostponedVariablesInitializerResolutionPart : ResolutionPart() {
}
}
internal object CompatibilityOfTypeVariableAsIntersectionTypePart : ResolutionPart() {
override fun KotlinResolutionCandidate.process(workIndex: Int) {
for ((_, variableWithConstraints) in csBuilder.currentStorage().notFixedTypeVariables) {
val constraints = variableWithConstraints.constraints.filter { csBuilder.isProperType(it.type) }
if (constraints.size <= 1) continue
if (constraints.any { it.kind.isLower() || it.kind.isEqual() }) continue
// See TypeBoundsImpl.computeValues(). It returns several values for such situation which means an error in OI
if (callComponents.statelessCallbacks.isOldIntersectionIsEmpty(constraints.map { it.type }.cast())) {
addDiagnostic(LowerPriorityToPreserveCompatibility)
return
}
}
}
}
internal object CheckExplicitReceiverKindConsistency : ResolutionPart() {
private fun KotlinResolutionCandidate.hasError(): Nothing =
error(
@@ -228,6 +228,7 @@ enum class KotlinCallKind(vararg resolutionPart: ResolutionPart) {
CheckArgumentsInParenthesis,
CheckExternalArgument,
EagerResolveOfCallableReferences,
CompatibilityOfTypeVariableAsIntersectionTypePart,
PostponedVariablesInitializerResolutionPart
),
INVOKE(*FUNCTION.resolutionSequence.toTypedArray()),