Check nullability in initial constraints
except constraints for receiver type (it can be accessed via safe call)
This commit is contained in:
+1
-1
@@ -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())
|
||||
|
||||
Vendored
+1
-1
@@ -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")
|
||||
|
||||
+11
-6
@@ -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)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user