From ca970f0a8b4459dec40919c93a0afb74fffdb73f Mon Sep 17 00:00:00 2001 From: Ivan Kochurkin Date: Tue, 1 Jun 2021 16:20:38 +0300 Subject: [PATCH] [FIR] Add ConeKotlinTypeConflictingProjection, return it from substituteArgument instead of ConeStarProjection in appropriate cases, remove plus operator from ProjectionKind --- .../checkers/ConeTypeCompatibilityChecker.kt | 1 + .../jetbrains/kotlin/fir/types/ConeTypes.kt | 15 ++++------ .../kotlin/fir/types/TypeRenderer.kt | 1 + .../kotlin/fir/backend/Fir2IrTypeConverter.kt | 18 +++++------ .../kotlin/fir/resolve/TypeExpansionUtils.kt | 30 +++++++++++++++---- .../kotlin/fir/RenderingForDebugInfo.kt | 1 + ...arationAndFirDeclarationEqualityChecker.kt | 1 + 7 files changed, 43 insertions(+), 24 deletions(-) diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/ConeTypeCompatibilityChecker.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/ConeTypeCompatibilityChecker.kt index 990b195d0eb..05494800283 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/ConeTypeCompatibilityChecker.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/ConeTypeCompatibilityChecker.kt @@ -312,6 +312,7 @@ internal object ConeTypeCompatibilityChecker { // considered compatible. is ConeKotlinTypeProjectionIn -> BoundTypeArgument(coneTypeProjection.type, Variance.IN_VARIANCE) is ConeKotlinTypeProjectionOut -> BoundTypeArgument(coneTypeProjection.type, Variance.OUT_VARIANCE) + is ConeKotlinTypeConflictingProjection -> BoundTypeArgument(coneTypeProjection.type, Variance.INVARIANT) is ConeKotlinType -> when ((typeParameter as? FirTypeParameter)?.variance) { Variance.IN_VARIANCE -> BoundTypeArgument(coneTypeProjection.type, Variance.IN_VARIANCE) diff --git a/compiler/fir/cones/src/org/jetbrains/kotlin/fir/types/ConeTypes.kt b/compiler/fir/cones/src/org/jetbrains/kotlin/fir/types/ConeTypes.kt index f400badb539..aab3d4982a1 100644 --- a/compiler/fir/cones/src/org/jetbrains/kotlin/fir/types/ConeTypes.kt +++ b/compiler/fir/cones/src/org/jetbrains/kotlin/fir/types/ConeTypes.kt @@ -15,16 +15,6 @@ import org.jetbrains.kotlin.utils.addToStdlib.foldMap enum class ProjectionKind { STAR, IN, OUT, INVARIANT; - - operator fun plus(other: ProjectionKind): ProjectionKind { - return when { - this == other -> this - this == STAR || other == STAR -> STAR - this == INVARIANT -> other - other == INVARIANT -> this - else -> STAR - } - } } sealed class ConeTypeProjection : TypeArgumentMarker { @@ -54,6 +44,11 @@ data class ConeKotlinTypeProjectionOut(override val type: ConeKotlinType) : Cone get() = ProjectionKind.OUT } +data class ConeKotlinTypeConflictingProjection(override val type: ConeKotlinType) : ConeKotlinTypeProjection() { + override val kind: ProjectionKind + get() = ProjectionKind.INVARIANT +} + val ConeTypeProjection.type: ConeKotlinType? get() = when (this) { ConeStarProjection -> null diff --git a/compiler/fir/cones/src/org/jetbrains/kotlin/fir/types/TypeRenderer.kt b/compiler/fir/cones/src/org/jetbrains/kotlin/fir/types/TypeRenderer.kt index 6698a77c771..8f90cd8439e 100644 --- a/compiler/fir/cones/src/org/jetbrains/kotlin/fir/types/TypeRenderer.kt +++ b/compiler/fir/cones/src/org/jetbrains/kotlin/fir/types/TypeRenderer.kt @@ -59,6 +59,7 @@ private fun ConeKotlinType.renderAttributes(): String { fun ConeTypeProjection.render(): String { return when (this) { ConeStarProjection -> "*" + is ConeKotlinTypeConflictingProjection -> "CONFLICTING-PROJECTION ${type.render()}" is ConeKotlinTypeProjectionIn -> "in ${type.render()}" is ConeKotlinTypeProjectionOut -> "out ${type.render()}" is ConeKotlinType -> render() diff --git a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrTypeConverter.kt b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrTypeConverter.kt index 2a2381ed5fb..4ada34d146f 100644 --- a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrTypeConverter.kt +++ b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrTypeConverter.kt @@ -9,7 +9,6 @@ import org.jetbrains.kotlin.fir.expressions.FirAnnotationCall import org.jetbrains.kotlin.fir.expressions.classId import org.jetbrains.kotlin.fir.languageVersionSettings import org.jetbrains.kotlin.fir.resolve.fullyExpandedType -import org.jetbrains.kotlin.fir.resolve.inference.inferenceComponents import org.jetbrains.kotlin.fir.resolve.substitution.AbstractConeSubstitutor import org.jetbrains.kotlin.fir.resolve.toSymbol import org.jetbrains.kotlin.fir.typeContext @@ -19,6 +18,7 @@ import org.jetbrains.kotlin.ir.expressions.IrConstructorCall import org.jetbrains.kotlin.ir.symbols.IrClassSymbol import org.jetbrains.kotlin.ir.types.IrType import org.jetbrains.kotlin.ir.types.IrTypeArgument +import org.jetbrains.kotlin.ir.types.IrTypeProjection import org.jetbrains.kotlin.ir.types.impl.IrSimpleTypeImpl import org.jetbrains.kotlin.ir.types.impl.IrStarProjectionImpl import org.jetbrains.kotlin.ir.types.impl.makeTypeProjection @@ -165,16 +165,16 @@ class Fir2IrTypeConverter( } private fun ConeTypeProjection.toIrTypeArgument(typeContext: ConversionTypeContext): IrTypeArgument { + fun toIrTypeArgument(type: ConeKotlinType, variance: Variance): IrTypeProjection { + val irType = type.toIrType(typeContext) + return makeTypeProjection(irType, if (typeContext.invariantProjection) Variance.INVARIANT else variance) + } + return when (this) { ConeStarProjection -> IrStarProjectionImpl - is ConeKotlinTypeProjectionIn -> { - val irType = this.type.toIrType(typeContext) - makeTypeProjection(irType, if (typeContext.invariantProjection) Variance.INVARIANT else Variance.IN_VARIANCE) - } - is ConeKotlinTypeProjectionOut -> { - val irType = this.type.toIrType(typeContext) - makeTypeProjection(irType, if (typeContext.invariantProjection) Variance.INVARIANT else Variance.OUT_VARIANCE) - } + is ConeKotlinTypeProjectionIn -> toIrTypeArgument(this.type, Variance.IN_VARIANCE) + is ConeKotlinTypeProjectionOut -> toIrTypeArgument(this.type, Variance.OUT_VARIANCE) + is ConeKotlinTypeConflictingProjection -> toIrTypeArgument(this.type, Variance.INVARIANT) is ConeKotlinType -> { if (this is ConeCapturedType && this in capturedTypeCache && this.isRecursive(mutableSetOf())) { // Recursive captured type, e.g., Recursive where R : Recursive, ... diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/TypeExpansionUtils.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/TypeExpansionUtils.kt index d0eac13e7a7..dd4433c2405 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/TypeExpansionUtils.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/TypeExpansionUtils.kt @@ -107,12 +107,32 @@ private fun mapTypeAliasArguments( else -> mappedType } - return when (mappedProjection.kind + projection.kind) { - ProjectionKind.STAR -> ConeStarProjection - ProjectionKind.IN -> ConeKotlinTypeProjectionIn(mappedType) - ProjectionKind.OUT -> ConeKotlinTypeProjectionOut(mappedType) - ProjectionKind.INVARIANT -> mappedType + fun convertProjectionKindToConeTypeProjection(projectionKind: ProjectionKind): ConeTypeProjection { + return when (projectionKind) { + ProjectionKind.STAR -> ConeStarProjection + ProjectionKind.IN -> ConeKotlinTypeProjectionIn(mappedType) + ProjectionKind.OUT -> ConeKotlinTypeProjectionOut(mappedType) + ProjectionKind.INVARIANT -> mappedType + } } + + if (mappedProjection.kind == projection.kind) { + return convertProjectionKindToConeTypeProjection(mappedProjection.kind) + } + + if (mappedProjection.kind == ProjectionKind.STAR || projection.kind == ProjectionKind.STAR) { + return ConeStarProjection + } + + if (mappedProjection.kind == ProjectionKind.INVARIANT) { + return convertProjectionKindToConeTypeProjection(projection.kind) + } + + if (projection.kind == ProjectionKind.INVARIANT) { + return convertProjectionKindToConeTypeProjection(mappedProjection.kind) + } + + return ConeKotlinTypeConflictingProjection(mappedType) } } diff --git a/compiler/tests-compiler-utils/tests/org/jetbrains/kotlin/fir/RenderingForDebugInfo.kt b/compiler/tests-compiler-utils/tests/org/jetbrains/kotlin/fir/RenderingForDebugInfo.kt index 665dc7aeccd..a5af3a51314 100644 --- a/compiler/tests-compiler-utils/tests/org/jetbrains/kotlin/fir/RenderingForDebugInfo.kt +++ b/compiler/tests-compiler-utils/tests/org/jetbrains/kotlin/fir/RenderingForDebugInfo.kt @@ -49,6 +49,7 @@ private fun ConeTypeProjection.renderForDebugInfo(): String { ConeStarProjection -> "*" is ConeKotlinTypeProjectionIn -> "in ${type.renderForDebugInfo()}" is ConeKotlinTypeProjectionOut -> "out ${type.renderForDebugInfo()}" + is ConeKotlinTypeConflictingProjection -> "CONFLICTING-PROJECTION ${type.renderForDebugInfo()}" is ConeKotlinType -> renderForDebugInfo() } } diff --git a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/fir/KtDeclarationAndFirDeclarationEqualityChecker.kt b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/fir/KtDeclarationAndFirDeclarationEqualityChecker.kt index 216ee58f3be..cd3e9ae002a 100644 --- a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/fir/KtDeclarationAndFirDeclarationEqualityChecker.kt +++ b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/fir/KtDeclarationAndFirDeclarationEqualityChecker.kt @@ -162,6 +162,7 @@ object KtDeclarationAndFirDeclarationEqualityChecker { ConeStarProjection -> "*" is ConeKotlinTypeProjectionIn -> "in ${type.renderTypeAsKotlinType()}" is ConeKotlinTypeProjectionOut -> "out ${type.renderTypeAsKotlinType()}" + is ConeKotlinTypeConflictingProjection -> "CONFLICTING-PROJECTION ${type.renderTypeAsKotlinType()}" is ConeKotlinType -> renderTypeAsKotlinType() }