From 9ac5dd2bced274542637d19d6aab21b3269f9ca5 Mon Sep 17 00:00:00 2001 From: Denis Zharkov Date: Thu, 20 Aug 2020 13:04:06 +0300 Subject: [PATCH] FIR: Use lookup tags for as type constructors instead of symbols It may help to avoid redundant symbols lookups --- .../kotlin/fir/symbols/ConeLookupTags.kt | 3 +- .../calls/AbstractConeCallConflictResolver.kt | 15 ++-- .../kotlin/fir/resolve/calls/Arguments.kt | 7 +- .../calls/ConeOverloadConflictResolver.kt | 18 ++-- .../kotlin/fir/types/ConeInferenceContext.kt | 23 ++--- .../kotlin/fir/types/ConeTypeContext.kt | 90 +++++++++++-------- .../types/FirCorrespondingSupertypesCache.kt | 44 ++++----- .../jetbrains/kotlin/fir/types/TypeUtils.kt | 5 +- .../fir/symbols/ConeTypeParameterLookupTag.kt | 8 +- .../kotlin/fir/symbols/FirBasedSymbol.kt | 5 +- .../fir/symbols/impl/FirClassifierSymbol.kt | 5 +- .../recursiveFlexibleAssertions.fir.kt | 2 +- 12 files changed, 116 insertions(+), 109 deletions(-) diff --git a/compiler/fir/cones/src/org/jetbrains/kotlin/fir/symbols/ConeLookupTags.kt b/compiler/fir/cones/src/org/jetbrains/kotlin/fir/symbols/ConeLookupTags.kt index 3c1da000d44..10defd9d344 100644 --- a/compiler/fir/cones/src/org/jetbrains/kotlin/fir/symbols/ConeLookupTags.kt +++ b/compiler/fir/cones/src/org/jetbrains/kotlin/fir/symbols/ConeLookupTags.kt @@ -7,8 +7,9 @@ package org.jetbrains.kotlin.fir.symbols import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.Name +import org.jetbrains.kotlin.types.model.TypeConstructorMarker -abstract class ConeClassifierLookupTag { +abstract class ConeClassifierLookupTag : TypeConstructorMarker { abstract val name: Name override fun toString(): String { diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/AbstractConeCallConflictResolver.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/AbstractConeCallConflictResolver.kt index 01ddc5d2001..341ba8c53f1 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/AbstractConeCallConflictResolver.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/AbstractConeCallConflictResolver.kt @@ -8,7 +8,10 @@ package org.jetbrains.kotlin.fir.resolve.calls import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.resolve.inference.InferenceComponents import org.jetbrains.kotlin.fir.symbols.StandardClassIds -import org.jetbrains.kotlin.fir.types.* +import org.jetbrains.kotlin.fir.types.ConeKotlinType +import org.jetbrains.kotlin.fir.types.arrayElementType +import org.jetbrains.kotlin.fir.types.classId +import org.jetbrains.kotlin.fir.types.coneType import org.jetbrains.kotlin.resolve.calls.results.* import org.jetbrains.kotlin.types.checker.requireOrDescribe import org.jetbrains.kotlin.types.model.KotlinTypeMarker @@ -108,7 +111,7 @@ abstract class AbstractConeCallConflictResolver( protected fun createFlatSignature(call: Candidate, variable: FirVariable<*>): FlatSignature { return FlatSignature( call, - (variable as? FirProperty)?.typeParameters?.map { it.symbol }.orEmpty(), + (variable as? FirProperty)?.typeParameters?.map { it.symbol.toLookupTag() }.orEmpty(), listOfNotNull(variable.receiverTypeRef?.coneType), variable.receiverTypeRef != null, false, @@ -121,7 +124,7 @@ abstract class AbstractConeCallConflictResolver( protected fun createFlatSignature(call: Candidate, constructor: FirConstructor): FlatSignature { return FlatSignature( call, - constructor.typeParameters.map { it.symbol }, + constructor.typeParameters.map { it.symbol.toLookupTag() }, computeParameterTypes(call, constructor), //constructor.receiverTypeRef != null, false, @@ -135,7 +138,7 @@ abstract class AbstractConeCallConflictResolver( protected fun createFlatSignature(call: Candidate, function: FirSimpleFunction): FlatSignature { return FlatSignature( call, - function.typeParameters.map { it.symbol }, + function.typeParameters.map { it.symbol.toLookupTag() }, computeParameterTypes(call, function), function.receiverTypeRef != null, function.valueParameters.any { it.isVararg }, @@ -163,7 +166,7 @@ abstract class AbstractConeCallConflictResolver( private fun createFlatSignature(call: Candidate, klass: FirClass<*>): FlatSignature { return FlatSignature( call, - (klass as? FirRegularClass)?.typeParameters?.map { it.symbol }.orEmpty(), + (klass as? FirRegularClass)?.typeParameters?.map { it.symbol.toLookupTag() }.orEmpty(), valueParameterTypes = emptyList(), hasExtensionReceiver = false, hasVarargs = false, @@ -176,4 +179,4 @@ abstract class AbstractConeCallConflictResolver( private fun createEmptyConstraintSystem(): SimpleConstraintSystem { return ConeSimpleConstraintSystemImpl(inferenceComponents.createConstraintSystem()) } -} \ No newline at end of file +} diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/Arguments.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/Arguments.kt index 0971efff03e..9f7b68b316f 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/Arguments.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/Arguments.kt @@ -10,13 +10,11 @@ import org.jetbrains.kotlin.fir.declarations.FirAnonymousFunction import org.jetbrains.kotlin.fir.declarations.FirFunction import org.jetbrains.kotlin.fir.declarations.FirValueParameter import org.jetbrains.kotlin.fir.expressions.* -import org.jetbrains.kotlin.fir.typeContext import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference import org.jetbrains.kotlin.fir.resolve.fullyExpandedType import org.jetbrains.kotlin.fir.resolve.inference.isBuiltinFunctionalType import org.jetbrains.kotlin.fir.resolve.inference.preprocessCallableReference import org.jetbrains.kotlin.fir.resolve.inference.preprocessLambdaArgument -import org.jetbrains.kotlin.fir.resolve.toSymbol import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.firUnsafe import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.resultType import org.jetbrains.kotlin.fir.returnExpressions @@ -24,13 +22,12 @@ import org.jetbrains.kotlin.fir.scopes.impl.FirILTTypeRefPlaceHolder import org.jetbrains.kotlin.fir.scopes.impl.FirIntegerOperator import org.jetbrains.kotlin.fir.scopes.impl.FirIntegerOperatorCall import org.jetbrains.kotlin.fir.symbols.StandardClassIds -import org.jetbrains.kotlin.fir.symbols.impl.FirTypeAliasSymbol +import org.jetbrains.kotlin.fir.typeContext import org.jetbrains.kotlin.fir.types.* import org.jetbrains.kotlin.resolve.calls.inference.ConstraintSystemBuilder import org.jetbrains.kotlin.resolve.calls.inference.addSubtypeConstraintIfCompatible import org.jetbrains.kotlin.resolve.calls.inference.model.SimpleConstraintSystemConstraintPosition import org.jetbrains.kotlin.types.model.CaptureStatus -import org.jetbrains.kotlin.utils.addToStdlib.safeAs fun Candidate.resolveArgumentExpression( csBuilder: ConstraintSystemBuilder, @@ -331,7 +328,7 @@ private fun Candidate.getExpectedTypeWithSAMConversion( return samResolver.getFunctionTypeForPossibleSamType(candidateExpectedType).apply { usesSAM = true - } ?: return null + } } fun FirExpression.isFunctional(session: FirSession): Boolean = diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/ConeOverloadConflictResolver.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/ConeOverloadConflictResolver.kt index 70ed26c8ad7..40300cf1ac9 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/ConeOverloadConflictResolver.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/ConeOverloadConflictResolver.kt @@ -12,7 +12,7 @@ import org.jetbrains.kotlin.fir.render import org.jetbrains.kotlin.fir.resolve.inference.InferenceComponents import org.jetbrains.kotlin.fir.resolve.inference.TypeParameterBasedTypeVariable import org.jetbrains.kotlin.fir.resolve.substitution.substitutorByMap -import org.jetbrains.kotlin.fir.symbols.impl.FirTypeParameterSymbol +import org.jetbrains.kotlin.fir.symbols.ConeTypeParameterLookupTag import org.jetbrains.kotlin.fir.types.coneType import org.jetbrains.kotlin.resolve.calls.inference.model.NewConstraintSystemImpl import org.jetbrains.kotlin.resolve.calls.inference.model.SimpleConstraintSystemConstraintPosition @@ -23,7 +23,6 @@ import org.jetbrains.kotlin.types.model.KotlinTypeMarker import org.jetbrains.kotlin.types.model.TypeParameterMarker import org.jetbrains.kotlin.types.model.TypeSubstitutorMarker import org.jetbrains.kotlin.types.model.TypeSystemInferenceExtensionContext -import org.jetbrains.kotlin.utils.addToStdlib.cast class ConeOverloadConflictResolver( specificityComparator: TypeSpecificityComparator, @@ -179,19 +178,20 @@ object NoSubstitutor : TypeSubstitutorMarker class ConeSimpleConstraintSystemImpl(val system: NewConstraintSystemImpl) : SimpleConstraintSystem { override fun registerTypeVariables(typeParameters: Collection): TypeSubstitutorMarker = with(context) { val csBuilder = system.getBuilder() - val substitutionMap = typeParameters.associateWith { - require(it is FirTypeParameterSymbol) - val variable = TypeParameterBasedTypeVariable(it) + val substitutionMap = typeParameters.associateBy({ (it as ConeTypeParameterLookupTag).typeParameterSymbol }) { + require(it is ConeTypeParameterLookupTag) + val variable = TypeParameterBasedTypeVariable(it.typeParameterSymbol) csBuilder.registerVariable(variable) variable.defaultType } - val substitutor = substitutorByMap(substitutionMap.cast()) + val substitutor = substitutorByMap(substitutionMap) for (typeParameter in typeParameters) { - require(typeParameter is FirTypeParameterSymbol) - for (upperBound in typeParameter.fir.bounds) { + require(typeParameter is ConeTypeParameterLookupTag) + for (upperBound in typeParameter.symbol.fir.bounds) { addSubtypeConstraint( - substitutionMap[typeParameter] ?: error("No ${typeParameter.fir.render()} in substitution map"), + substitutionMap[typeParameter.typeParameterSymbol] + ?: error("No ${typeParameter.symbol.fir.render()} in substitution map"), substitutor.substituteOrSelf(upperBound.coneType) ) } diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/types/ConeInferenceContext.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/types/ConeInferenceContext.kt index 033fc69a237..b2d7b425db2 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/types/ConeInferenceContext.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/types/ConeInferenceContext.kt @@ -11,10 +11,9 @@ import org.jetbrains.kotlin.fir.resolve.calls.NoSubstitutor import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProvider import org.jetbrains.kotlin.fir.resolve.substitution.AbstractConeSubstitutor import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor +import org.jetbrains.kotlin.fir.symbols.ConeClassLikeLookupTag +import org.jetbrains.kotlin.fir.symbols.ConeTypeParameterLookupTag import org.jetbrains.kotlin.fir.symbols.StandardClassIds -import org.jetbrains.kotlin.fir.symbols.impl.FirClassLikeSymbol -import org.jetbrains.kotlin.fir.symbols.impl.FirClassifierSymbol -import org.jetbrains.kotlin.fir.symbols.impl.FirTypeParameterSymbol import org.jetbrains.kotlin.fir.types.impl.ConeClassLikeTypeImpl import org.jetbrains.kotlin.fir.types.impl.ConeTypeParameterTypeImpl import org.jetbrains.kotlin.types.AbstractTypeChecker @@ -56,16 +55,15 @@ interface ConeInferenceContext : TypeSystemInferenceExtensionContext, ConeTypeCo nullable: Boolean, isExtensionFunction: Boolean ): SimpleTypeMarker { - require(constructor is FirClassifierSymbol<*>) @Suppress("UNCHECKED_CAST") return when (constructor) { - is FirClassLikeSymbol<*> -> ConeClassLikeTypeImpl( - constructor.toLookupTag(), + is ConeClassLikeLookupTag -> ConeClassLikeTypeImpl( + constructor, (arguments as List).toTypedArray(), nullable ) - is FirTypeParameterSymbol -> ConeTypeParameterTypeImpl( - constructor.toLookupTag(), + is ConeTypeParameterLookupTag -> ConeTypeParameterTypeImpl( + constructor, nullable ) else -> error("!") @@ -183,7 +181,7 @@ interface ConeInferenceContext : TypeSystemInferenceExtensionContext, ConeTypeCo } override fun TypeConstructorMarker.isUnitTypeConstructor(): Boolean { - return this is FirClassLikeSymbol<*> && this.classId == StandardClassIds.Unit + return this is ConeClassLikeLookupTag && this.classId == StandardClassIds.Unit } override fun Collection.singleBestRepresentative(): KotlinTypeMarker? { @@ -346,10 +344,13 @@ interface ConeInferenceContext : TypeSystemInferenceExtensionContext, ConeTypeCo } override fun TypeConstructorMarker.toErrorType(): SimpleTypeMarker { - require(this is ErrorTypeConstructor) - return ConeClassErrorType(ConeIntermediateDiagnostic(reason)) + if (this is ErrorTypeConstructor) return createErrorType(reason) + if (this is ConeClassLikeLookupTag) return createErrorType("Not found classifier: $classId") + return createErrorType("Unknown reason") } + private fun createErrorType(reason: String) = ConeClassErrorType(ConeIntermediateDiagnostic(reason)) + override fun findCommonIntegerLiteralTypesSuperType(explicitSupertypes: List): SimpleTypeMarker? { return ConeIntegerLiteralTypeImpl.findCommonSuperType(explicitSupertypes) } diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/types/ConeTypeContext.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/types/ConeTypeContext.kt index e0338606fe4..c8a1b30f0ba 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/types/ConeTypeContext.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/types/ConeTypeContext.kt @@ -17,6 +17,8 @@ import org.jetbrains.kotlin.fir.resolve.substitution.substitutorByMap import org.jetbrains.kotlin.fir.resolve.toSymbol import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.firUnsafe import org.jetbrains.kotlin.fir.symbols.AbstractFirBasedSymbol +import org.jetbrains.kotlin.fir.symbols.ConeClassLikeLookupTag +import org.jetbrains.kotlin.fir.symbols.ConeTypeParameterLookupTag import org.jetbrains.kotlin.fir.symbols.StandardClassIds import org.jetbrains.kotlin.fir.symbols.impl.* import org.jetbrains.kotlin.name.FqName @@ -68,7 +70,7 @@ interface ConeTypeContext : TypeSystemContext, TypeSystemOptimizationContext, Ty override fun KotlinTypeMarker.isError(): Boolean { assert(this is ConeKotlinType) - return this is ConeClassErrorType || this is ConeKotlinErrorType || this.typeConstructor() is ErrorTypeConstructor + return this is ConeClassErrorType || this is ConeKotlinErrorType || this.typeConstructor().isError() } override fun KotlinTypeMarker.isUninferredParameter(): Boolean { @@ -118,9 +120,8 @@ interface ConeTypeContext : TypeSystemContext, TypeSystemOptimizationContext, Ty override fun SimpleTypeMarker.typeConstructor(): TypeConstructorMarker { return when (this) { - is ConeClassLikeType -> lookupTag.toSymbol(session) - ?: ErrorTypeConstructor("Unresolved: $lookupTag") - is ConeTypeParameterType -> lookupTag.typeParameterSymbol + is ConeClassLikeType -> lookupTag + is ConeTypeParameterType -> lookupTag is ConeCapturedType -> constructor is ConeTypeVariableType -> lookupTag as ConeTypeVariableTypeConstructor // TODO: WTF is ConeIntersectionType -> this @@ -195,14 +196,19 @@ interface ConeTypeContext : TypeSystemContext, TypeSystemOptimizationContext, Ty override fun TypeConstructorMarker.parametersCount(): Int { //require(this is ConeSymbol) return when (this) { - is FirTypeParameterSymbol, + is ConeTypeParameterLookupTag, is ConeCapturedTypeConstructor, is ErrorTypeConstructor, is ConeTypeVariableTypeConstructor, is ConeIntersectionType -> 0 - is FirAnonymousObjectSymbol -> fir.typeParameters.size - is FirRegularClassSymbol -> fir.typeParameters.size - is FirTypeAliasSymbol -> fir.typeParameters.size + is ConeClassLikeLookupTag -> { + when(val symbol = toSymbol(session)) { + is FirAnonymousObjectSymbol -> symbol.fir.typeParameters.size + is FirRegularClassSymbol -> symbol.fir.typeParameters.size + is FirTypeAliasSymbol -> symbol.fir.typeParameters.size + else -> 0 + } + } is ConeIntegerLiteralType -> 0 else -> error("?!:10") } @@ -210,23 +216,29 @@ interface ConeTypeContext : TypeSystemContext, TypeSystemOptimizationContext, Ty override fun TypeConstructorMarker.getParameter(index: Int): TypeParameterMarker { //require(this is ConeSymbol) - return when (this) { - is FirTypeParameterSymbol -> error("?!:11") - is FirAnonymousObjectSymbol -> fir.typeParameters[index].symbol - is FirRegularClassSymbol -> fir.typeParameters[index].symbol - is FirTypeAliasSymbol -> fir.typeParameters[index].symbol + return when (val symbol = toClassLikeSymbol()) { + is FirAnonymousObjectSymbol -> symbol.fir.typeParameters[index].symbol.toLookupTag() + is FirRegularClassSymbol -> symbol.fir.typeParameters[index].symbol.toLookupTag() + is FirTypeAliasSymbol -> symbol.fir.typeParameters[index].symbol.toLookupTag() else -> error("?!:12") } } + private fun TypeConstructorMarker.toClassLikeSymbol(): FirClassLikeSymbol<*>? = (this as? ConeClassLikeLookupTag)?.toSymbol(session) + override fun TypeConstructorMarker.supertypes(): Collection { if (this is ErrorTypeConstructor) return emptyList() //require(this is ConeSymbol) return when (this) { is ConeTypeVariableTypeConstructor -> emptyList() - is FirTypeParameterSymbol -> fir.bounds.map { it.coneType } - is FirClassSymbol<*> -> fir.superConeTypes - is FirTypeAliasSymbol -> listOfNotNull(fir.expandedConeType) + is ConeTypeParameterLookupTag -> symbol.fir.bounds.map { it.coneType } + is ConeClassLikeLookupTag -> { + when (val symbol = toClassLikeSymbol()) { + is FirClassSymbol<*> -> symbol.fir.superConeTypes + is FirTypeAliasSymbol -> listOfNotNull(symbol.fir.expandedConeType) + else -> emptyList() + } + } is ConeCapturedTypeConstructor -> supertypes!! is ConeIntersectionType -> intersectedTypes is ConeIntegerLiteralType -> supertypes @@ -240,26 +252,26 @@ interface ConeTypeContext : TypeSystemContext, TypeSystemOptimizationContext, Ty override fun TypeConstructorMarker.isClassTypeConstructor(): Boolean { //assert(this is ConeSymbol) - return this is FirClassSymbol<*> + return this is ConeClassLikeLookupTag } override fun TypeParameterMarker.getVariance(): TypeVariance { - require(this is FirTypeParameterSymbol) - return this.fir.variance.convertVariance() + require(this is ConeTypeParameterLookupTag) + return this.symbol.fir.variance.convertVariance() } override fun TypeParameterMarker.upperBoundCount(): Int { - require(this is FirTypeParameterSymbol) - return this.fir.bounds.size + require(this is ConeTypeParameterLookupTag) + return this.symbol.fir.bounds.size } override fun TypeParameterMarker.getUpperBound(index: Int): KotlinTypeMarker { - require(this is FirTypeParameterSymbol) - return this.fir.bounds[index].coneType + require(this is ConeTypeParameterLookupTag) + return this.symbol.fir.bounds[index].coneType } override fun TypeParameterMarker.getTypeConstructor(): TypeConstructorMarker { - require(this is FirTypeParameterSymbol) + require(this is ConeTypeParameterLookupTag) return this } @@ -284,8 +296,9 @@ interface ConeTypeContext : TypeSystemContext, TypeSystemOptimizationContext, Ty } override fun TypeConstructorMarker.isCommonFinalClassConstructor(): Boolean { - if (this is FirAnonymousObjectSymbol) return true - val classSymbol = this as? FirRegularClassSymbol ?: return false + val symbol = toClassLikeSymbol() ?: return false + if (symbol is FirAnonymousObjectSymbol) return true + val classSymbol = symbol as? FirRegularClassSymbol ?: return false val fir = classSymbol.fir return fir.modality == Modality.FINAL && fir.classKind != ClassKind.ENUM_ENTRY && @@ -350,11 +363,11 @@ interface ConeTypeContext : TypeSystemContext, TypeSystemOptimizationContext, Ty } override fun TypeConstructorMarker.isAnyConstructor(): Boolean { - return this is FirClassLikeSymbol<*> && classId == StandardClassIds.Any + return this is ConeClassLikeLookupTag && classId == StandardClassIds.Any } override fun TypeConstructorMarker.isNothingConstructor(): Boolean { - return this is FirClassLikeSymbol<*> && classId == StandardClassIds.Nothing + return this is ConeClassLikeLookupTag && classId == StandardClassIds.Nothing } override fun SimpleTypeMarker.isSingleClassifierType(): Boolean { @@ -367,8 +380,8 @@ interface ConeTypeContext : TypeSystemContext, TypeSystemOptimizationContext, Ty if (this is ConeDefinitelyNotNullType) return true require(this is ConeLookupTagBasedType) val typeConstructor = this.typeConstructor() - return typeConstructor is FirClassSymbol<*> || - typeConstructor is FirTypeParameterSymbol + return typeConstructor is ConeClassLikeLookupTag || + typeConstructor is ConeTypeParameterLookupTag } override fun captureFromExpression(type: KotlinTypeMarker): KotlinTypeMarker? { @@ -431,8 +444,7 @@ interface ConeTypeContext : TypeSystemContext, TypeSystemOptimizationContext, Ty } private fun TypeConstructorMarker.toFirRegularClass(): FirRegularClass? { - if (this !is FirClassLikeSymbol<*>) return null - return fir as? FirRegularClass + return toClassLikeSymbol()?.fir as? FirRegularClass } override fun nullableAnyType(): SimpleTypeMarker = TODO("not implemented") @@ -460,7 +472,7 @@ interface ConeTypeContext : TypeSystemContext, TypeSystemOptimizationContext, Ty } override fun TypeConstructorMarker.getTypeParameterClassifier(): TypeParameterMarker? { - return this as? FirTypeParameterSymbol + return this as? ConeTypeParameterLookupTag } override fun TypeConstructorMarker.isInlineClass(): Boolean { @@ -472,8 +484,8 @@ interface ConeTypeContext : TypeSystemContext, TypeSystemOptimizationContext, Ty } override fun TypeParameterMarker.getRepresentativeUpperBound(): KotlinTypeMarker { - require(this is FirTypeParameterSymbol) - return this.fir.bounds.getOrNull(0)?.let { it.coneType } + require(this is ConeTypeParameterLookupTag) + return this.symbol.fir.bounds.getOrNull(0)?.coneType ?: session.builtinTypes.nullableAnyType.type } @@ -492,11 +504,11 @@ interface ConeTypeContext : TypeSystemContext, TypeSystemOptimizationContext, Ty getClassFqNameUnsafe()?.startsWith(Name.identifier("kotlin")) == true override fun TypeConstructorMarker.getClassFqNameUnsafe(): FqNameUnsafe? { - if (this !is FirClassLikeSymbol<*>) return null - return toLookupTag().classId.asSingleFqName().toUnsafe() + if (this !is ConeClassLikeLookupTag) return null + return classId.asSingleFqName().toUnsafe() } - override fun TypeParameterMarker.getName() = (this as FirTypeParameterSymbol).name + override fun TypeParameterMarker.getName() = (this as ConeTypeParameterLookupTag).name override fun TypeParameterMarker.isReified(): Boolean = TODO("not implemented") @@ -506,7 +518,7 @@ interface ConeTypeContext : TypeSystemContext, TypeSystemOptimizationContext, Ty } override fun TypeConstructorMarker.isError(): Boolean { - return this is ErrorTypeConstructor + return this is ErrorTypeConstructor || (this is ConeClassLikeLookupTag && this.toSymbol(session) == null) } } diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/types/FirCorrespondingSupertypesCache.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/types/FirCorrespondingSupertypesCache.kt index 77fa2d23380..65c7af0dea6 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/types/FirCorrespondingSupertypesCache.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/types/FirCorrespondingSupertypesCache.kt @@ -10,6 +10,7 @@ import org.jetbrains.kotlin.fir.FirSessionComponent import org.jetbrains.kotlin.fir.declarations.FirClassLikeDeclaration import org.jetbrains.kotlin.fir.declarations.FirTypeParameterRefsOwner import org.jetbrains.kotlin.fir.resolve.toSymbol +import org.jetbrains.kotlin.fir.symbols.ConeClassLikeLookupTag import org.jetbrains.kotlin.fir.symbols.impl.FirClassLikeSymbol import org.jetbrains.kotlin.types.AbstractTypeCheckerContext import org.jetbrains.kotlin.types.model.CaptureStatus @@ -18,22 +19,22 @@ import org.jetbrains.kotlin.types.model.TypeConstructorMarker class FirCorrespondingSupertypesCache(private val session: FirSession) : FirSessionComponent { private val context = ConeTypeCheckerContext(isErrorTypeEqualsToAnything = false, isStubTypeEqualsToAnything = true, session = session) - private val cache = HashMap, Map, List>?>(1000, 0.5f) + private val cache = HashMap>?>(1000, 0.5f) fun getCorrespondingSupertypes( type: ConeKotlinType, supertypeConstructor: TypeConstructorMarker ): List? { - if (type !is ConeClassLikeType || supertypeConstructor !is FirClassLikeSymbol<*>) return null + if (type !is ConeClassLikeType || supertypeConstructor !is ConeClassLikeLookupTag) return null - val symbol = type.lookupTag.toSymbol(session) ?: return null - if (symbol == supertypeConstructor) return listOf(captureType(type)) + val lookupTag = type.lookupTag + if (lookupTag == supertypeConstructor) return listOf(captureType(type)) - if (symbol !in cache) { - cache[symbol] = computeSupertypesMap(type, symbol) + if (lookupTag !in cache) { + cache[lookupTag] = computeSupertypesMap(lookupTag) } - val resultTypes = cache[symbol]?.getOrDefault(supertypeConstructor, emptyList()) ?: return null + val resultTypes = cache[lookupTag]?.getOrDefault(supertypeConstructor, emptyList()) ?: return null if (type.typeArguments.isEmpty()) return resultTypes val capturedType = captureType(type) @@ -46,18 +47,12 @@ class FirCorrespondingSupertypesCache(private val session: FirSession) : FirSess private fun captureType(type: ConeClassLikeType): ConeClassLikeType = (context.captureFromArguments(type, CaptureStatus.FOR_SUBTYPING) ?: type) as ConeClassLikeType - private fun computeSupertypesMap( - subtype: ConeLookupTagBasedType, - subtypeSymbol: FirClassLikeSymbol<*> - ): Map, List>? { - val resultingMap = HashMap, List>() + private fun computeSupertypesMap(subtypeLookupTag: ConeClassLikeLookupTag): Map>? { + val resultingMap = HashMap>() - val subtypeClassSymbol: FirClassLikeSymbol<*> = with(context) { - subtype.typeConstructor() as? FirClassLikeSymbol<*> ?: return null - } - val subtypeFirClass: FirClassLikeDeclaration<*> = subtypeClassSymbol.fir + val subtypeFirClass: FirClassLikeDeclaration<*> = subtypeLookupTag.toSymbol(session)?.fir ?: return null - val defaultType = subtypeClassSymbol.toLookupTag().constructClassType( + val defaultType = subtypeLookupTag.constructClassType( (subtypeFirClass as? FirTypeParameterRefsOwner)?.typeParameters?.map { it.symbol.toLookupTag().constructType(emptyArray(), isNullable = false) }?.toTypedArray().orEmpty(), @@ -67,25 +62,24 @@ class FirCorrespondingSupertypesCache(private val session: FirSession) : FirSess if (context.anySupertype( defaultType, { it !is ConeClassLikeType || it.lookupTag.toSymbol(session) !is FirClassLikeSymbol<*> } - ) { supertype -> computeSupertypePolicyAndPutInMap(supertype, subtypeSymbol, resultingMap) } + ) { supertype -> computeSupertypePolicyAndPutInMap(supertype, resultingMap) } ) { return null } - return resultingMap + return resultingMap.also { + it.remove(subtypeLookupTag) // Just optimization: do not preserve mapping from MyClass to MyClas itself + } } private fun computeSupertypePolicyAndPutInMap( supertype: SimpleTypeMarker, - subtypeSymbol: FirClassLikeSymbol<*>, - resultingMap: MutableMap, List> + resultingMap: MutableMap> ): AbstractTypeCheckerContext.SupertypesPolicy { - val supertypeSymbol = (supertype as ConeClassLikeType).lookupTag.toSymbol(session) as FirClassLikeSymbol<*> + val supertypeLookupTag = (supertype as ConeClassLikeType).lookupTag val captured = context.captureFromArguments(supertype, CaptureStatus.FOR_SUBTYPING) as ConeClassLikeType? ?: supertype - if (supertypeSymbol != subtypeSymbol) { - resultingMap[supertypeSymbol] = listOf(captured) - } + resultingMap[supertypeLookupTag] = listOf(captured) return when { with(context) { captured.argumentsCount() } == 0 -> { diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/types/TypeUtils.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/types/TypeUtils.kt index 7f037c424b3..4141dd18666 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/types/TypeUtils.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/types/TypeUtils.kt @@ -7,7 +7,6 @@ package org.jetbrains.kotlin.fir.types import org.jetbrains.kotlin.fir.FirSession import org.jetbrains.kotlin.fir.resolve.fullyExpandedType -import org.jetbrains.kotlin.fir.resolve.toSymbol import org.jetbrains.kotlin.fir.symbols.ConeClassLikeLookupTag import org.jetbrains.kotlin.fir.symbols.ConeClassifierLookupTag import org.jetbrains.kotlin.fir.symbols.ConeTypeParameterLookupTag @@ -122,7 +121,7 @@ fun ConeTypeContext.hasNullableSuperType(type: ConeKotlinType): Boolean { if (type is ConeClassLikeType) return false if (type !is ConeLookupTagBasedType) return false // TODO? - val symbol = type.lookupTag.toSymbol(session) ?: return false // TODO?! + val symbol = type.lookupTag for (superType in symbol.supertypes()) { if (superType.isNullableType()) return true } @@ -242,4 +241,4 @@ fun FirTypeRef.isExtensionFunctionType(session: FirSession): Boolean { fun ConeKotlinType.isExtensionFunctionType(session: FirSession): Boolean { val type = this.lowerBoundIfFlexible().fullyExpandedType(session) return type.attributes.extensionFunctionType != null -} \ No newline at end of file +} diff --git a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/symbols/ConeTypeParameterLookupTag.kt b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/symbols/ConeTypeParameterLookupTag.kt index 7e555e0853f..682f248a087 100644 --- a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/symbols/ConeTypeParameterLookupTag.kt +++ b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/symbols/ConeTypeParameterLookupTag.kt @@ -5,13 +5,15 @@ package org.jetbrains.kotlin.fir.symbols -import org.jetbrains.kotlin.fir.symbols.impl.FirClassifierSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirTypeParameterSymbol import org.jetbrains.kotlin.name.Name +import org.jetbrains.kotlin.types.model.TypeParameterMarker -data class ConeTypeParameterLookupTag(val typeParameterSymbol: FirTypeParameterSymbol) : ConeClassifierLookupTagWithFixedSymbol() { +data class ConeTypeParameterLookupTag( + val typeParameterSymbol: FirTypeParameterSymbol +) : ConeClassifierLookupTagWithFixedSymbol(), TypeParameterMarker { override val name: Name get() = typeParameterSymbol.name - override val symbol: FirClassifierSymbol<*> + override val symbol: FirTypeParameterSymbol get() = typeParameterSymbol } diff --git a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/symbols/FirBasedSymbol.kt b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/symbols/FirBasedSymbol.kt index b49678eeea8..cf72810d43f 100644 --- a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/symbols/FirBasedSymbol.kt +++ b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/symbols/FirBasedSymbol.kt @@ -7,10 +7,9 @@ package org.jetbrains.kotlin.fir.symbols import org.jetbrains.kotlin.fir.FirSymbolOwner import org.jetbrains.kotlin.fir.declarations.FirDeclaration -import org.jetbrains.kotlin.types.model.TypeConstructorMarker -interface FirBasedSymbol : TypeConstructorMarker where E : FirSymbolOwner, E : FirDeclaration { +interface FirBasedSymbol where E : FirSymbolOwner, E : FirDeclaration { val fir: E fun bind(e: E) -} \ No newline at end of file +} diff --git a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/symbols/impl/FirClassifierSymbol.kt b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/symbols/impl/FirClassifierSymbol.kt index 5e31c2a99e4..b1a2a8defe4 100644 --- a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/symbols/impl/FirClassifierSymbol.kt +++ b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/symbols/impl/FirClassifierSymbol.kt @@ -9,9 +9,8 @@ import org.jetbrains.kotlin.fir.FirSymbolOwner import org.jetbrains.kotlin.fir.declarations.FirDeclaration import org.jetbrains.kotlin.fir.symbols.AbstractFirBasedSymbol import org.jetbrains.kotlin.fir.symbols.ConeClassifierLookupTag -import org.jetbrains.kotlin.types.model.TypeParameterMarker -abstract class FirClassifierSymbol : AbstractFirBasedSymbol(), TypeParameterMarker +abstract class FirClassifierSymbol : AbstractFirBasedSymbol() where E : FirSymbolOwner, E : FirDeclaration { abstract fun toLookupTag(): ConeClassifierLookupTag -} \ No newline at end of file +} diff --git a/compiler/testData/diagnostics/testsWithStdLib/inference/recursiveFlexibleAssertions.fir.kt b/compiler/testData/diagnostics/testsWithStdLib/inference/recursiveFlexibleAssertions.fir.kt index 2d3225d00fb..a46a0003bb5 100644 --- a/compiler/testData/diagnostics/testsWithStdLib/inference/recursiveFlexibleAssertions.fir.kt +++ b/compiler/testData/diagnostics/testsWithStdLib/inference/recursiveFlexibleAssertions.fir.kt @@ -75,5 +75,5 @@ fun test() { } // TODO: FIR // {AbstractAssert<*, out Any!>! & EnumerableAssert<*, {Comparable<*> & java.io.Serializable!}>!} with unfolded flexible nullability - ..ERROR CLASS: Unresolved: !> & EnumerableAssert<*, out kotlin.Comparable & java.io.Serializable..kotlin.Comparable? & java.io.Serializable?>..AbstractAssert<*, out ERROR CLASS: Unresolved: ..ERROR CLASS: Unresolved: !>? & EnumerableAssert<*, out kotlin.Comparable & java.io.Serializable..kotlin.Comparable? & java.io.Serializable?>?, out ERROR CLASS: Unresolved: ..ERROR CLASS: Unresolved: !> & EnumerableAssert..ERROR CLASS: Unresolved: !> & EnumerableAssert<*, out kotlin.Comparable & java.io.Serializable..kotlin.Comparable? & java.io.Serializable?>..AbstractAssert<*, out ERROR CLASS: Unresolved: ..ERROR CLASS: Unresolved: !>? & EnumerableAssert<*, out kotlin.Comparable & java.io.Serializable..kotlin.Comparable? & java.io.Serializable?>?, out kotlin.Comparable & java.io.Serializable..kotlin.Comparable? & java.io.Serializable?>..AbstractAssert..ERROR CLASS: Unresolved: !> & EnumerableAssert<*, out kotlin.Comparable & java.io.Serializable..kotlin.Comparable? & java.io.Serializable?>..AbstractAssert<*, out ERROR CLASS: Unresolved: ..ERROR CLASS: Unresolved: !>? & EnumerableAssert<*, out kotlin.Comparable & java.io.Serializable..kotlin.Comparable? & java.io.Serializable?>?, out ERROR CLASS: Unresolved: ..ERROR CLASS: Unresolved: !>? & EnumerableAssert..ERROR CLASS: Unresolved: !> & EnumerableAssert<*, out kotlin.Comparable & java.io.Serializable..kotlin.Comparable? & java.io.Serializable?>..AbstractAssert<*, out ERROR CLASS: Unresolved: ..ERROR CLASS: Unresolved: !>? & EnumerableAssert<*, out kotlin.Comparable & java.io.Serializable..kotlin.Comparable? & java.io.Serializable?>?, out kotlin.Comparable & java.io.Serializable..kotlin.Comparable? & java.io.Serializable?>?")!>assertion + ..ERROR CLASS: Not found classifier: /!> & EnumerableAssert<*, out kotlin.Comparable & java.io.Serializable..kotlin.Comparable? & java.io.Serializable?>..AbstractAssert<*, out ERROR CLASS: Not found classifier: /..ERROR CLASS: Not found classifier: /!>? & EnumerableAssert<*, out kotlin.Comparable & java.io.Serializable..kotlin.Comparable? & java.io.Serializable?>?, out ERROR CLASS: Not found classifier: /..ERROR CLASS: Not found classifier: /!> & EnumerableAssert..ERROR CLASS: Not found classifier: /!> & EnumerableAssert<*, out kotlin.Comparable & java.io.Serializable..kotlin.Comparable? & java.io.Serializable?>..AbstractAssert<*, out ERROR CLASS: Not found classifier: /..ERROR CLASS: Not found classifier: /!>? & EnumerableAssert<*, out kotlin.Comparable & java.io.Serializable..kotlin.Comparable? & java.io.Serializable?>?, out kotlin.Comparable & java.io.Serializable..kotlin.Comparable? & java.io.Serializable?>..AbstractAssert..ERROR CLASS: Not found classifier: /!> & EnumerableAssert<*, out kotlin.Comparable & java.io.Serializable..kotlin.Comparable? & java.io.Serializable?>..AbstractAssert<*, out ERROR CLASS: Not found classifier: /..ERROR CLASS: Not found classifier: /!>? & EnumerableAssert<*, out kotlin.Comparable & java.io.Serializable..kotlin.Comparable? & java.io.Serializable?>?, out ERROR CLASS: Not found classifier: /..ERROR CLASS: Not found classifier: /!>? & EnumerableAssert..ERROR CLASS: Not found classifier: /!> & EnumerableAssert<*, out kotlin.Comparable & java.io.Serializable..kotlin.Comparable? & java.io.Serializable?>..AbstractAssert<*, out ERROR CLASS: Not found classifier: /..ERROR CLASS: Not found classifier: /!>? & EnumerableAssert<*, out kotlin.Comparable & java.io.Serializable..kotlin.Comparable? & java.io.Serializable?>?, out kotlin.Comparable & java.io.Serializable..kotlin.Comparable? & java.io.Serializable?>?")!>assertion }