[FE 1.0] Properly handle intersection types in check if cast possible or not

^KT-47685 Fixed
This commit is contained in:
Dmitriy Novozhilov
2021-07-12 10:43:53 +03:00
committed by teamcityserver
parent f0c4d06fc9
commit 47b0071560
8 changed files with 123 additions and 0 deletions
@@ -3837,6 +3837,12 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirDiagnosti
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
@TestMetadata("kt614.kt")
public void testKt614() throws Exception {
@@ -3837,6 +3837,12 @@ public class FirOldFrontendDiagnosticsWithLightTreeTestGenerated extends Abstrac
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
@TestMetadata("kt614.kt")
public void testKt614() throws Exception {
@@ -43,6 +43,10 @@ object CastDiagnosticsUtil {
rhsType: KotlinType,
platformToKotlinClassMapper: PlatformToKotlinClassMapper
): Boolean {
val typeConstructor = lhsType.constructor
if (typeConstructor is IntersectionTypeConstructor) {
return typeConstructor.supertypes.any { isCastPossible(it, rhsType, platformToKotlinClassMapper) }
}
val rhsNullable = TypeUtils.isNullableType(rhsType)
val lhsNullable = TypeUtils.isNullableType(lhsType)
if (KotlinBuiltIns.isNothing(lhsType)) return true
+29
View File
@@ -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
}
+29
View File
@@ -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
}
+37
View File
@@ -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
}
@@ -3843,6 +3843,12 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest {
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
@TestMetadata("kt614.kt")
public void testKt614() throws Exception {
@@ -3837,6 +3837,12 @@ public class DiagnosisCompilerTestFE10TestdataTestGenerated extends AbstractDiag
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
@TestMetadata("kt614.kt")
public void testKt614() throws Exception {