[NI] Don't discriminate Nothing-type from resulting ones
^KT-32106 Fixed
This commit is contained in:
committed by
Pavel Kirpichenkov
parent
a8e9a6a1d0
commit
ae1630f376
-9
@@ -23,15 +23,6 @@ class TrivialConstraintTypeInferenceOracle private constructor(context: TypeSyst
|
|||||||
return constraint.kind == ConstraintKind.LOWER && constraint.type.typeConstructor().isNothingConstructor()
|
return constraint.kind == ConstraintKind.LOWER && constraint.type.typeConstructor().isNothingConstructor()
|
||||||
}
|
}
|
||||||
|
|
||||||
// This function controls the choice between sub and super result type
|
|
||||||
// Even that Nothing(?) is the most specific type for subtype, it doesn't bring valuable information to the user,
|
|
||||||
// therefore it is discriminated in favor of supertype
|
|
||||||
fun isSuitableResultedType(
|
|
||||||
resultType: KotlinTypeMarker
|
|
||||||
): Boolean {
|
|
||||||
return !resultType.typeConstructor().isNothingConstructor()
|
|
||||||
}
|
|
||||||
|
|
||||||
// It's possible to generate Nothing-like constraints inside incorporation mechanism:
|
// It's possible to generate Nothing-like constraints inside incorporation mechanism:
|
||||||
// For instance, when two type variables are in subtyping relation `T <: K`, after incorporation
|
// For instance, when two type variables are in subtyping relation `T <: K`, after incorporation
|
||||||
// there will be constraint `approximation(out K) <: K` => `Nothing <: K`, which is innocent
|
// there will be constraint `approximation(out K) <: K` => `Nothing <: K`, which is innocent
|
||||||
|
|||||||
+1
-1
@@ -23,7 +23,7 @@ class Test {
|
|||||||
val Int.c: Int get() = 42
|
val Int.c: Int get() = 42
|
||||||
|
|
||||||
val test1: () -> Right = <!RESERVED_SYNTAX_IN_CALLABLE_REFERENCE_LHS!><!DEBUG_INFO_MISSING_UNRESOLVED!>a<!>.<!DEBUG_INFO_MISSING_UNRESOLVED!>b<!><<!DEBUG_INFO_MISSING_UNRESOLVED!>Int<!>>.<!DEBUG_INFO_MISSING_UNRESOLVED!>c<!><!>::<!DEBUG_INFO_MISSING_UNRESOLVED!>foo<!>
|
val test1: () -> Right = <!RESERVED_SYNTAX_IN_CALLABLE_REFERENCE_LHS!><!DEBUG_INFO_MISSING_UNRESOLVED!>a<!>.<!DEBUG_INFO_MISSING_UNRESOLVED!>b<!><<!DEBUG_INFO_MISSING_UNRESOLVED!>Int<!>>.<!DEBUG_INFO_MISSING_UNRESOLVED!>c<!><!>::<!DEBUG_INFO_MISSING_UNRESOLVED!>foo<!>
|
||||||
val test1a: () -> Right = a.<!NI;DEBUG_INFO_LEAKING_THIS!>b<!>.<!NI;DEBUG_INFO_LEAKING_THIS!>c<!>::foo
|
val test1a: () -> Right = a.b.c::foo
|
||||||
|
|
||||||
val test2: () -> Right = <!RESERVED_SYNTAX_IN_CALLABLE_REFERENCE_LHS!><!DEBUG_INFO_MISSING_UNRESOLVED!>a<!>.<!DEBUG_INFO_MISSING_UNRESOLVED!>b<!><<!DEBUG_INFO_MISSING_UNRESOLVED!>Int<!>>.<!DEBUG_INFO_MISSING_UNRESOLVED!>c<!><!>?::<!DEBUG_INFO_MISSING_UNRESOLVED!>foo<!>
|
val test2: () -> Right = <!RESERVED_SYNTAX_IN_CALLABLE_REFERENCE_LHS!><!DEBUG_INFO_MISSING_UNRESOLVED!>a<!>.<!DEBUG_INFO_MISSING_UNRESOLVED!>b<!><<!DEBUG_INFO_MISSING_UNRESOLVED!>Int<!>>.<!DEBUG_INFO_MISSING_UNRESOLVED!>c<!><!>?::<!DEBUG_INFO_MISSING_UNRESOLVED!>foo<!>
|
||||||
}
|
}
|
||||||
@@ -8,6 +8,6 @@ fun foo(): String {
|
|||||||
}
|
}
|
||||||
fun bar(): String {
|
fun bar(): String {
|
||||||
val x = fn() ?: return ""
|
val x = fn() ?: return ""
|
||||||
<!OI;UNREACHABLE_CODE!>val <!OI;UNUSED_VARIABLE!>y<!> =<!> x<!UNNECESSARY_SAFE_CALL!>?.<!>let { throw Exception() } <!OI;UNREACHABLE_CODE, OI;USELESS_ELVIS!>?: "unreachable"<!>
|
<!UNREACHABLE_CODE!>val <!UNUSED_VARIABLE!>y<!> =<!> x<!UNNECESSARY_SAFE_CALL!>?.<!>let { throw Exception() } <!NI;UNREACHABLE_CODE, NI;USELESS_ELVIS, OI;UNREACHABLE_CODE, OI;USELESS_ELVIS!>?: "unreachable"<!>
|
||||||
<!OI;UNREACHABLE_CODE!>return y<!>
|
<!UNREACHABLE_CODE!>return y<!>
|
||||||
}
|
}
|
||||||
Vendored
+1
-1
@@ -25,5 +25,5 @@ fun test(s: SelectorFor<State>): Double {
|
|||||||
val e = s { return p1 }
|
val e = s { return p1 }
|
||||||
e checkType { _<AbstractSelector<State, Nothing>>() }
|
e checkType { _<AbstractSelector<State, Nothing>>() }
|
||||||
|
|
||||||
<!OI;UNREACHABLE_CODE!>return<!> null!!
|
<!UNREACHABLE_CODE!>return<!> null!!
|
||||||
}
|
}
|
||||||
Vendored
+12
@@ -0,0 +1,12 @@
|
|||||||
|
// !DIAGNOSTICS: -UNUSED_PARAMETER -UNUSED_EXPRESSION -ASSIGNED_BUT_NEVER_ACCESSED_VARIABLE -UNUSED_VALUE
|
||||||
|
|
||||||
|
class Out<out T : Any>(result: T?)
|
||||||
|
|
||||||
|
fun main() {
|
||||||
|
val a = Out(null)
|
||||||
|
|
||||||
|
<!DEBUG_INFO_EXPRESSION_TYPE("Out<kotlin.Nothing>")!>a<!>
|
||||||
|
|
||||||
|
var b: Out<Int>? = null
|
||||||
|
b = a
|
||||||
|
}
|
||||||
compiler/testData/diagnostics/tests/inference/nothingType/inferArgumentToNothingFromNullConstant.txt
Vendored
+10
@@ -0,0 +1,10 @@
|
|||||||
|
package
|
||||||
|
|
||||||
|
public fun main(): kotlin.Unit
|
||||||
|
|
||||||
|
public final class Out</*0*/ out T : kotlin.Any> {
|
||||||
|
public constructor Out</*0*/ out T : kotlin.Any>(/*0*/ result: T?)
|
||||||
|
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||||
|
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||||
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
}
|
||||||
+3
-3
@@ -1,12 +1,12 @@
|
|||||||
// !LANGUAGE: +NewInference
|
// !WITH_NEW_INFERENCE
|
||||||
// !DIAGNOSTICS: -UNUSED_PARAMETER -UNUSED_VARIABLE
|
// !DIAGNOSTICS: -UNUSED_PARAMETER -UNUSED_VARIABLE
|
||||||
|
|
||||||
fun <K> select2(x: K, y: K): K = TODO()
|
fun <K> select2(x: K, y: K): K = TODO()
|
||||||
fun <K> select3(x: K, y: K, z: K): K = TODO()
|
fun <K> select3(x: K, y: K, z: K): K = TODO()
|
||||||
|
|
||||||
fun test2(f: ((String) -> Int)?) {
|
fun test2(f: ((String) -> Int)?) {
|
||||||
val a0: ((Int) -> Int)? = select2({ it -> it }, null)
|
val a0: ((Int) -> Int)? = select2(<!TYPE_MISMATCH!>{ <!OI;CANNOT_INFER_PARAMETER_TYPE!>it<!> -> <!OI;DEBUG_INFO_ELEMENT_WITH_ERROR_TYPE!>it<!> }<!>, null)
|
||||||
val b0: ((Nothing) -> Unit)? = select2({ it -> <!UNUSED_EXPRESSION!>it<!> }, null)
|
val b0: ((Nothing) -> Unit)? = select2(<!TYPE_MISMATCH!>{ <!OI;CANNOT_INFER_PARAMETER_TYPE!>it<!> -> <!OI;DEBUG_INFO_ELEMENT_WITH_ERROR_TYPE!>it<!> }<!>, null)
|
||||||
|
|
||||||
select3({ it.length }, f, null)
|
select3({ it.length }, f, null)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,6 @@
|
|||||||
// !DIAGNOSTICS: -UNREACHABLE_CODE
|
// !DIAGNOSTICS: -UNREACHABLE_CODE
|
||||||
|
|
||||||
fun foo() {
|
fun foo() {
|
||||||
val <!OI;UNUSED_VARIABLE!>text<!>: List<Any> = null!!
|
val <!UNUSED_VARIABLE!>text<!>: List<Any> = null!!
|
||||||
text.<!UNRESOLVED_REFERENCE!>map<!> <!DEBUG_INFO_ELEMENT_WITH_ERROR_TYPE!>Any<!><!SYNTAX!>?<!>::<!DEBUG_INFO_MISSING_UNRESOLVED!>toString<!>
|
text.<!UNRESOLVED_REFERENCE!>map<!> <!DEBUG_INFO_ELEMENT_WITH_ERROR_TYPE!>Any<!><!SYNTAX!>?<!>::<!DEBUG_INFO_MISSING_UNRESOLVED!>toString<!>
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -19,5 +19,5 @@ fun foo(): A.() -> Int {
|
|||||||
val b: Int = foo()(A())
|
val b: Int = foo()(A())
|
||||||
val c: Int = (foo())(A())
|
val c: Int = (foo())(A())
|
||||||
|
|
||||||
<!OI;UNREACHABLE_CODE!>return<!> null!!
|
<!UNREACHABLE_CODE!>return<!> null!!
|
||||||
}
|
}
|
||||||
@@ -4,7 +4,7 @@ fun foo(): String {
|
|||||||
s = null
|
s = null
|
||||||
<!DEBUG_INFO_CONSTANT!>s<!>?.length
|
<!DEBUG_INFO_CONSTANT!>s<!>?.length
|
||||||
<!OI;DEBUG_INFO_CONSTANT!>s<!><!UNSAFE_CALL!>.<!>length
|
<!OI;DEBUG_INFO_CONSTANT!>s<!><!UNSAFE_CALL!>.<!>length
|
||||||
if (<!SENSELESS_COMPARISON!><!DEBUG_INFO_CONSTANT!>s<!> == null<!>) return <!ALWAYS_NULL!>s<!>!!
|
if (<!SENSELESS_COMPARISON!><!DEBUG_INFO_CONSTANT!>s<!> == null<!>) <!NI;UNREACHABLE_CODE!>return<!> <!ALWAYS_NULL!>s<!>!!
|
||||||
var t: String? = "y"
|
var t: String? = "y"
|
||||||
if (t == null) t = "x"
|
if (t == null) t = "x"
|
||||||
var x: Int? = null
|
var x: Int? = null
|
||||||
|
|||||||
+1
-1
@@ -1,7 +1,7 @@
|
|||||||
// !WITH_NEW_INFERENCE
|
// !WITH_NEW_INFERENCE
|
||||||
class MyClass
|
class MyClass
|
||||||
|
|
||||||
operator fun MyClass.inc(): MyClass { <!OI;UNREACHABLE_CODE!>return<!> null!! }
|
operator fun MyClass.inc(): MyClass { <!UNREACHABLE_CODE!>return<!> null!! }
|
||||||
|
|
||||||
public fun box() : MyClass? {
|
public fun box() : MyClass? {
|
||||||
var i : MyClass?
|
var i : MyClass?
|
||||||
|
|||||||
+1
-1
@@ -1,7 +1,7 @@
|
|||||||
// !WITH_NEW_INFERENCE
|
// !WITH_NEW_INFERENCE
|
||||||
class MyClass
|
class MyClass
|
||||||
|
|
||||||
operator fun MyClass.inc(): MyClass { <!OI;UNREACHABLE_CODE!>return<!> null!! }
|
operator fun MyClass.inc(): MyClass { <!UNREACHABLE_CODE!>return<!> null!! }
|
||||||
|
|
||||||
public fun box() {
|
public fun box() {
|
||||||
var i : MyClass?
|
var i : MyClass?
|
||||||
|
|||||||
@@ -7,19 +7,19 @@ val test1: (String) -> Boolean =
|
|||||||
|
|
||||||
val test2: (String) -> Boolean =
|
val test2: (String) -> Boolean =
|
||||||
when {
|
when {
|
||||||
true -> {{ true }}
|
true -> <!NI;TYPE_MISMATCH!>{{ true }}<!>
|
||||||
else -> null!!
|
else -> null!!
|
||||||
}
|
}
|
||||||
|
|
||||||
val test3: (String) -> Boolean =
|
val test3: (String) -> Boolean =
|
||||||
when {
|
when {
|
||||||
true -> { <!UNUSED_ANONYMOUS_PARAMETER!>s<!> -> true }
|
true -> <!NI;TYPE_MISMATCH!>{ <!UNUSED_ANONYMOUS_PARAMETER!>s<!> -> true }<!>
|
||||||
else -> null!!
|
else -> null!!
|
||||||
}
|
}
|
||||||
|
|
||||||
val test4: (String) -> Boolean =
|
val test4: (String) -> Boolean =
|
||||||
when {
|
when {
|
||||||
true -> <!NI;TYPE_MISMATCH!>{ <!EXPECTED_PARAMETERS_NUMBER_MISMATCH!><!UNUSED_ANONYMOUS_PARAMETER!>s1<!>, <!CANNOT_INFER_PARAMETER_TYPE, UNUSED_ANONYMOUS_PARAMETER!>s2<!><!> -> true }<!>
|
true -> <!NI;TYPE_MISMATCH!>{ <!OI;EXPECTED_PARAMETERS_NUMBER_MISMATCH!><!UNUSED_ANONYMOUS_PARAMETER!>s1<!>, <!OI;CANNOT_INFER_PARAMETER_TYPE, UNUSED_ANONYMOUS_PARAMETER!>s2<!><!> -> true }<!>
|
||||||
else -> null!!
|
else -> null!!
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ val <!OI;IMPLICIT_NOTHING_PROPERTY_TYPE!>test1<!> = when {
|
|||||||
}
|
}
|
||||||
|
|
||||||
val test1a: () -> Boolean = when {
|
val test1a: () -> Boolean = when {
|
||||||
true -> { { true } }
|
true -> <!NI;TYPE_MISMATCH!>{ { true } }<!>
|
||||||
else -> TODO()
|
else -> TODO()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -33,7 +33,7 @@ val <!OI;IMPLICIT_NOTHING_PROPERTY_TYPE!>test3<!> = when {
|
|||||||
}
|
}
|
||||||
|
|
||||||
val test3a: () -> Boolean = when {
|
val test3a: () -> Boolean = when {
|
||||||
true -> { { true } }
|
true -> <!NI;TYPE_MISMATCH!>{ { true } }<!>
|
||||||
true -> { { true } }
|
true -> <!NI;TYPE_MISMATCH!>{ { true } }<!>
|
||||||
else -> TODO()
|
else -> TODO()
|
||||||
}
|
}
|
||||||
@@ -385,7 +385,7 @@ fun case_13(b: Boolean, c: Boolean, d: Boolean) {
|
|||||||
* ISSUES: KT-28329
|
* ISSUES: KT-28329
|
||||||
*/
|
*/
|
||||||
fun case_14(z: Boolean?) {
|
fun case_14(z: Boolean?) {
|
||||||
if (true && true && true && true && EnumClassWithNullableProperty.B.prop_1 != null || z != null || <!ALWAYS_NULL!>z<!>!! && true && true) {
|
if (true && true && true && true && EnumClassWithNullableProperty.B.prop_1 != null || z != null || <!ALWAYS_NULL!>z<!>!! <!UNREACHABLE_CODE!>&& true && true<!>) {
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Int?")!>EnumClassWithNullableProperty.B.prop_1<!>
|
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Int?")!>EnumClassWithNullableProperty.B.prop_1<!>
|
||||||
|
|||||||
@@ -123,8 +123,8 @@ fun case_8(x: Any?, z: Any) {
|
|||||||
|
|
||||||
// TESTCASE NUMBER: 9
|
// TESTCASE NUMBER: 9
|
||||||
fun case_9(x: Any?, z: Any) {
|
fun case_9(x: Any?, z: Any) {
|
||||||
var y = select(x) ?: return null!!
|
var y = select(x) ?: <!UNREACHABLE_CODE!>return<!> null!!
|
||||||
z == y || throw null!!
|
z == y || <!UNREACHABLE_CODE!>throw<!> null!!
|
||||||
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Any?")!>x<!>
|
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Any?")!>x<!>
|
||||||
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Any")!>y<!>
|
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Any")!>y<!>
|
||||||
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Any")!>y<!>.equals(10)
|
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Any")!>y<!>.equals(10)
|
||||||
|
|||||||
@@ -285,7 +285,7 @@ fun case_24(a: ((() -> Unit) -> Unit), b: (() -> Unit)) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// TESTCASE NUMBER: 25
|
// TESTCASE NUMBER: 25
|
||||||
fun case_25(a: (() -> Unit) -> Unit, b: (() -> Unit) -> Unit = if (<!SENSELESS_COMPARISON!>a == null<!>) <!DEBUG_INFO_EXPRESSION_TYPE("(() -> kotlin.Unit) -> kotlin.Unit & kotlin.Nothing")!>a<!> else {{}}) {
|
fun case_25(a: (() -> Unit) -> Unit, b: (() -> Unit) -> Unit = if (<!SENSELESS_COMPARISON!>a == null<!>) <!DEBUG_INFO_EXPRESSION_TYPE("(() -> kotlin.Unit) -> kotlin.Unit & kotlin.Nothing"), DEBUG_INFO_SMARTCAST!>a<!> else <!TYPE_MISMATCH!>{{}}<!>) {
|
||||||
<!DEBUG_INFO_EXPRESSION_TYPE("(() -> kotlin.Unit) -> kotlin.Unit")!>a<!>
|
<!DEBUG_INFO_EXPRESSION_TYPE("(() -> kotlin.Unit) -> kotlin.Unit")!>a<!>
|
||||||
<!DEBUG_INFO_EXPRESSION_TYPE("(() -> kotlin.Unit) -> kotlin.Unit")!>b<!>
|
<!DEBUG_INFO_EXPRESSION_TYPE("(() -> kotlin.Unit) -> kotlin.Unit")!>b<!>
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -686,7 +686,7 @@ fun case_33(a: ((Float) -> Int?)?, b: Float?, c: Boolean?) {
|
|||||||
fun case_34(z1: Boolean?) {
|
fun case_34(z1: Boolean?) {
|
||||||
var z = null
|
var z = null
|
||||||
|
|
||||||
if (true && true && true && true && EnumClassWithNullableProperty.A.prop_1 != <!DEBUG_INFO_CONSTANT!>implicitNullableNothingProperty<!> && <!SENSELESS_COMPARISON!>EnumClassWithNullableProperty.A.prop_1 !== null<!> && EnumClassWithNullableProperty.A.prop_1 !== <!DEBUG_INFO_CONSTANT!>z<!> || z1 != <!DEBUG_INFO_CONSTANT!>implicitNullableNothingProperty<!> || <!ALWAYS_NULL!>z1<!>!! && true && true) {
|
if (true && true && true && true && EnumClassWithNullableProperty.A.prop_1 != <!DEBUG_INFO_CONSTANT!>implicitNullableNothingProperty<!> && <!SENSELESS_COMPARISON!>EnumClassWithNullableProperty.A.prop_1 !== null<!> && EnumClassWithNullableProperty.A.prop_1 !== <!DEBUG_INFO_CONSTANT!>z<!> || z1 != <!DEBUG_INFO_CONSTANT!>implicitNullableNothingProperty<!> || <!ALWAYS_NULL!>z1<!>!! <!UNREACHABLE_CODE!>&& true && true<!>) {
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Int?")!>EnumClassWithNullableProperty.A.prop_1<!>
|
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Int?")!>EnumClassWithNullableProperty.A.prop_1<!>
|
||||||
|
|||||||
@@ -10602,6 +10602,11 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTest {
|
|||||||
runTest("compiler/testData/diagnostics/tests/inference/nothingType/implicitNothingConstraintFromReturn.kt");
|
runTest("compiler/testData/diagnostics/tests/inference/nothingType/implicitNothingConstraintFromReturn.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("inferArgumentToNothingFromNullConstant.kt")
|
||||||
|
public void testInferArgumentToNothingFromNullConstant() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/tests/inference/nothingType/inferArgumentToNothingFromNullConstant.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("kt24490.kt")
|
@TestMetadata("kt24490.kt")
|
||||||
public void testKt24490() throws Exception {
|
public void testKt24490() throws Exception {
|
||||||
runTest("compiler/testData/diagnostics/tests/inference/nothingType/kt24490.kt");
|
runTest("compiler/testData/diagnostics/tests/inference/nothingType/kt24490.kt");
|
||||||
|
|||||||
Generated
+5
@@ -10597,6 +10597,11 @@ public class DiagnosticsUsingJavacTestGenerated extends AbstractDiagnosticsUsing
|
|||||||
runTest("compiler/testData/diagnostics/tests/inference/nothingType/implicitNothingConstraintFromReturn.kt");
|
runTest("compiler/testData/diagnostics/tests/inference/nothingType/implicitNothingConstraintFromReturn.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("inferArgumentToNothingFromNullConstant.kt")
|
||||||
|
public void testInferArgumentToNothingFromNullConstant() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/tests/inference/nothingType/inferArgumentToNothingFromNullConstant.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("kt24490.kt")
|
@TestMetadata("kt24490.kt")
|
||||||
public void testKt24490() throws Exception {
|
public void testKt24490() throws Exception {
|
||||||
runTest("compiler/testData/diagnostics/tests/inference/nothingType/kt24490.kt");
|
runTest("compiler/testData/diagnostics/tests/inference/nothingType/kt24490.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user