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 <T> infer(<!UNUSED_PARAMETER!>a<!>: A<T>) : T {<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
|
||||||
|
|
||||||
fun test(nothing: Nothing?) {
|
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 {
|
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 <T> asList(<!UNUSED_PARAMETER!>t<!>: T) : List<T>? {<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
|
||||||
|
|
||||||
fun main(args : Array<String>) {
|
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
|
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
|
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
|
val extendedGetter : Int
|
||||||
get() {
|
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) {
|
fun test(a: Int) {
|
||||||
foo(a, null)
|
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) {
|
fun test1(a: Int) {
|
||||||
foo(a, throw Exception())
|
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>) {
|
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!>a<!>)
|
||||||
l.<!TYPE_INFERENCE_INCORPORATION_ERROR!>contains1<!>(<!TYPE_MISMATCH!>""<!>)
|
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")
|
@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.builtIns
|
||||||
import org.jetbrains.kotlin.types.typeUtil.getNestedArguments
|
import org.jetbrains.kotlin.types.typeUtil.getNestedArguments
|
||||||
import org.jetbrains.kotlin.types.typeUtil.isDefaultBound
|
import org.jetbrains.kotlin.types.typeUtil.isDefaultBound
|
||||||
|
import org.jetbrains.kotlin.types.typeUtil.makeNotNullable
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
public class ConstraintSystemImpl : ConstraintSystem {
|
public class ConstraintSystemImpl : ConstraintSystem {
|
||||||
@@ -474,15 +475,19 @@ public class ConstraintSystemImpl : ConstraintSystem {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun satisfyInitialConstraints(): Boolean {
|
private fun satisfyInitialConstraints(): Boolean {
|
||||||
fun JetType.substituteAndMakeNullable(): JetType? {
|
fun JetType.substitute(): JetType? {
|
||||||
val substitutor = getSubstitutor(substituteOriginal = false) { TypeProjectionImpl(ErrorUtils.createUninferredParameterType(it)) }
|
val substitutor = getSubstitutor(substituteOriginal = false) { TypeProjectionImpl(ErrorUtils.createUninferredParameterType(it)) }
|
||||||
val result = substitutor.substitute(this, Variance.INVARIANT) ?: return null
|
return substitutor.substitute(this, Variance.INVARIANT) ?: return null
|
||||||
return TypeUtils.makeNullable(result)
|
|
||||||
}
|
}
|
||||||
return initialConstraints.all {
|
return initialConstraints.all {
|
||||||
val resultSubType = it.subtype.substituteAndMakeNullable() ?: return false
|
constraint ->
|
||||||
val resultSuperType = it.superType.substituteAndMakeNullable() ?: return false
|
val resultSubType = constraint.subtype.substitute()?.let {
|
||||||
when (it.kind) {
|
// 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)
|
SUB_TYPE -> JetTypeChecker.DEFAULT.isSubtypeOf(resultSubType, resultSuperType)
|
||||||
EQUAL -> JetTypeChecker.DEFAULT.equalTypes(resultSubType, resultSuperType)
|
EQUAL -> JetTypeChecker.DEFAULT.equalTypes(resultSubType, resultSuperType)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user