[FE 1.0] Properly handle intersection types in check if cast possible or not
^KT-47685 Fixed
This commit is contained in:
committed by
teamcityserver
parent
f0c4d06fc9
commit
47b0071560
+6
@@ -3837,6 +3837,12 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirDiagnosti
|
|||||||
runTest("compiler/testData/diagnostics/tests/cast/kt15161.kt");
|
runTest("compiler/testData/diagnostics/tests/cast/kt15161.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("kt47685.kt")
|
||||||
|
public void testKt47685() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/tests/cast/kt47685.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("kt614.kt")
|
@TestMetadata("kt614.kt")
|
||||||
public void testKt614() throws Exception {
|
public void testKt614() throws Exception {
|
||||||
|
|||||||
+6
@@ -3837,6 +3837,12 @@ public class FirOldFrontendDiagnosticsWithLightTreeTestGenerated extends Abstrac
|
|||||||
runTest("compiler/testData/diagnostics/tests/cast/kt15161.kt");
|
runTest("compiler/testData/diagnostics/tests/cast/kt15161.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("kt47685.kt")
|
||||||
|
public void testKt47685() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/tests/cast/kt47685.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("kt614.kt")
|
@TestMetadata("kt614.kt")
|
||||||
public void testKt614() throws Exception {
|
public void testKt614() throws Exception {
|
||||||
|
|||||||
@@ -43,6 +43,10 @@ object CastDiagnosticsUtil {
|
|||||||
rhsType: KotlinType,
|
rhsType: KotlinType,
|
||||||
platformToKotlinClassMapper: PlatformToKotlinClassMapper
|
platformToKotlinClassMapper: PlatformToKotlinClassMapper
|
||||||
): Boolean {
|
): Boolean {
|
||||||
|
val typeConstructor = lhsType.constructor
|
||||||
|
if (typeConstructor is IntersectionTypeConstructor) {
|
||||||
|
return typeConstructor.supertypes.any { isCastPossible(it, rhsType, platformToKotlinClassMapper) }
|
||||||
|
}
|
||||||
val rhsNullable = TypeUtils.isNullableType(rhsType)
|
val rhsNullable = TypeUtils.isNullableType(rhsType)
|
||||||
val lhsNullable = TypeUtils.isNullableType(lhsType)
|
val lhsNullable = TypeUtils.isNullableType(lhsType)
|
||||||
if (KotlinBuiltIns.isNothing(lhsType)) return true
|
if (KotlinBuiltIns.isNothing(lhsType)) return true
|
||||||
|
|||||||
@@ -0,0 +1,29 @@
|
|||||||
|
// KT-47685
|
||||||
|
interface KtFunction {
|
||||||
|
fun foo() {}
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class ASTDelegatePsiElement {
|
||||||
|
fun bar() {}
|
||||||
|
}
|
||||||
|
|
||||||
|
class KtNamedFunction : ASTDelegatePsiElement(), KtFunction {
|
||||||
|
fun baz() {}
|
||||||
|
}
|
||||||
|
class KtFunctionLiteral : ASTDelegatePsiElement(), KtFunction
|
||||||
|
|
||||||
|
fun test_1(namedFunction: KtNamedFunction, functionLiteral: KtFunctionLiteral, cond: Boolean) {
|
||||||
|
val function = when (cond) {
|
||||||
|
true -> namedFunction
|
||||||
|
false -> functionLiteral
|
||||||
|
}
|
||||||
|
// approve that foo has type (ASTDelegatePsiElement & KtFunction)
|
||||||
|
function.foo()
|
||||||
|
function.bar()
|
||||||
|
|
||||||
|
if (function is KtNamedFunction) {
|
||||||
|
function.baz()
|
||||||
|
}
|
||||||
|
|
||||||
|
val myNamedFunction = function as KtNamedFunction
|
||||||
|
}
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
// KT-47685
|
||||||
|
interface KtFunction {
|
||||||
|
fun foo() {}
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class ASTDelegatePsiElement {
|
||||||
|
fun bar() {}
|
||||||
|
}
|
||||||
|
|
||||||
|
class KtNamedFunction : ASTDelegatePsiElement(), KtFunction {
|
||||||
|
fun baz() {}
|
||||||
|
}
|
||||||
|
class KtFunctionLiteral : ASTDelegatePsiElement(), KtFunction
|
||||||
|
|
||||||
|
fun test_1(namedFunction: KtNamedFunction, functionLiteral: KtFunctionLiteral, cond: Boolean) {
|
||||||
|
val function = when (cond) {
|
||||||
|
true -> namedFunction
|
||||||
|
false -> functionLiteral
|
||||||
|
}
|
||||||
|
// approve that foo has type (ASTDelegatePsiElement & KtFunction)
|
||||||
|
function.foo()
|
||||||
|
function.bar()
|
||||||
|
|
||||||
|
if (function is KtNamedFunction) {
|
||||||
|
<!DEBUG_INFO_SMARTCAST!>function<!>.baz()
|
||||||
|
}
|
||||||
|
|
||||||
|
val myNamedFunction = function as KtNamedFunction
|
||||||
|
}
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
package
|
||||||
|
|
||||||
|
public fun test_1(/*0*/ namedFunction: KtNamedFunction, /*1*/ functionLiteral: KtFunctionLiteral, /*2*/ cond: kotlin.Boolean): kotlin.Unit
|
||||||
|
|
||||||
|
public abstract class ASTDelegatePsiElement {
|
||||||
|
public constructor ASTDelegatePsiElement()
|
||||||
|
public final fun bar(): kotlin.Unit
|
||||||
|
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 interface KtFunction {
|
||||||
|
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||||
|
public open fun foo(): kotlin.Unit
|
||||||
|
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||||
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class KtFunctionLiteral : ASTDelegatePsiElement, KtFunction {
|
||||||
|
public constructor KtFunctionLiteral()
|
||||||
|
public final override /*1*/ /*fake_override*/ fun bar(): kotlin.Unit
|
||||||
|
public open override /*2*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||||
|
public open override /*1*/ /*fake_override*/ fun foo(): kotlin.Unit
|
||||||
|
public open override /*2*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||||
|
public open override /*2*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class KtNamedFunction : ASTDelegatePsiElement, KtFunction {
|
||||||
|
public constructor KtNamedFunction()
|
||||||
|
public final override /*1*/ /*fake_override*/ fun bar(): kotlin.Unit
|
||||||
|
public final fun baz(): kotlin.Unit
|
||||||
|
public open override /*2*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||||
|
public open override /*1*/ /*fake_override*/ fun foo(): kotlin.Unit
|
||||||
|
public open override /*2*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||||
|
public open override /*2*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
}
|
||||||
Generated
+6
@@ -3843,6 +3843,12 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest {
|
|||||||
runTest("compiler/testData/diagnostics/tests/cast/kt15161.kt");
|
runTest("compiler/testData/diagnostics/tests/cast/kt15161.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("kt47685.kt")
|
||||||
|
public void testKt47685() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/tests/cast/kt47685.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("kt614.kt")
|
@TestMetadata("kt614.kt")
|
||||||
public void testKt614() throws Exception {
|
public void testKt614() throws Exception {
|
||||||
|
|||||||
+6
@@ -3837,6 +3837,12 @@ public class DiagnosisCompilerTestFE10TestdataTestGenerated extends AbstractDiag
|
|||||||
runTest("compiler/testData/diagnostics/tests/cast/kt15161.kt");
|
runTest("compiler/testData/diagnostics/tests/cast/kt15161.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("kt47685.kt")
|
||||||
|
public void testKt47685() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/tests/cast/kt47685.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("kt614.kt")
|
@TestMetadata("kt614.kt")
|
||||||
public void testKt614() throws Exception {
|
public void testKt614() throws Exception {
|
||||||
|
|||||||
Reference in New Issue
Block a user