[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:
+2
-2
@@ -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)
|
||||
|
||||
@@ -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 {
|
||||
|
||||
+3
-3
@@ -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
|
||||
}<!>
|
||||
|
||||
+2
-2
@@ -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[""] }
|
||||
|
||||
+3
-1
@@ -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
@@ -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 {
|
||||
|
||||
+1
-1
@@ -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
@@ -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
@@ -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()
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user