[FIR] Never create ConeSubstitutorByMap with empty substitution
Relates to KT-66323
This commit is contained in:
committed by
Space Team
parent
6c691b497a
commit
624bea3ecf
@@ -307,7 +307,7 @@ fun createSubstitutionForSupertype(superType: ConeLookupTagBasedType, session: F
|
||||
it as? ConeKotlinType ?: ConeErrorType(ConeSimpleDiagnostic("illegal projection usage", DiagnosticKind.IllegalProjectionUsage))
|
||||
}
|
||||
val mapping = klass.typeParameters.map { it.symbol }.zip(arguments).toMap()
|
||||
return ConeSubstitutorByMap(mapping, session)
|
||||
return ConeSubstitutorByMap.create(mapping, session)
|
||||
}
|
||||
|
||||
fun FirRegularClassSymbol.getSuperClassSymbolOrAny(session: FirSession): FirRegularClassSymbol {
|
||||
|
||||
+28
-8
@@ -67,7 +67,7 @@ fun wrapProjection(old: ConeTypeProjection, newType: ConeKotlinType): ConeTypePr
|
||||
|
||||
abstract class AbstractConeSubstitutor(protected val typeContext: ConeTypeContext) : ConeSubstitutor() {
|
||||
abstract fun substituteType(type: ConeKotlinType): ConeKotlinType?
|
||||
open fun substituteArgument(projection: ConeTypeProjection, index: Int): ConeTypeProjection? {
|
||||
override fun substituteArgument(projection: ConeTypeProjection, index: Int): ConeTypeProjection? {
|
||||
val type = (projection as? ConeKotlinTypeProjection)?.type ?: return null
|
||||
val newType = substituteOrNull(type) ?: return null
|
||||
return wrapProjection(projection, newType)
|
||||
@@ -212,12 +212,7 @@ abstract class AbstractConeSubstitutor(protected val typeContext: ConeTypeContex
|
||||
}
|
||||
|
||||
fun substitutorByMap(substitution: Map<FirTypeParameterSymbol, ConeKotlinType>, useSiteSession: FirSession): ConeSubstitutor {
|
||||
// If all arguments match parameters, then substitutor isn't needed
|
||||
if (substitution.all { (parameterSymbol, argumentType) ->
|
||||
(argumentType as? ConeTypeParameterType)?.lookupTag?.typeParameterSymbol == parameterSymbol && !argumentType.isMarkedNullable
|
||||
}
|
||||
) return ConeSubstitutor.Empty
|
||||
return ConeSubstitutorByMap(substitution, useSiteSession)
|
||||
return ConeSubstitutorByMap.create(substitution, useSiteSession, allowIdenticalSubstitution = false)
|
||||
}
|
||||
|
||||
data class ChainedSubstitutor(val first: ConeSubstitutor, val second: ConeSubstitutor) : ConeSubstitutor() {
|
||||
@@ -226,6 +221,11 @@ data class ChainedSubstitutor(val first: ConeSubstitutor, val second: ConeSubsti
|
||||
return second.substituteOrNull(type)
|
||||
}
|
||||
|
||||
override fun substituteArgument(projection: ConeTypeProjection, index: Int): ConeTypeProjection? {
|
||||
first.substituteArgument(projection, index)?.let { return second.substituteArgument(projection, index) }
|
||||
return second.substituteArgument(projection, index)
|
||||
}
|
||||
|
||||
override fun toString(): String {
|
||||
return "$first then $second"
|
||||
}
|
||||
@@ -237,11 +237,31 @@ fun ConeSubstitutor.chain(other: ConeSubstitutor): ConeSubstitutor {
|
||||
return ChainedSubstitutor(this, other)
|
||||
}
|
||||
|
||||
class ConeSubstitutorByMap(
|
||||
class ConeSubstitutorByMap private constructor(
|
||||
// Used only for sake of optimizations at org.jetbrains.kotlin.analysis.api.fir.types.KtFirMapBackedSubstitutor
|
||||
val substitution: Map<FirTypeParameterSymbol, ConeKotlinType>,
|
||||
private val useSiteSession: FirSession
|
||||
) : AbstractConeSubstitutor(useSiteSession.typeContext) {
|
||||
companion object {
|
||||
fun create(
|
||||
substitution: Map<FirTypeParameterSymbol, ConeKotlinType>,
|
||||
useSiteSession: FirSession,
|
||||
allowIdenticalSubstitution: Boolean = true,
|
||||
): ConeSubstitutor {
|
||||
if (substitution.isEmpty()) return Empty
|
||||
|
||||
if (!allowIdenticalSubstitution) {
|
||||
// If all arguments match parameters, then substitutor isn't needed
|
||||
val substitutionIsIdentical = substitution.all { (parameterSymbol, argumentType) ->
|
||||
(argumentType as? ConeTypeParameterType)?.lookupTag?.typeParameterSymbol == parameterSymbol && !argumentType.isMarkedNullable
|
||||
}
|
||||
if (substitutionIsIdentical) {
|
||||
return Empty
|
||||
}
|
||||
}
|
||||
return ConeSubstitutorByMap(substitution, useSiteSession)
|
||||
}
|
||||
}
|
||||
|
||||
private val hashCode by lazy(LazyThreadSafetyMode.PUBLICATION) {
|
||||
substitution.hashCode()
|
||||
|
||||
@@ -79,7 +79,7 @@ class FirLocalScope private constructor(
|
||||
val klass = classes[name]
|
||||
if (klass != null) {
|
||||
val substitution = klass.typeParameterSymbols.associateWith { it.toConeType() }
|
||||
processor(klass, ConeSubstitutorByMap(substitution, useSiteSession))
|
||||
processor(klass, ConeSubstitutorByMap.create(substitution, useSiteSession))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -37,7 +37,7 @@ abstract class FirNestedClassifierScope(val klass: FirClass, val useSiteSession:
|
||||
val substitution = klass.typeParameters.associate {
|
||||
it.symbol to it.toConeType()
|
||||
}
|
||||
ConeSubstitutorByMap(substitution, useSiteSession)
|
||||
ConeSubstitutorByMap.create(substitution, useSiteSession)
|
||||
}
|
||||
processor(matchedClass, substitutor)
|
||||
}
|
||||
|
||||
+2
-2
@@ -77,8 +77,8 @@ class FirScriptDeclarationsScope(
|
||||
) {
|
||||
val matchedClass = classIndex[name] ?: return
|
||||
val substitution = matchedClass.typeParameterSymbols.associateWith { it.toConeType() }
|
||||
processor(matchedClass, ConeSubstitutorByMap(substitution, useSiteSession))
|
||||
processor(matchedClass, ConeSubstitutorByMap.create(substitution, useSiteSession))
|
||||
}
|
||||
|
||||
override fun getClassifierNames(): Set<Name> = classIndex.keys
|
||||
}
|
||||
}
|
||||
|
||||
@@ -424,7 +424,7 @@ interface ConeInferenceContext : TypeSystemInferenceExtensionContext, ConeTypeCo
|
||||
val typeParameterErasureMap = this.extractTypeParameters()
|
||||
.map { (it as ConeTypeParameterLookupTag).typeParameterSymbol }
|
||||
.eraseToUpperBoundsAssociated(session)
|
||||
val substitutor by lazy { ConeSubstitutorByMap(typeParameterErasureMap, session) }
|
||||
val substitutor by lazy { ConeSubstitutorByMap.create(typeParameterErasureMap, session) }
|
||||
val typeWithErasedTypeParameters = if (argumentsCount() != 0) {
|
||||
replaceArgumentsDeeply {
|
||||
val type = it.getType()
|
||||
|
||||
@@ -19,7 +19,7 @@ fun createExpectActualTypeParameterSubstitutor(
|
||||
val substitution = expectActualTypeParameters.associate { (expectedParameterSymbol, actualParameterSymbol) ->
|
||||
expectedParameterSymbol to actualParameterSymbol.toLookupTag().constructType(emptyArray(), isNullable = false)
|
||||
}
|
||||
val substitutor = ConeSubstitutorByMap(
|
||||
val substitutor = ConeSubstitutorByMap.create(
|
||||
substitution,
|
||||
useSiteSession
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user