[FIR] Add smartcasts from == if equals is from Any
^KT-49127 Fixed
This commit is contained in:
committed by
teamcityserver
parent
ac718cd1c4
commit
1f0b62b25f
compiler/fir/analysis-tests/testData/resolve/smartcasts/smartcastsFromEquals_differentModule.fir.txt
Vendored
+96
@@ -0,0 +1,96 @@
|
||||
Module: lib
|
||||
FILE: module_lib_smartcastsFromEquals_differentModule.kt
|
||||
public final class Final<T> : R|kotlin/Any| {
|
||||
public constructor<T>(): R|Final<T>| {
|
||||
super<R|kotlin/Any|>()
|
||||
}
|
||||
|
||||
}
|
||||
public open class Base<T> : R|kotlin/Any| {
|
||||
public constructor<T>(): R|Base<T>| {
|
||||
super<R|kotlin/Any|>()
|
||||
}
|
||||
|
||||
}
|
||||
public final class Derived<T> : R|Base<T>| {
|
||||
public constructor<T>(): R|Derived<T>| {
|
||||
super<R|Base<T>|>()
|
||||
}
|
||||
|
||||
}
|
||||
public final class FinalWithOverride<T> : R|kotlin/Any| {
|
||||
public constructor<T>(): R|FinalWithOverride<T>| {
|
||||
super<R|kotlin/Any|>()
|
||||
}
|
||||
|
||||
public final override operator fun equals(other: R|kotlin/Any?|): R|kotlin/Boolean| {
|
||||
^equals ===(this@R|/FinalWithOverride|, R|<local>/other|)
|
||||
}
|
||||
|
||||
}
|
||||
Module: main
|
||||
FILE: module_main_smartcastsFromEquals_differentModule.kt
|
||||
public final fun testFinal(x: R|Final<*>|, y: R|Final<kotlin/Int>|): R|kotlin/Unit| {
|
||||
when () {
|
||||
==(R|<local>/x|, R|<local>/y|) -> {
|
||||
<Inapplicable(INAPPLICABLE): /takeIntFinal>#(R|<local>/x|)
|
||||
}
|
||||
}
|
||||
|
||||
when () {
|
||||
===(R|<local>/x|, R|<local>/y|) -> {
|
||||
R|/takeIntFinal|(R|<local>/x|)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
public final fun testBase(x: R|Base<*>|, y: R|Base<kotlin/Int>|): R|kotlin/Unit| {
|
||||
when () {
|
||||
==(R|<local>/x|, R|<local>/y|) -> {
|
||||
<Inapplicable(INAPPLICABLE): /takeIntBase>#(R|<local>/x|)
|
||||
}
|
||||
}
|
||||
|
||||
when () {
|
||||
===(R|<local>/x|, R|<local>/y|) -> {
|
||||
R|/takeIntBase|(R|<local>/x|)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
public final fun testDerived(x: R|Derived<*>|, y: R|Derived<kotlin/Int>|): R|kotlin/Unit| {
|
||||
when () {
|
||||
==(R|<local>/x|, R|<local>/y|) -> {
|
||||
<Inapplicable(INAPPLICABLE): /takeIntDerived>#(R|<local>/x|)
|
||||
}
|
||||
}
|
||||
|
||||
when () {
|
||||
===(R|<local>/x|, R|<local>/y|) -> {
|
||||
R|/takeIntDerived|(R|<local>/x|)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
public final fun testFinalWithOverride(x: R|FinalWithOverride<*>|, y: R|FinalWithOverride<kotlin/Int>|): R|kotlin/Unit| {
|
||||
when () {
|
||||
==(R|<local>/x|, R|<local>/y|) -> {
|
||||
<Inapplicable(INAPPLICABLE): /takeIntFinalWithOverride>#(R|<local>/x|)
|
||||
}
|
||||
}
|
||||
|
||||
when () {
|
||||
===(R|<local>/x|, R|<local>/y|) -> {
|
||||
R|/takeIntFinalWithOverride|(R|<local>/x|)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
public final fun takeIntFinal(x: R|Final<kotlin/Int>|): R|kotlin/Unit| {
|
||||
}
|
||||
public final fun takeIntBase(x: R|Base<kotlin/Int>|): R|kotlin/Unit| {
|
||||
}
|
||||
public final fun takeIntDerived(x: R|Derived<kotlin/Int>|): R|kotlin/Unit| {
|
||||
}
|
||||
public final fun takeIntFinalWithOverride(x: R|FinalWithOverride<kotlin/Int>|): R|kotlin/Unit| {
|
||||
}
|
||||
Vendored
+60
@@ -0,0 +1,60 @@
|
||||
// SKIP_JAVAC
|
||||
// This directive is needed to skip this test in LazyBodyIsNotTouchedTilContractsPhaseTestGenerated,
|
||||
// because it fails to parse module structure of multimodule test
|
||||
// ISSUE: KT-49127
|
||||
|
||||
// MODULE: lib
|
||||
class Final<T>
|
||||
|
||||
open class Base<T>
|
||||
|
||||
class Derived<T> : Base<T>()
|
||||
|
||||
class FinalWithOverride<T> {
|
||||
override fun equals(other: Any?): Boolean {
|
||||
// some custom implementation
|
||||
return this === other
|
||||
}
|
||||
}
|
||||
|
||||
// MODULE: main(lib)
|
||||
fun testFinal(x: Final<*>, y: Final<Int>) {
|
||||
if (x == y) {
|
||||
takeIntFinal(<!ARGUMENT_TYPE_MISMATCH!>x<!>) // Error
|
||||
}
|
||||
if (x === y) {
|
||||
takeIntFinal(x) // OK
|
||||
}
|
||||
}
|
||||
|
||||
fun testBase(x: Base<*>, y: Base<Int>) {
|
||||
if (x == y) {
|
||||
takeIntBase(<!ARGUMENT_TYPE_MISMATCH!>x<!>) // Error
|
||||
}
|
||||
if (x === y) {
|
||||
takeIntBase(x) // OK
|
||||
}
|
||||
}
|
||||
|
||||
fun testDerived(x: Derived<*>, y: Derived<Int>) {
|
||||
if (x == y) {
|
||||
takeIntDerived(<!ARGUMENT_TYPE_MISMATCH!>x<!>) // Error
|
||||
}
|
||||
if (x === y) {
|
||||
takeIntDerived(x) // OK
|
||||
}
|
||||
}
|
||||
|
||||
fun testFinalWithOverride(x: FinalWithOverride<*>, y: FinalWithOverride<Int>) {
|
||||
if (x == y) {
|
||||
takeIntFinalWithOverride(<!ARGUMENT_TYPE_MISMATCH!>x<!>) // Error
|
||||
}
|
||||
if (x === y) {
|
||||
takeIntFinalWithOverride(x) // OK
|
||||
}
|
||||
}
|
||||
|
||||
fun takeIntFinal(x: Final<Int>) {}
|
||||
fun takeIntBase(x: Base<Int>) {}
|
||||
fun takeIntDerived(x: Derived<Int>) {}
|
||||
fun takeIntFinalWithOverride(x: FinalWithOverride<Int>) {}
|
||||
Vendored
+93
@@ -0,0 +1,93 @@
|
||||
FILE: smartcastsFromEquals_sameModule.kt
|
||||
public final class Final<T> : R|kotlin/Any| {
|
||||
public constructor<T>(): R|Final<T>| {
|
||||
super<R|kotlin/Any|>()
|
||||
}
|
||||
|
||||
}
|
||||
public open class Base<T> : R|kotlin/Any| {
|
||||
public constructor<T>(): R|Base<T>| {
|
||||
super<R|kotlin/Any|>()
|
||||
}
|
||||
|
||||
}
|
||||
public final class Derived<T> : R|Base<T>| {
|
||||
public constructor<T>(): R|Derived<T>| {
|
||||
super<R|Base<T>|>()
|
||||
}
|
||||
|
||||
}
|
||||
public final class FinalWithOverride<T> : R|kotlin/Any| {
|
||||
public constructor<T>(): R|FinalWithOverride<T>| {
|
||||
super<R|kotlin/Any|>()
|
||||
}
|
||||
|
||||
public final override operator fun equals(other: R|kotlin/Any?|): R|kotlin/Boolean| {
|
||||
^equals ===(this@R|/FinalWithOverride|, R|<local>/other|)
|
||||
}
|
||||
|
||||
}
|
||||
public final fun testFinal(x: R|Final<*>|, y: R|Final<kotlin/Int>|): R|kotlin/Unit| {
|
||||
when () {
|
||||
==(R|<local>/x|, R|<local>/y|) -> {
|
||||
R|/takeIntFinal|(R|<local>/x|)
|
||||
}
|
||||
}
|
||||
|
||||
when () {
|
||||
===(R|<local>/x|, R|<local>/y|) -> {
|
||||
R|/takeIntFinal|(R|<local>/x|)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
public final fun testBase(x: R|Base<*>|, y: R|Base<kotlin/Int>|): R|kotlin/Unit| {
|
||||
when () {
|
||||
==(R|<local>/x|, R|<local>/y|) -> {
|
||||
<Inapplicable(INAPPLICABLE): /takeIntBase>#(R|<local>/x|)
|
||||
}
|
||||
}
|
||||
|
||||
when () {
|
||||
===(R|<local>/x|, R|<local>/y|) -> {
|
||||
R|/takeIntBase|(R|<local>/x|)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
public final fun testDerived(x: R|Derived<*>|, y: R|Derived<kotlin/Int>|): R|kotlin/Unit| {
|
||||
when () {
|
||||
==(R|<local>/x|, R|<local>/y|) -> {
|
||||
R|/takeIntDerived|(R|<local>/x|)
|
||||
}
|
||||
}
|
||||
|
||||
when () {
|
||||
===(R|<local>/x|, R|<local>/y|) -> {
|
||||
R|/takeIntDerived|(R|<local>/x|)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
public final fun testFinalWithOverride(x: R|FinalWithOverride<*>|, y: R|FinalWithOverride<kotlin/Int>|): R|kotlin/Unit| {
|
||||
when () {
|
||||
==(R|<local>/x|, R|<local>/y|) -> {
|
||||
<Inapplicable(INAPPLICABLE): /takeIntFinalWithOverride>#(R|<local>/x|)
|
||||
}
|
||||
}
|
||||
|
||||
when () {
|
||||
===(R|<local>/x|, R|<local>/y|) -> {
|
||||
R|/takeIntFinalWithOverride|(R|<local>/x|)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
public final fun takeIntFinal(x: R|Final<kotlin/Int>|): R|kotlin/Unit| {
|
||||
}
|
||||
public final fun takeIntBase(x: R|Base<kotlin/Int>|): R|kotlin/Unit| {
|
||||
}
|
||||
public final fun takeIntDerived(x: R|Derived<kotlin/Int>|): R|kotlin/Unit| {
|
||||
}
|
||||
public final fun takeIntFinalWithOverride(x: R|FinalWithOverride<kotlin/Int>|): R|kotlin/Unit| {
|
||||
}
|
||||
+55
@@ -0,0 +1,55 @@
|
||||
// ISSUE: KT-49127
|
||||
|
||||
class Final<T>
|
||||
|
||||
open class Base<T>
|
||||
|
||||
class Derived<T> : Base<T>()
|
||||
|
||||
class FinalWithOverride<T> {
|
||||
override fun equals(other: Any?): Boolean {
|
||||
// some custom implementation
|
||||
return this === other
|
||||
}
|
||||
}
|
||||
|
||||
fun testFinal(x: Final<*>, y: Final<Int>) {
|
||||
if (x == y) {
|
||||
takeIntFinal(x) // OK
|
||||
}
|
||||
if (x === y) {
|
||||
takeIntFinal(x) // OK
|
||||
}
|
||||
}
|
||||
|
||||
fun testBase(x: Base<*>, y: Base<Int>) {
|
||||
if (x == y) {
|
||||
takeIntBase(<!ARGUMENT_TYPE_MISMATCH!>x<!>) // Error
|
||||
}
|
||||
if (x === y) {
|
||||
takeIntBase(x) // OK
|
||||
}
|
||||
}
|
||||
|
||||
fun testDerived(x: Derived<*>, y: Derived<Int>) {
|
||||
if (x == y) {
|
||||
takeIntDerived(x) // OK
|
||||
}
|
||||
if (x === y) {
|
||||
takeIntDerived(x) // OK
|
||||
}
|
||||
}
|
||||
|
||||
fun testFinalWithOverride(x: FinalWithOverride<*>, y: FinalWithOverride<Int>) {
|
||||
if (x == y) {
|
||||
takeIntFinalWithOverride(<!ARGUMENT_TYPE_MISMATCH!>x<!>) // Error
|
||||
}
|
||||
if (x === y) {
|
||||
takeIntFinalWithOverride(x) // OK
|
||||
}
|
||||
}
|
||||
|
||||
fun takeIntFinal(x: Final<Int>) {}
|
||||
fun takeIntBase(x: Base<Int>) {}
|
||||
fun takeIntDerived(x: Derived<Int>) {}
|
||||
fun takeIntFinalWithOverride(x: FinalWithOverride<Int>) {}
|
||||
Reference in New Issue
Block a user