Refactoring: Improve createExpectActualTypeParameterSubstitutor API
Review: https://jetbrains.team/p/kt/reviews/12279/files Motivation: make sure that cases like KT-62027 won't happen again Review: https://jetbrains.team/p/kt/reviews/12279/files Now it's responsibility of the `createExpectActualTypeParameterSubstitutor` calller to think about the case when parameters size isn't equal. You must not be able to create a substitutor if type parameters sizes are not equal Improvement in `createExpectActualTypeParameterSubstitutor` API also improves `AbstractExpectActualCompatibilityChecker.getCallablesCompatibility` API. Because suppose that you accidentally created a redundant wrapping substitutor => you need to handle the case of not equal type parameters size on the call site => you start thinking why you should do that on the call site? It must be a responsibility of `getCallablesCompatibility` => you realize that you created a redundant wrapping substitutor
This commit is contained in:
+9
-4
@@ -19,6 +19,7 @@ import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
|
||||
import org.jetbrains.kotlin.fir.types.areCompatibleExpectActualTypes
|
||||
import org.jetbrains.kotlin.fir.types.createExpectActualTypeParameterSubstitutor
|
||||
import org.jetbrains.kotlin.resolve.multiplatform.ExpectActualCompatibility
|
||||
import org.jetbrains.kotlin.utils.zipIfSizesAreEqual
|
||||
|
||||
object FirActualCallableDeclarationChecker : FirCallableDeclarationChecker() {
|
||||
override fun check(declaration: FirCallableDeclaration, context: CheckerContext, reporter: DiagnosticReporter) {
|
||||
@@ -34,12 +35,16 @@ object FirActualCallableDeclarationChecker : FirCallableDeclarationChecker() {
|
||||
val expectTypeParameters = expectFunctionSymbol.getContainingClassSymbol(expectFunctionSymbol.moduleData.session)
|
||||
?.typeParameterSymbols.orEmpty()
|
||||
val actualClassTypeParameters = actualFunctionSymbol.getContainingClassSymbol(context.session)?.typeParameterSymbols.orEmpty()
|
||||
val parentSubstitutor =
|
||||
createExpectActualTypeParameterSubstitutor(expectTypeParameters, actualClassTypeParameters, context.session)
|
||||
|
||||
val parentSubstitutor = createExpectActualTypeParameterSubstitutor(
|
||||
// It's responsibility of AbstractExpectActualCompatibilityChecker to report that
|
||||
(expectTypeParameters zipIfSizesAreEqual actualClassTypeParameters) ?: return,
|
||||
context.session
|
||||
)
|
||||
|
||||
val substitutor = createExpectActualTypeParameterSubstitutor(
|
||||
expectFunctionSymbol.typeParameterSymbols,
|
||||
actualFunctionSymbol.typeParameterSymbols,
|
||||
// It's responsibility of AbstractExpectActualCompatibilityChecker to check that
|
||||
(expectFunctionSymbol.typeParameterSymbols zipIfSizesAreEqual actualFunctionSymbol.typeParameterSymbols) ?: return,
|
||||
context.session,
|
||||
parentSubstitutor
|
||||
)
|
||||
|
||||
@@ -13,12 +13,11 @@ import org.jetbrains.kotlin.fir.symbols.impl.FirTypeParameterSymbol
|
||||
import org.jetbrains.kotlin.types.AbstractTypeChecker
|
||||
|
||||
fun createExpectActualTypeParameterSubstitutor(
|
||||
expectedTypeParameters: List<FirTypeParameterSymbol>,
|
||||
actualTypeParameters: List<FirTypeParameterSymbol>,
|
||||
expectActualTypeParameters: List<Pair<FirTypeParameterSymbol, FirTypeParameterSymbol>>,
|
||||
useSiteSession: FirSession,
|
||||
parentSubstitutor: ConeSubstitutor? = null
|
||||
): ConeSubstitutor {
|
||||
val substitution = expectedTypeParameters.zip(actualTypeParameters).associate { (expectedParameterSymbol, actualParameterSymbol) ->
|
||||
val substitution = expectActualTypeParameters.associate { (expectedParameterSymbol, actualParameterSymbol) ->
|
||||
expectedParameterSymbol to actualParameterSymbol.toLookupTag().constructType(emptyArray(), isNullable = false)
|
||||
}
|
||||
val substitutor = ConeSubstitutorByMap(
|
||||
|
||||
+3
-7
@@ -36,8 +36,6 @@ import org.jetbrains.kotlin.types.model.KotlinTypeMarker
|
||||
import org.jetbrains.kotlin.types.model.SimpleTypeMarker
|
||||
import org.jetbrains.kotlin.types.model.TypeSubstitutorMarker
|
||||
import org.jetbrains.kotlin.types.model.TypeSystemContext
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.UnsafeCastFunction
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.castAll
|
||||
|
||||
class FirExpectActualMatchingContextImpl private constructor(
|
||||
private val actualSession: FirSession,
|
||||
@@ -147,15 +145,13 @@ class FirExpectActualMatchingContextImpl private constructor(
|
||||
override val PropertySymbolMarker.setter: FunctionSymbolMarker?
|
||||
get() = asSymbol().setterSymbol
|
||||
|
||||
@OptIn(UnsafeCastFunction::class)
|
||||
override fun createExpectActualTypeParameterSubstitutor(
|
||||
expectTypeParameters: List<TypeParameterSymbolMarker>,
|
||||
actualTypeParameters: List<TypeParameterSymbolMarker>,
|
||||
expectActualTypeParameters: List<Pair<TypeParameterSymbolMarker, TypeParameterSymbolMarker>>,
|
||||
parentSubstitutor: TypeSubstitutorMarker?,
|
||||
): TypeSubstitutorMarker {
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
return createExpectActualTypeParameterSubstitutor(
|
||||
expectTypeParameters.castAll<FirTypeParameterSymbol>(),
|
||||
actualTypeParameters.castAll<FirTypeParameterSymbol>(),
|
||||
expectActualTypeParameters as List<Pair<FirTypeParameterSymbol, FirTypeParameterSymbol>>,
|
||||
actualSession,
|
||||
parentSubstitutor as ConeSubstitutor?
|
||||
)
|
||||
|
||||
+3
-8
@@ -19,6 +19,7 @@ import org.jetbrains.kotlin.fir.types.*
|
||||
import org.jetbrains.kotlin.mpp.CallableSymbolMarker
|
||||
import org.jetbrains.kotlin.resolve.calls.mpp.AbstractExpectActualCompatibilityChecker
|
||||
import org.jetbrains.kotlin.resolve.multiplatform.ExpectActualCompatibility
|
||||
import org.jetbrains.kotlin.utils.zipIfSizesAreEqual
|
||||
|
||||
object FirExpectActualResolver {
|
||||
fun findExpectForActual(
|
||||
@@ -46,14 +47,8 @@ object FirExpectActualResolver {
|
||||
val expectTypeParameters = expectContainingClass?.typeParameterSymbols.orEmpty()
|
||||
val actualTypeParameters = actualContainingClass?.typeParameterSymbols.orEmpty()
|
||||
|
||||
parentSubstitutor = when (expectTypeParameters.size == actualTypeParameters.size) {
|
||||
true -> createExpectActualTypeParameterSubstitutor(
|
||||
expectTypeParameters,
|
||||
actualTypeParameters,
|
||||
useSiteSession,
|
||||
)
|
||||
false -> null
|
||||
}
|
||||
parentSubstitutor = (expectTypeParameters zipIfSizesAreEqual actualTypeParameters)
|
||||
?.let { createExpectActualTypeParameterSubstitutor(it, useSiteSession) }
|
||||
|
||||
when (actualSymbol) {
|
||||
is FirConstructorSymbol -> expectContainingClass?.getConstructors(scopeSession)
|
||||
|
||||
Reference in New Issue
Block a user