[FIR2IR] Properly calculate the type of delegated function call
```
interface A {
fun <T> foo(): T
}
class B(val a: A) : A by A {
generated fun <T'> foo(): T' {
return a.foo() // <------
}
}
```
There was a problem that type of generated delegated call used
an unsubstituted type of the original delegated declaration, which led
to a situation when (see example) type of call `a.foo()` was not `T'`
but `T`, which led to incorrect IR and further exceptions on backend
^KT-64257 Fixed
^KT-64284 Obsolete
This commit is contained in:
committed by
Space Team
parent
c48753900c
commit
94c46d384a
+4
-4
@@ -75,7 +75,7 @@ FILE fqName:<root> fileName:/delegatedGenericImplementation.kt
|
||||
$receiver: VALUE_PARAMETER name:<this> type:C of <root>.Test1.<get-id>
|
||||
BLOCK_BODY
|
||||
RETURN type=kotlin.Nothing from='public open fun <get-id> <C> (): kotlin.collections.Map<E of <root>.Test1, C of <root>.Test1.<get-id>>? declared in <root>.Test1'
|
||||
CALL 'public abstract fun <get-id> <C> (): kotlin.collections.Map<A of <root>.IBase, C of <root>.IBase.<get-id>>? declared in <root>.IBase' type=kotlin.collections.Map<A of <root>.IBase, C of <root>.IBase.<get-id>>? origin=null
|
||||
CALL 'public abstract fun <get-id> <C> (): kotlin.collections.Map<A of <root>.IBase, C of <root>.IBase.<get-id>>? declared in <root>.IBase' type=kotlin.collections.Map<E of <root>.Test1, C of <root>.Test1.<get-id>>? origin=null
|
||||
<C>: C of <root>.Test1.<get-id>
|
||||
$this: GET_FIELD 'FIELD DELEGATE name:$$delegate_0 type:<root>.IBase<E of <root>.Test1> visibility:private [final]' type=<root>.IBase<E of <root>.Test1> origin=null
|
||||
receiver: GET_VAR '<this>: <root>.Test1<E of <root>.Test1> declared in <root>.Test1.<get-id>' type=<root>.Test1<E of <root>.Test1> origin=null
|
||||
@@ -92,7 +92,7 @@ FILE fqName:<root> fileName:/delegatedGenericImplementation.kt
|
||||
$receiver: VALUE_PARAMETER name:<this> type:kotlin.collections.List<D of <root>.Test1.<get-x>>
|
||||
BLOCK_BODY
|
||||
RETURN type=kotlin.Nothing from='public open fun <get-x> <D> (): D of <root>.Test1.<get-x>? declared in <root>.Test1'
|
||||
CALL 'public abstract fun <get-x> <D> (): D of <root>.IBase.<get-x>? declared in <root>.IBase' type=D of <root>.IBase.<get-x>? origin=null
|
||||
CALL 'public abstract fun <get-x> <D> (): D of <root>.IBase.<get-x>? declared in <root>.IBase' type=D of <root>.Test1.<get-x>? origin=null
|
||||
<D>: D of <root>.Test1.<get-x>
|
||||
$this: GET_FIELD 'FIELD DELEGATE name:$$delegate_0 type:<root>.IBase<E of <root>.Test1> visibility:private [final]' type=<root>.IBase<E of <root>.Test1> origin=null
|
||||
receiver: GET_VAR '<this>: <root>.Test1<E of <root>.Test1> declared in <root>.Test1.<get-x>' type=<root>.Test1<E of <root>.Test1> origin=null
|
||||
@@ -177,7 +177,7 @@ FILE fqName:<root> fileName:/delegatedGenericImplementation.kt
|
||||
$receiver: VALUE_PARAMETER name:<this> type:C of <root>.Test2.<get-id>
|
||||
BLOCK_BODY
|
||||
RETURN type=kotlin.Nothing from='public open fun <get-id> <C> (): kotlin.collections.Map<kotlin.String, C of <root>.Test2.<get-id>>? declared in <root>.Test2'
|
||||
CALL 'public abstract fun <get-id> <C> (): kotlin.collections.Map<A of <root>.IBase, C of <root>.IBase.<get-id>>? declared in <root>.IBase' type=kotlin.collections.Map<A of <root>.IBase, C of <root>.IBase.<get-id>>? origin=null
|
||||
CALL 'public abstract fun <get-id> <C> (): kotlin.collections.Map<A of <root>.IBase, C of <root>.IBase.<get-id>>? declared in <root>.IBase' type=kotlin.collections.Map<kotlin.String, C of <root>.Test2.<get-id>>? origin=null
|
||||
<C>: C of <root>.Test2.<get-id>
|
||||
$this: GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:j type:<root>.IBase<kotlin.String> visibility:private' type=<root>.IBase<kotlin.String> origin=null
|
||||
receiver: GET_VAR '<this>: <root>.Test2 declared in <root>.Test2.<get-id>' type=<root>.Test2 origin=null
|
||||
@@ -194,7 +194,7 @@ FILE fqName:<root> fileName:/delegatedGenericImplementation.kt
|
||||
$receiver: VALUE_PARAMETER name:<this> type:kotlin.collections.List<D of <root>.Test2.<get-x>>
|
||||
BLOCK_BODY
|
||||
RETURN type=kotlin.Nothing from='public open fun <get-x> <D> (): D of <root>.Test2.<get-x>? declared in <root>.Test2'
|
||||
CALL 'public abstract fun <get-x> <D> (): D of <root>.IBase.<get-x>? declared in <root>.IBase' type=D of <root>.IBase.<get-x>? origin=null
|
||||
CALL 'public abstract fun <get-x> <D> (): D of <root>.IBase.<get-x>? declared in <root>.IBase' type=D of <root>.Test2.<get-x>? origin=null
|
||||
<D>: D of <root>.Test2.<get-x>
|
||||
$this: GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:j type:<root>.IBase<kotlin.String> visibility:private' type=<root>.IBase<kotlin.String> origin=null
|
||||
receiver: GET_VAR '<this>: <root>.Test2 declared in <root>.Test2.<get-x>' type=<root>.Test2 origin=null
|
||||
|
||||
@@ -1,65 +0,0 @@
|
||||
FILE fqName:<root> fileName:/kt35550.kt
|
||||
CLASS INTERFACE name:I modality:ABSTRACT visibility:public superTypes:[kotlin.Any]
|
||||
$this: VALUE_PARAMETER INSTANCE_RECEIVER name:<this> type:<root>.I
|
||||
PROPERTY name:id visibility:public modality:OPEN [val]
|
||||
FUN name:<get-id> visibility:public modality:OPEN <T> ($this:<root>.I, $receiver:T of <root>.I.<get-id>) returnType:T of <root>.I.<get-id>
|
||||
correspondingProperty: PROPERTY name:id visibility:public modality:OPEN [val]
|
||||
TYPE_PARAMETER name:T index:0 variance: superTypes:[kotlin.Any?] reified:false
|
||||
$this: VALUE_PARAMETER name:<this> type:<root>.I
|
||||
$receiver: VALUE_PARAMETER name:<this> type:T of <root>.I.<get-id>
|
||||
BLOCK_BODY
|
||||
RETURN type=kotlin.Nothing from='public open fun <get-id> <T> (): T of <root>.I.<get-id> declared in <root>.I'
|
||||
GET_VAR '<this>: T of <root>.I.<get-id> declared in <root>.I.<get-id>' type=T of <root>.I.<get-id> 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 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:A modality:FINAL visibility:public superTypes:[<root>.I]
|
||||
$this: VALUE_PARAMETER INSTANCE_RECEIVER name:<this> type:<root>.A
|
||||
CONSTRUCTOR visibility:public <> (i:<root>.I) returnType:<root>.A [primary]
|
||||
VALUE_PARAMETER name:i index:0 type:<root>.I
|
||||
BLOCK_BODY
|
||||
DELEGATING_CONSTRUCTOR_CALL 'public constructor <init> () declared in kotlin.Any'
|
||||
INSTANCE_INITIALIZER_CALL classDescriptor='CLASS CLASS name:A modality:FINAL visibility:public superTypes:[<root>.I]'
|
||||
FIELD DELEGATE name:$$delegate_0 type:<root>.I visibility:private [final]
|
||||
EXPRESSION_BODY
|
||||
GET_VAR 'i: <root>.I declared in <root>.A.<init>' type=<root>.I origin=null
|
||||
PROPERTY DELEGATED_MEMBER name:id visibility:public modality:OPEN [val]
|
||||
overridden:
|
||||
public open id: T of <root>.I.<get-id>
|
||||
FUN DELEGATED_MEMBER name:<get-id> visibility:public modality:OPEN <T> ($this:<root>.A, $receiver:T of <root>.A.<get-id>) returnType:T of <root>.A.<get-id>
|
||||
correspondingProperty: PROPERTY DELEGATED_MEMBER name:id visibility:public modality:OPEN [val]
|
||||
overridden:
|
||||
public open fun <get-id> <T> (): T of <root>.I.<get-id> declared in <root>.I
|
||||
TYPE_PARAMETER name:T index:0 variance: superTypes:[kotlin.Any?] reified:false
|
||||
$this: VALUE_PARAMETER name:<this> type:<root>.A
|
||||
$receiver: VALUE_PARAMETER name:<this> type:T of <root>.A.<get-id>
|
||||
BLOCK_BODY
|
||||
RETURN type=kotlin.Nothing from='public open fun <get-id> <T> (): T of <root>.A.<get-id> declared in <root>.A'
|
||||
CALL 'public open fun <get-id> <T> (): T of <root>.I.<get-id> declared in <root>.I' type=T of <root>.I.<get-id> origin=null
|
||||
<T>: T of <root>.A.<get-id>
|
||||
$this: GET_FIELD 'FIELD DELEGATE name:$$delegate_0 type:<root>.I visibility:private [final]' type=<root>.I origin=null
|
||||
receiver: GET_VAR '<this>: <root>.A declared in <root>.A.<get-id>' type=<root>.A origin=null
|
||||
$receiver: GET_VAR '<this>: T of <root>.A.<get-id> declared in <root>.A.<get-id>' type=T of <root>.A.<get-id> 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 declared in <root>.I
|
||||
$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 <root>.I
|
||||
$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 <root>.I
|
||||
$this: VALUE_PARAMETER name:<this> type:kotlin.Any
|
||||
@@ -1,22 +0,0 @@
|
||||
interface I {
|
||||
val <T : Any?> T.id: T
|
||||
get(): T {
|
||||
return <this>
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class A : I {
|
||||
constructor(i: I) /* primary */ {
|
||||
super/*Any*/()
|
||||
/* <init>() */
|
||||
|
||||
}
|
||||
|
||||
private /* final field */ val $$delegate_0: I = i
|
||||
override val <T : Any?> T.id: T
|
||||
override get(): T {
|
||||
return (<this>.#$$delegate_0, <this>).<get-id><T>()
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
// FIR_IDENTICAL
|
||||
interface I {
|
||||
val <T> T.id: T
|
||||
get() = this
|
||||
|
||||
@@ -48,7 +48,7 @@ FILE fqName:<root> fileName:/kt43342.kt
|
||||
VALUE_PARAMETER name:key index:0 type:K of <root>.ControlFlowInfo
|
||||
BLOCK_BODY
|
||||
RETURN type=kotlin.Nothing from='public open fun get (key: K of <root>.ControlFlowInfo): V of <root>.ControlFlowInfo? declared in <root>.ControlFlowInfo'
|
||||
CALL 'public abstract fun get (key: K of kotlin.collections.Map): V of kotlin.collections.Map? declared in kotlin.collections.Map' type=V of kotlin.collections.Map? origin=null
|
||||
CALL 'public abstract fun get (key: K of kotlin.collections.Map): V of kotlin.collections.Map? declared in kotlin.collections.Map' type=V of <root>.ControlFlowInfo? origin=null
|
||||
$this: GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:map type:kotlin.collections.Map<K of <root>.ControlFlowInfo, V of <root>.ControlFlowInfo> visibility:private [final]' type=kotlin.collections.Map<K of <root>.ControlFlowInfo, V of <root>.ControlFlowInfo> origin=null
|
||||
receiver: GET_VAR '<this>: <root>.ControlFlowInfo<K of <root>.ControlFlowInfo, V of <root>.ControlFlowInfo> declared in <root>.ControlFlowInfo.get' type=<root>.ControlFlowInfo<K of <root>.ControlFlowInfo, V of <root>.ControlFlowInfo> origin=null
|
||||
key: GET_VAR 'key: K of <root>.ControlFlowInfo declared in <root>.ControlFlowInfo.get' type=K of <root>.ControlFlowInfo origin=null
|
||||
@@ -71,7 +71,7 @@ FILE fqName:<root> fileName:/kt43342.kt
|
||||
$this: VALUE_PARAMETER name:<this> type:<root>.ControlFlowInfo<K of <root>.ControlFlowInfo, V of <root>.ControlFlowInfo>
|
||||
BLOCK_BODY
|
||||
RETURN type=kotlin.Nothing from='public open fun <get-entries> (): kotlin.collections.Set<kotlin.collections.Map.Entry<K of <root>.ControlFlowInfo, V of <root>.ControlFlowInfo>> declared in <root>.ControlFlowInfo'
|
||||
CALL 'public abstract fun <get-entries> (): kotlin.collections.Set<kotlin.collections.Map.Entry<K of kotlin.collections.Map, V of kotlin.collections.Map>> declared in kotlin.collections.Map' type=kotlin.collections.Set<kotlin.collections.Map.Entry<K of kotlin.collections.Map, V of kotlin.collections.Map>> origin=null
|
||||
CALL 'public abstract fun <get-entries> (): kotlin.collections.Set<kotlin.collections.Map.Entry<K of kotlin.collections.Map, V of kotlin.collections.Map>> declared in kotlin.collections.Map' type=kotlin.collections.Set<kotlin.collections.Map.Entry<K of <root>.ControlFlowInfo, V of <root>.ControlFlowInfo>> origin=null
|
||||
$this: GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:map type:kotlin.collections.Map<K of <root>.ControlFlowInfo, V of <root>.ControlFlowInfo> visibility:private [final]' type=kotlin.collections.Map<K of <root>.ControlFlowInfo, V of <root>.ControlFlowInfo> origin=null
|
||||
receiver: GET_VAR '<this>: <root>.ControlFlowInfo<K of <root>.ControlFlowInfo, V of <root>.ControlFlowInfo> declared in <root>.ControlFlowInfo.<get-entries>' type=<root>.ControlFlowInfo<K of <root>.ControlFlowInfo, V of <root>.ControlFlowInfo> origin=null
|
||||
PROPERTY DELEGATED_MEMBER name:keys visibility:public modality:OPEN [val]
|
||||
@@ -84,7 +84,7 @@ FILE fqName:<root> fileName:/kt43342.kt
|
||||
$this: VALUE_PARAMETER name:<this> type:<root>.ControlFlowInfo<K of <root>.ControlFlowInfo, V of <root>.ControlFlowInfo>
|
||||
BLOCK_BODY
|
||||
RETURN type=kotlin.Nothing from='public open fun <get-keys> (): kotlin.collections.Set<K of <root>.ControlFlowInfo> declared in <root>.ControlFlowInfo'
|
||||
CALL 'public abstract fun <get-keys> (): kotlin.collections.Set<K of kotlin.collections.Map> declared in kotlin.collections.Map' type=kotlin.collections.Set<K of kotlin.collections.Map> origin=null
|
||||
CALL 'public abstract fun <get-keys> (): kotlin.collections.Set<K of kotlin.collections.Map> declared in kotlin.collections.Map' type=kotlin.collections.Set<K of <root>.ControlFlowInfo> origin=null
|
||||
$this: GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:map type:kotlin.collections.Map<K of <root>.ControlFlowInfo, V of <root>.ControlFlowInfo> visibility:private [final]' type=kotlin.collections.Map<K of <root>.ControlFlowInfo, V of <root>.ControlFlowInfo> origin=null
|
||||
receiver: GET_VAR '<this>: <root>.ControlFlowInfo<K of <root>.ControlFlowInfo, V of <root>.ControlFlowInfo> declared in <root>.ControlFlowInfo.<get-keys>' type=<root>.ControlFlowInfo<K of <root>.ControlFlowInfo, V of <root>.ControlFlowInfo> origin=null
|
||||
PROPERTY DELEGATED_MEMBER name:size visibility:public modality:OPEN [val]
|
||||
@@ -110,7 +110,7 @@ FILE fqName:<root> fileName:/kt43342.kt
|
||||
$this: VALUE_PARAMETER name:<this> type:<root>.ControlFlowInfo<K of <root>.ControlFlowInfo, V of <root>.ControlFlowInfo>
|
||||
BLOCK_BODY
|
||||
RETURN type=kotlin.Nothing from='public open fun <get-values> (): kotlin.collections.Collection<V of <root>.ControlFlowInfo> declared in <root>.ControlFlowInfo'
|
||||
CALL 'public abstract fun <get-values> (): kotlin.collections.Collection<V of kotlin.collections.Map> declared in kotlin.collections.Map' type=kotlin.collections.Collection<V of kotlin.collections.Map> origin=null
|
||||
CALL 'public abstract fun <get-values> (): kotlin.collections.Collection<V of kotlin.collections.Map> declared in kotlin.collections.Map' type=kotlin.collections.Collection<V of <root>.ControlFlowInfo> origin=null
|
||||
$this: GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:map type:kotlin.collections.Map<K of <root>.ControlFlowInfo, V of <root>.ControlFlowInfo> visibility:private [final]' type=kotlin.collections.Map<K of <root>.ControlFlowInfo, V of <root>.ControlFlowInfo> origin=null
|
||||
receiver: GET_VAR '<this>: <root>.ControlFlowInfo<K of <root>.ControlFlowInfo, V of <root>.ControlFlowInfo> declared in <root>.ControlFlowInfo.<get-values>' type=<root>.ControlFlowInfo<K of <root>.ControlFlowInfo, V of <root>.ControlFlowInfo> origin=null
|
||||
FUN FAKE_OVERRIDE name:getOrDefault visibility:public modality:OPEN <> ($this:kotlin.collections.Map<K of <root>.ControlFlowInfo, V of <root>.ControlFlowInfo>, key:K of <root>.ControlFlowInfo, defaultValue:V of <root>.ControlFlowInfo) returnType:V of <root>.ControlFlowInfo [fake_override]
|
||||
|
||||
Reference in New Issue
Block a user