PSI2IR Use resulting descriptor extension receiver type

Use resulting descriptor extension receiver type instead of
ReceiverValue.type (which can contain captured types, which would be
approximated, and cause IR validation errors).
This commit is contained in:
Dmitry Petrov
2020-03-02 17:28:06 +03:00
parent 51749b9747
commit 01c4e66edb
6 changed files with 123 additions and 1 deletions
@@ -1847,6 +1847,11 @@ public class Fir2IrTextTestGenerated extends AbstractFir2IrTextTest {
runTest("compiler/testData/ir/irText/types/genericPropertyReferenceType.kt");
}
@TestMetadata("inStarProjectionInReceiverType.kt")
public void testInStarProjectionInReceiverType() throws Exception {
runTest("compiler/testData/ir/irText/types/inStarProjectionInReceiverType.kt");
}
@TestMetadata("intersectionType1_NI.kt")
public void testIntersectionType1_NI() throws Exception {
runTest("compiler/testData/ir/irText/types/intersectionType1_NI.kt");
@@ -56,7 +56,13 @@ fun StatementGenerator.generateReceiver(ktDefaultElement: KtElement, receiver: R
generateReceiver(ktDefaultElement.startOffsetSkippingComments, ktDefaultElement.endOffset, receiver)
fun StatementGenerator.generateReceiver(defaultStartOffset: Int, defaultEndOffset: Int, receiver: ReceiverValue): IntermediateValue {
val irReceiverType = receiver.type.toIrType()
val irReceiverType =
when (receiver) {
is ExtensionReceiver ->
receiver.declarationDescriptor.extensionReceiverParameter!!.type.toIrType()
else ->
receiver.type.toIrType()
}
if (receiver is TransientReceiver) return TransientReceiverValue(irReceiverType)
@@ -0,0 +1,45 @@
FILE fqName:<root> fileName:/inStarProjectionInReceiverType.kt
CLASS INTERFACE name:Foo modality:ABSTRACT visibility:public superTypes:[kotlin.Any]
$this: VALUE_PARAMETER INSTANCE_RECEIVER name:<this> type:<root>.Foo<T of <root>.Foo>
TYPE_PARAMETER name:T index:0 variance:in superTypes:[kotlin.Any?]
PROPERTY name:x visibility:public modality:ABSTRACT [val]
FUN DEFAULT_PROPERTY_ACCESSOR name:<get-x> visibility:public modality:ABSTRACT <> ($this:<root>.Foo<T of <root>.Foo>) returnType:kotlin.Int
correspondingProperty: PROPERTY name:x visibility:public modality:ABSTRACT [val]
$this: VALUE_PARAMETER name:<this> type:<root>.Foo<T of <root>.Foo>
FUN name:foo visibility:public modality:ABSTRACT <> ($this:<root>.Foo<T of <root>.Foo>, x:T of <root>.Foo) returnType:kotlin.Unit
$this: VALUE_PARAMETER name:<this> type:<root>.Foo<T of <root>.Foo>
VALUE_PARAMETER name:x index:0 type:T of <root>.Foo
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
FUN name:testReceiver visibility:public modality:FINAL <> ($receiver:<root>.Foo<*>) returnType:kotlin.Int
$receiver: VALUE_PARAMETER name:<this> type:<root>.Foo<*>
BLOCK_BODY
RETURN type=kotlin.Nothing from='public final fun testReceiver (): kotlin.Int declared in <root>'
CALL 'public abstract fun <get-x> (): kotlin.Int declared in <root>.Foo' type=kotlin.Int origin=GET_PROPERTY
$this: GET_VAR '<this>: <root>.Foo<*> declared in <root>.testReceiver' type=<root>.Foo<*> origin=null
FUN name:testSmartCastOnExtensionReceiver visibility:public modality:FINAL <> ($receiver:<root>.Foo<*>) returnType:kotlin.Unit
$receiver: VALUE_PARAMETER name:<this> type:<root>.Foo<*>
BLOCK_BODY
TYPE_OP type=<root>.Foo<kotlin.String> origin=CAST typeOperand=<root>.Foo<kotlin.String>
GET_VAR '<this>: <root>.Foo<*> declared in <root>.testSmartCastOnExtensionReceiver' type=<root>.Foo<*> origin=null
CALL 'public abstract fun foo (x: T of <root>.Foo): kotlin.Unit declared in <root>.Foo' type=kotlin.Unit origin=null
$this: TYPE_OP type=<root>.Foo<kotlin.String> origin=IMPLICIT_CAST typeOperand=<root>.Foo<kotlin.String>
GET_VAR '<this>: <root>.Foo<*> declared in <root>.testSmartCastOnExtensionReceiver' type=<root>.Foo<*> origin=null
x: CONST String type=kotlin.String value="string"
FUN name:testValueParameter visibility:public modality:FINAL <> (vp:<root>.Foo<*>) returnType:kotlin.Int
VALUE_PARAMETER name:vp index:0 type:<root>.Foo<*>
BLOCK_BODY
RETURN type=kotlin.Nothing from='public final fun testValueParameter (vp: <root>.Foo<*>): kotlin.Int declared in <root>'
CALL 'public abstract fun <get-x> (): kotlin.Int declared in <root>.Foo' type=kotlin.Int origin=GET_PROPERTY
$this: GET_VAR 'vp: <root>.Foo<*> declared in <root>.testValueParameter' type=<root>.Foo<*> origin=null
@@ -0,0 +1,15 @@
// !LANGUAGE: +NewInference
interface Foo<in T> {
val x: Int
fun foo(x: T)
}
fun Foo<*>.testReceiver() = x
fun Foo<*>.testSmartCastOnExtensionReceiver() {
this as Foo<String>
foo("string")
}
fun testValueParameter(vp: Foo<*>) = vp.x
@@ -0,0 +1,46 @@
FILE fqName:<root> fileName:/inStarProjectionInReceiverType.kt
CLASS INTERFACE name:Foo modality:ABSTRACT visibility:public superTypes:[kotlin.Any]
$this: VALUE_PARAMETER INSTANCE_RECEIVER name:<this> type:<root>.Foo<T of <root>.Foo>
TYPE_PARAMETER name:T index:0 variance:in superTypes:[kotlin.Any?]
PROPERTY name:x visibility:public modality:ABSTRACT [val]
FUN DEFAULT_PROPERTY_ACCESSOR name:<get-x> visibility:public modality:ABSTRACT <> ($this:<root>.Foo<T of <root>.Foo>) returnType:kotlin.Int
correspondingProperty: PROPERTY name:x visibility:public modality:ABSTRACT [val]
$this: VALUE_PARAMETER name:<this> type:<root>.Foo<T of <root>.Foo>
FUN name:foo visibility:public modality:ABSTRACT <> ($this:<root>.Foo<T of <root>.Foo>, x:T of <root>.Foo) returnType:kotlin.Unit
$this: VALUE_PARAMETER name:<this> type:<root>.Foo<T of <root>.Foo>
VALUE_PARAMETER name:x index:0 type:T of <root>.Foo
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
FUN name:testReceiver visibility:public modality:FINAL <> ($receiver:<root>.Foo<*>) returnType:kotlin.Int
$receiver: VALUE_PARAMETER name:<this> type:<root>.Foo<*>
BLOCK_BODY
RETURN type=kotlin.Nothing from='public final fun testReceiver (): kotlin.Int declared in <root>'
CALL 'public abstract fun <get-x> (): kotlin.Int declared in <root>.Foo' type=kotlin.Int origin=GET_PROPERTY
$this: GET_VAR '<this>: <root>.Foo<*> declared in <root>.testReceiver' type=<root>.Foo<*> origin=null
FUN name:testSmartCastOnExtensionReceiver visibility:public modality:FINAL <> ($receiver:<root>.Foo<*>) returnType:kotlin.Unit
$receiver: VALUE_PARAMETER name:<this> type:<root>.Foo<*>
BLOCK_BODY
TYPE_OP type=kotlin.Unit origin=IMPLICIT_COERCION_TO_UNIT typeOperand=kotlin.Unit
TYPE_OP type=<root>.Foo<kotlin.String> origin=CAST typeOperand=<root>.Foo<kotlin.String>
GET_VAR '<this>: <root>.Foo<*> declared in <root>.testSmartCastOnExtensionReceiver' type=<root>.Foo<*> origin=null
CALL 'public abstract fun foo (x: T of <root>.Foo): kotlin.Unit declared in <root>.Foo' type=kotlin.Unit origin=null
$this: TYPE_OP type=<root>.Foo<kotlin.String> origin=IMPLICIT_CAST typeOperand=<root>.Foo<kotlin.String>
GET_VAR '<this>: <root>.Foo<*> declared in <root>.testSmartCastOnExtensionReceiver' type=<root>.Foo<*> origin=null
x: CONST String type=kotlin.String value="string"
FUN name:testValueParameter visibility:public modality:FINAL <> (vp:<root>.Foo<*>) returnType:kotlin.Int
VALUE_PARAMETER name:vp index:0 type:<root>.Foo<*>
BLOCK_BODY
RETURN type=kotlin.Nothing from='public final fun testValueParameter (vp: <root>.Foo<*>): kotlin.Int declared in <root>'
CALL 'public abstract fun <get-x> (): kotlin.Int declared in <root>.Foo' type=kotlin.Int origin=GET_PROPERTY
$this: GET_VAR 'vp: <root>.Foo<*> declared in <root>.testValueParameter' type=<root>.Foo<*> origin=null
@@ -1846,6 +1846,11 @@ public class IrTextTestCaseGenerated extends AbstractIrTextTestCase {
runTest("compiler/testData/ir/irText/types/genericPropertyReferenceType.kt");
}
@TestMetadata("inStarProjectionInReceiverType.kt")
public void testInStarProjectionInReceiverType() throws Exception {
runTest("compiler/testData/ir/irText/types/inStarProjectionInReceiverType.kt");
}
@TestMetadata("intersectionType1_NI.kt")
public void testIntersectionType1_NI() throws Exception {
runTest("compiler/testData/ir/irText/types/intersectionType1_NI.kt");