From 98cce8e05bfa00411d80385b522f8583c9fce17e Mon Sep 17 00:00:00 2001 From: Ivan Kochurkin Date: Tue, 9 Nov 2021 23:25:35 +0300 Subject: [PATCH] [FIR] Support of intersection types in bareTypes.doUnify ^KT-48832 Fixed --- .../resolve/types/castToBareType.fir.txt | 2 +- .../testData/resolve/types/castToBareType.kt | 2 +- .../transformers/body/resolve/bareTypes.kt | 23 +++++++++++++++++++ 3 files changed, 25 insertions(+), 2 deletions(-) diff --git a/compiler/fir/analysis-tests/testData/resolve/types/castToBareType.fir.txt b/compiler/fir/analysis-tests/testData/resolve/types/castToBareType.fir.txt index 4497e5bd014..a7d5415a3b2 100644 --- a/compiler/fir/analysis-tests/testData/resolve/types/castToBareType.fir.txt +++ b/compiler/fir/analysis-tests/testData/resolve/types/castToBareType.fir.txt @@ -16,6 +16,6 @@ FILE: castToBareType.kt public final fun foo(firAdaptee: R|FirFunction<*>|): R|kotlin/Unit| { } public final fun test(symbol: R|AbstractFirBasedSymbol<*>|): R|kotlin/Unit| { - lval firAdaptee: R|FirFunction & FirDeclaration)> & FirDeclaration)> & FirDeclaration)> & FirDeclaration)>| = (R|/symbol|.R|SubstitutionOverride| as R|FirFunction & FirDeclaration)> & FirDeclaration)> & FirDeclaration)> & FirDeclaration)>|) + lval firAdaptee: R|FirFunction & FirDeclaration)> & FirDeclaration)> & FirDeclaration)>>| = (R|/symbol|.R|SubstitutionOverride| as R|FirFunction & FirDeclaration)> & FirDeclaration)> & FirDeclaration)>>|) R|/foo|(R|/firAdaptee|) } diff --git a/compiler/fir/analysis-tests/testData/resolve/types/castToBareType.kt b/compiler/fir/analysis-tests/testData/resolve/types/castToBareType.kt index dc4a47403f1..e601551638f 100644 --- a/compiler/fir/analysis-tests/testData/resolve/types/castToBareType.kt +++ b/compiler/fir/analysis-tests/testData/resolve/types/castToBareType.kt @@ -12,6 +12,6 @@ interface AbstractFirBasedSymbol where E : FirSymbolOwner, E : FirDeclarat fun foo(firAdaptee: FirFunction<*>) {} fun test(symbol: AbstractFirBasedSymbol<*>) { - val firAdaptee = symbol.fir as FirFunction // TODO: KT-48832 + val firAdaptee = symbol.fir as FirFunction foo(firAdaptee) } diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/bareTypes.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/bareTypes.kt index 69f6da8899a..b2caf13ffd3 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/bareTypes.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/bareTypes.kt @@ -16,6 +16,7 @@ import org.jetbrains.kotlin.fir.resolve.fullyExpandedType import org.jetbrains.kotlin.fir.resolve.toSymbol import org.jetbrains.kotlin.fir.types.* import org.jetbrains.kotlin.types.AbstractTypeChecker +import org.jetbrains.kotlin.types.model.KotlinTypeMarker fun BodyResolveComponents.computeRepresentativeTypeForBareType(type: ConeClassLikeType, originalType: ConeKotlinType): ConeKotlinType? { originalType.lowerBoundIfFlexible().fullyExpandedType(session).let { @@ -90,6 +91,28 @@ private fun BodyResolveComponents.doUnify( val originalType = originalTypeProjection.type val typeWithParameters = typeWithParametersProjection.type + if (originalType is ConeIntersectionType) { + val intersectionResult = mutableMapOf() + for (intersectedType in originalType.intersectedTypes) { + val localResult = mutableMapOf() + if (!doUnify(intersectedType, typeWithParametersProjection, targetTypeParameters, localResult)) return false + for ((typeParameter, typeProjection) in localResult) { + val existingTypeProjection = intersectionResult[typeParameter] + if (existingTypeProjection == null + || (typeProjection is KotlinTypeMarker && + existingTypeProjection is KotlinTypeMarker && + AbstractTypeChecker.isSubtypeOf(session.typeContext, typeProjection, existingTypeProjection)) + ) { + intersectionResult[typeParameter] = typeProjection + } + } + } + for ((key, value) in intersectionResult) { + result[key] = value + } + return true + } + // in Foo ~ in X => Foo ~ X if (originalTypeProjection.kind == typeWithParametersProjection.kind && originalTypeProjection.kind != ProjectionKind.INVARIANT && originalTypeProjection.kind != ProjectionKind.STAR) {