K2: update return type properly for delegated members #KT-61443 Fixed

This commit is contained in:
Mikhail Glukhikh
2023-09-14 13:18:39 +02:00
committed by Space Team
parent 1b9197dd17
commit 53e4e2f6b1
5 changed files with 184 additions and 4 deletions
@@ -54,7 +54,7 @@ class FirDelegatedMemberScope(
private fun buildScope(delegateField: FirField): FirTypeScope? = delegateField.symbol.resolvedReturnType.scope(
session,
scopeSession,
FakeOverrideTypeCalculator.DoNothing,
FakeOverrideTypeCalculator.Forced,
requiredMembersPhase = null,
)
@@ -6,8 +6,8 @@
package org.jetbrains.kotlin.fir.scopes.impl
import org.jetbrains.kotlin.fir.declarations.FirCallableDeclaration
import org.jetbrains.kotlin.fir.isIntersectionOverride
import org.jetbrains.kotlin.fir.isSubstitutionOverride
import org.jetbrains.kotlin.fir.isDelegated
import org.jetbrains.kotlin.fir.isSubstitutionOrIntersectionOverride
import org.jetbrains.kotlin.fir.scopes.FakeOverrideTypeCalculator
import org.jetbrains.kotlin.fir.scopes.FirDelegatingTypeScope
import org.jetbrains.kotlin.fir.scopes.FirTypeScope
@@ -54,7 +54,7 @@ class FirScopeWithFakeOverrideTypeCalculator(
}
private fun updateReturnType(declaration: FirCallableDeclaration) {
if (declaration.isSubstitutionOverride || declaration.isIntersectionOverride) {
if (declaration.isSubstitutionOrIntersectionOverride || declaration.isDelegated) {
fakeOverrideTypeCalculator.computeReturnType(declaration)
}
}
@@ -69,6 +69,7 @@ var FirRegularClass.isNewPlaceForBodyGeneration: Boolean? by FirDeclarationDataR
val FirCallableDeclaration.isIntersectionOverride: Boolean get() = origin == FirDeclarationOrigin.IntersectionOverride
val FirCallableDeclaration.isSubstitutionOverride: Boolean get() = origin is FirDeclarationOrigin.SubstitutionOverride
val FirCallableDeclaration.isSubstitutionOrIntersectionOverride: Boolean get() = isSubstitutionOverride || isIntersectionOverride
val FirCallableDeclaration.isDelegated: Boolean get() = origin == FirDeclarationOrigin.Delegated
val FirCallableSymbol<*>.isIntersectionOverride: Boolean get() = origin == FirDeclarationOrigin.IntersectionOverride
val FirCallableSymbol<*>.isSubstitutionOverride: Boolean get() = origin is FirDeclarationOrigin.SubstitutionOverride
@@ -0,0 +1,131 @@
FILE fqName:<root> fileName:/substitutionOverrideWithDelegate.kt
FUN name:foo visibility:public modality:FINAL <> () returnType:kotlin.Unit
BLOCK_BODY
RETURN type=kotlin.Nothing from='public final fun foo (): kotlin.Unit declared in <root>'
CALL 'public open fun invoke (): kotlin.Unit declared in <root>.DelegatedB' type=kotlin.Unit origin=null
$this: CONSTRUCTOR_CALL 'public constructor <init> () declared in <root>.DelegatedB' type=<root>.DelegatedB origin=null
CLASS INTERFACE name:A modality:ABSTRACT visibility:public superTypes:[kotlin.Any]
$this: VALUE_PARAMETER INSTANCE_RECEIVER name:<this> type:<root>.A
FUN name:invoke visibility:public modality:OPEN <> ($this:<root>.A) returnType:kotlin.Unit [operator]
$this: VALUE_PARAMETER name:<this> type:<root>.A
BLOCK_BODY
FUN name:invoke visibility:public modality:OPEN <> ($this:<root>.A, value:kotlin.String) returnType:kotlin.Unit [operator]
$this: VALUE_PARAMETER name:<this> type:<root>.A
VALUE_PARAMETER name:value index:0 type:kotlin.String
BLOCK_BODY
RETURN type=kotlin.Nothing from='public open fun invoke (value: kotlin.String): kotlin.Unit declared in <root>.A'
CALL 'public final fun bar (value: kotlin.String): kotlin.Unit declared in <root>' type=kotlin.Unit origin=null
$receiver: GET_VAR '<this>: <root>.A declared in <root>.A.invoke' type=<root>.A origin=null
value: GET_VAR 'value: kotlin.String declared in <root>.A.invoke' type=kotlin.String 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
FUN name:bar visibility:public modality:FINAL <> ($receiver:<root>.A, value:kotlin.String) returnType:kotlin.Unit
$receiver: VALUE_PARAMETER name:<this> type:<root>.A
VALUE_PARAMETER name:value index:0 type:kotlin.String
BLOCK_BODY
CLASS CLASS name:DelegatedB modality:OPEN visibility:public superTypes:[<root>.B<kotlin.String>]
$this: VALUE_PARAMETER INSTANCE_RECEIVER name:<this> type:<root>.DelegatedB
CONSTRUCTOR visibility:public <> () returnType:<root>.DelegatedB [primary]
BLOCK_BODY
DELEGATING_CONSTRUCTOR_CALL 'public constructor <init> () declared in kotlin.Any'
INSTANCE_INITIALIZER_CALL classDescriptor='CLASS CLASS name:DelegatedB modality:OPEN visibility:public superTypes:[<root>.B<kotlin.String>]'
FUN DELEGATED_MEMBER name:invoke visibility:public modality:OPEN <> ($this:<root>.DelegatedB) returnType:kotlin.Unit [operator]
overridden:
public open fun invoke (): kotlin.Unit declared in <root>.B
$this: VALUE_PARAMETER name:<this> type:<root>.DelegatedB
BLOCK_BODY
CALL 'public open fun invoke (): kotlin.Unit declared in <root>.A' type=kotlin.Unit origin=null
$this: GET_FIELD 'FIELD DELEGATE name:$$delegate_0 type:<root>.C<kotlin.String> visibility:private [final]' type=<root>.C<kotlin.String> origin=null
receiver: GET_VAR '<this>: <root>.DelegatedB declared in <root>.DelegatedB.invoke' type=<root>.DelegatedB origin=null
FUN DELEGATED_MEMBER name:invoke visibility:public modality:OPEN <> ($this:<root>.DelegatedB, value:kotlin.String) returnType:kotlin.Unit [operator]
overridden:
public open fun invoke (value: kotlin.String): kotlin.Unit declared in <root>.B
$this: VALUE_PARAMETER name:<this> type:<root>.DelegatedB
VALUE_PARAMETER name:value index:0 type:kotlin.String
BLOCK_BODY
CALL 'public open fun invoke (value: kotlin.String): kotlin.Unit declared in <root>.A' type=kotlin.Unit origin=null
$this: GET_FIELD 'FIELD DELEGATE name:$$delegate_0 type:<root>.C<kotlin.String> visibility:private [final]' type=<root>.C<kotlin.String> origin=null
receiver: GET_VAR '<this>: <root>.DelegatedB declared in <root>.DelegatedB.invoke' type=<root>.DelegatedB origin=null
value: GET_VAR 'value: kotlin.String declared in <root>.DelegatedB.invoke' type=kotlin.String origin=null
FIELD DELEGATE name:$$delegate_0 type:<root>.C<kotlin.String> visibility:private [final]
EXPRESSION_BODY
CONSTRUCTOR_CALL 'public constructor <init> () declared in <root>.C' type=<root>.C<kotlin.String> origin=null
<class: T>: kotlin.String
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>.B
$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>.B
$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>.B
$this: VALUE_PARAMETER name:<this> type:kotlin.Any
CLASS INTERFACE name:B modality:ABSTRACT visibility:public superTypes:[<root>.A]
$this: VALUE_PARAMETER INSTANCE_RECEIVER name:<this> type:<root>.B<T of <root>.B>
TYPE_PARAMETER name:T index:0 variance:out superTypes:[kotlin.Any?] reified:false
FUN FAKE_OVERRIDE name:invoke visibility:public modality:OPEN <> ($this:<root>.A) returnType:kotlin.Unit [fake_override,operator]
overridden:
public open fun invoke (): kotlin.Unit declared in <root>.A
$this: VALUE_PARAMETER name:<this> type:<root>.A
FUN FAKE_OVERRIDE name:invoke visibility:public modality:OPEN <> ($this:<root>.A, value:kotlin.String) returnType:kotlin.Unit [fake_override,operator]
overridden:
public open fun invoke (value: kotlin.String): kotlin.Unit declared in <root>.A
$this: VALUE_PARAMETER name:<this> type:<root>.A
VALUE_PARAMETER name:value index:0 type:kotlin.String
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>.A
$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>.A
$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>.A
$this: VALUE_PARAMETER name:<this> type:kotlin.Any
CLASS CLASS name:C modality:FINAL visibility:public superTypes:[<root>.B<T of <root>.C>]
$this: VALUE_PARAMETER INSTANCE_RECEIVER name:<this> type:<root>.C<T of <root>.C>
TYPE_PARAMETER name:T index:0 variance:out superTypes:[kotlin.Any?] reified:false
CONSTRUCTOR visibility:public <> () returnType:<root>.C<T of <root>.C> [primary]
BLOCK_BODY
DELEGATING_CONSTRUCTOR_CALL 'public constructor <init> () declared in kotlin.Any'
INSTANCE_INITIALIZER_CALL classDescriptor='CLASS CLASS name:C modality:FINAL visibility:public superTypes:[<root>.B<T of <root>.C>]'
FUN FAKE_OVERRIDE name:invoke visibility:public modality:OPEN <> ($this:<root>.A) returnType:kotlin.Unit [fake_override,operator]
overridden:
public open fun invoke (): kotlin.Unit declared in <root>.B
$this: VALUE_PARAMETER name:<this> type:<root>.A
FUN FAKE_OVERRIDE name:invoke visibility:public modality:OPEN <> ($this:<root>.A, value:kotlin.String) returnType:kotlin.Unit [fake_override,operator]
overridden:
public open fun invoke (value: kotlin.String): kotlin.Unit declared in <root>.B
$this: VALUE_PARAMETER name:<this> type:<root>.A
VALUE_PARAMETER name:value index:0 type:kotlin.String
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>.B
$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>.B
$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>.B
$this: VALUE_PARAMETER name:<this> type:kotlin.Any
@@ -0,0 +1,48 @@
fun foo() {
return DelegatedB().invoke()
}
interface A {
operator fun invoke() {
}
operator fun invoke(value: String) {
return <this>.bar(value = value)
}
}
fun A.bar(value: String) {
}
open class DelegatedB : B<String> {
constructor() /* primary */ {
super/*Any*/()
/* <init>() */
}
override operator fun invoke() {
<this>.#$$delegate_0.invoke()
}
override operator fun invoke(value: String) {
<this>.#$$delegate_0.invoke(value = value)
}
private /* final field */ val $$delegate_0: C<String> = C<String>()
}
interface B<out T : Any?> : A {
}
class C<out T : Any?> : B<T> {
constructor() /* primary */ {
super/*Any*/()
/* <init>() */
}
}