Check nullability in initial constraints

except constraints for receiver type (it can be accessed via safe call)
This commit is contained in:
Svetlana Isakova
2015-10-17 17:40:52 +03:00
parent bb9f7094e0
commit cb34498278
6 changed files with 18 additions and 13 deletions
@@ -41,6 +41,7 @@ import org.jetbrains.kotlin.types.checker.TypeCheckingProcedureCallbacks
import org.jetbrains.kotlin.types.typeUtil.builtIns
import org.jetbrains.kotlin.types.typeUtil.getNestedArguments
import org.jetbrains.kotlin.types.typeUtil.isDefaultBound
import org.jetbrains.kotlin.types.typeUtil.makeNotNullable
import java.util.*
public class ConstraintSystemImpl : ConstraintSystem {
@@ -474,15 +475,19 @@ public class ConstraintSystemImpl : ConstraintSystem {
}
private fun satisfyInitialConstraints(): Boolean {
fun JetType.substituteAndMakeNullable(): JetType? {
fun JetType.substitute(): JetType? {
val substitutor = getSubstitutor(substituteOriginal = false) { TypeProjectionImpl(ErrorUtils.createUninferredParameterType(it)) }
val result = substitutor.substitute(this, Variance.INVARIANT) ?: return null
return TypeUtils.makeNullable(result)
return substitutor.substitute(this, Variance.INVARIANT) ?: return null
}
return initialConstraints.all {
val resultSubType = it.subtype.substituteAndMakeNullable() ?: return false
val resultSuperType = it.superType.substituteAndMakeNullable() ?: return false
when (it.kind) {
constraint ->
val resultSubType = constraint.subtype.substitute()?.let {
// the call might be done via safe access, so we check for notNullable receiver type;
// 'unsafe call' error is reported otherwise later
if (constraint.position.kind != ConstraintPositionKind.RECEIVER_POSITION) it else it.makeNotNullable()
} ?: return false
val resultSuperType = constraint.superType.substitute() ?: return false
when (constraint.kind) {
SUB_TYPE -> JetTypeChecker.DEFAULT.isSubtypeOf(resultSubType, resultSuperType)
EQUAL -> JetTypeChecker.DEFAULT.equalTypes(resultSubType, resultSuperType)
}