Fix coercion to Unit when variable already have other constraints
Don't add `Unit` if variable has an upper constraint T <: A. It's impossible to coerce variable T to Unit as constraint system will be always contradictory: T := Unit => Unit should be subtype of A #KT-39900 Fixed
This commit is contained in:
+2
-2
@@ -10,7 +10,7 @@ import org.jetbrains.kotlin.config.LanguageFeature
|
||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.synthetic.SyntheticMemberDescriptor
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.NewConstraintSystem
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.addSubtypeConstraintIfCompatible
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.addEqualityConstraintIfCompatible
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.components.KotlinConstraintSystemCompleter
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.components.KotlinConstraintSystemCompleter.ConstraintSystemCompletionMode
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.components.TrivialConstraintTypeInferenceOracle
|
||||
@@ -285,7 +285,7 @@ class KotlinCallCompleter(
|
||||
}
|
||||
|
||||
expectedType === TypeUtils.UNIT_EXPECTED_TYPE ->
|
||||
csBuilder.addSubtypeConstraintIfCompatible(
|
||||
csBuilder.addEqualityConstraintIfCompatible(
|
||||
returnType, csBuilder.builtIns.unitType, ExpectedTypeConstraintPosition(resolvedCall.atom)
|
||||
)
|
||||
|
||||
|
||||
+1
-2
@@ -35,7 +35,6 @@ class PostponedArgumentsAnalyzer(
|
||||
fun canBeProper(type: KotlinTypeMarker): Boolean
|
||||
|
||||
fun hasUpperOrEqualUnitConstraint(type: KotlinTypeMarker): Boolean
|
||||
fun hasEqualNothingConstraint(type: KotlinTypeMarker): Boolean
|
||||
|
||||
// mutable operations
|
||||
fun addOtherSystem(otherSystem: ConstraintStorage)
|
||||
@@ -123,7 +122,7 @@ class PostponedArgumentsAnalyzer(
|
||||
c.canBeProper(rawReturnType) -> substitute(rawReturnType)
|
||||
|
||||
// For Unit-coercion
|
||||
c.hasUpperOrEqualUnitConstraint(rawReturnType) && !c.hasEqualNothingConstraint(rawReturnType) -> builtIns.unitType
|
||||
c.hasUpperOrEqualUnitConstraint(rawReturnType) -> builtIns.unitType
|
||||
|
||||
else -> null
|
||||
}
|
||||
|
||||
+23
-1
@@ -17,6 +17,7 @@
|
||||
package org.jetbrains.kotlin.resolve.calls.inference
|
||||
|
||||
import org.jetbrains.kotlin.resolve.calls.components.PostponedArgumentsAnalyzer
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.model.ConstraintKind
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.model.ConstraintPosition
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.model.ConstraintStorage
|
||||
import org.jetbrains.kotlin.resolve.calls.model.CallableReferenceKotlinCallArgument
|
||||
@@ -62,9 +63,30 @@ fun ConstraintSystemBuilder.addSubtypeConstraintIfCompatible(
|
||||
lowerType: KotlinTypeMarker,
|
||||
upperType: KotlinTypeMarker,
|
||||
position: ConstraintPosition
|
||||
): Boolean =
|
||||
addConstraintIfCompatible(lowerType, upperType, position, ConstraintKind.LOWER)
|
||||
|
||||
fun ConstraintSystemBuilder.addEqualityConstraintIfCompatible(
|
||||
lowerType: KotlinTypeMarker,
|
||||
upperType: KotlinTypeMarker,
|
||||
position: ConstraintPosition
|
||||
): Boolean =
|
||||
addConstraintIfCompatible(lowerType, upperType, position, ConstraintKind.EQUALITY)
|
||||
|
||||
private fun ConstraintSystemBuilder.addConstraintIfCompatible(
|
||||
lowerType: KotlinTypeMarker,
|
||||
upperType: KotlinTypeMarker,
|
||||
position: ConstraintPosition,
|
||||
kind: ConstraintKind
|
||||
) =
|
||||
runTransaction {
|
||||
if (!hasContradiction) addSubtypeConstraint(lowerType, upperType, position)
|
||||
if (!hasContradiction) {
|
||||
when (kind) {
|
||||
ConstraintKind.LOWER -> addSubtypeConstraint(lowerType, upperType, position)
|
||||
ConstraintKind.UPPER -> addSubtypeConstraint(upperType, lowerType, position)
|
||||
ConstraintKind.EQUALITY -> addEqualityConstraint(lowerType, upperType, position)
|
||||
}
|
||||
}
|
||||
!hasContradiction
|
||||
}
|
||||
|
||||
|
||||
-6
@@ -389,10 +389,4 @@ class NewConstraintSystemImpl(
|
||||
val constraints = storage.notFixedTypeVariables[type.typeConstructor()]?.constraints ?: return false
|
||||
return constraints.any { (it.kind == ConstraintKind.UPPER || it.kind == ConstraintKind.EQUALITY) && it.type.isUnit() }
|
||||
}
|
||||
|
||||
override fun hasEqualNothingConstraint(type: KotlinTypeMarker): Boolean {
|
||||
checkState(State.BUILDING, State.COMPLETION, State.FREEZED)
|
||||
val constraints = storage.notFixedTypeVariables[type.typeConstructor()]?.constraints ?: return false
|
||||
return constraints.any { (it.kind == ConstraintKind.EQUALITY) && it.type.isNothing() }
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user