FIR: Use intersection of all upper bounds for parameterized types in
ConeKotlinType.canBeNull. ^KT-45903 In progress
This commit is contained in:
committed by
TeamCityServer
parent
ac85f9d983
commit
21a3a14289
+18
@@ -21649,6 +21649,24 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
|
|||||||
runTest("compiler/testData/codegen/box/javaInterop/notNullAssertions/staticCallErrorMessage.kt");
|
runTest("compiler/testData/codegen/box/javaInterop/notNullAssertions/staticCallErrorMessage.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("typeParameterWithMixedNullableAndNotNullableBounds.kt")
|
||||||
|
public void testTypeParameterWithMixedNullableAndNotNullableBounds() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/javaInterop/notNullAssertions/typeParameterWithMixedNullableAndNotNullableBounds.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("typeParameterWithMultipleNotNullableBounds.kt")
|
||||||
|
public void testTypeParameterWithMultipleNotNullableBounds() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/javaInterop/notNullAssertions/typeParameterWithMultipleNotNullableBounds.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("typeParameterWithMultipleNullableBounds.kt")
|
||||||
|
public void testTypeParameterWithMultipleNullableBounds() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/javaInterop/notNullAssertions/typeParameterWithMultipleNullableBounds.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Nested
|
@Nested
|
||||||
@TestMetadata("compiler/testData/codegen/box/javaInterop/notNullAssertions/enhancedNullability")
|
@TestMetadata("compiler/testData/codegen/box/javaInterop/notNullAssertions/enhancedNullability")
|
||||||
@TestDataPath("$PROJECT_ROOT")
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
|||||||
Generated
+18
@@ -2737,6 +2737,24 @@ public class Fir2IrTextTestGenerated extends AbstractFir2IrTextTest {
|
|||||||
runTest("compiler/testData/ir/irText/types/nullChecks/platformTypeReceiver.kt");
|
runTest("compiler/testData/ir/irText/types/nullChecks/platformTypeReceiver.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("typeParameterWithMixedNullableAndNotNullableBounds.kt")
|
||||||
|
public void testTypeParameterWithMixedNullableAndNotNullableBounds() throws Exception {
|
||||||
|
runTest("compiler/testData/ir/irText/types/nullChecks/typeParameterWithMixedNullableAndNotNullableBounds.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("typeParameterWithMultipleNotNullableBounds.kt")
|
||||||
|
public void testTypeParameterWithMultipleNotNullableBounds() throws Exception {
|
||||||
|
runTest("compiler/testData/ir/irText/types/nullChecks/typeParameterWithMultipleNotNullableBounds.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("typeParameterWithMultipleNullableBounds.kt")
|
||||||
|
public void testTypeParameterWithMultipleNullableBounds() throws Exception {
|
||||||
|
runTest("compiler/testData/ir/irText/types/nullChecks/typeParameterWithMultipleNullableBounds.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Nested
|
@Nested
|
||||||
@TestMetadata("compiler/testData/ir/irText/types/nullChecks/nullCheckOnLambdaResult")
|
@TestMetadata("compiler/testData/ir/irText/types/nullChecks/nullCheckOnLambdaResult")
|
||||||
@TestDataPath("$PROJECT_ROOT")
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ package org.jetbrains.kotlin.fir.types
|
|||||||
import org.jetbrains.kotlin.builtins.functions.FunctionClassKind
|
import org.jetbrains.kotlin.builtins.functions.FunctionClassKind
|
||||||
import org.jetbrains.kotlin.fir.expressions.FirAnnotationCall
|
import org.jetbrains.kotlin.fir.expressions.FirAnnotationCall
|
||||||
import org.jetbrains.kotlin.fir.render
|
import org.jetbrains.kotlin.fir.render
|
||||||
|
import org.jetbrains.kotlin.fir.symbols.impl.FirTypeParameterSymbol
|
||||||
import org.jetbrains.kotlin.name.StandardClassIds
|
import org.jetbrains.kotlin.name.StandardClassIds
|
||||||
import org.jetbrains.kotlin.fir.types.impl.FirImplicitBuiltinTypeRef
|
import org.jetbrains.kotlin.fir.types.impl.FirImplicitBuiltinTypeRef
|
||||||
import org.jetbrains.kotlin.name.ClassId
|
import org.jetbrains.kotlin.name.ClassId
|
||||||
@@ -165,8 +166,8 @@ val ConeKotlinType.canBeNull: Boolean
|
|||||||
return when (this) {
|
return when (this) {
|
||||||
is ConeFlexibleType -> upperBound.canBeNull
|
is ConeFlexibleType -> upperBound.canBeNull
|
||||||
is ConeDefinitelyNotNullType -> false
|
is ConeDefinitelyNotNullType -> false
|
||||||
is ConeTypeParameterType -> this.lookupTag.typeParameterSymbol.fir.bounds.any { it.canBeNull }
|
is ConeTypeParameterType -> this.lookupTag.typeParameterSymbol.fir.bounds.all { it.coneType.canBeNull }
|
||||||
is ConeIntersectionType -> intersectedTypes.any { it.canBeNull }
|
is ConeIntersectionType -> intersectedTypes.all { it.canBeNull }
|
||||||
else -> isNullable
|
else -> isNullable
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -180,4 +181,4 @@ val ConeKotlinType?.functionTypeKind: FunctionClassKind?
|
|||||||
}
|
}
|
||||||
|
|
||||||
val FirResolvedTypeRef.functionTypeKind: FunctionClassKind?
|
val FirResolvedTypeRef.functionTypeKind: FunctionClassKind?
|
||||||
get() = type.functionTypeKind
|
get() = type.functionTypeKind
|
||||||
|
|||||||
+26
@@ -0,0 +1,26 @@
|
|||||||
|
// TARGET_BACKEND: JVM
|
||||||
|
// IGNORE_BACKEND: JVM, JVM_IR
|
||||||
|
|
||||||
|
// Note: This fails on non-FIR because of KT-45903 (missing not-null assertion on argument).
|
||||||
|
|
||||||
|
// FILE: typeParameterWithMixedNullableAndNotNullableBounds.kt
|
||||||
|
fun <T> f(x: T): Int where T : CharSequence?, T : Comparable<T> {
|
||||||
|
try {
|
||||||
|
return x.compareTo(x)
|
||||||
|
} catch (e: NullPointerException) {
|
||||||
|
return 42
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun box() = try {
|
||||||
|
val r = f(J.s())
|
||||||
|
if (r == 42) "FAIL" else "Unexpected, x.compareTo(x) should have NPE'd"
|
||||||
|
} catch (e: NullPointerException) {
|
||||||
|
"OK"
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// FILE: J.java
|
||||||
|
public class J {
|
||||||
|
public static String s() { return null; }
|
||||||
|
}
|
||||||
+22
@@ -0,0 +1,22 @@
|
|||||||
|
// TARGET_BACKEND: JVM
|
||||||
|
// FILE: typeParameterWithMultipleNotNullableBounds.kt
|
||||||
|
fun <T> f(x: T): Int where T : CharSequence, T : Comparable<T> {
|
||||||
|
try {
|
||||||
|
return x.compareTo(x)
|
||||||
|
} catch (e: NullPointerException) {
|
||||||
|
return 42
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun box() = try {
|
||||||
|
val r = f(J.s())
|
||||||
|
if (r == 42) "FAIL" else "Unexpected, x.compareTo(x) should have NPE'd"
|
||||||
|
} catch (e: NullPointerException) {
|
||||||
|
"OK"
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// FILE: J.java
|
||||||
|
public class J {
|
||||||
|
public static String s() { return null; }
|
||||||
|
}
|
||||||
+12
@@ -0,0 +1,12 @@
|
|||||||
|
// TARGET_BACKEND: JVM
|
||||||
|
// FILE: typeParameterWithMultipleNullableBounds.kt
|
||||||
|
fun <T> f(x: T): Int? where T : CharSequence?, T : Comparable<T>? {
|
||||||
|
return x?.compareTo(x)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun box() = f(J.s()) ?: "OK"
|
||||||
|
|
||||||
|
// FILE: J.java
|
||||||
|
public class J {
|
||||||
|
public static String s() { return null; }
|
||||||
|
}
|
||||||
+8
@@ -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 */
|
||||||
|
}
|
||||||
+21
@@ -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
|
||||||
Vendored
+16
@@ -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; }
|
||||||
|
}
|
||||||
+8
@@ -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 */
|
||||||
|
}
|
||||||
Vendored
+19
@@ -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
|
||||||
Vendored
+8
@@ -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 */
|
||||||
|
}
|
||||||
Vendored
+21
@@ -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
|
||||||
+16
@@ -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; }
|
||||||
|
}
|
||||||
Vendored
+8
@@ -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 */
|
||||||
|
}
|
||||||
Vendored
+19
@@ -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
|
||||||
Vendored
+14
@@ -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 */
|
||||||
|
}
|
||||||
Vendored
+30
@@ -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
|
||||||
+16
@@ -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; }
|
||||||
|
}
|
||||||
Vendored
+14
@@ -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 */
|
||||||
|
}
|
||||||
+30
@@ -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
|
||||||
+18
@@ -21631,6 +21631,24 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
|||||||
runTest("compiler/testData/codegen/box/javaInterop/notNullAssertions/staticCallErrorMessage.kt");
|
runTest("compiler/testData/codegen/box/javaInterop/notNullAssertions/staticCallErrorMessage.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("typeParameterWithMixedNullableAndNotNullableBounds.kt")
|
||||||
|
public void testTypeParameterWithMixedNullableAndNotNullableBounds() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/javaInterop/notNullAssertions/typeParameterWithMixedNullableAndNotNullableBounds.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("typeParameterWithMultipleNotNullableBounds.kt")
|
||||||
|
public void testTypeParameterWithMultipleNotNullableBounds() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/javaInterop/notNullAssertions/typeParameterWithMultipleNotNullableBounds.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("typeParameterWithMultipleNullableBounds.kt")
|
||||||
|
public void testTypeParameterWithMultipleNullableBounds() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/javaInterop/notNullAssertions/typeParameterWithMultipleNullableBounds.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Nested
|
@Nested
|
||||||
@TestMetadata("compiler/testData/codegen/box/javaInterop/notNullAssertions/enhancedNullability")
|
@TestMetadata("compiler/testData/codegen/box/javaInterop/notNullAssertions/enhancedNullability")
|
||||||
@TestDataPath("$PROJECT_ROOT")
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
|||||||
+18
@@ -21649,6 +21649,24 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
|
|||||||
runTest("compiler/testData/codegen/box/javaInterop/notNullAssertions/staticCallErrorMessage.kt");
|
runTest("compiler/testData/codegen/box/javaInterop/notNullAssertions/staticCallErrorMessage.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("typeParameterWithMixedNullableAndNotNullableBounds.kt")
|
||||||
|
public void testTypeParameterWithMixedNullableAndNotNullableBounds() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/javaInterop/notNullAssertions/typeParameterWithMixedNullableAndNotNullableBounds.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("typeParameterWithMultipleNotNullableBounds.kt")
|
||||||
|
public void testTypeParameterWithMultipleNotNullableBounds() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/javaInterop/notNullAssertions/typeParameterWithMultipleNotNullableBounds.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("typeParameterWithMultipleNullableBounds.kt")
|
||||||
|
public void testTypeParameterWithMultipleNullableBounds() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/javaInterop/notNullAssertions/typeParameterWithMultipleNullableBounds.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Nested
|
@Nested
|
||||||
@TestMetadata("compiler/testData/codegen/box/javaInterop/notNullAssertions/enhancedNullability")
|
@TestMetadata("compiler/testData/codegen/box/javaInterop/notNullAssertions/enhancedNullability")
|
||||||
@TestDataPath("$PROJECT_ROOT")
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
|||||||
Generated
+18
@@ -2737,6 +2737,24 @@ public class IrTextTestGenerated extends AbstractIrTextTest {
|
|||||||
runTest("compiler/testData/ir/irText/types/nullChecks/platformTypeReceiver.kt");
|
runTest("compiler/testData/ir/irText/types/nullChecks/platformTypeReceiver.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("typeParameterWithMixedNullableAndNotNullableBounds.kt")
|
||||||
|
public void testTypeParameterWithMixedNullableAndNotNullableBounds() throws Exception {
|
||||||
|
runTest("compiler/testData/ir/irText/types/nullChecks/typeParameterWithMixedNullableAndNotNullableBounds.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("typeParameterWithMultipleNotNullableBounds.kt")
|
||||||
|
public void testTypeParameterWithMultipleNotNullableBounds() throws Exception {
|
||||||
|
runTest("compiler/testData/ir/irText/types/nullChecks/typeParameterWithMultipleNotNullableBounds.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("typeParameterWithMultipleNullableBounds.kt")
|
||||||
|
public void testTypeParameterWithMultipleNullableBounds() throws Exception {
|
||||||
|
runTest("compiler/testData/ir/irText/types/nullChecks/typeParameterWithMultipleNullableBounds.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Nested
|
@Nested
|
||||||
@TestMetadata("compiler/testData/ir/irText/types/nullChecks/nullCheckOnLambdaResult")
|
@TestMetadata("compiler/testData/ir/irText/types/nullChecks/nullCheckOnLambdaResult")
|
||||||
@TestDataPath("$PROJECT_ROOT")
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
|||||||
+15
@@ -18025,6 +18025,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
|
|||||||
runTest("compiler/testData/codegen/box/javaInterop/notNullAssertions/kt24258.kt");
|
runTest("compiler/testData/codegen/box/javaInterop/notNullAssertions/kt24258.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("typeParameterWithMixedNullableAndNotNullableBounds.kt")
|
||||||
|
public void ignoreTypeParameterWithMixedNullableAndNotNullableBounds() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/javaInterop/notNullAssertions/typeParameterWithMixedNullableAndNotNullableBounds.kt");
|
||||||
|
}
|
||||||
|
|
||||||
private void runTest(String testDataFilePath) throws Exception {
|
private void runTest(String testDataFilePath) throws Exception {
|
||||||
KotlinTestUtils.runTest(this::doTest, TargetBackend.JVM, testDataFilePath);
|
KotlinTestUtils.runTest(this::doTest, TargetBackend.JVM, testDataFilePath);
|
||||||
}
|
}
|
||||||
@@ -18133,6 +18138,16 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
|
|||||||
runTest("compiler/testData/codegen/box/javaInterop/notNullAssertions/staticCallErrorMessage.kt");
|
runTest("compiler/testData/codegen/box/javaInterop/notNullAssertions/staticCallErrorMessage.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("typeParameterWithMultipleNotNullableBounds.kt")
|
||||||
|
public void testTypeParameterWithMultipleNotNullableBounds() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/javaInterop/notNullAssertions/typeParameterWithMultipleNotNullableBounds.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("typeParameterWithMultipleNullableBounds.kt")
|
||||||
|
public void testTypeParameterWithMultipleNullableBounds() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/javaInterop/notNullAssertions/typeParameterWithMultipleNullableBounds.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("compiler/testData/codegen/box/javaInterop/notNullAssertions/enhancedNullability")
|
@TestMetadata("compiler/testData/codegen/box/javaInterop/notNullAssertions/enhancedNullability")
|
||||||
@TestDataPath("$PROJECT_ROOT")
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
@RunWith(JUnit3RunnerWithInners.class)
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
|||||||
Reference in New Issue
Block a user