FIR: Use intersection of all upper bounds for parameterized types in

ConeKotlinType.canBeNull.

^KT-45903 In progress
This commit is contained in:
Mark Punzalan
2021-04-05 23:08:18 +00:00
committed by TeamCityServer
parent ac85f9d983
commit 21a3a14289
25 changed files with 417 additions and 3 deletions
@@ -0,0 +1,8 @@
fun <T> f(x: T): Int where T : CharSequence?, T : Comparable<T> {
return x.compareTo(other = x)
}
fun test() {
f<@FlexibleNullability String?>(x = s() /*!! @FlexibleNullability String */) /*~> Unit */
f<@FlexibleNullability String?>(x = #STRING /*!! @FlexibleNullability String */) /*~> Unit */
}
@@ -0,0 +1,21 @@
FILE fqName:<root> fileName:/typeParameterWithMixedNullableAndNotNullableBounds.kt
FUN name:f visibility:public modality:FINAL <T> (x:T of <root>.f) returnType:kotlin.Int
TYPE_PARAMETER name:T index:0 variance: superTypes:[kotlin.CharSequence?; kotlin.Comparable<T of <root>.f>]
VALUE_PARAMETER name:x index:0 type:T of <root>.f
BLOCK_BODY
RETURN type=kotlin.Nothing from='public final fun f <T> (x: T of <root>.f): kotlin.Int declared in <root>'
CALL 'public abstract fun compareTo (other: T of kotlin.Comparable): kotlin.Int [operator] declared in kotlin.Comparable' type=kotlin.Int origin=null
$this: GET_VAR 'x: T of <root>.f declared in <root>.f' type=T of <root>.f origin=null
other: GET_VAR 'x: T of <root>.f declared in <root>.f' type=T of <root>.f origin=null
FUN name:test visibility:public modality:FINAL <> () returnType:kotlin.Unit
BLOCK_BODY
TYPE_OP type=kotlin.Unit origin=IMPLICIT_COERCION_TO_UNIT typeOperand=kotlin.Unit
CALL 'public final fun f <T> (x: T of <root>.f): kotlin.Int declared in <root>' type=kotlin.Int origin=null
<T>: @[FlexibleNullability] kotlin.String?
x: TYPE_OP type=@[FlexibleNullability] kotlin.String origin=IMPLICIT_NOTNULL typeOperand=@[FlexibleNullability] kotlin.String
CALL 'public open fun s (): @[FlexibleNullability] kotlin.String? declared in <root>.J' type=@[FlexibleNullability] kotlin.String? origin=null
TYPE_OP type=kotlin.Unit origin=IMPLICIT_COERCION_TO_UNIT typeOperand=kotlin.Unit
CALL 'public final fun f <T> (x: T of <root>.f): kotlin.Int declared in <root>' type=kotlin.Int origin=null
<T>: @[FlexibleNullability] kotlin.String?
x: TYPE_OP type=@[FlexibleNullability] kotlin.String origin=IMPLICIT_NOTNULL typeOperand=@[FlexibleNullability] kotlin.String
GET_FIELD 'FIELD IR_EXTERNAL_JAVA_DECLARATION_STUB name:STRING type:@[FlexibleNullability] kotlin.String? visibility:public [static]' type=@[FlexibleNullability] kotlin.String? origin=GET_PROPERTY
@@ -0,0 +1,16 @@
// FILE: typeParameterWithMixedNullableAndNotNullableBounds.kt
fun <T> f(x: T): Int where T : CharSequence?, T : Comparable<T> {
return x.compareTo(x)
}
fun test() {
f(J.s())
f(J.STRING)
}
// FILE: J.java
public class J {
public static String STRING = s()
public static String s() { return null; }
}
@@ -0,0 +1,8 @@
fun <T> f(x: T): Int where T : CharSequence?, T : Comparable<T> {
return x.compareTo(other = x)
}
fun test() {
f<@FlexibleNullability String?>(x = s()) /*~> Unit */
f<@FlexibleNullability String?>(x = super.#STRING) /*~> Unit */
}
@@ -0,0 +1,19 @@
FILE fqName:<root> fileName:/typeParameterWithMixedNullableAndNotNullableBounds.kt
FUN name:f visibility:public modality:FINAL <T> (x:T of <root>.f) returnType:kotlin.Int
TYPE_PARAMETER name:T index:0 variance: superTypes:[kotlin.CharSequence?; kotlin.Comparable<T of <root>.f>]
VALUE_PARAMETER name:x index:0 type:T of <root>.f
BLOCK_BODY
RETURN type=kotlin.Nothing from='public final fun f <T> (x: T of <root>.f): kotlin.Int declared in <root>'
CALL 'public abstract fun compareTo (other: T of kotlin.Comparable): kotlin.Int [operator] declared in kotlin.Comparable' type=kotlin.Int origin=null
$this: GET_VAR 'x: T of <root>.f declared in <root>.f' type=T of <root>.f origin=null
other: GET_VAR 'x: T of <root>.f declared in <root>.f' type=T of <root>.f origin=null
FUN name:test visibility:public modality:FINAL <> () returnType:kotlin.Unit
BLOCK_BODY
TYPE_OP type=kotlin.Unit origin=IMPLICIT_COERCION_TO_UNIT typeOperand=kotlin.Unit
CALL 'public final fun f <T> (x: T of <root>.f): kotlin.Int declared in <root>' type=kotlin.Int origin=null
<T>: @[FlexibleNullability] kotlin.String?
x: CALL 'public open fun s (): @[FlexibleNullability] kotlin.String? declared in <root>.J' type=@[FlexibleNullability] kotlin.String? origin=null
TYPE_OP type=kotlin.Unit origin=IMPLICIT_COERCION_TO_UNIT typeOperand=kotlin.Unit
CALL 'public final fun f <T> (x: T of <root>.f): kotlin.Int declared in <root>' type=kotlin.Int origin=null
<T>: @[FlexibleNullability] kotlin.String?
x: GET_FIELD 'FIELD IR_EXTERNAL_JAVA_DECLARATION_STUB name:STRING type:@[FlexibleNullability] kotlin.String? visibility:public [static]' type=@[FlexibleNullability] kotlin.String? origin=GET_PROPERTY
@@ -0,0 +1,8 @@
fun <T> f(x: T): Int where T : CharSequence, T : Comparable<T> {
return x.compareTo(other = x)
}
fun test() {
f<@FlexibleNullability String?>(x = s() /*!! @FlexibleNullability String */) /*~> Unit */
f<@FlexibleNullability String?>(x = #STRING /*!! @FlexibleNullability String */) /*~> Unit */
}
@@ -0,0 +1,21 @@
FILE fqName:<root> fileName:/typeParameterWithMultipleNotNullableBounds.kt
FUN name:f visibility:public modality:FINAL <T> (x:T of <root>.f) returnType:kotlin.Int
TYPE_PARAMETER name:T index:0 variance: superTypes:[kotlin.CharSequence; kotlin.Comparable<T of <root>.f>]
VALUE_PARAMETER name:x index:0 type:T of <root>.f
BLOCK_BODY
RETURN type=kotlin.Nothing from='public final fun f <T> (x: T of <root>.f): kotlin.Int declared in <root>'
CALL 'public abstract fun compareTo (other: T of kotlin.Comparable): kotlin.Int [operator] declared in kotlin.Comparable' type=kotlin.Int origin=null
$this: GET_VAR 'x: T of <root>.f declared in <root>.f' type=T of <root>.f origin=null
other: GET_VAR 'x: T of <root>.f declared in <root>.f' type=T of <root>.f origin=null
FUN name:test visibility:public modality:FINAL <> () returnType:kotlin.Unit
BLOCK_BODY
TYPE_OP type=kotlin.Unit origin=IMPLICIT_COERCION_TO_UNIT typeOperand=kotlin.Unit
CALL 'public final fun f <T> (x: T of <root>.f): kotlin.Int declared in <root>' type=kotlin.Int origin=null
<T>: @[FlexibleNullability] kotlin.String?
x: TYPE_OP type=@[FlexibleNullability] kotlin.String origin=IMPLICIT_NOTNULL typeOperand=@[FlexibleNullability] kotlin.String
CALL 'public open fun s (): @[FlexibleNullability] kotlin.String? declared in <root>.J' type=@[FlexibleNullability] kotlin.String? origin=null
TYPE_OP type=kotlin.Unit origin=IMPLICIT_COERCION_TO_UNIT typeOperand=kotlin.Unit
CALL 'public final fun f <T> (x: T of <root>.f): kotlin.Int declared in <root>' type=kotlin.Int origin=null
<T>: @[FlexibleNullability] kotlin.String?
x: TYPE_OP type=@[FlexibleNullability] kotlin.String origin=IMPLICIT_NOTNULL typeOperand=@[FlexibleNullability] kotlin.String
GET_FIELD 'FIELD IR_EXTERNAL_JAVA_DECLARATION_STUB name:STRING type:@[FlexibleNullability] kotlin.String? visibility:public [static]' type=@[FlexibleNullability] kotlin.String? origin=GET_PROPERTY
@@ -0,0 +1,16 @@
// FILE: typeParameterWithMultipleNotNullableBounds.kt
fun <T> f(x: T): Int where T : CharSequence, T : Comparable<T> {
return x.compareTo(x)
}
fun test() {
f(J.s())
f(J.STRING)
}
// FILE: J.java
public class J {
public static String STRING = s()
public static String s() { return null; }
}
@@ -0,0 +1,8 @@
fun <T> f(x: T): Int where T : CharSequence, T : Comparable<T> {
return x.compareTo(other = x)
}
fun test() {
f<@FlexibleNullability String?>(x = s()) /*~> Unit */
f<@FlexibleNullability String?>(x = super.#STRING) /*~> Unit */
}
@@ -0,0 +1,19 @@
FILE fqName:<root> fileName:/typeParameterWithMultipleNotNullableBounds.kt
FUN name:f visibility:public modality:FINAL <T> (x:T of <root>.f) returnType:kotlin.Int
TYPE_PARAMETER name:T index:0 variance: superTypes:[kotlin.CharSequence; kotlin.Comparable<T of <root>.f>]
VALUE_PARAMETER name:x index:0 type:T of <root>.f
BLOCK_BODY
RETURN type=kotlin.Nothing from='public final fun f <T> (x: T of <root>.f): kotlin.Int declared in <root>'
CALL 'public abstract fun compareTo (other: T of kotlin.Comparable): kotlin.Int [operator] declared in kotlin.Comparable' type=kotlin.Int origin=null
$this: GET_VAR 'x: T of <root>.f declared in <root>.f' type=T of <root>.f origin=null
other: GET_VAR 'x: T of <root>.f declared in <root>.f' type=T of <root>.f origin=null
FUN name:test visibility:public modality:FINAL <> () returnType:kotlin.Unit
BLOCK_BODY
TYPE_OP type=kotlin.Unit origin=IMPLICIT_COERCION_TO_UNIT typeOperand=kotlin.Unit
CALL 'public final fun f <T> (x: T of <root>.f): kotlin.Int declared in <root>' type=kotlin.Int origin=null
<T>: @[FlexibleNullability] kotlin.String?
x: CALL 'public open fun s (): @[FlexibleNullability] kotlin.String? declared in <root>.J' type=@[FlexibleNullability] kotlin.String? origin=null
TYPE_OP type=kotlin.Unit origin=IMPLICIT_COERCION_TO_UNIT typeOperand=kotlin.Unit
CALL 'public final fun f <T> (x: T of <root>.f): kotlin.Int declared in <root>' type=kotlin.Int origin=null
<T>: @[FlexibleNullability] kotlin.String?
x: GET_FIELD 'FIELD IR_EXTERNAL_JAVA_DECLARATION_STUB name:STRING type:@[FlexibleNullability] kotlin.String? visibility:public [static]' type=@[FlexibleNullability] kotlin.String? origin=GET_PROPERTY
@@ -0,0 +1,14 @@
fun <T> f(x: T): Int? where T : CharSequence?, T : Comparable<T>? {
return { // BLOCK
val tmp0_safe_receiver: T = x
when {
EQEQ(arg0 = tmp0_safe_receiver, arg1 = null) -> null
else -> tmp0_safe_receiver.compareTo(other = x)
}
}
}
fun test() {
f<@FlexibleNullability String?>(x = s()) /*~> Unit */
f<@FlexibleNullability String?>(x = #STRING) /*~> Unit */
}
@@ -0,0 +1,30 @@
FILE fqName:<root> fileName:/typeParameterWithMultipleNullableBounds.kt
FUN name:f visibility:public modality:FINAL <T> (x:T of <root>.f) returnType:kotlin.Int?
TYPE_PARAMETER name:T index:0 variance: superTypes:[kotlin.CharSequence?; kotlin.Comparable<T of <root>.f>?]
VALUE_PARAMETER name:x index:0 type:T of <root>.f
BLOCK_BODY
RETURN type=kotlin.Nothing from='public final fun f <T> (x: T of <root>.f): kotlin.Int? declared in <root>'
BLOCK type=kotlin.Int? origin=SAFE_CALL
VAR IR_TEMPORARY_VARIABLE name:tmp_0 type:T of <root>.f [val]
GET_VAR 'x: T of <root>.f declared in <root>.f' type=T of <root>.f origin=null
WHEN type=kotlin.Int? origin=null
BRANCH
if: CALL 'public final fun EQEQ (arg0: kotlin.Any?, arg1: kotlin.Any?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EQEQ
arg0: GET_VAR 'val tmp_0: T of <root>.f [val] declared in <root>.f' type=T of <root>.f origin=null
arg1: CONST Null type=kotlin.Nothing? value=null
then: CONST Null type=kotlin.Nothing? value=null
BRANCH
if: CONST Boolean type=kotlin.Boolean value=true
then: CALL 'public abstract fun compareTo (other: T of kotlin.Comparable): kotlin.Int [operator] declared in kotlin.Comparable' type=kotlin.Int origin=null
$this: GET_VAR 'val tmp_0: T of <root>.f [val] declared in <root>.f' type=T of <root>.f origin=null
other: GET_VAR 'x: T of <root>.f declared in <root>.f' type=T of <root>.f origin=null
FUN name:test visibility:public modality:FINAL <> () returnType:kotlin.Unit
BLOCK_BODY
TYPE_OP type=kotlin.Unit origin=IMPLICIT_COERCION_TO_UNIT typeOperand=kotlin.Unit
CALL 'public final fun f <T> (x: T of <root>.f): kotlin.Int? declared in <root>' type=kotlin.Int? origin=null
<T>: @[FlexibleNullability] kotlin.String?
x: CALL 'public open fun s (): @[FlexibleNullability] kotlin.String? declared in <root>.J' type=@[FlexibleNullability] kotlin.String? origin=null
TYPE_OP type=kotlin.Unit origin=IMPLICIT_COERCION_TO_UNIT typeOperand=kotlin.Unit
CALL 'public final fun f <T> (x: T of <root>.f): kotlin.Int? declared in <root>' type=kotlin.Int? origin=null
<T>: @[FlexibleNullability] kotlin.String?
x: GET_FIELD 'FIELD IR_EXTERNAL_JAVA_DECLARATION_STUB name:STRING type:@[FlexibleNullability] kotlin.String? visibility:public [static]' type=@[FlexibleNullability] kotlin.String? origin=GET_PROPERTY
@@ -0,0 +1,16 @@
// FILE: typeParameterWithMultipleNullableBounds.kt
fun <T> f(x: T): Int? where T : CharSequence?, T : Comparable<T>? {
return x?.compareTo(x)
}
fun test() {
f(J.s())
f(J.STRING)
}
// FILE: J.java
public class J {
public static String STRING = s()
public static String s() { return null; }
}
@@ -0,0 +1,14 @@
fun <T> f(x: T): Int? where T : CharSequence?, T : Comparable<T>? {
return { // BLOCK
val tmp0_safe_receiver: T = x
when {
EQEQ(arg0 = tmp0_safe_receiver, arg1 = null) -> null
else -> tmp0_safe_receiver.compareTo(other = x)
}
}
}
fun test() {
f<@FlexibleNullability String?>(x = s()) /*~> Unit */
f<@FlexibleNullability String?>(x = super.#STRING) /*~> Unit */
}
@@ -0,0 +1,30 @@
FILE fqName:<root> fileName:/typeParameterWithMultipleNullableBounds.kt
FUN name:f visibility:public modality:FINAL <T> (x:T of <root>.f) returnType:kotlin.Int?
TYPE_PARAMETER name:T index:0 variance: superTypes:[kotlin.CharSequence?; kotlin.Comparable<T of <root>.f>?]
VALUE_PARAMETER name:x index:0 type:T of <root>.f
BLOCK_BODY
RETURN type=kotlin.Nothing from='public final fun f <T> (x: T of <root>.f): kotlin.Int? declared in <root>'
BLOCK type=kotlin.Int? origin=SAFE_CALL
VAR IR_TEMPORARY_VARIABLE name:tmp_0 type:T of <root>.f [val]
GET_VAR 'x: T of <root>.f declared in <root>.f' type=T of <root>.f origin=null
WHEN type=kotlin.Int? origin=null
BRANCH
if: CALL 'public final fun EQEQ (arg0: kotlin.Any?, arg1: kotlin.Any?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EQEQ
arg0: GET_VAR 'val tmp_0: T of <root>.f [val] declared in <root>.f' type=T of <root>.f origin=null
arg1: CONST Null type=kotlin.Nothing? value=null
then: CONST Null type=kotlin.Nothing? value=null
BRANCH
if: CONST Boolean type=kotlin.Boolean value=true
then: CALL 'public abstract fun compareTo (other: T of kotlin.Comparable): kotlin.Int [operator] declared in kotlin.Comparable' type=kotlin.Int origin=null
$this: GET_VAR 'val tmp_0: T of <root>.f [val] declared in <root>.f' type=T of <root>.f origin=null
other: GET_VAR 'x: T of <root>.f declared in <root>.f' type=T of <root>.f origin=null
FUN name:test visibility:public modality:FINAL <> () returnType:kotlin.Unit
BLOCK_BODY
TYPE_OP type=kotlin.Unit origin=IMPLICIT_COERCION_TO_UNIT typeOperand=kotlin.Unit
CALL 'public final fun f <T> (x: T of <root>.f): kotlin.Int? declared in <root>' type=kotlin.Int? origin=null
<T>: @[FlexibleNullability] kotlin.String?
x: CALL 'public open fun s (): @[FlexibleNullability] kotlin.String? declared in <root>.J' type=@[FlexibleNullability] kotlin.String? origin=null
TYPE_OP type=kotlin.Unit origin=IMPLICIT_COERCION_TO_UNIT typeOperand=kotlin.Unit
CALL 'public final fun f <T> (x: T of <root>.f): kotlin.Int? declared in <root>' type=kotlin.Int? origin=null
<T>: @[FlexibleNullability] kotlin.String?
x: GET_FIELD 'FIELD IR_EXTERNAL_JAVA_DECLARATION_STUB name:STRING type:@[FlexibleNullability] kotlin.String? visibility:public [static]' type=@[FlexibleNullability] kotlin.String? origin=GET_PROPERTY