[FIR] Completely unwrap original argument when computing type arguments

When computing the conversion type for a type operator call, the
argument needs to be fully unwrapped before getting the resolved type.
This avoids the situation when the argument is a when-subject and the
assumed original type is not correct. Before, only smart-casts were
unwrapped, and this change will also unwrap when-subjects (as well as a
few other FirExpressions).

^KT-62114 Fixed
This commit is contained in:
Brian Norman
2023-10-04 16:48:49 -05:00
committed by Space Team
parent 23bdfd226f
commit 2e6dbbe020
5 changed files with 88 additions and 1 deletions
@@ -1,3 +1,5 @@
// ISSUE: KT-62114
open class A {
class B : A() {
val a = "FAIL"
@@ -27,3 +29,26 @@ class C {
else return ""
}
}
sealed class Received<out T> {
sealed class Error<out T> : Received<T>() {
data class SomeError<out T>(val details: T?) : Error<T>()
}
}
val Received<String>.thisRaisesUnresolvedReference: Boolean
get() = if (this is Received.Error<*>) {
when (this) {
is Received.Error.SomeError -> details?.length == 0
}
} else {
false
}
val Received<String>.thisIsFine: Boolean
get() = if (this is Received.Error<*>) {
if (this is Received.Error.SomeError) { details?.length == 0 }
else false
} else {
false
}
@@ -1,3 +1,5 @@
// ISSUE: KT-62114
open class A {
class B : A() {
val a = "FAIL"
@@ -27,3 +29,26 @@ class C {
else return ""
}
}
sealed class Received<out T> {
sealed class Error<out T> : Received<T>() {
data class SomeError<out T>(val details: T?) : Error<T>()
}
}
val Received<String>.thisRaisesUnresolvedReference: Boolean
get() = if (this is Received.Error<*>) {
when (<!DEBUG_INFO_SMARTCAST!>this<!>) {
is Received.Error.SomeError -> <!DEBUG_INFO_IMPLICIT_RECEIVER_SMARTCAST!>details<!>?.length == 0
}
} else {
false
}
val Received<String>.thisIsFine: Boolean
get() = if (this is Received.Error<*>) {
if (this is Received.Error.SomeError) { <!DEBUG_INFO_IMPLICIT_RECEIVER_SMARTCAST!>details<!>?.length == 0 }
else false
} else {
false
}
@@ -1,5 +1,7 @@
package
public val Received<kotlin.String>.thisIsFine: kotlin.Boolean
public val Received<kotlin.String>.thisRaisesUnresolvedReference: kotlin.Boolean
public fun A?.bar(): kotlin.Unit
public fun A.gav(): kotlin.String
@@ -36,3 +38,28 @@ public final class C {
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
public final fun A?.complex(): kotlin.String
}
public sealed class Received</*0*/ out T> {
protected constructor Received</*0*/ out T>()
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
public sealed class Error</*0*/ out T> : Received<T> {
protected constructor Error</*0*/ out T>()
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
public final data class SomeError</*0*/ out T> : Received.Error<T> {
public constructor SomeError</*0*/ out T>(/*0*/ details: T?)
public final val details: T?
public final operator /*synthesized*/ fun component1(): T?
public final /*synthesized*/ fun copy(/*0*/ details: T? = ...): Received.Error.SomeError<T>
public open override /*1*/ /*synthesized*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*synthesized*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*synthesized*/ fun toString(): kotlin.String
}
}
}