FIR: in case of smart cast, use original type for FirThisRcvrExpression

Before this commit, we used type after smart cast both for original
FirThisReceiverExpression and for wrapping FirExpressionWithSmartCast.
However, this makes FIR2IR implicit cast generator work incorrectly
(it decides not to insert implicit cast because original type is the same).
After this commit, expressions have different types and implicit cast
generator works properly.
This commit is contained in:
Mikhail Glukhikh
2021-01-19 18:19:45 +03:00
parent 4fd4f504d0
commit 06ee768c6a
18 changed files with 988 additions and 797 deletions
@@ -0,0 +1,39 @@
interface SimpleTypeMarker {
}
class SimpleType : SimpleTypeMarker {
constructor() /* primary */ {
super/*Any*/()
/* <init>() */
}
fun foo(): String {
return "OK"
}
}
interface User {
fun SimpleTypeMarker.bar(): String {
require(value = <this> is SimpleType)
return <this> /*as SimpleType */.foo()
}
}
class UserImpl {
constructor() /* primary */ {
super/*Any*/()
/* <init>() */
}
fun SimpleTypeMarker.bar(): String {
require(value = <this> is SimpleType)
return <this> /*as SimpleType */.foo()
}
}
@@ -0,0 +1,96 @@
FILE fqName:<root> fileName:/SimpleTypeMarker.kt
CLASS INTERFACE name:SimpleTypeMarker modality:ABSTRACT visibility:public superTypes:[kotlin.Any]
$this: VALUE_PARAMETER INSTANCE_RECEIVER name:<this> type:<root>.SimpleTypeMarker
FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean [fake_override,operator]
overridden:
public open fun equals (other: kotlin.Any?): kotlin.Boolean [operator] declared in kotlin.Any
$this: VALUE_PARAMETER name:<this> type:kotlin.Any
VALUE_PARAMETER name:other index:0 type:kotlin.Any?
FUN FAKE_OVERRIDE name:hashCode visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.Int [fake_override]
overridden:
public open fun hashCode (): kotlin.Int declared in kotlin.Any
$this: VALUE_PARAMETER name:<this> type:kotlin.Any
FUN FAKE_OVERRIDE name:toString visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.String [fake_override]
overridden:
public open fun toString (): kotlin.String declared in kotlin.Any
$this: VALUE_PARAMETER name:<this> type:kotlin.Any
CLASS CLASS name:SimpleType modality:FINAL visibility:public superTypes:[<root>.SimpleTypeMarker]
$this: VALUE_PARAMETER INSTANCE_RECEIVER name:<this> type:<root>.SimpleType
CONSTRUCTOR visibility:public <> () returnType:<root>.SimpleType [primary]
BLOCK_BODY
DELEGATING_CONSTRUCTOR_CALL 'public constructor <init> () [primary] declared in kotlin.Any'
INSTANCE_INITIALIZER_CALL classDescriptor='CLASS CLASS name:SimpleType modality:FINAL visibility:public superTypes:[<root>.SimpleTypeMarker]'
FUN name:foo visibility:public modality:FINAL <> ($this:<root>.SimpleType) returnType:kotlin.String
$this: VALUE_PARAMETER name:<this> type:<root>.SimpleType
BLOCK_BODY
RETURN type=kotlin.Nothing from='public final fun foo (): kotlin.String declared in <root>.SimpleType'
CONST String type=kotlin.String value="OK"
FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean [fake_override,operator]
overridden:
public open fun equals (other: kotlin.Any?): kotlin.Boolean [operator] declared in kotlin.Any
$this: VALUE_PARAMETER name:<this> type:kotlin.Any
VALUE_PARAMETER name:other index:0 type:kotlin.Any?
FUN FAKE_OVERRIDE name:hashCode visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.Int [fake_override]
overridden:
public open fun hashCode (): kotlin.Int declared in kotlin.Any
$this: VALUE_PARAMETER name:<this> type:kotlin.Any
FUN FAKE_OVERRIDE name:toString visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.String [fake_override]
overridden:
public open fun toString (): kotlin.String declared in kotlin.Any
$this: VALUE_PARAMETER name:<this> type:kotlin.Any
CLASS INTERFACE name:User modality:ABSTRACT visibility:public superTypes:[kotlin.Any]
$this: VALUE_PARAMETER INSTANCE_RECEIVER name:<this> type:<root>.User
FUN name:bar visibility:public modality:OPEN <> ($this:<root>.User, $receiver:<root>.SimpleTypeMarker) returnType:kotlin.String
$this: VALUE_PARAMETER name:<this> type:<root>.User
$receiver: VALUE_PARAMETER name:<this> type:<root>.SimpleTypeMarker
BLOCK_BODY
CALL 'public final fun require (value: kotlin.Boolean): kotlin.Unit [inline] declared in kotlin.PreconditionsKt' type=kotlin.Unit origin=null
value: TYPE_OP type=kotlin.Boolean origin=INSTANCEOF typeOperand=<root>.SimpleType
GET_VAR '<this>: <root>.SimpleTypeMarker declared in <root>.User.bar' type=<root>.SimpleTypeMarker origin=null
RETURN type=kotlin.Nothing from='public open fun bar (): kotlin.String declared in <root>.User'
CALL 'public final fun foo (): kotlin.String declared in <root>.SimpleType' type=kotlin.String origin=null
$this: TYPE_OP type=<root>.SimpleType origin=IMPLICIT_CAST typeOperand=<root>.SimpleType
GET_VAR '<this>: <root>.SimpleTypeMarker declared in <root>.User.bar' type=<root>.SimpleTypeMarker origin=null
FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean [fake_override,operator]
overridden:
public open fun equals (other: kotlin.Any?): kotlin.Boolean [operator] declared in kotlin.Any
$this: VALUE_PARAMETER name:<this> type:kotlin.Any
VALUE_PARAMETER name:other index:0 type:kotlin.Any?
FUN FAKE_OVERRIDE name:hashCode visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.Int [fake_override]
overridden:
public open fun hashCode (): kotlin.Int declared in kotlin.Any
$this: VALUE_PARAMETER name:<this> type:kotlin.Any
FUN FAKE_OVERRIDE name:toString visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.String [fake_override]
overridden:
public open fun toString (): kotlin.String declared in kotlin.Any
$this: VALUE_PARAMETER name:<this> type:kotlin.Any
CLASS CLASS name:UserImpl modality:FINAL visibility:public superTypes:[kotlin.Any]
$this: VALUE_PARAMETER INSTANCE_RECEIVER name:<this> type:<root>.UserImpl
CONSTRUCTOR visibility:public <> () returnType:<root>.UserImpl [primary]
BLOCK_BODY
DELEGATING_CONSTRUCTOR_CALL 'public constructor <init> () [primary] declared in kotlin.Any'
INSTANCE_INITIALIZER_CALL classDescriptor='CLASS CLASS name:UserImpl modality:FINAL visibility:public superTypes:[kotlin.Any]'
FUN name:bar visibility:public modality:FINAL <> ($this:<root>.UserImpl, $receiver:<root>.SimpleTypeMarker) returnType:kotlin.String
$this: VALUE_PARAMETER name:<this> type:<root>.UserImpl
$receiver: VALUE_PARAMETER name:<this> type:<root>.SimpleTypeMarker
BLOCK_BODY
CALL 'public final fun require (value: kotlin.Boolean): kotlin.Unit [inline] declared in kotlin.PreconditionsKt' type=kotlin.Unit origin=null
value: TYPE_OP type=kotlin.Boolean origin=INSTANCEOF typeOperand=<root>.SimpleType
GET_VAR '<this>: <root>.SimpleTypeMarker declared in <root>.UserImpl.bar' type=<root>.SimpleTypeMarker origin=null
RETURN type=kotlin.Nothing from='public final fun bar (): kotlin.String declared in <root>.UserImpl'
CALL 'public final fun foo (): kotlin.String declared in <root>.SimpleType' type=kotlin.String origin=null
$this: TYPE_OP type=<root>.SimpleType origin=IMPLICIT_CAST typeOperand=<root>.SimpleType
GET_VAR '<this>: <root>.SimpleTypeMarker declared in <root>.UserImpl.bar' type=<root>.SimpleTypeMarker origin=null
FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean [fake_override,operator]
overridden:
public open fun equals (other: kotlin.Any?): kotlin.Boolean [operator] declared in kotlin.Any
$this: VALUE_PARAMETER name:<this> type:kotlin.Any
VALUE_PARAMETER name:other index:0 type:kotlin.Any?
FUN FAKE_OVERRIDE name:hashCode visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.Int [fake_override]
overridden:
public open fun hashCode (): kotlin.Int declared in kotlin.Any
$this: VALUE_PARAMETER name:<this> type:kotlin.Any
FUN FAKE_OVERRIDE name:toString visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.String [fake_override]
overridden:
public open fun toString (): kotlin.String declared in kotlin.Any
$this: VALUE_PARAMETER name:<this> type:kotlin.Any
@@ -0,0 +1,22 @@
// WITH_RUNTIME
interface SimpleTypeMarker
class SimpleType : SimpleTypeMarker {
fun foo() = "OK"
}
interface User {
fun SimpleTypeMarker.bar(): String {
require(this is SimpleType)
return this.foo()
}
}
class UserImpl {
fun SimpleTypeMarker.bar(): String {
require(this is SimpleType)
return this.foo()
}
}
@@ -0,0 +1,39 @@
interface SimpleTypeMarker {
}
class SimpleType : SimpleTypeMarker {
constructor() /* primary */ {
super/*Any*/()
/* <init>() */
}
fun foo(): String {
return "OK"
}
}
interface User {
fun SimpleTypeMarker.bar(): String {
require(value = <this> is SimpleType)
return <this> /*as SimpleType */.foo()
}
}
class UserImpl {
constructor() /* primary */ {
super/*Any*/()
/* <init>() */
}
fun SimpleTypeMarker.bar(): String {
require(value = <this> is SimpleType)
return <this> /*as SimpleType */.foo()
}
}
@@ -0,0 +1,96 @@
FILE fqName:<root> fileName:/SimpleTypeMarker.kt
CLASS INTERFACE name:SimpleTypeMarker modality:ABSTRACT visibility:public superTypes:[kotlin.Any]
$this: VALUE_PARAMETER INSTANCE_RECEIVER name:<this> type:<root>.SimpleTypeMarker
FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean [fake_override,operator]
overridden:
public open fun equals (other: kotlin.Any?): kotlin.Boolean [operator] declared in kotlin.Any
$this: VALUE_PARAMETER name:<this> type:kotlin.Any
VALUE_PARAMETER name:other index:0 type:kotlin.Any?
FUN FAKE_OVERRIDE name:hashCode visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.Int [fake_override]
overridden:
public open fun hashCode (): kotlin.Int declared in kotlin.Any
$this: VALUE_PARAMETER name:<this> type:kotlin.Any
FUN FAKE_OVERRIDE name:toString visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.String [fake_override]
overridden:
public open fun toString (): kotlin.String declared in kotlin.Any
$this: VALUE_PARAMETER name:<this> type:kotlin.Any
CLASS CLASS name:SimpleType modality:FINAL visibility:public superTypes:[<root>.SimpleTypeMarker]
$this: VALUE_PARAMETER INSTANCE_RECEIVER name:<this> type:<root>.SimpleType
CONSTRUCTOR visibility:public <> () returnType:<root>.SimpleType [primary]
BLOCK_BODY
DELEGATING_CONSTRUCTOR_CALL 'public constructor <init> () [primary] declared in kotlin.Any'
INSTANCE_INITIALIZER_CALL classDescriptor='CLASS CLASS name:SimpleType modality:FINAL visibility:public superTypes:[<root>.SimpleTypeMarker]'
FUN name:foo visibility:public modality:FINAL <> ($this:<root>.SimpleType) returnType:kotlin.String
$this: VALUE_PARAMETER name:<this> type:<root>.SimpleType
BLOCK_BODY
RETURN type=kotlin.Nothing from='public final fun foo (): kotlin.String declared in <root>.SimpleType'
CONST String type=kotlin.String value="OK"
FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean [fake_override,operator]
overridden:
public open fun equals (other: kotlin.Any?): kotlin.Boolean [fake_override,operator] declared in <root>.SimpleTypeMarker
$this: VALUE_PARAMETER name:<this> type:kotlin.Any
VALUE_PARAMETER name:other index:0 type:kotlin.Any?
FUN FAKE_OVERRIDE name:hashCode visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.Int [fake_override]
overridden:
public open fun hashCode (): kotlin.Int [fake_override] declared in <root>.SimpleTypeMarker
$this: VALUE_PARAMETER name:<this> type:kotlin.Any
FUN FAKE_OVERRIDE name:toString visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.String [fake_override]
overridden:
public open fun toString (): kotlin.String [fake_override] declared in <root>.SimpleTypeMarker
$this: VALUE_PARAMETER name:<this> type:kotlin.Any
CLASS INTERFACE name:User modality:ABSTRACT visibility:public superTypes:[kotlin.Any]
$this: VALUE_PARAMETER INSTANCE_RECEIVER name:<this> type:<root>.User
FUN name:bar visibility:public modality:OPEN <> ($this:<root>.User, $receiver:<root>.SimpleTypeMarker) returnType:kotlin.String
$this: VALUE_PARAMETER name:<this> type:<root>.User
$receiver: VALUE_PARAMETER name:<this> type:<root>.SimpleTypeMarker
BLOCK_BODY
CALL 'public final fun require (value: kotlin.Boolean): kotlin.Unit [inline] declared in kotlin.PreconditionsKt' type=kotlin.Unit origin=null
value: TYPE_OP type=kotlin.Boolean origin=INSTANCEOF typeOperand=<root>.SimpleType
GET_VAR '<this>: <root>.SimpleTypeMarker declared in <root>.User.bar' type=<root>.SimpleTypeMarker origin=null
RETURN type=kotlin.Nothing from='public open fun bar (): kotlin.String declared in <root>.User'
CALL 'public final fun foo (): kotlin.String declared in <root>.SimpleType' type=kotlin.String origin=null
$this: TYPE_OP type=<root>.SimpleType origin=IMPLICIT_CAST typeOperand=<root>.SimpleType
GET_VAR '<this>: <root>.SimpleTypeMarker declared in <root>.User.bar' type=<root>.SimpleTypeMarker origin=null
FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean [fake_override,operator]
overridden:
public open fun equals (other: kotlin.Any?): kotlin.Boolean [operator] declared in kotlin.Any
$this: VALUE_PARAMETER name:<this> type:kotlin.Any
VALUE_PARAMETER name:other index:0 type:kotlin.Any?
FUN FAKE_OVERRIDE name:hashCode visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.Int [fake_override]
overridden:
public open fun hashCode (): kotlin.Int declared in kotlin.Any
$this: VALUE_PARAMETER name:<this> type:kotlin.Any
FUN FAKE_OVERRIDE name:toString visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.String [fake_override]
overridden:
public open fun toString (): kotlin.String declared in kotlin.Any
$this: VALUE_PARAMETER name:<this> type:kotlin.Any
CLASS CLASS name:UserImpl modality:FINAL visibility:public superTypes:[kotlin.Any]
$this: VALUE_PARAMETER INSTANCE_RECEIVER name:<this> type:<root>.UserImpl
CONSTRUCTOR visibility:public <> () returnType:<root>.UserImpl [primary]
BLOCK_BODY
DELEGATING_CONSTRUCTOR_CALL 'public constructor <init> () [primary] declared in kotlin.Any'
INSTANCE_INITIALIZER_CALL classDescriptor='CLASS CLASS name:UserImpl modality:FINAL visibility:public superTypes:[kotlin.Any]'
FUN name:bar visibility:public modality:FINAL <> ($this:<root>.UserImpl, $receiver:<root>.SimpleTypeMarker) returnType:kotlin.String
$this: VALUE_PARAMETER name:<this> type:<root>.UserImpl
$receiver: VALUE_PARAMETER name:<this> type:<root>.SimpleTypeMarker
BLOCK_BODY
CALL 'public final fun require (value: kotlin.Boolean): kotlin.Unit [inline] declared in kotlin.PreconditionsKt' type=kotlin.Unit origin=null
value: TYPE_OP type=kotlin.Boolean origin=INSTANCEOF typeOperand=<root>.SimpleType
GET_VAR '<this>: <root>.SimpleTypeMarker declared in <root>.UserImpl.bar' type=<root>.SimpleTypeMarker origin=null
RETURN type=kotlin.Nothing from='public final fun bar (): kotlin.String declared in <root>.UserImpl'
CALL 'public final fun foo (): kotlin.String declared in <root>.SimpleType' type=kotlin.String origin=null
$this: TYPE_OP type=<root>.SimpleType origin=IMPLICIT_CAST typeOperand=<root>.SimpleType
GET_VAR '<this>: <root>.SimpleTypeMarker declared in <root>.UserImpl.bar' type=<root>.SimpleTypeMarker origin=null
FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean [fake_override,operator]
overridden:
public open fun equals (other: kotlin.Any?): kotlin.Boolean [operator] declared in kotlin.Any
$this: VALUE_PARAMETER name:<this> type:kotlin.Any
VALUE_PARAMETER name:other index:0 type:kotlin.Any?
FUN FAKE_OVERRIDE name:hashCode visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.Int [fake_override]
overridden:
public open fun hashCode (): kotlin.Int declared in kotlin.Any
$this: VALUE_PARAMETER name:<this> type:kotlin.Any
FUN FAKE_OVERRIDE name:toString visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.String [fake_override]
overridden:
public open fun toString (): kotlin.String declared in kotlin.Any
$this: VALUE_PARAMETER name:<this> type:kotlin.Any