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
@@ -6,7 +6,7 @@ interface A<T>
fun <T> infer(<!UNUSED_PARAMETER!>a<!>: A<T>) : T {<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
fun test(nothing: Nothing?) {
val <!UNUSED_VARIABLE!>i<!> = <!TYPE_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>infer<!>(<!TYPE_MISMATCH!>nothing<!>)
val <!UNUSED_VARIABLE!>i<!> = <!TYPE_INFERENCE_INCORPORATION_ERROR!>infer<!>(<!TYPE_MISMATCH!>nothing<!>)
}
fun sum(<!UNUSED_PARAMETER!>a<!> : IntArray) : Int {
@@ -5,5 +5,5 @@ package d
fun <T> asList(<!UNUSED_PARAMETER!>t<!>: T) : List<T>? {<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
fun main(args : Array<String>) {
val <!UNUSED_VARIABLE!>list<!> : List<String> = <!TYPE_MISMATCH!>asList("")<!>
val <!UNUSED_VARIABLE!>list<!> : List<String> = <!TYPE_INFERENCE_EXPECTED_TYPE_MISMATCH!>asList("")<!>
}
@@ -11,14 +11,14 @@ abstract class Buggy {
}
val anotherThree : Int
get() = <!TYPE_MISMATCH!>coll.find{ it > 3 }<!> // does not work here
get() = coll.<!TYPE_INFERENCE_EXPECTED_TYPE_MISMATCH!>find{ it > 3 }<!> // does not work here
val yetAnotherThree : Int
get() = <!TYPE_MISMATCH!>coll.find({ v:Int -> v > 3 })<!> // neither here
get() = coll.<!TYPE_INFERENCE_EXPECTED_TYPE_MISMATCH!>find({ v:Int -> v > 3 })<!> // neither here
val extendedGetter : Int
get() {
return <!TYPE_MISMATCH!>coll.find{ it > 3 }<!> // not even here!
return coll.<!TYPE_INFERENCE_EXPECTED_TYPE_MISMATCH!>find{ it > 3 }<!> // not even here!
}
}
@@ -7,7 +7,7 @@ fun <T> bar(a: T, b: Map<T, String>) = b.get(a)
fun test(a: Int) {
foo(a, null)
bar(a, <!NULL_FOR_NONNULL_TYPE!>null<!>)
<!TYPE_INFERENCE_INCORPORATION_ERROR!>bar<!>(a, <!NULL_FOR_NONNULL_TYPE!>null<!>)
}
fun test1(a: Int) {
foo(a, throw Exception())
@@ -21,7 +21,7 @@ fun <T> List<T>.contains1(e: @kotlin.internal.NoInfer T): Boolean = true
fun test(i: Int?, a: Any, l: List<Int>) {
l.<!TYPE_INFERENCE_INCORPORATION_ERROR!>contains1<!>(<!TYPE_MISMATCH!>a<!>)
l.<!TYPE_INFERENCE_INCORPORATION_ERROR!>contains1<!>(<!TYPE_MISMATCH!>""<!>)
l.contains1(<!TYPE_MISMATCH!>i<!>)
l.<!TYPE_INFERENCE_INCORPORATION_ERROR!>contains1<!>(<!TYPE_MISMATCH!>i<!>)
}
@Suppress("INVISIBLE_MEMBER", "INVISIBLE_REFERENCE")
@@ -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)
}