[FIR2IR] Properly approximate intersection types during fir2ir conversion
^KT-62544 Fixed
This commit is contained in:
committed by
Space Team
parent
8c6da9fddb
commit
9366847e96
+6
-6
@@ -100,9 +100,9 @@ FILE fqName:<root> fileName:/delegationToIntersectionType.kt
|
||||
VALUE_PARAMETER name:c index:0 type:<root>.C
|
||||
VALUE_PARAMETER name:d index:1 type:<root>.D
|
||||
BLOCK_BODY
|
||||
VAR name:intersection type:<root>.A [val]
|
||||
CALL 'public final fun select <T> (a: T of <root>.select, b: T of <root>.select): T of <root>.select declared in <root>' type=<root>.A origin=null
|
||||
<T>: <root>.A
|
||||
VAR name:intersection type:kotlin.Any [val]
|
||||
CALL 'public final fun select <T> (a: T of <root>.select, b: T of <root>.select): T of <root>.select declared in <root>' type=kotlin.Any origin=null
|
||||
<T>: kotlin.Any
|
||||
a: GET_VAR 'c: <root>.C declared in <root>.test' type=<root>.C origin=null
|
||||
b: GET_VAR 'd: <root>.D declared in <root>.test' type=<root>.D origin=null
|
||||
RETURN type=kotlin.Nothing from='public final fun test (c: <root>.C, d: <root>.D): kotlin.String declared in <root>'
|
||||
@@ -114,9 +114,9 @@ FILE fqName:<root> fileName:/delegationToIntersectionType.kt
|
||||
BLOCK_BODY
|
||||
DELEGATING_CONSTRUCTOR_CALL 'public constructor <init> () declared in kotlin.Any'
|
||||
INSTANCE_INITIALIZER_CALL classDescriptor='CLASS CLASS name:<no name provided> modality:FINAL visibility:local superTypes:[<root>.B]'
|
||||
FIELD DELEGATE name:$$delegate_0 type:<root>.A visibility:private [final]
|
||||
FIELD DELEGATE name:$$delegate_0 type:kotlin.Any visibility:private [final]
|
||||
EXPRESSION_BODY
|
||||
GET_VAR 'val intersection: <root>.A declared in <root>.test' type=<root>.A origin=null
|
||||
GET_VAR 'val intersection: kotlin.Any declared in <root>.test' type=kotlin.Any origin=null
|
||||
FUN DELEGATED_MEMBER name:foo visibility:public modality:OPEN <> ($this:<root>.test.<no name provided>) returnType:kotlin.String
|
||||
overridden:
|
||||
public abstract fun foo (): kotlin.String declared in <root>.B
|
||||
@@ -125,7 +125,7 @@ FILE fqName:<root> fileName:/delegationToIntersectionType.kt
|
||||
RETURN type=kotlin.Nothing from='public open fun foo (): kotlin.String declared in <root>.test.<no name provided>'
|
||||
CALL 'public abstract fun foo (): kotlin.String declared in <root>.B' type=kotlin.String origin=null
|
||||
$this: TYPE_OP type=<root>.B origin=IMPLICIT_CAST typeOperand=<root>.B
|
||||
GET_FIELD 'FIELD DELEGATE name:$$delegate_0 type:<root>.A visibility:private [final]' type=<root>.A origin=null
|
||||
GET_FIELD 'FIELD DELEGATE name:$$delegate_0 type:kotlin.Any visibility:private [final]' type=kotlin.Any origin=null
|
||||
receiver: GET_VAR '<this>: <root>.test.<no name provided> declared in <root>.test.<no name provided>.foo' type=<root>.test.<no name provided> origin=null
|
||||
FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean [fake_override,operator]
|
||||
overridden:
|
||||
|
||||
+6
-6
@@ -104,9 +104,9 @@ FILE fqName:<root> fileName:/delegationToIntersectionType2.kt
|
||||
VALUE_PARAMETER name:c index:0 type:<root>.C
|
||||
VALUE_PARAMETER name:d index:1 type:<root>.D
|
||||
BLOCK_BODY
|
||||
VAR name:intersection type:<root>.A [val]
|
||||
CALL 'public final fun select <T> (a: T of <root>.select, b: T of <root>.select): T of <root>.select declared in <root>' type=<root>.A origin=null
|
||||
<T>: <root>.A
|
||||
VAR name:intersection type:kotlin.Any [val]
|
||||
CALL 'public final fun select <T> (a: T of <root>.select, b: T of <root>.select): T of <root>.select declared in <root>' type=kotlin.Any origin=null
|
||||
<T>: kotlin.Any
|
||||
a: GET_VAR 'c: <root>.C declared in <root>.test' type=<root>.C origin=null
|
||||
b: GET_VAR 'd: <root>.D declared in <root>.test' type=<root>.D origin=null
|
||||
RETURN type=kotlin.Nothing from='public final fun test (c: <root>.C, d: <root>.D): kotlin.String declared in <root>'
|
||||
@@ -119,9 +119,9 @@ FILE fqName:<root> fileName:/delegationToIntersectionType2.kt
|
||||
BLOCK_BODY
|
||||
DELEGATING_CONSTRUCTOR_CALL 'public constructor <init> () declared in kotlin.Any'
|
||||
INSTANCE_INITIALIZER_CALL classDescriptor='CLASS CLASS name:<no name provided> modality:FINAL visibility:local superTypes:[<root>.A]'
|
||||
FIELD DELEGATE name:$$delegate_0 type:<root>.A visibility:private [final]
|
||||
FIELD DELEGATE name:$$delegate_0 type:kotlin.Any visibility:private [final]
|
||||
EXPRESSION_BODY
|
||||
GET_VAR 'val intersection: <root>.A declared in <root>.test' type=<root>.A origin=null
|
||||
GET_VAR 'val intersection: kotlin.Any declared in <root>.test' type=kotlin.Any origin=null
|
||||
FUN DELEGATED_MEMBER name:foo visibility:public modality:OPEN <> ($this:<root>.test.<no name provided>) returnType:kotlin.Any
|
||||
overridden:
|
||||
public abstract fun foo (): kotlin.Any declared in <root>.A
|
||||
@@ -130,7 +130,7 @@ FILE fqName:<root> fileName:/delegationToIntersectionType2.kt
|
||||
RETURN type=kotlin.Nothing from='public open fun foo (): kotlin.Any declared in <root>.test.<no name provided>'
|
||||
CALL 'public abstract fun foo (): kotlin.String declared in <root>.B' type=kotlin.String origin=null
|
||||
$this: TYPE_OP type=<root>.B origin=IMPLICIT_CAST typeOperand=<root>.B
|
||||
GET_FIELD 'FIELD DELEGATE name:$$delegate_0 type:<root>.A visibility:private [final]' type=<root>.A origin=null
|
||||
GET_FIELD 'FIELD DELEGATE name:$$delegate_0 type:kotlin.Any visibility:private [final]' type=kotlin.Any origin=null
|
||||
receiver: GET_VAR '<this>: <root>.test.<no name provided> declared in <root>.test.<no name provided>.foo' type=<root>.test.<no name provided> origin=null
|
||||
FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean [fake_override,operator]
|
||||
overridden:
|
||||
|
||||
+40
@@ -0,0 +1,40 @@
|
||||
// TARGET_BACKEND: JVM_IR
|
||||
// ISSUE: KT-62544
|
||||
|
||||
// FILE: Base.java
|
||||
public interface Base {
|
||||
String get();
|
||||
}
|
||||
|
||||
// FILE: Impl.java
|
||||
class Impl {}
|
||||
|
||||
// FILE: O.java
|
||||
public class O extends Impl implements Base {
|
||||
@Override
|
||||
public String get() { return "O"; }
|
||||
}
|
||||
|
||||
// FILE: K.java
|
||||
public class K extends Impl implements Base {
|
||||
@Override
|
||||
public String get() { return "K"; }
|
||||
}
|
||||
|
||||
// FILE: box.kt
|
||||
package test
|
||||
|
||||
import O
|
||||
import K
|
||||
|
||||
fun <A, B : A, C : A> foo(
|
||||
b: B,
|
||||
c: C,
|
||||
f: (A) -> String
|
||||
): String {
|
||||
return f(b) + f(c)
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
return foo(O(), K()) { it.get() }
|
||||
}
|
||||
-51
@@ -1,51 +0,0 @@
|
||||
@kotlin.Metadata
|
||||
public interface A {
|
||||
// source: 'nonApproxToValidSupertype.kt'
|
||||
}
|
||||
|
||||
@kotlin.Metadata
|
||||
public interface B {
|
||||
// source: 'nonApproxToValidSupertype.kt'
|
||||
}
|
||||
|
||||
@kotlin.Metadata
|
||||
public final class G {
|
||||
// source: 'nonApproxToValidSupertype.kt'
|
||||
public method <init>(): void
|
||||
public final method check(@org.jetbrains.annotations.NotNull p0: IFoo): void
|
||||
}
|
||||
|
||||
@kotlin.Metadata
|
||||
public interface IFoo {
|
||||
// source: 'nonApproxToValidSupertype.kt'
|
||||
public abstract method accept(@org.jetbrains.annotations.NotNull p0: X): void
|
||||
}
|
||||
|
||||
@kotlin.Metadata
|
||||
final class NonApproxToValidSupertypeKt$test$1 {
|
||||
// source: 'nonApproxToValidSupertype.kt'
|
||||
enclosing method NonApproxToValidSupertypeKt.test()V
|
||||
public final static field INSTANCE: NonApproxToValidSupertypeKt$test$1
|
||||
inner (anonymous) class NonApproxToValidSupertypeKt$test$1
|
||||
static method <clinit>(): void
|
||||
method <init>(): void
|
||||
public final method accept(p0: X): void
|
||||
}
|
||||
|
||||
@kotlin.Metadata
|
||||
public final class NonApproxToValidSupertypeKt {
|
||||
// source: 'nonApproxToValidSupertype.kt'
|
||||
inner (anonymous) class NonApproxToValidSupertypeKt$test$1
|
||||
public final static method sel(p0: java.lang.Object, p1: java.lang.Object): java.lang.Object
|
||||
public final static method test(): void
|
||||
}
|
||||
|
||||
@kotlin.Metadata
|
||||
public interface X {
|
||||
// source: 'nonApproxToValidSupertype.kt'
|
||||
}
|
||||
|
||||
@kotlin.Metadata
|
||||
public interface Z {
|
||||
// source: 'nonApproxToValidSupertype.kt'
|
||||
}
|
||||
@@ -1,6 +1,3 @@
|
||||
// K1 generates `accept(Object)` and bridge `accept(X)` in the SAM adapter.
|
||||
// K2 generates `accept(X)` only. It is fine though, because if `check`'s parameter is passed where Z is expected, checkcast is added.
|
||||
|
||||
interface X
|
||||
interface Z
|
||||
|
||||
|
||||
-62
@@ -1,62 +0,0 @@
|
||||
@kotlin.Metadata
|
||||
public interface A {
|
||||
// source: 'nonApproxToValidSupertype2.kt'
|
||||
}
|
||||
|
||||
@kotlin.Metadata
|
||||
public interface B {
|
||||
// source: 'nonApproxToValidSupertype2.kt'
|
||||
}
|
||||
|
||||
@kotlin.Metadata
|
||||
public final class G {
|
||||
// source: 'nonApproxToValidSupertype2.kt'
|
||||
public method <init>(): void
|
||||
public final method check(@org.jetbrains.annotations.NotNull p0: IFoo): void
|
||||
}
|
||||
|
||||
@kotlin.Metadata
|
||||
public interface IFoo {
|
||||
// source: 'nonApproxToValidSupertype2.kt'
|
||||
public abstract method accept(@org.jetbrains.annotations.NotNull p0: U): void
|
||||
}
|
||||
|
||||
@kotlin.Metadata
|
||||
final class NonApproxToValidSupertype2Kt$test$1 {
|
||||
// source: 'nonApproxToValidSupertype2.kt'
|
||||
enclosing method NonApproxToValidSupertype2Kt.test()V
|
||||
public final static field INSTANCE: NonApproxToValidSupertype2Kt$test$1
|
||||
inner (anonymous) class NonApproxToValidSupertype2Kt$test$1
|
||||
static method <clinit>(): void
|
||||
method <init>(): void
|
||||
public synthetic bridge method accept(p0: U): void
|
||||
public final method accept(p0: X): void
|
||||
}
|
||||
|
||||
@kotlin.Metadata
|
||||
public final class NonApproxToValidSupertype2Kt {
|
||||
// source: 'nonApproxToValidSupertype2.kt'
|
||||
inner (anonymous) class NonApproxToValidSupertype2Kt$test$1
|
||||
public final static method sel(p0: java.lang.Object, p1: java.lang.Object): java.lang.Object
|
||||
public final static method test(): void
|
||||
}
|
||||
|
||||
@kotlin.Metadata
|
||||
public interface U {
|
||||
// source: 'nonApproxToValidSupertype2.kt'
|
||||
}
|
||||
|
||||
@kotlin.Metadata
|
||||
public interface W {
|
||||
// source: 'nonApproxToValidSupertype2.kt'
|
||||
}
|
||||
|
||||
@kotlin.Metadata
|
||||
public interface X {
|
||||
// source: 'nonApproxToValidSupertype2.kt'
|
||||
}
|
||||
|
||||
@kotlin.Metadata
|
||||
public interface Z {
|
||||
// source: 'nonApproxToValidSupertype2.kt'
|
||||
}
|
||||
@@ -1,6 +1,3 @@
|
||||
// K1 generates `accept(Object)` and bridge `accept(U)` in the SAM adapter.
|
||||
// K2 generates `accept(X)` and bridge `accept(U)`. It is fine though, because if `check`'s parameter is passed where Z or W is expected, checkcast is added.
|
||||
|
||||
interface X: U, W
|
||||
interface Z: U, W
|
||||
|
||||
|
||||
Reference in New Issue
Block a user