[FIR, IR] Check for strict subtypes during actualization
^KT-65775 Fixed Review: https://jetbrains.team/p/kt/reviews/14906/timeline
This commit is contained in:
+6
@@ -24765,6 +24765,12 @@ public class DiagnosticCompilerTestFE10TestdataTestGenerated extends AbstractDia
|
||||
runTest("compiler/testData/diagnostics/tests/multiplatform/actualMissingConstructor.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("actualTypealiasCycle.kt")
|
||||
public void testActualTypealiasCycle() {
|
||||
runTest("compiler/testData/diagnostics/tests/multiplatform/actualTypealiasCycle.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("actualTypealiasForNotExpectClass.kt")
|
||||
public void testActualTypealiasForNotExpectClass() {
|
||||
|
||||
+6
@@ -24765,6 +24765,12 @@ public class LLFirPreresolvedReversedDiagnosticCompilerFE10TestDataTestGenerated
|
||||
runTest("compiler/testData/diagnostics/tests/multiplatform/actualMissingConstructor.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("actualTypealiasCycle.kt")
|
||||
public void testActualTypealiasCycle() {
|
||||
runTest("compiler/testData/diagnostics/tests/multiplatform/actualTypealiasCycle.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("actualTypealiasForNotExpectClass.kt")
|
||||
public void testActualTypealiasForNotExpectClass() {
|
||||
|
||||
+6
@@ -32,6 +32,12 @@ public class FirOldFrontendMPPDiagnosticsWithLightTreeTestGenerated extends Abst
|
||||
runTest("compiler/testData/diagnostics/tests/multiplatform/actualMissingConstructor.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("actualTypealiasCycle.kt")
|
||||
public void testActualTypealiasCycle() {
|
||||
runTest("compiler/testData/diagnostics/tests/multiplatform/actualTypealiasCycle.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("actualTypealiasForNotExpectClass.kt")
|
||||
public void testActualTypealiasForNotExpectClass() {
|
||||
|
||||
+6
@@ -32,6 +32,12 @@ public class FirOldFrontendMPPDiagnosticsWithPsiTestGenerated extends AbstractFi
|
||||
runTest("compiler/testData/diagnostics/tests/multiplatform/actualMissingConstructor.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("actualTypealiasCycle.kt")
|
||||
public void testActualTypealiasCycle() {
|
||||
runTest("compiler/testData/diagnostics/tests/multiplatform/actualTypealiasCycle.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("actualTypealiasForNotExpectClass.kt")
|
||||
public void testActualTypealiasForNotExpectClass() {
|
||||
|
||||
+3
-6
@@ -15,8 +15,6 @@ import org.jetbrains.kotlin.fir.declarations.utils.isExpect
|
||||
import org.jetbrains.kotlin.fir.declarations.utils.isJava
|
||||
import org.jetbrains.kotlin.fir.expressions.*
|
||||
import org.jetbrains.kotlin.fir.resolve.*
|
||||
import org.jetbrains.kotlin.fir.resolve.providers.getRegularClassSymbolByClassId
|
||||
import org.jetbrains.kotlin.fir.resolve.providers.symbolProvider
|
||||
import org.jetbrains.kotlin.fir.resolve.providers.toSymbol
|
||||
import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor
|
||||
import org.jetbrains.kotlin.fir.scopes.*
|
||||
@@ -35,7 +33,6 @@ import org.jetbrains.kotlin.resolve.calls.mpp.ExpectActualMatchingContext.Annota
|
||||
import org.jetbrains.kotlin.resolve.checkers.OptInNames
|
||||
import org.jetbrains.kotlin.resolve.multiplatform.ExpectActualMatchingCompatibility
|
||||
import org.jetbrains.kotlin.types.AbstractTypeChecker
|
||||
import org.jetbrains.kotlin.types.AbstractTypeRefiner
|
||||
import org.jetbrains.kotlin.types.TypeCheckerState
|
||||
import org.jetbrains.kotlin.types.Variance
|
||||
import org.jetbrains.kotlin.types.model.*
|
||||
@@ -346,11 +343,11 @@ class FirExpectActualMatchingContextImpl private constructor(
|
||||
return ConeClassLikeTypeImpl(lookupTag, argumentsWithOutProjection, isNullable)
|
||||
}
|
||||
|
||||
override fun actualTypeIsSubtypeOfExpectType(expectType: KotlinTypeMarker, actualType: KotlinTypeMarker): Boolean {
|
||||
override fun isSubtypeOf(superType: KotlinTypeMarker, subType: KotlinTypeMarker): Boolean {
|
||||
return AbstractTypeChecker.isSubtypeOf(
|
||||
createTypeCheckerState(),
|
||||
subType = actualType,
|
||||
superType = expectType
|
||||
subType = subType,
|
||||
superType = superType
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
+3
-3
@@ -393,11 +393,11 @@ internal abstract class IrExpectActualMatchingContext(
|
||||
return typeContext.newTypeCheckerState(errorTypesEqualToAnything = true, stubTypesEqualToAnything = false)
|
||||
}
|
||||
|
||||
override fun actualTypeIsSubtypeOfExpectType(expectType: KotlinTypeMarker, actualType: KotlinTypeMarker): Boolean {
|
||||
override fun isSubtypeOf(superType: KotlinTypeMarker, subType: KotlinTypeMarker): Boolean {
|
||||
return AbstractTypeChecker.isSubtypeOf(
|
||||
createTypeCheckerState(),
|
||||
subType = actualType.actualize(),
|
||||
superType = expectType.actualize()
|
||||
subType = subType.actualize(),
|
||||
superType = superType.actualize()
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
+3
-4
@@ -165,10 +165,9 @@ object AbstractExpectActualChecker {
|
||||
val expectSupertypes = expectClassSymbol.superTypes.filterNot { it.typeConstructor().isAnyConstructor() }
|
||||
val actualType = actualClassSymbol.defaultType
|
||||
return expectSupertypes.all { expectSupertype ->
|
||||
actualTypeIsSubtypeOfExpectType(
|
||||
expectType = substitutor.safeSubstitute(expectSupertype),
|
||||
actualType = actualType
|
||||
)
|
||||
val expectType = substitutor.safeSubstitute(expectSupertype)
|
||||
isSubtypeOf(superType = expectType, subType = actualType) &&
|
||||
!isSubtypeOf(superType = actualType, subType = expectType)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+3
-3
@@ -131,9 +131,9 @@ interface ExpectActualMatchingContext<T : DeclarationSymbolMarker> : TypeSystemC
|
||||
dynamicTypesEqualToAnything: Boolean = true
|
||||
): Boolean
|
||||
|
||||
fun actualTypeIsSubtypeOfExpectType(
|
||||
expectType: KotlinTypeMarker,
|
||||
actualType: KotlinTypeMarker
|
||||
fun isSubtypeOf(
|
||||
superType: KotlinTypeMarker,
|
||||
subType: KotlinTypeMarker
|
||||
): Boolean
|
||||
|
||||
fun RegularClassSymbolMarker.isNotSamInterface(): Boolean
|
||||
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
// MODULE: m1-common
|
||||
// FILE: common.kt
|
||||
|
||||
open class A {}
|
||||
<!EXPECT_ACTUAL_INCOMPATIBILITY{JVM}("B; B; some supertypes are missing in the actual declaration")!>expect class B : A<!>
|
||||
|
||||
expect open class A2() {}
|
||||
<!EXPECT_ACTUAL_INCOMPATIBILITY{JVM}("B2; B2; some supertypes are missing in the actual declaration")!>expect open class B2 : A2 {}<!>
|
||||
|
||||
expect open class A3
|
||||
|
||||
// MODULE: m2-jvm()()(m1-common)
|
||||
// FILE: jvm.kt
|
||||
|
||||
actual typealias <!ACTUAL_WITHOUT_EXPECT("actual typealias B = A; The following declaration is incompatible because some supertypes are missing in the actual declaration: expect class B : A")!>B<!> = A
|
||||
|
||||
actual typealias A2 = B2
|
||||
actual open class <!ACTUAL_WITHOUT_EXPECT("actual class B2 : Any; The following declaration is incompatible because some supertypes are missing in the actual declaration: expect class B2 : A2")!>B2<!> {}
|
||||
|
||||
actual typealias A3 = Any
|
||||
@@ -0,0 +1,20 @@
|
||||
// MODULE: m1-common
|
||||
// FILE: common.kt
|
||||
|
||||
open class A {}
|
||||
expect class B : A
|
||||
|
||||
expect open class A2() {}
|
||||
expect open class B2 : <!CYCLIC_INHERITANCE_HIERARCHY{JVM}!>A2<!> {}
|
||||
|
||||
expect open class A3
|
||||
|
||||
// MODULE: m2-jvm()()(m1-common)
|
||||
// FILE: jvm.kt
|
||||
|
||||
actual typealias <!ACTUAL_WITHOUT_EXPECT!>B<!> = A
|
||||
|
||||
actual typealias A2 = B2
|
||||
actual open class B2 {}
|
||||
|
||||
actual typealias A3 = Any
|
||||
@@ -0,0 +1,20 @@
|
||||
// MODULE: m1-common
|
||||
// FILE: common.kt
|
||||
|
||||
open class A {}
|
||||
expect class B : A
|
||||
|
||||
expect open class A2() {}
|
||||
expect open class B2 : A2 {}
|
||||
|
||||
expect open class A3
|
||||
|
||||
// MODULE: m2-jvm()()(m1-common)
|
||||
// FILE: jvm.kt
|
||||
|
||||
actual typealias <!ACTUAL_WITHOUT_EXPECT!>B<!> = A
|
||||
|
||||
actual typealias A2 = B2
|
||||
actual open class <!ACTUAL_WITHOUT_EXPECT!>B2<!> {}
|
||||
|
||||
actual typealias A3 = Any
|
||||
Generated
+6
@@ -24765,6 +24765,12 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest {
|
||||
runTest("compiler/testData/diagnostics/tests/multiplatform/actualMissingConstructor.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("actualTypealiasCycle.kt")
|
||||
public void testActualTypealiasCycle() {
|
||||
runTest("compiler/testData/diagnostics/tests/multiplatform/actualTypealiasCycle.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("actualTypealiasForNotExpectClass.kt")
|
||||
public void testActualTypealiasForNotExpectClass() {
|
||||
|
||||
Reference in New Issue
Block a user