[FIR] Use type without smartcast for local variable with smartcasted initializer
This commit is contained in:
@@ -0,0 +1,40 @@
|
||||
// ISSUE: KT-44932
|
||||
// WITH_STDLIB
|
||||
|
||||
abstract class PsiElement {
|
||||
abstract val parent: PsiElement
|
||||
}
|
||||
|
||||
class KtNameReferenceExpression(override val parent: PsiElement) : PsiElement()
|
||||
|
||||
class OtherElement(override val parent: PsiElement) : PsiElement()
|
||||
|
||||
class KtDotQualifiedExpression : PsiElement() {
|
||||
override val parent: PsiElement
|
||||
get() = this
|
||||
|
||||
val psi: PsiElement = EndElement()
|
||||
}
|
||||
|
||||
class EndElement : PsiElement() {
|
||||
override val parent: PsiElement
|
||||
get() = this
|
||||
}
|
||||
|
||||
fun mark(element: PsiElement): String {
|
||||
when (element) {
|
||||
is KtNameReferenceExpression -> {
|
||||
var parent = element
|
||||
repeat(2) {
|
||||
parent = parent.parent
|
||||
(parent as? KtDotQualifiedExpression)?.psi?.let { return mark(it) }
|
||||
}
|
||||
}
|
||||
}
|
||||
return if (element is EndElement) "OK" else "Fail"
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
val element = KtNameReferenceExpression(OtherElement(KtDotQualifiedExpression()))
|
||||
return mark(element)
|
||||
}
|
||||
+1
-1
@@ -22,7 +22,7 @@ fun test2() {
|
||||
}
|
||||
|
||||
<set-x>(<set-?> = 0)
|
||||
val <unary>: Int = <get-x>()
|
||||
val <unary>: Int? = <get-x>()
|
||||
<set-x>(<set-?> = <unary>.inc())
|
||||
<unary> /*~> Unit */
|
||||
<set-x>(<set-?> = <get-x>().plus(other = 1))
|
||||
|
||||
@@ -47,13 +47,13 @@ FILE fqName:<root> fileName:/localDelegatedProperties.kt
|
||||
value: GET_VAR '<set-?>: kotlin.Int? declared in <root>.test2.<set-x>' type=kotlin.Int? origin=null
|
||||
CALL 'local final fun <set-x> (<set-?>: kotlin.Int?): kotlin.Unit declared in <root>.test2' type=kotlin.Unit origin=EQ
|
||||
<set-?>: CONST Int type=kotlin.Int value=0
|
||||
VAR IR_TEMPORARY_VARIABLE name:tmp_0 type:kotlin.Int [val]
|
||||
VAR IR_TEMPORARY_VARIABLE name:tmp_0 type:kotlin.Int? [val]
|
||||
CALL 'local final fun <get-x> (): kotlin.Int? declared in <root>.test2' type=kotlin.Int? origin=GET_LOCAL_PROPERTY
|
||||
CALL 'local final fun <set-x> (<set-?>: kotlin.Int?): kotlin.Unit declared in <root>.test2' type=kotlin.Unit origin=EQ
|
||||
<set-?>: CALL 'public final fun inc (): kotlin.Int [operator] declared in kotlin.Int' type=kotlin.Int origin=null
|
||||
$this: GET_VAR 'val tmp_0: kotlin.Int [val] declared in <root>.test2' type=kotlin.Int origin=null
|
||||
$this: GET_VAR 'val tmp_0: kotlin.Int? [val] declared in <root>.test2' type=kotlin.Int? origin=null
|
||||
TYPE_OP type=kotlin.Unit origin=IMPLICIT_COERCION_TO_UNIT typeOperand=kotlin.Unit
|
||||
GET_VAR 'val tmp_0: kotlin.Int [val] declared in <root>.test2' type=kotlin.Int origin=null
|
||||
GET_VAR 'val tmp_0: kotlin.Int? [val] declared in <root>.test2' type=kotlin.Int? origin=null
|
||||
CALL 'local final fun <set-x> (<set-?>: kotlin.Int?): kotlin.Unit declared in <root>.test2' type=kotlin.Unit origin=EQ
|
||||
<set-?>: CALL 'public final fun plus (other: kotlin.Int): kotlin.Int [operator] declared in kotlin.Int' type=kotlin.Int origin=null
|
||||
$this: CALL 'local final fun <get-x> (): kotlin.Int? declared in <root>.test2' type=kotlin.Int? origin=GET_LOCAL_PROPERTY
|
||||
|
||||
Vendored
+6
-6
@@ -63,8 +63,8 @@ fun test4(fn: Function1<Int, Unit>) {
|
||||
when {
|
||||
fn is IFoo -> { // BLOCK
|
||||
val <<array>>: A = A
|
||||
val <<index_0>>: IFoo = fn /*as IFoo */
|
||||
<<array>>.set(i = <<index_0>>, newValue = <<array>>.get(i = <<index_0>>).plus(other = 1))
|
||||
val <<index_0>>: Function1<Int, Unit> = fn /*as IFoo */
|
||||
<<array>>.set(i = <<index_0>> /*as IFoo */, newValue = <<array>>.get(i = <<index_0>> /*as IFoo */).plus(other = 1))
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -73,8 +73,8 @@ fun test5(a: Any) {
|
||||
a as Function1<Int, Unit> /*~> Unit */
|
||||
{ // BLOCK
|
||||
val <<array>>: A = A
|
||||
val <<index_0>>: Function1<Int, Unit> = a /*as Function1<Int, Unit> */
|
||||
<<array>>.set(i = <<index_0>> /*-> IFoo */, newValue = <<array>>.get(i = <<index_0>> /*-> IFoo */).plus(other = 1))
|
||||
val <<index_0>>: Any = a /*as Function1<Int, Unit> */
|
||||
<<array>>.set(i = <<index_0>> /*as Function1<Int, Unit> */ /*-> IFoo */, newValue = <<array>>.get(i = <<index_0>> /*as Function1<Int, Unit> */ /*-> IFoo */).plus(other = 1))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -83,8 +83,8 @@ fun test6(a: Any) {
|
||||
a /*as Function1<Int, Unit> */ as IFoo /*~> Unit */
|
||||
{ // BLOCK
|
||||
val <<array>>: A = A
|
||||
val <<index_0>>: Function1<Int, Unit> = a /*as Function1<Int, Unit> */
|
||||
<<array>>.set(i = <<index_0>>, newValue = <<array>>.get(i = <<index_0>>).plus(other = 1))
|
||||
val <<index_0>>: Any = a /*as Function1<Int, Unit> */
|
||||
<<array>>.set(i = <<index_0>> /*as Function1<Int, Unit> */, newValue = <<array>>.get(i = <<index_0>> /*as Function1<Int, Unit> */).plus(other = 1))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+15
-9
@@ -136,16 +136,18 @@ FILE fqName:<root> fileName:/caoWithAdaptationForSam.kt
|
||||
then: BLOCK type=kotlin.Unit origin=null
|
||||
VAR IR_TEMPORARY_VARIABLE name:tmp_2 type:<root>.A [val]
|
||||
GET_OBJECT 'CLASS OBJECT name:A modality:FINAL visibility:public superTypes:[kotlin.Any]' type=<root>.A
|
||||
VAR IR_TEMPORARY_VARIABLE name:tmp_3 type:<root>.IFoo [val]
|
||||
VAR IR_TEMPORARY_VARIABLE name:tmp_3 type:kotlin.Function1<kotlin.Int, kotlin.Unit> [val]
|
||||
TYPE_OP type=<root>.IFoo origin=IMPLICIT_CAST typeOperand=<root>.IFoo
|
||||
GET_VAR 'fn: kotlin.Function1<kotlin.Int, kotlin.Unit> declared in <root>.test4' type=kotlin.Function1<kotlin.Int, kotlin.Unit> origin=null
|
||||
CALL 'public final fun set (i: <root>.IFoo, newValue: kotlin.Int): kotlin.Unit [operator] declared in <root>' type=kotlin.Unit origin=null
|
||||
$receiver: GET_VAR 'val tmp_2: <root>.A [val] declared in <root>.test4' type=<root>.A origin=null
|
||||
i: GET_VAR 'val tmp_3: <root>.IFoo [val] declared in <root>.test4' type=<root>.IFoo origin=null
|
||||
i: TYPE_OP type=<root>.IFoo origin=IMPLICIT_CAST typeOperand=<root>.IFoo
|
||||
GET_VAR 'val tmp_3: kotlin.Function1<kotlin.Int, kotlin.Unit> [val] declared in <root>.test4' type=kotlin.Function1<kotlin.Int, kotlin.Unit> origin=null
|
||||
newValue: CALL 'public final fun plus (other: kotlin.Int): kotlin.Int [operator] declared in kotlin.Int' type=kotlin.Int origin=null
|
||||
$this: CALL 'public final fun get (i: <root>.IFoo): kotlin.Int [operator] declared in <root>' type=kotlin.Int origin=null
|
||||
$receiver: GET_VAR 'val tmp_2: <root>.A [val] declared in <root>.test4' type=<root>.A origin=null
|
||||
i: GET_VAR 'val tmp_3: <root>.IFoo [val] declared in <root>.test4' type=<root>.IFoo origin=null
|
||||
i: TYPE_OP type=<root>.IFoo origin=IMPLICIT_CAST typeOperand=<root>.IFoo
|
||||
GET_VAR 'val tmp_3: kotlin.Function1<kotlin.Int, kotlin.Unit> [val] declared in <root>.test4' type=kotlin.Function1<kotlin.Int, kotlin.Unit> origin=null
|
||||
other: CONST Int type=kotlin.Int value=1
|
||||
FUN name:test5 visibility:public modality:FINAL <> (a:kotlin.Any) returnType:kotlin.Unit
|
||||
VALUE_PARAMETER name:a index:0 type:kotlin.Any
|
||||
@@ -156,18 +158,20 @@ FILE fqName:<root> fileName:/caoWithAdaptationForSam.kt
|
||||
BLOCK type=kotlin.Unit origin=null
|
||||
VAR IR_TEMPORARY_VARIABLE name:tmp_4 type:<root>.A [val]
|
||||
GET_OBJECT 'CLASS OBJECT name:A modality:FINAL visibility:public superTypes:[kotlin.Any]' type=<root>.A
|
||||
VAR IR_TEMPORARY_VARIABLE name:tmp_5 type:kotlin.Function1<kotlin.Int, kotlin.Unit> [val]
|
||||
VAR IR_TEMPORARY_VARIABLE name:tmp_5 type:kotlin.Any [val]
|
||||
TYPE_OP type=kotlin.Function1<kotlin.Int, kotlin.Unit> origin=IMPLICIT_CAST typeOperand=kotlin.Function1<kotlin.Int, kotlin.Unit>
|
||||
GET_VAR 'a: kotlin.Any declared in <root>.test5' type=kotlin.Any origin=null
|
||||
CALL 'public final fun set (i: <root>.IFoo, newValue: kotlin.Int): kotlin.Unit [operator] declared in <root>' type=kotlin.Unit origin=null
|
||||
$receiver: GET_VAR 'val tmp_4: <root>.A [val] declared in <root>.test5' type=<root>.A origin=null
|
||||
i: TYPE_OP type=<root>.IFoo origin=SAM_CONVERSION typeOperand=<root>.IFoo
|
||||
GET_VAR 'val tmp_5: kotlin.Function1<kotlin.Int, kotlin.Unit> [val] declared in <root>.test5' type=kotlin.Function1<kotlin.Int, kotlin.Unit> origin=null
|
||||
TYPE_OP type=kotlin.Function1<kotlin.Int, kotlin.Unit> origin=IMPLICIT_CAST typeOperand=kotlin.Function1<kotlin.Int, kotlin.Unit>
|
||||
GET_VAR 'val tmp_5: kotlin.Any [val] declared in <root>.test5' type=kotlin.Any origin=null
|
||||
newValue: CALL 'public final fun plus (other: kotlin.Int): kotlin.Int [operator] declared in kotlin.Int' type=kotlin.Int origin=null
|
||||
$this: CALL 'public final fun get (i: <root>.IFoo): kotlin.Int [operator] declared in <root>' type=kotlin.Int origin=null
|
||||
$receiver: GET_VAR 'val tmp_4: <root>.A [val] declared in <root>.test5' type=<root>.A origin=null
|
||||
i: TYPE_OP type=<root>.IFoo origin=SAM_CONVERSION typeOperand=<root>.IFoo
|
||||
GET_VAR 'val tmp_5: kotlin.Function1<kotlin.Int, kotlin.Unit> [val] declared in <root>.test5' type=kotlin.Function1<kotlin.Int, kotlin.Unit> origin=null
|
||||
TYPE_OP type=kotlin.Function1<kotlin.Int, kotlin.Unit> origin=IMPLICIT_CAST typeOperand=kotlin.Function1<kotlin.Int, kotlin.Unit>
|
||||
GET_VAR 'val tmp_5: kotlin.Any [val] declared in <root>.test5' type=kotlin.Any origin=null
|
||||
other: CONST Int type=kotlin.Int value=1
|
||||
FUN name:test6 visibility:public modality:FINAL <> (a:kotlin.Any) returnType:kotlin.Unit
|
||||
VALUE_PARAMETER name:a index:0 type:kotlin.Any
|
||||
@@ -182,14 +186,16 @@ FILE fqName:<root> fileName:/caoWithAdaptationForSam.kt
|
||||
BLOCK type=kotlin.Unit origin=null
|
||||
VAR IR_TEMPORARY_VARIABLE name:tmp_6 type:<root>.A [val]
|
||||
GET_OBJECT 'CLASS OBJECT name:A modality:FINAL visibility:public superTypes:[kotlin.Any]' type=<root>.A
|
||||
VAR IR_TEMPORARY_VARIABLE name:tmp_7 type:kotlin.Function1<kotlin.Int, kotlin.Unit> [val]
|
||||
VAR IR_TEMPORARY_VARIABLE name:tmp_7 type:kotlin.Any [val]
|
||||
TYPE_OP type=kotlin.Function1<kotlin.Int, kotlin.Unit> origin=IMPLICIT_CAST typeOperand=kotlin.Function1<kotlin.Int, kotlin.Unit>
|
||||
GET_VAR 'a: kotlin.Any declared in <root>.test6' type=kotlin.Any origin=null
|
||||
CALL 'public final fun set (i: <root>.IFoo, newValue: kotlin.Int): kotlin.Unit [operator] declared in <root>' type=kotlin.Unit origin=null
|
||||
$receiver: GET_VAR 'val tmp_6: <root>.A [val] declared in <root>.test6' type=<root>.A origin=null
|
||||
i: GET_VAR 'val tmp_7: kotlin.Function1<kotlin.Int, kotlin.Unit> [val] declared in <root>.test6' type=kotlin.Function1<kotlin.Int, kotlin.Unit> origin=null
|
||||
i: TYPE_OP type=kotlin.Function1<kotlin.Int, kotlin.Unit> origin=IMPLICIT_CAST typeOperand=kotlin.Function1<kotlin.Int, kotlin.Unit>
|
||||
GET_VAR 'val tmp_7: kotlin.Any [val] declared in <root>.test6' type=kotlin.Any origin=null
|
||||
newValue: CALL 'public final fun plus (other: kotlin.Int): kotlin.Int [operator] declared in kotlin.Int' type=kotlin.Int origin=null
|
||||
$this: CALL 'public final fun get (i: <root>.IFoo): kotlin.Int [operator] declared in <root>' type=kotlin.Int origin=null
|
||||
$receiver: GET_VAR 'val tmp_6: <root>.A [val] declared in <root>.test6' type=<root>.A origin=null
|
||||
i: GET_VAR 'val tmp_7: kotlin.Function1<kotlin.Int, kotlin.Unit> [val] declared in <root>.test6' type=kotlin.Function1<kotlin.Int, kotlin.Unit> origin=null
|
||||
i: TYPE_OP type=kotlin.Function1<kotlin.Int, kotlin.Unit> origin=IMPLICIT_CAST typeOperand=kotlin.Function1<kotlin.Int, kotlin.Unit>
|
||||
GET_VAR 'val tmp_7: kotlin.Any [val] declared in <root>.test6' type=kotlin.Any origin=null
|
||||
other: CONST Int type=kotlin.Int value=1
|
||||
|
||||
@@ -14,9 +14,9 @@ fun test(x: Any) {
|
||||
x is IC1 -> x /*as IC1 */ is IC2
|
||||
else -> false
|
||||
} -> { // BLOCK
|
||||
val <destruct>: IC1 = x /*as IC1 */
|
||||
val x1: Int = <destruct>.component1()
|
||||
val x2: String = <destruct> /*as IC2 */.component2()
|
||||
val <destruct>: Any = x /*as IC1 */
|
||||
val x1: Int = <destruct> /*as IC1 */.component1()
|
||||
val x2: String = <destruct> /*as IC1 */ /*as IC2 */.component2()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -49,13 +49,15 @@ FILE fqName:<root> fileName:/multipleSmartCasts.kt
|
||||
if: CONST Boolean type=kotlin.Boolean value=true
|
||||
then: CONST Boolean type=kotlin.Boolean value=false
|
||||
then: BLOCK type=kotlin.Unit origin=null
|
||||
VAR IR_TEMPORARY_VARIABLE name:tmp_0 type:<root>.IC1 [val]
|
||||
VAR IR_TEMPORARY_VARIABLE name:tmp_0 type:kotlin.Any [val]
|
||||
TYPE_OP type=<root>.IC1 origin=IMPLICIT_CAST typeOperand=<root>.IC1
|
||||
GET_VAR 'x: kotlin.Any declared in <root>.test' type=kotlin.Any origin=null
|
||||
VAR name:x1 type:kotlin.Int [val]
|
||||
CALL 'public abstract fun component1 (): kotlin.Int [operator] declared in <root>.IC1' type=kotlin.Int origin=null
|
||||
$this: GET_VAR 'val tmp_0: <root>.IC1 [val] declared in <root>.test' type=<root>.IC1 origin=null
|
||||
$this: TYPE_OP type=<root>.IC1 origin=IMPLICIT_CAST typeOperand=<root>.IC1
|
||||
GET_VAR 'val tmp_0: kotlin.Any [val] declared in <root>.test' type=kotlin.Any origin=null
|
||||
VAR name:x2 type:kotlin.String [val]
|
||||
CALL 'public abstract fun component2 (): kotlin.String [operator] declared in <root>.IC2' type=kotlin.String origin=null
|
||||
$this: TYPE_OP type=<root>.IC2 origin=IMPLICIT_CAST typeOperand=<root>.IC2
|
||||
GET_VAR 'val tmp_0: <root>.IC1 [val] declared in <root>.test' type=<root>.IC1 origin=null
|
||||
TYPE_OP type=<root>.IC1 origin=IMPLICIT_CAST typeOperand=<root>.IC1
|
||||
GET_VAR 'val tmp_0: kotlin.Any [val] declared in <root>.test' type=kotlin.Any origin=null
|
||||
|
||||
+3
-3
@@ -18,7 +18,7 @@ fun test(x: I1) {
|
||||
when {
|
||||
x !is I2 -> return Unit
|
||||
}
|
||||
val <destruct>: I2 = x /*as I2 */
|
||||
val c1: Int = <destruct>.component1()
|
||||
val c2: String = <destruct>.component2()
|
||||
val <destruct>: I1 = x /*as I2 */
|
||||
val c1: Int = <destruct> /*as I2 */.component1()
|
||||
val c2: String = <destruct> /*as I2 */.component2()
|
||||
}
|
||||
|
||||
+5
-3
@@ -48,12 +48,14 @@ FILE fqName:<root> fileName:/smartCastsWithDestructuring.kt
|
||||
GET_VAR 'x: <root>.I1 declared in <root>.test' type=<root>.I1 origin=null
|
||||
then: RETURN type=kotlin.Nothing from='public final fun test (x: <root>.I1): kotlin.Unit declared in <root>'
|
||||
GET_OBJECT 'CLASS IR_EXTERNAL_DECLARATION_STUB OBJECT name:Unit modality:FINAL visibility:public superTypes:[kotlin.Any]' type=kotlin.Unit
|
||||
VAR IR_TEMPORARY_VARIABLE name:tmp_0 type:<root>.I2 [val]
|
||||
VAR IR_TEMPORARY_VARIABLE name:tmp_0 type:<root>.I1 [val]
|
||||
TYPE_OP type=<root>.I2 origin=IMPLICIT_CAST typeOperand=<root>.I2
|
||||
GET_VAR 'x: <root>.I1 declared in <root>.test' type=<root>.I1 origin=null
|
||||
VAR name:c1 type:kotlin.Int [val]
|
||||
CALL 'public final fun component1 (): kotlin.Int [operator] declared in <root>' type=kotlin.Int origin=null
|
||||
$receiver: GET_VAR 'val tmp_0: <root>.I2 [val] declared in <root>.test' type=<root>.I2 origin=null
|
||||
$receiver: TYPE_OP type=<root>.I2 origin=IMPLICIT_CAST typeOperand=<root>.I2
|
||||
GET_VAR 'val tmp_0: <root>.I1 [val] declared in <root>.test' type=<root>.I1 origin=null
|
||||
VAR name:c2 type:kotlin.String [val]
|
||||
CALL 'public final fun component2 (): kotlin.String [operator] declared in <root>' type=kotlin.String origin=null
|
||||
$receiver: GET_VAR 'val tmp_0: <root>.I2 [val] declared in <root>.test' type=<root>.I2 origin=null
|
||||
$receiver: TYPE_OP type=<root>.I2 origin=IMPLICIT_CAST typeOperand=<root>.I2
|
||||
GET_VAR 'val tmp_0: <root>.I1 [val] declared in <root>.test' type=<root>.I1 origin=null
|
||||
|
||||
Reference in New Issue
Block a user