[NI] Turn off KnownTypeParameterSubstitutor for NI

The main consequence of it is that TYPE_MISMATCH range for control
structures became wider.

Also, for extra safety, don't change behaviour of OI.
This commit is contained in:
Dmitry Savvinov
2017-12-07 13:18:24 +03:00
parent 4ed6928e6b
commit 33f9576dd1
15 changed files with 53 additions and 49 deletions
@@ -133,8 +133,8 @@ public class ControlStructureTypingUtils {
@NotNull KotlinType expectedType,
@NotNull LanguageVersionSettings languageVersionSettings
) {
if (construct == ResolveConstruct.ELVIS
|| construct == ResolveConstruct.EXCL_EXCL
if (languageVersionSettings.supportsFeature(LanguageFeature.NewInference)
|| construct == ResolveConstruct.ELVIS
|| TypeUtils.noExpectedType(expectedType)
|| TypeUtils.isDontCarePlaceholder(expectedType)
|| KotlinBuiltIns.isUnitOrNullableUnit(expectedType)
+5 -5
View File
@@ -67,7 +67,7 @@ fun blockAndAndMismatch5() : Int {
(return <!CONSTANT_EXPECTED_TYPE_MISMATCH!>true<!>) || (return <!CONSTANT_EXPECTED_TYPE_MISMATCH!>false<!>)
}
fun blockReturnValueTypeMatch1() : Int {
return if (1 > 2) <!CONSTANT_EXPECTED_TYPE_MISMATCH!>1.0<!> else <!OI;CONSTANT_EXPECTED_TYPE_MISMATCH!>2.0<!>
return <!NI;TYPE_MISMATCH, NI;TYPE_MISMATCH!>if (1 > 2) <!OI;CONSTANT_EXPECTED_TYPE_MISMATCH!>1.0<!> else <!OI;CONSTANT_EXPECTED_TYPE_MISMATCH!>2.0<!><!>
}
fun blockReturnValueTypeMatch2() : Int {
return <!TYPE_MISMATCH!><!INVALID_IF_AS_EXPRESSION!>if<!> (1 > 2) 1<!>
@@ -134,8 +134,8 @@ fun blockNoReturnIfUnitInOneBranch(): Int {
}
}
<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
fun nonBlockReturnIfEmptyIf(): Int = if (1 < 2) <!TYPE_MISMATCH!>{}<!> else <!OI;TYPE_MISMATCH!>{}<!>
fun nonBlockNoReturnIfUnitInOneBranch(): Int = if (1 < 2) <!TYPE_MISMATCH!>{}<!> else 2
fun nonBlockReturnIfEmptyIf(): Int = <!NI;TYPE_MISMATCH, NI;TYPE_MISMATCH!>if (1 < 2) <!OI;TYPE_MISMATCH!>{}<!> else <!OI;TYPE_MISMATCH!>{}<!><!>
fun nonBlockNoReturnIfUnitInOneBranch(): Int = <!NI;TYPE_MISMATCH, NI;TYPE_MISMATCH!>if (1 < 2) <!OI;TYPE_MISMATCH!>{}<!> else 2<!>
val a = <!RETURN_NOT_ALLOWED!>return<!> 1
@@ -146,14 +146,14 @@ fun illegalConstantBlock(): String {
return <!CONSTANT_EXPECTED_TYPE_MISMATCH!>1<!>
}
fun illegalIfBody(): Int =
if (1 < 2) <!CONSTANT_EXPECTED_TYPE_MISMATCH!>'a'<!> else <!NI;TYPE_MISMATCH!>{ <!OI;CONSTANT_EXPECTED_TYPE_MISMATCH!>1.0<!> }<!>
<!NI;TYPE_MISMATCH, NI;TYPE_MISMATCH, NI;TYPE_MISMATCH!>if (1 < 2) <!OI;CONSTANT_EXPECTED_TYPE_MISMATCH!>'a'<!> else { <!OI;CONSTANT_EXPECTED_TYPE_MISMATCH!>1.0<!> }<!>
fun illegalIfBlock(): Boolean {
if (1 < 2)
return false
else { return <!CONSTANT_EXPECTED_TYPE_MISMATCH!>1<!> }
}
fun illegalReturnIf(): Char {
return if (1 < 2) 'a' else <!NI;TYPE_MISMATCH!>{ <!OI;CONSTANT_EXPECTED_TYPE_MISMATCH!>1<!> }<!>
return <!NI;TYPE_MISMATCH!>if (1 < 2) 'a' else { <!OI;CONSTANT_EXPECTED_TYPE_MISMATCH!>1<!> }<!>
}
fun returnNothing(): Nothing {
@@ -25,11 +25,11 @@ fun <T> bind2(r: Option<T>): Option<T> {
}
fun <T, R> bind3(r: Option<T>): Option<T> {
return if (r is Some) <!NI;TYPE_MISMATCH, NI;TYPE_MISMATCH, NI;TYPE_MISMATCH, NI;TYPE_MISMATCH, NI;TYPE_MISMATCH!>{
return <!NI;TYPE_MISMATCH, NI;TYPE_MISMATCH, NI;TYPE_MISMATCH, NI;TYPE_MISMATCH, NI;TYPE_MISMATCH!>if (r is Some) {
// Diagnoses an error correctly
if (true) <!OI;TYPE_MISMATCH!>None<R>()<!> else r
}<!>
else r
}
else r<!>
}
fun <T> bindWhen(r: Option<T>): Option<T> {
@@ -2,9 +2,9 @@
package f
fun test(a: Boolean, b: Boolean): Int {
return if(a) {
return <!NI;TYPE_MISMATCH, NI;TYPE_MISMATCH!>if(a) {
1
} else <!NI;TYPE_MISMATCH!>{
} else {
<!OI;TYPE_MISMATCH!><!INVALID_IF_AS_EXPRESSION!>if<!> (b) {
3
}<!>
@@ -30,11 +30,11 @@ val testSafeCall4: String? = J.m[""]?.let { it.toString() }
val testIf1: String = if (true) J.s else J.s
val testIf2: String? = if (true) J.s else J.s
val testIf3: String = if (true) <!TYPE_MISMATCH!>J.m[""]<!> else <!OI;TYPE_MISMATCH!>J.m[""]<!>
val testIf3: String = <!NI;TYPE_MISMATCH, NI;TYPE_MISMATCH!>if (true) <!OI;TYPE_MISMATCH!>J.m[""]<!> else <!OI;TYPE_MISMATCH!>J.m[""]<!><!>
val testIf4: String? = if (true) J.m[""] else J.m[""]
val testWhen1: String = when { else -> J.s }
val testWhen2: String? = when { else -> J.s }
val testWhen3: String = when { else -> <!TYPE_MISMATCH!>J.m[""]<!> }
val testWhen3: String = <!NI;TYPE_MISMATCH!>when { else -> <!OI;TYPE_MISMATCH!>J.m[""]<!> }<!>
val testWhen4: String? = when { else -> J.m[""] }
@@ -1,3 +1,5 @@
// !WITH_NEW_INFERENCE
fun bar(x: Int): Int = x + 1
fun foo() {
@@ -5,6 +7,6 @@ fun foo() {
val <!UNUSED_VARIABLE!>a<!> = object {
fun baz() = bar(if (x == null) 0 else <!DEBUG_INFO_SMARTCAST!>x<!>)
fun quux(): Int = if (x == null) <!TYPE_MISMATCH, DEBUG_INFO_CONSTANT!>x<!> else <!DEBUG_INFO_SMARTCAST!>x<!>
fun quux(): Int = <!NI;TYPE_MISMATCH!>if (x == null) <!OI;TYPE_MISMATCH, DEBUG_INFO_CONSTANT!>x<!> else <!DEBUG_INFO_SMARTCAST!>x<!><!>
}
}
@@ -9,7 +9,7 @@ fun foo(): Int {
if (x != null) return x
val y: Int? = null
if (y == null) return if (<!SENSELESS_COMPARISON!><!DEBUG_INFO_CONSTANT!>y<!> != null<!>) y else <!TYPE_MISMATCH, DEBUG_INFO_CONSTANT!>y<!>
if (y == null) return <!NI;TYPE_MISMATCH, NI;TYPE_MISMATCH!>if (<!SENSELESS_COMPARISON!><!DEBUG_INFO_CONSTANT!>y<!> != null<!>) y else <!OI;TYPE_MISMATCH, DEBUG_INFO_CONSTANT!>y<!><!>
val z: Int? = null
if (z != null) return if (<!SENSELESS_COMPARISON!>z == null<!>) z else z
@@ -1,4 +1,5 @@
// !DIAGNOSTICS: -USELESS_CAST -UNUSED_PARAMETER -UNUSED_VARIABLE
// !WITH_NEW_INFERENCE
// FILE: j/Base.java
package j;
@@ -38,7 +39,7 @@ fun <T> listOf2(x1: T, x2: T): List<T> = null!!
fun <T> arrayOf2(x1: T, x2: T): Array<T> = null!!
fun test() {
val test1: Base = if (true) d1 else d2
val test1: Base = <!NI;INACCESSIBLE_TYPE!>if (true) d1 else d2<!>
val test2 = <!INACCESSIBLE_TYPE!>if (true) d1 else d2<!>
@@ -47,10 +48,10 @@ fun test() {
else -> d2
}<!>
val test4: Base = when {
val test4: Base = <!NI;INACCESSIBLE_TYPE!>when {
true -> d1
else -> d2
}
}<!>
val test5 = <!INACCESSIBLE_TYPE!>select(d1, d2)<!>
@@ -10,13 +10,13 @@ interface C
fun <!OI;IMPLICIT_INTERSECTION_TYPE!>foo<!>(b: B) = if (b is A && b is C) b else null
// Ok: given explicitly
fun gav(b: B): A? = if (b is A && b is C) <!DEBUG_INFO_SMARTCAST!>b<!> else null
fun gav(b: B): A? = if (b is A && b is C) <!OI;DEBUG_INFO_SMARTCAST!>b<!> else null
class My(b: B) {
// Error!
val <!OI;IMPLICIT_INTERSECTION_TYPE!>x<!> = if (b is A && b is C) b else null
// Ok: given explicitly
val y: C? = if (b is A && b is C) <!DEBUG_INFO_SMARTCAST!>b<!> else null
val y: C? = if (b is A && b is C) <!OI;DEBUG_INFO_SMARTCAST!>b<!> else null
// Error!
fun <!OI;IMPLICIT_INTERSECTION_TYPE!>foo<!>(b: B) = if (b is A && b is C) b else null
}
+3 -3
View File
@@ -142,10 +142,10 @@ fun getStringLength(obj : Any) : Char? {
}
fun toInt(i: Int?): Int = if (i != null) <!DEBUG_INFO_SMARTCAST!>i<!> else 0
fun illegalWhenBody(a: Any): Int = <!NO_ELSE_IN_WHEN!>when<!>(a) {
fun illegalWhenBody(a: Any): Int = <!NI;TYPE_MISMATCH!><!NO_ELSE_IN_WHEN!>when<!>(a) {
is Int -> <!DEBUG_INFO_SMARTCAST!>a<!>
is String -> <!TYPE_MISMATCH!>a<!>
}
is String -> <!OI;TYPE_MISMATCH!>a<!>
}<!>
fun illegalWhenBlock(a: Any): Int {
when(a) {
is Int -> return <!DEBUG_INFO_SMARTCAST!>a<!>
@@ -1,3 +1,4 @@
// !WITH_NEW_INFERENCE
//KT-2146 Nullability casts in when.
package kt2146
@@ -9,46 +10,46 @@ fun f1(s: Int?): Int {
}
fun f2(s: Int?): Int {
return when (s) {
!is Int -> <!TYPE_MISMATCH!>s<!>
return <!NI;TYPE_MISMATCH!>when (s) {
!is Int -> <!OI;TYPE_MISMATCH!>s<!>
else -> <!DEBUG_INFO_SMARTCAST!>s<!>
}
}<!>
}
fun f3(s: Int?): Int {
return when (s) {
return <!NI;TYPE_MISMATCH!>when (s) {
is Int -> <!DEBUG_INFO_SMARTCAST!>s<!>
else -> <!TYPE_MISMATCH!>s<!>
}
else -> <!OI;TYPE_MISMATCH!>s<!>
}<!>
}
fun f4(s: Int?): Int {
return when {
return <!NI;TYPE_MISMATCH!>when {
s == 4 -> <!DEBUG_INFO_SMARTCAST!>s<!>
s == null -> <!TYPE_MISMATCH, DEBUG_INFO_CONSTANT!>s<!>
s == null -> <!OI;TYPE_MISMATCH, DEBUG_INFO_CONSTANT!>s<!>
else -> <!DEBUG_INFO_SMARTCAST!>s<!>
}
}<!>
}
fun f5(s: Int?): Int {
return when (s) {
s -> <!TYPE_MISMATCH!>s<!>
return <!NI;TYPE_MISMATCH!>when (s) {
s -> <!OI;TYPE_MISMATCH!>s<!>
s!! -> <!DEBUG_INFO_SMARTCAST!>s<!>
s -> <!DEBUG_INFO_SMARTCAST!>s<!>
else -> 0
}
}<!>
}
fun f6(s: Int?): Int {
return when {
return <!NI;TYPE_MISMATCH!>when {
s is Int -> <!DEBUG_INFO_SMARTCAST!>s<!>
else -> <!TYPE_MISMATCH!>s<!>
}
else -> <!OI;TYPE_MISMATCH!>s<!>
}<!>
}
fun f7(s: Int?): Int {
return when {
s !is Int -> <!TYPE_MISMATCH!>s<!>
return <!NI;TYPE_MISMATCH!>when {
s !is Int -> <!OI;TYPE_MISMATCH!>s<!>
else -> <!DEBUG_INFO_SMARTCAST!>s<!>
}
}<!>
}
@@ -14,7 +14,7 @@ class Example {
public fun foo(): String {
// Smart cast is not possible if property is delegated
return if (p != null) <!NI;SMARTCAST_IMPOSSIBLE, SMARTCAST_IMPOSSIBLE!>p<!> else ""
return <!NI;TYPE_MISMATCH!>if (p != null) <!NI;SMARTCAST_IMPOSSIBLE, SMARTCAST_IMPOSSIBLE!>p<!> else ""<!>
}
public fun bar(): String {
@@ -3,7 +3,7 @@
fun basic(): String {
var current: String? = null
current = if (current == null) "bar" else current
current = if (current == null) "bar" else <!NI;DEBUG_INFO_SMARTCAST!>current<!>
return <!DEBUG_INFO_SMARTCAST!>current<!>
}
+3 -3
View File
@@ -1,10 +1,10 @@
// !WITH_NEW_INFERENCE
val test: Int = if (true) <!NI;TYPE_MISMATCH, NI;TYPE_MISMATCH!>{
val test: Int = <!NI;TYPE_MISMATCH, NI;TYPE_MISMATCH, NI;TYPE_MISMATCH!>if (true) {
when (2) {
1 -> 1
else -> <!OI;NULL_FOR_NONNULL_TYPE!>null<!>
}
}<!>
}
else {
2
}
}<!>
+2 -2
View File
@@ -1,11 +1,11 @@
// !WITH_NEW_INFERENCE
fun test1(): Int {
val x: String = if (true) <!NI;TYPE_MISMATCH, NI;TYPE_MISMATCH, NI;TYPE_MISMATCH, NI;TYPE_MISMATCH!>{
val x: String = <!NI;TYPE_MISMATCH, NI;TYPE_MISMATCH, NI;TYPE_MISMATCH, NI;TYPE_MISMATCH!>if (true) {
when {
true -> <!OI;TYPE_MISMATCH!>Any()<!>
else -> <!OI;NULL_FOR_NONNULL_TYPE!>null<!>
}
}<!> else ""
} else ""<!>
return x.hashCode()
}