FIR2IR: add implicit NOT_NULL cast for @FlexibleNullability type

This commit is contained in:
Jinseong Jeon
2020-11-12 21:54:05 -08:00
committed by teamcityserver
parent b658e99f91
commit 4cb32cd38a
24 changed files with 81 additions and 48 deletions
@@ -30,6 +30,7 @@ import org.jetbrains.kotlin.ir.expressions.*
import org.jetbrains.kotlin.ir.expressions.impl.IrTypeOperatorCallImpl
import org.jetbrains.kotlin.ir.types.IrType
import org.jetbrains.kotlin.ir.types.removeAnnotations
import org.jetbrains.kotlin.ir.types.withHasQuestionMark
import org.jetbrains.kotlin.ir.util.classId
import org.jetbrains.kotlin.ir.util.coerceToUnitIfNeeded
import org.jetbrains.kotlin.ir.util.parentAsClass
@@ -209,6 +210,9 @@ class Fir2IrImplicitCastInserter(
expectedType.isUnit -> {
coerceToUnitIfNeeded(type, irBuiltIns)
}
valueType.isNullabilityFlexible() && valueType.canBeNull && !expectedType.acceptsNullValues() -> {
insertImplicitNotNullCastIfNeeded(expression)
}
valueType.hasEnhancedNullability() && !expectedType.acceptsNullValues() -> {
insertImplicitNotNullCastIfNeeded(expression)
}
@@ -218,8 +222,16 @@ class Fir2IrImplicitCastInserter(
}
}
private fun FirTypeRef.isNullabilityFlexible(): Boolean {
if (hasFlexibleNullability()) {
return true
}
val flexibility = coneTypeSafe<ConeFlexibleType>() ?: return false
return flexibility.lowerBound.isMarkedNullable != flexibility.upperBound.isMarkedNullable
}
private fun FirTypeRef.acceptsNullValues(): Boolean =
isMarkedNullable == true || hasEnhancedNullability()
canBeNull || hasEnhancedNullability()
private fun IrExpression.insertImplicitNotNullCastIfNeeded(expression: FirExpression): IrExpression {
// [TypeOperatorLowering] will retrieve the source (from start offset to end offset) as an assertion message.
@@ -227,9 +239,11 @@ class Fir2IrImplicitCastInserter(
if (expression.source == null) {
return this
}
// Cast type massage 1. Remove @EnhancedNullability
// Cast type massage 2. Convert it to a non-null variant (in case of @FlexibleNullability)
val castType = type.removeAnnotations {
it.symbol.owner.parentAsClass.classId == CompilerConeAttributes.EnhancedNullability.ANNOTATION_CLASS_ID
}
}.withHasQuestionMark(false)
return IrTypeOperatorCallImpl(
this.startOffset,
this.endOffset,
@@ -138,3 +138,20 @@ private fun ConeTypeParameterType.hasNotNullUpperBound(): Boolean {
}
}
}
val FirTypeRef.canBeNull: Boolean
get() = coneType.canBeNull
val ConeKotlinType.canBeNull: Boolean
get() {
if (isMarkedNullable) {
return true
}
return when (this) {
is ConeFlexibleType -> upperBound.canBeNull
is ConeDefinitelyNotNullType -> false
is ConeTypeParameterType -> this.lookupTag.typeParameterSymbol.fir.bounds.any { it.canBeNull }
is ConeIntersectionType -> intersectedTypes.any { it.canBeNull }
else -> isNullable
}
}
@@ -1,4 +1,3 @@
// IGNORE_BACKEND_FIR: JVM_IR
// TARGET_BACKEND: JVM
// JVM_TARGET: 1.8
// WITH_RUNTIME
@@ -1,4 +1,3 @@
// IGNORE_BACKEND_FIR: JVM_IR
// TARGET_BACKEND: JVM
// JVM_TARGET: 1.8
// WITH_RUNTIME
@@ -1,4 +1,3 @@
// IGNORE_BACKEND_FIR: JVM_IR
// TARGET_BACKEND: JVM
// FULL_JDK
@@ -1,4 +1,3 @@
// IGNORE_BACKEND_FIR: JVM_IR
// TARGET_BACKEND: JVM
// FILE: test.kt
fun f(x: String) = "Fail 1"
@@ -1,5 +1,4 @@
// TARGET_BACKEND: JVM
// IGNORE_BACKEND_FIR: JVM_IR
// FILE: stringVsTConstrained.kt
fun <T> useTConstrained(xs: Array<T>, fn: () -> T) = fn()
@@ -1,4 +1,3 @@
// IGNORE_BACKEND_FIR: JVM_IR
// TARGET_BACKEND: JVM
// FILE: test.kt
fun f(x: String) = "Fail 1"
@@ -1,4 +1,3 @@
// IGNORE_BACKEND_FIR: JVM_IR
import java.util.ArrayList
fun foo(): Any {
@@ -1,4 +1,3 @@
// IGNORE_BACKEND_FIR: JVM_IR
class A<T> {
fun add(element: T) {}
}
@@ -1,8 +1,4 @@
// FILE: test/CallableDescriptor.java
// IGNORE_BACKEND_FIR: JVM_IR
// Here FIR adds implicit NOT_NULL cast for `origin`, resulting in an assertion being added,
// which is the correct (yet mismatching) behavior, according to https://youtrack.jetbrains.com/issue/KT-35656
// JVM_IR:
// Here in 'original in emptySet<D>()' T = '@EnhancedNullability CallableDescriptor' is inferred for 'Iterable<T>.contains(T)'.
// Using value of '@EnhancedNullability CallableDescriptor' type where '@EnhancedNullability CallableDescriptor' is expected
@@ -1,4 +1,3 @@
// IGNORE_BACKEND_FIR: JVM_IR
// FILE: j/J.java
package j;
@@ -1,4 +1,3 @@
// IGNORE_BACKEND_FIR: JVM_IR
// FILE: j/J.java
package j;
@@ -1,5 +1,4 @@
// !API_VERSION: LATEST
// IGNORE_BACKEND_FIR: JVM_IR
// FILE: j/J.java
package j;
@@ -2,5 +2,6 @@ FILE fqName:<root> fileName:/implicitCastOnPlatformType.kt
FUN name:test visibility:public modality:FINAL <> () returnType:kotlin.String
BLOCK_BODY
RETURN type=kotlin.Nothing from='public final fun test (): kotlin.String declared in <root>'
CALL 'public open fun getProperty (p0: kotlin.String?): kotlin.String? declared in java.lang.System' type=kotlin.String? origin=null
p0: CONST String type=kotlin.String value="test"
TYPE_OP type=kotlin.String origin=IMPLICIT_NOTNULL typeOperand=kotlin.String
CALL 'public open fun getProperty (p0: kotlin.String?): kotlin.String? declared in java.lang.System' type=kotlin.String? origin=null
p0: CONST String type=kotlin.String value="test"
@@ -25,7 +25,8 @@ FILE fqName:<root> fileName:/nullCheckOnLambdaReturn.kt
FUN LOCAL_FUNCTION_FOR_LAMBDA name:<anonymous> visibility:local modality:FINAL <> () returnType:kotlin.Any
BLOCK_BODY
RETURN type=kotlin.Nothing from='local final fun <anonymous> (): kotlin.Any declared in <root>.test1'
CALL 'public open fun foo (): kotlin.String? declared in <root>.J' type=kotlin.String? origin=null
TYPE_OP type=kotlin.String origin=IMPLICIT_NOTNULL typeOperand=kotlin.String
CALL 'public open fun foo (): kotlin.String? declared in <root>.J' type=kotlin.String? origin=null
PROPERTY name:test2 visibility:public modality:FINAL [val]
FIELD PROPERTY_BACKING_FIELD name:test2 type:kotlin.Function0<kotlin.Any> visibility:private [final,static]
EXPRESSION_BODY
@@ -7,15 +7,16 @@ FILE fqName:<root> fileName:/genericSamSmartcast.kt
if: TYPE_OP type=kotlin.Boolean origin=INSTANCEOF typeOperand=<root>.A<*>
GET_VAR 'x: kotlin.Any declared in <root>.f' type=kotlin.Any origin=null
then: RETURN type=kotlin.Nothing from='public final fun f (x: kotlin.Any): kotlin.String declared in <root>'
CALL 'public open fun call (block: <root>.A.I<T of <root>.A?>?): kotlin.String? declared in <root>.A' type=kotlin.String? origin=null
$this: TYPE_OP type=<root>.A<*> origin=IMPLICIT_CAST typeOperand=<root>.A<*>
GET_VAR 'x: kotlin.Any declared in <root>.f' type=kotlin.Any origin=null
block: TYPE_OP type=<root>.A.I<kotlin.Any?>? origin=SAM_CONVERSION typeOperand=<root>.A.I<kotlin.Any?>?
FUN_EXPR type=kotlin.Function1<kotlin.Any?, kotlin.String?> origin=LAMBDA
FUN LOCAL_FUNCTION_FOR_LAMBDA name:<anonymous> visibility:local modality:FINAL <> (y:kotlin.Any?) returnType:kotlin.String?
VALUE_PARAMETER name:y index:0 type:kotlin.Any?
BLOCK_BODY
RETURN type=kotlin.Nothing from='local final fun <anonymous> (y: kotlin.Any?): kotlin.String? declared in <root>.f'
CONST String type=kotlin.String value="OK"
TYPE_OP type=kotlin.String origin=IMPLICIT_NOTNULL typeOperand=kotlin.String
CALL 'public open fun call (block: <root>.A.I<T of <root>.A?>?): kotlin.String? declared in <root>.A' type=kotlin.String? origin=null
$this: TYPE_OP type=<root>.A<*> origin=IMPLICIT_CAST typeOperand=<root>.A<*>
GET_VAR 'x: kotlin.Any declared in <root>.f' type=kotlin.Any origin=null
block: TYPE_OP type=<root>.A.I<kotlin.Any?>? origin=SAM_CONVERSION typeOperand=<root>.A.I<kotlin.Any?>?
FUN_EXPR type=kotlin.Function1<kotlin.Any?, kotlin.String?> origin=LAMBDA
FUN LOCAL_FUNCTION_FOR_LAMBDA name:<anonymous> visibility:local modality:FINAL <> (y:kotlin.Any?) returnType:kotlin.String?
VALUE_PARAMETER name:y index:0 type:kotlin.Any?
BLOCK_BODY
RETURN type=kotlin.Nothing from='local final fun <anonymous> (y: kotlin.Any?): kotlin.String? declared in <root>.f'
CONST String type=kotlin.String value="OK"
RETURN type=kotlin.Nothing from='public final fun f (x: kotlin.Any): kotlin.String declared in <root>'
CONST String type=kotlin.String value="Fail"
@@ -33,4 +33,5 @@ FILE fqName:<root> fileName:/samConstructors.kt
RETURN type=kotlin.Nothing from='local final fun <anonymous> (a: kotlin.Int?, b: kotlin.Int?): kotlin.Int declared in <root>.test4'
CALL 'public final fun minus (other: kotlin.Int): kotlin.Int [operator] declared in kotlin.Int' type=kotlin.Int origin=MINUS
$this: GET_VAR 'a: kotlin.Int? declared in <root>.test4.<anonymous>' type=kotlin.Int? origin=null
other: GET_VAR 'b: kotlin.Int? declared in <root>.test4.<anonymous>' type=kotlin.Int? origin=null
other: TYPE_OP type=kotlin.Int origin=IMPLICIT_NOTNULL typeOperand=kotlin.Int
GET_VAR 'b: kotlin.Int? declared in <root>.test4.<anonymous>' type=kotlin.Int? origin=null
@@ -141,7 +141,8 @@ FILE fqName:<root> fileName:/enhancedNullabilityInDestructuringAssignment.kt
$this: GET_VAR 'val tmp_1: <root>.Q<@[FlexibleNullability] kotlin.String, kotlin.String?>? [val] declared in <root>.test2' type=<root>.Q<@[FlexibleNullability] kotlin.String, kotlin.String?>? origin=null
CALL 'public final fun use (x: kotlin.Any, y: kotlin.Any): kotlin.Unit declared in <root>' type=kotlin.Unit origin=null
x: GET_VAR 'val x: @[FlexibleNullability] kotlin.String [val] declared in <root>.test2' type=@[FlexibleNullability] kotlin.String origin=null
y: GET_VAR 'val y: kotlin.String? [val] declared in <root>.test2' type=kotlin.String? origin=null
y: TYPE_OP type=kotlin.String origin=IMPLICIT_NOTNULL typeOperand=kotlin.String
GET_VAR 'val y: kotlin.String? [val] declared in <root>.test2' type=kotlin.String? origin=null
FUN name:test2Desugared visibility:public modality:FINAL <> () returnType:kotlin.Unit
BLOCK_BODY
VAR name:tmp type:<root>.Q<@[FlexibleNullability] kotlin.String, kotlin.String?>? [val]
@@ -154,7 +155,8 @@ FILE fqName:<root> fileName:/enhancedNullabilityInDestructuringAssignment.kt
$this: GET_VAR 'val tmp: <root>.Q<@[FlexibleNullability] kotlin.String, kotlin.String?>? [val] declared in <root>.test2Desugared' type=<root>.Q<@[FlexibleNullability] kotlin.String, kotlin.String?>? origin=null
CALL 'public final fun use (x: kotlin.Any, y: kotlin.Any): kotlin.Unit declared in <root>' type=kotlin.Unit origin=null
x: GET_VAR 'val x: @[FlexibleNullability] kotlin.String [val] declared in <root>.test2Desugared' type=@[FlexibleNullability] kotlin.String origin=null
y: GET_VAR 'val y: kotlin.String? [val] declared in <root>.test2Desugared' type=kotlin.String? origin=null
y: TYPE_OP type=kotlin.String origin=IMPLICIT_NOTNULL typeOperand=kotlin.String
GET_VAR 'val y: kotlin.String? [val] declared in <root>.test2Desugared' type=kotlin.String? origin=null
FUN name:test3 visibility:public modality:FINAL <> () returnType:kotlin.Unit
BLOCK_BODY
VAR IR_TEMPORARY_VARIABLE name:tmp_2 type:<root>.Q<@[FlexibleNullability] kotlin.String, kotlin.String?> [val]
@@ -168,7 +170,8 @@ FILE fqName:<root> fileName:/enhancedNullabilityInDestructuringAssignment.kt
$this: GET_VAR 'val tmp_2: <root>.Q<@[FlexibleNullability] kotlin.String, kotlin.String?> [val] declared in <root>.test3' type=<root>.Q<@[FlexibleNullability] kotlin.String, kotlin.String?> origin=null
CALL 'public final fun use (x: kotlin.Any, y: kotlin.Any): kotlin.Unit declared in <root>' type=kotlin.Unit origin=null
x: GET_VAR 'val x: @[FlexibleNullability] kotlin.String [val] declared in <root>.test3' type=@[FlexibleNullability] kotlin.String origin=null
y: GET_VAR 'val y: kotlin.String? [val] declared in <root>.test3' type=kotlin.String? origin=null
y: TYPE_OP type=kotlin.String origin=IMPLICIT_NOTNULL typeOperand=kotlin.String
GET_VAR 'val y: kotlin.String? [val] declared in <root>.test3' type=kotlin.String? origin=null
FUN name:test4 visibility:public modality:FINAL <> () returnType:kotlin.Unit
BLOCK_BODY
VAR IR_TEMPORARY_VARIABLE name:tmp_3 type:kotlin.collections.IndexedValue<<root>.P?> [val]
@@ -185,4 +188,5 @@ FILE fqName:<root> fileName:/enhancedNullabilityInDestructuringAssignment.kt
$this: GET_VAR 'val tmp_3: kotlin.collections.IndexedValue<<root>.P?> [val] declared in <root>.test4' type=kotlin.collections.IndexedValue<<root>.P?> origin=null
CALL 'public final fun use (x: kotlin.Any, y: kotlin.Any): kotlin.Unit declared in <root>' type=kotlin.Unit origin=null
x: GET_VAR 'val x: kotlin.Int [val] declared in <root>.test4' type=kotlin.Int origin=null
y: GET_VAR 'val y: <root>.P? [val] declared in <root>.test4' type=<root>.P? origin=null
y: TYPE_OP type=<root>.P origin=IMPLICIT_NOTNULL typeOperand=<root>.P
GET_VAR 'val y: <root>.P? [val] declared in <root>.test4' type=<root>.P? origin=null
@@ -75,7 +75,8 @@ FILE fqName:<root> fileName:/enhancedNullabilityInForLoop.kt
CALL 'public abstract fun next (): T of kotlin.collections.MutableIterator [fake_override,operator] declared in kotlin.collections.MutableIterator' type=<root>.P? origin=FOR_LOOP_NEXT
$this: GET_VAR 'val tmp_3: kotlin.collections.MutableIterator<<root>.P?> [val] declared in <root>.testForInListUse' type=kotlin.collections.MutableIterator<<root>.P?> origin=null
CALL 'public final fun use (s: <root>.P): kotlin.Unit declared in <root>' type=kotlin.Unit origin=null
s: GET_VAR 'val x: <root>.P? [val] declared in <root>.testForInListUse' type=<root>.P? origin=null
s: TYPE_OP type=<root>.P origin=IMPLICIT_NOTNULL typeOperand=<root>.P
GET_VAR 'val x: <root>.P? [val] declared in <root>.testForInListUse' type=<root>.P? origin=null
CALL 'public open fun use (s: @[EnhancedNullability] <root>.P): kotlin.Unit declared in <root>.J' type=kotlin.Unit origin=null
s: GET_VAR 'val x: <root>.P? [val] declared in <root>.testForInListUse' type=<root>.P? origin=null
FUN name:testForInArrayUse visibility:public modality:FINAL <> (j:<root>.J) returnType:kotlin.Unit
@@ -94,7 +95,8 @@ FILE fqName:<root> fileName:/enhancedNullabilityInForLoop.kt
CALL 'public abstract fun next (): T of kotlin.collections.Iterator [operator] declared in kotlin.collections.Iterator' type=<root>.P? origin=FOR_LOOP_NEXT
$this: GET_VAR 'val tmp_4: kotlin.collections.Iterator<<root>.P?> [val] declared in <root>.testForInArrayUse' type=kotlin.collections.Iterator<<root>.P?> origin=null
CALL 'public final fun use (s: <root>.P): kotlin.Unit declared in <root>' type=kotlin.Unit origin=null
s: GET_VAR 'val x: <root>.P? [val] declared in <root>.testForInArrayUse' type=<root>.P? origin=null
s: TYPE_OP type=<root>.P origin=IMPLICIT_NOTNULL typeOperand=<root>.P
GET_VAR 'val x: <root>.P? [val] declared in <root>.testForInArrayUse' type=<root>.P? origin=null
CALL 'public open fun use (s: @[EnhancedNullability] <root>.P): kotlin.Unit declared in <root>.J' type=kotlin.Unit origin=null
s: GET_VAR 'val x: <root>.P? [val] declared in <root>.testForInArrayUse' type=<root>.P? origin=null
CLASS INTERFACE name:K modality:ABSTRACT visibility:public superTypes:[kotlin.Any]
@@ -31,8 +31,9 @@ FILE fqName:<root> fileName:/explicitEqualsAndCompareToCallsOnPlatformTypeReceiv
CALL 'public open fun compareTo (other: kotlin.Double): kotlin.Int [operator] declared in kotlin.Double' type=kotlin.Int origin=null
$this: CALL 'public open fun null0 (): kotlin.Double? declared in <root>.JavaClass' type=kotlin.Double? origin=null
$this: GET_VAR '<this>: <root>.JavaClass declared in <root>.testPlatformCompareToPlatform' type=<root>.JavaClass origin=null
other: CALL 'public open fun null0 (): kotlin.Double? declared in <root>.JavaClass' type=kotlin.Double? origin=null
$this: GET_VAR '<this>: <root>.JavaClass declared in <root>.testPlatformCompareToPlatform' type=<root>.JavaClass origin=null
other: TYPE_OP type=kotlin.Double origin=IMPLICIT_NOTNULL typeOperand=kotlin.Double
CALL 'public open fun null0 (): kotlin.Double? declared in <root>.JavaClass' type=kotlin.Double? origin=null
$this: GET_VAR '<this>: <root>.JavaClass declared in <root>.testPlatformCompareToPlatform' type=<root>.JavaClass origin=null
FUN name:testPlatformCompareToKotlin visibility:public modality:FINAL <> ($receiver:<root>.JavaClass) returnType:kotlin.Int
$receiver: VALUE_PARAMETER name:<this> type:<root>.JavaClass
BLOCK_BODY
@@ -47,5 +48,6 @@ FILE fqName:<root> fileName:/explicitEqualsAndCompareToCallsOnPlatformTypeReceiv
RETURN type=kotlin.Nothing from='public final fun testKotlinCompareToPlatform (): kotlin.Int declared in <root>'
CALL 'public open fun compareTo (other: kotlin.Double): kotlin.Int [operator] declared in kotlin.Double' type=kotlin.Int origin=null
$this: CONST Double type=kotlin.Double value=0.0
other: CALL 'public open fun null0 (): kotlin.Double? declared in <root>.JavaClass' type=kotlin.Double? origin=null
$this: GET_VAR '<this>: <root>.JavaClass declared in <root>.testKotlinCompareToPlatform' type=<root>.JavaClass origin=null
other: TYPE_OP type=kotlin.Double origin=IMPLICIT_NOTNULL typeOperand=kotlin.Double
CALL 'public open fun null0 (): kotlin.Double? declared in <root>.JavaClass' type=kotlin.Double? origin=null
$this: GET_VAR '<this>: <root>.JavaClass declared in <root>.testKotlinCompareToPlatform' type=<root>.JavaClass origin=null
@@ -63,16 +63,19 @@ FILE fqName:<root> fileName:/implicitNotNullOnPlatformType.kt
FUN name:test visibility:public modality:FINAL <> () returnType:kotlin.Unit
BLOCK_BODY
CALL 'public final fun f (s: kotlin.String): kotlin.Unit declared in <root>' type=kotlin.Unit origin=null
s: CALL 'public open fun s (): kotlin.String? declared in <root>.J' type=kotlin.String? origin=null
s: TYPE_OP type=kotlin.String origin=IMPLICIT_NOTNULL typeOperand=kotlin.String
CALL 'public open fun s (): kotlin.String? declared in <root>.J' type=kotlin.String? origin=null
CALL 'public final fun f (s: kotlin.String): kotlin.Unit declared in <root>' type=kotlin.Unit origin=null
s: GET_FIELD 'FIELD IR_EXTERNAL_JAVA_DECLARATION_STUB name:STRING type:kotlin.String? visibility:public [static]' type=kotlin.String? origin=GET_PROPERTY
s: TYPE_OP type=kotlin.String origin=IMPLICIT_NOTNULL typeOperand=kotlin.String
GET_FIELD 'FIELD IR_EXTERNAL_JAVA_DECLARATION_STUB name:STRING type:kotlin.String? visibility:public [static]' type=kotlin.String? origin=GET_PROPERTY
FUN name:testContains visibility:public modality:FINAL <> (m:<root>.MySet) returnType:kotlin.Unit
VALUE_PARAMETER name:m index:0 type:<root>.MySet
BLOCK_BODY
TYPE_OP type=kotlin.Unit origin=IMPLICIT_COERCION_TO_UNIT typeOperand=kotlin.Unit
CALL 'public final fun contains (element: kotlin.String): kotlin.Boolean [operator] declared in <root>.MySet' type=kotlin.Boolean origin=null
$this: GET_VAR 'm: <root>.MySet declared in <root>.testContains' type=<root>.MySet origin=null
element: GET_FIELD 'FIELD IR_EXTERNAL_JAVA_DECLARATION_STUB name:STRING type:kotlin.String? visibility:public [static]' type=kotlin.String? origin=GET_PROPERTY
element: TYPE_OP type=kotlin.String origin=IMPLICIT_NOTNULL typeOperand=kotlin.String
GET_FIELD 'FIELD IR_EXTERNAL_JAVA_DECLARATION_STUB name:STRING type:kotlin.String? visibility:public [static]' type=kotlin.String? origin=GET_PROPERTY
TYPE_OP type=kotlin.Unit origin=IMPLICIT_COERCION_TO_UNIT typeOperand=kotlin.Unit
CALL 'public final fun contains (element: kotlin.String): kotlin.Boolean [operator] declared in <root>.MySet' type=kotlin.Boolean origin=null
$this: GET_VAR 'm: <root>.MySet declared in <root>.testContains' type=<root>.MySet origin=null
@@ -18,4 +18,5 @@ FILE fqName:<root> fileName:/stringVsTConstrained.kt
FUN LOCAL_FUNCTION_FOR_LAMBDA name:<anonymous> visibility:local modality:FINAL <> () returnType:kotlin.String
BLOCK_BODY
RETURN type=kotlin.Nothing from='local final fun <anonymous> (): kotlin.String declared in <root>.testWithNullCheck'
CALL 'public open fun string (): kotlin.String? declared in <root>.J' type=kotlin.String? origin=null
TYPE_OP type=kotlin.String origin=IMPLICIT_NOTNULL typeOperand=kotlin.String
CALL 'public open fun string (): kotlin.String? declared in <root>.J' type=kotlin.String? origin=null
@@ -21,6 +21,7 @@ FILE fqName:<root> fileName:/smartCastOnFieldReceiverOfGenericType.kt
TYPE_OP type=<root>.JCell<kotlin.String> origin=CAST typeOperand=<root>.JCell<kotlin.String>
GET_VAR 'a: kotlin.Any declared in <root>.testGetField' type=kotlin.Any origin=null
RETURN type=kotlin.Nothing from='public final fun testGetField (a: kotlin.Any): kotlin.String declared in <root>'
GET_FIELD 'FIELD IR_EXTERNAL_JAVA_DECLARATION_STUB name:value type:T of <root>.JCell? visibility:public' type=kotlin.String? origin=GET_PROPERTY
receiver: TYPE_OP type=<root>.JCell<kotlin.String> origin=IMPLICIT_CAST typeOperand=<root>.JCell<kotlin.String>
GET_VAR 'a: kotlin.Any declared in <root>.testGetField' type=kotlin.Any origin=null
TYPE_OP type=kotlin.String origin=IMPLICIT_NOTNULL typeOperand=kotlin.String
GET_FIELD 'FIELD IR_EXTERNAL_JAVA_DECLARATION_STUB name:value type:T of <root>.JCell? visibility:public' type=kotlin.String? origin=GET_PROPERTY
receiver: TYPE_OP type=<root>.JCell<kotlin.String> origin=IMPLICIT_CAST typeOperand=<root>.JCell<kotlin.String>
GET_VAR 'a: kotlin.Any declared in <root>.testGetField' type=kotlin.Any origin=null