FIR: make inference context mandatory in withNullability() etc.

This commit is contained in:
Mikhail Glukhikh
2021-05-05 13:32:38 +03:00
committed by TeamCityServer
parent bb37728e4f
commit 7ee6597873
10 changed files with 59 additions and 35 deletions
@@ -9,6 +9,7 @@ import org.jetbrains.kotlin.fir.expressions.FirAnnotationCall
import org.jetbrains.kotlin.fir.expressions.classId import org.jetbrains.kotlin.fir.expressions.classId
import org.jetbrains.kotlin.fir.languageVersionSettings import org.jetbrains.kotlin.fir.languageVersionSettings
import org.jetbrains.kotlin.fir.resolve.fullyExpandedType 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.substitution.AbstractConeSubstitutor
import org.jetbrains.kotlin.fir.resolve.toSymbol import org.jetbrains.kotlin.fir.resolve.toSymbol
import org.jetbrains.kotlin.fir.typeContext import org.jetbrains.kotlin.fir.typeContext
@@ -222,6 +223,9 @@ class Fir2IrTypeConverter(
private fun approximateType(type: ConeKotlinType): ConeKotlinType { private fun approximateType(type: ConeKotlinType): ConeKotlinType {
if (type is ConeClassLikeType && type.typeArguments.isEmpty()) return type if (type is ConeClassLikeType && type.typeArguments.isEmpty()) return type
val substitutor = object : AbstractConeSubstitutor() { val substitutor = object : AbstractConeSubstitutor() {
override val typeInferenceContext: ConeInferenceContext
get() = session.inferenceComponents.ctx
override fun substituteType(type: ConeKotlinType): ConeKotlinType? { override fun substituteType(type: ConeKotlinType): ConeKotlinType? {
return if (type is ConeIntersectionType) { return if (type is ConeIntersectionType) {
type.alternativeType?.let { substituteOrSelf(it) } type.alternativeType?.let { substituteOrSelf(it) }
@@ -665,6 +665,9 @@ class CallAndReferenceGenerator(
} }
private val starProjectionApproximator = object : AbstractConeSubstitutor() { private val starProjectionApproximator = object : AbstractConeSubstitutor() {
override val typeInferenceContext: ConeInferenceContext
get() = session.inferenceComponents.ctx
override fun substituteType(type: ConeKotlinType): ConeKotlinType? { override fun substituteType(type: ConeKotlinType): ConeKotlinType? {
if (type !is ConeClassLikeType || type.typeArguments.none { it == ConeStarProjection }) return null if (type !is ConeClassLikeType || type.typeArguments.none { it == ConeStarProjection }) return null
val fir = type.lookupTag.toSymbol(session)?.fir as? FirTypeParameterRefsOwner ?: return null val fir = type.lookupTag.toSymbol(session)?.fir as? FirTypeParameterRefsOwner ?: return null
@@ -25,6 +25,7 @@ import org.jetbrains.kotlin.fir.references.impl.FirReferencePlaceholderForResolv
import org.jetbrains.kotlin.fir.resolve.bindSymbolToLookupTag import org.jetbrains.kotlin.fir.resolve.bindSymbolToLookupTag
import org.jetbrains.kotlin.fir.resolve.defaultType import org.jetbrains.kotlin.fir.resolve.defaultType
import org.jetbrains.kotlin.fir.resolve.diagnostics.ConeUnresolvedReferenceError import org.jetbrains.kotlin.fir.resolve.diagnostics.ConeUnresolvedReferenceError
import org.jetbrains.kotlin.fir.resolve.inference.inferenceComponents
import org.jetbrains.kotlin.fir.resolve.providers.getClassDeclaredPropertySymbols import org.jetbrains.kotlin.fir.resolve.providers.getClassDeclaredPropertySymbols
import org.jetbrains.kotlin.fir.resolve.symbolProvider import org.jetbrains.kotlin.fir.resolve.symbolProvider
import org.jetbrains.kotlin.fir.resolve.toSymbol import org.jetbrains.kotlin.fir.resolve.toSymbol
@@ -274,7 +275,7 @@ private fun computeRawProjection(
session: FirSession, session: FirSession,
parameter: FirTypeParameter, parameter: FirTypeParameter,
attr: TypeComponentPosition, attr: TypeComponentPosition,
erasedUpperBound: ConeKotlinType = parameter.getErasedUpperBound() erasedUpperBound: ConeKotlinType = parameter.getErasedUpperBound(session)
) = when (attr) { ) = when (attr) {
// Raw(List<T>) => (List<Any?>..List<*>) // Raw(List<T>) => (List<Any?>..List<*>)
// Raw(Enum<T>) => (Enum<Enum<*>>..Enum<out Enum<*>>) // Raw(Enum<T>) => (Enum<Enum<*>>..Enum<out Enum<*>>)
@@ -306,6 +307,7 @@ private fun computeRawProjection(
// ErasedUpperBound(T : A) = A // UpperBound(T) is a type A without arguments // ErasedUpperBound(T : A) = A // UpperBound(T) is a type A without arguments
// ErasedUpperBound(T : F) = UpperBound(F) // UB(T) is another type parameter F // ErasedUpperBound(T : F) = UpperBound(F) // UB(T) is another type parameter F
private fun FirTypeParameter.getErasedUpperBound( private fun FirTypeParameter.getErasedUpperBound(
session: FirSession,
// Calculation of `potentiallyRecursiveTypeParameter.upperBounds` may recursively depend on `this.getErasedUpperBound` // Calculation of `potentiallyRecursiveTypeParameter.upperBounds` may recursively depend on `this.getErasedUpperBound`
// E.g. `class A<T extends A, F extends A>` // E.g. `class A<T extends A, F extends A>`
// To prevent recursive calls return defaultValue() instead // To prevent recursive calls return defaultValue() instead
@@ -318,10 +320,11 @@ private fun FirTypeParameter.getErasedUpperBound(
val firstUpperBound = this.bounds.first().coneType val firstUpperBound = this.bounds.first().coneType
return getErasedVersionOfFirstUpperBound(firstUpperBound, mutableSetOf(this, potentiallyRecursiveTypeParameter), defaultValue) return getErasedVersionOfFirstUpperBound(session, firstUpperBound, mutableSetOf(this, potentiallyRecursiveTypeParameter), defaultValue)
} }
private fun getErasedVersionOfFirstUpperBound( private fun getErasedVersionOfFirstUpperBound(
session: FirSession,
firstUpperBound: ConeKotlinType, firstUpperBound: ConeKotlinType,
alreadyVisitedParameters: MutableSet<FirTypeParameter?>, alreadyVisitedParameters: MutableSet<FirTypeParameter?>,
defaultValue: () -> ConeKotlinType defaultValue: () -> ConeKotlinType
@@ -332,18 +335,18 @@ private fun getErasedVersionOfFirstUpperBound(
is ConeFlexibleType -> { is ConeFlexibleType -> {
val lowerBound = val lowerBound =
getErasedVersionOfFirstUpperBound(firstUpperBound.lowerBound, alreadyVisitedParameters, defaultValue) getErasedVersionOfFirstUpperBound(session, firstUpperBound.lowerBound, alreadyVisitedParameters, defaultValue)
.lowerBoundIfFlexible() .lowerBoundIfFlexible()
if (firstUpperBound.upperBound is ConeTypeParameterType) { if (firstUpperBound.upperBound is ConeTypeParameterType) {
// Avoid exponential complexity // Avoid exponential complexity
ConeFlexibleType( ConeFlexibleType(
lowerBound, lowerBound,
lowerBound.withNullability(ConeNullability.NULLABLE) lowerBound.withNullability(ConeNullability.NULLABLE, session.inferenceComponents.ctx)
) )
} else { } else {
ConeFlexibleType( ConeFlexibleType(
lowerBound, lowerBound,
getErasedVersionOfFirstUpperBound(firstUpperBound.upperBound, alreadyVisitedParameters, defaultValue) getErasedVersionOfFirstUpperBound(session, firstUpperBound.upperBound, alreadyVisitedParameters, defaultValue)
) )
} }
} }
@@ -352,7 +355,7 @@ private fun getErasedVersionOfFirstUpperBound(
if (alreadyVisitedParameters.add(current)) { if (alreadyVisitedParameters.add(current)) {
val nextUpperBound = current.bounds.first().coneType val nextUpperBound = current.bounds.first().coneType
getErasedVersionOfFirstUpperBound(nextUpperBound, alreadyVisitedParameters, defaultValue) getErasedVersionOfFirstUpperBound(session, nextUpperBound, alreadyVisitedParameters, defaultValue)
} else { } else {
defaultValue() defaultValue()
} }
@@ -433,7 +436,7 @@ private fun FirRegularClass.createRawArguments(
defaultArgs: List<ConeStarProjection>, defaultArgs: List<ConeStarProjection>,
position: TypeComponentPosition position: TypeComponentPosition
): List<ConeTypeProjection> = typeParameters.filterIsInstance<FirTypeParameter>().map { typeParameter -> ): List<ConeTypeProjection> = typeParameters.filterIsInstance<FirTypeParameter>().map { typeParameter ->
val erasedUpperBound = typeParameter.getErasedUpperBound { val erasedUpperBound = typeParameter.getErasedUpperBound(session) {
defaultType().withArguments(defaultArgs.toTypedArray()) defaultType().withArguments(defaultArgs.toTypedArray())
} }
computeRawProjection(session, typeParameter, position, erasedUpperBound) computeRawProjection(session, typeParameter, position, erasedUpperBound)
@@ -299,7 +299,9 @@ fun FirCheckedSafeCallSubject.propagateTypeFromOriginalReceiver(nullableReceiver
val expandedReceiverType = if (receiverType is ConeClassLikeType) receiverType.fullyExpandedType(session) else receiverType val expandedReceiverType = if (receiverType is ConeClassLikeType) receiverType.fullyExpandedType(session) else receiverType
val resolvedTypeRef = typeRef.resolvedTypeFromPrototype(expandedReceiverType.makeConeTypeDefinitelyNotNullOrNotNull()) val resolvedTypeRef = typeRef.resolvedTypeFromPrototype(
expandedReceiverType.makeConeTypeDefinitelyNotNullOrNotNull(session.inferenceComponents.ctx)
)
replaceTypeRef(resolvedTypeRef) replaceTypeRef(resolvedTypeRef)
session.lookupTracker?.recordTypeResolveAsLookup(resolvedTypeRef, source, null) session.lookupTracker?.recordTypeResolveAsLookup(resolvedTypeRef, source, null)
} }
@@ -8,6 +8,7 @@ package org.jetbrains.kotlin.fir.resolve
import org.jetbrains.kotlin.fir.FirSession import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.declarations.FirTypeAlias import org.jetbrains.kotlin.fir.declarations.FirTypeAlias
import org.jetbrains.kotlin.fir.declarations.expandedConeType import org.jetbrains.kotlin.fir.declarations.expandedConeType
import org.jetbrains.kotlin.fir.resolve.inference.inferenceComponents
import org.jetbrains.kotlin.fir.resolve.substitution.AbstractConeSubstitutor import org.jetbrains.kotlin.fir.resolve.substitution.AbstractConeSubstitutor
import org.jetbrains.kotlin.fir.symbols.impl.FirTypeAliasSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirTypeAliasSymbol
import org.jetbrains.kotlin.fir.typeContext import org.jetbrains.kotlin.fir.typeContext
@@ -62,7 +63,7 @@ fun ConeClassLikeType.directExpansionType(
val resultType = expandedConeType(typeAlias)?.applyNullabilityFrom(useSiteSession, this) ?: return null val resultType = expandedConeType(typeAlias)?.applyNullabilityFrom(useSiteSession, this) ?: return null
if (resultType.typeArguments.isEmpty()) return resultType if (resultType.typeArguments.isEmpty()) return resultType
return mapTypeAliasArguments(typeAlias, this, resultType) as? ConeClassLikeType return mapTypeAliasArguments(typeAlias, this, resultType, useSiteSession) as? ConeClassLikeType
} }
private fun ConeClassLikeType.applyNullabilityFrom( private fun ConeClassLikeType.applyNullabilityFrom(
@@ -77,6 +78,7 @@ private fun mapTypeAliasArguments(
typeAlias: FirTypeAlias, typeAlias: FirTypeAlias,
abbreviatedType: ConeClassLikeType, abbreviatedType: ConeClassLikeType,
resultingType: ConeClassLikeType, resultingType: ConeClassLikeType,
useSiteSession: FirSession,
): ConeKotlinType { ): ConeKotlinType {
if (typeAlias.typeParameters.isNotEmpty() && abbreviatedType.typeArguments.isEmpty()) { if (typeAlias.typeParameters.isNotEmpty() && abbreviatedType.typeArguments.isEmpty()) {
return resultingType.lookupTag.constructClassType(emptyArray(), resultingType.isNullable) return resultingType.lookupTag.constructClassType(emptyArray(), resultingType.isNullable)
@@ -84,6 +86,9 @@ private fun mapTypeAliasArguments(
val typeAliasMap = typeAlias.typeParameters.map { it.symbol }.zip(abbreviatedType.typeArguments).toMap() val typeAliasMap = typeAlias.typeParameters.map { it.symbol }.zip(abbreviatedType.typeArguments).toMap()
val substitutor = object : AbstractConeSubstitutor() { val substitutor = object : AbstractConeSubstitutor() {
override val typeInferenceContext: ConeInferenceContext
get() = useSiteSession.inferenceComponents.ctx
override fun substituteType(type: ConeKotlinType): ConeKotlinType? { override fun substituteType(type: ConeKotlinType): ConeKotlinType? {
return null return null
} }
@@ -16,6 +16,8 @@ import org.jetbrains.kotlin.types.model.TypeSubstitutorMarker
import org.jetbrains.kotlin.types.model.typeConstructor import org.jetbrains.kotlin.types.model.typeConstructor
abstract class AbstractConeSubstitutor : ConeSubstitutor() { abstract class AbstractConeSubstitutor : ConeSubstitutor() {
abstract val typeInferenceContext: ConeInferenceContext
private fun wrapProjection(old: ConeTypeProjection, newType: ConeKotlinType): ConeTypeProjection { private fun wrapProjection(old: ConeTypeProjection, newType: ConeKotlinType): ConeTypeProjection {
return when (old) { return when (old) {
is ConeStarProjection -> old is ConeStarProjection -> old
@@ -35,8 +37,8 @@ abstract class AbstractConeSubstitutor : ConeSubstitutor() {
fun ConeKotlinType?.updateNullabilityIfNeeded(originalType: ConeKotlinType): ConeKotlinType? { fun ConeKotlinType?.updateNullabilityIfNeeded(originalType: ConeKotlinType): ConeKotlinType? {
return when { return when {
originalType is ConeDefinitelyNotNullType -> this?.withNullability(ConeNullability.NOT_NULL) originalType is ConeDefinitelyNotNullType -> this?.withNullability(ConeNullability.NOT_NULL, typeInferenceContext)
originalType.isMarkedNullable -> this?.withNullability(ConeNullability.NULLABLE) originalType.isMarkedNullable -> this?.withNullability(ConeNullability.NULLABLE, typeInferenceContext)
else -> this else -> this
} }
} }
@@ -44,7 +46,7 @@ abstract class AbstractConeSubstitutor : ConeSubstitutor() {
override fun substituteOrNull(type: ConeKotlinType): ConeKotlinType? { override fun substituteOrNull(type: ConeKotlinType): ConeKotlinType? {
val newType = substituteType(type) val newType = substituteType(type)
if (newType != null && type is ConeDefinitelyNotNullType) { if (newType != null && type is ConeDefinitelyNotNullType) {
return newType.makeConeTypeDefinitelyNotNullOrNotNull() return newType.makeConeTypeDefinitelyNotNullOrNotNull(typeInferenceContext)
} }
return (newType ?: type.substituteRecursive()) return (newType ?: type.substituteRecursive())
} }
@@ -82,7 +84,7 @@ abstract class AbstractConeSubstitutor : ConeSubstitutor() {
} }
private fun ConeDefinitelyNotNullType.substituteOriginal(): ConeKotlinType? { private fun ConeDefinitelyNotNullType.substituteOriginal(): ConeKotlinType? {
val substituted = substituteOrNull(original)?.withNullability(ConeNullability.NOT_NULL) ?: return null val substituted = substituteOrNull(original)?.withNullability(ConeNullability.NOT_NULL, typeInferenceContext) ?: return null
return ConeDefinitelyNotNullType.create(substituted) ?: substituted return ConeDefinitelyNotNullType.create(substituted) ?: substituted
} }
@@ -157,6 +159,9 @@ data class ConeSubstitutorByMap(
val substitution: Map<FirTypeParameterSymbol, ConeKotlinType>, val substitution: Map<FirTypeParameterSymbol, ConeKotlinType>,
val useSiteSession: FirSession val useSiteSession: FirSession
) : AbstractConeSubstitutor() { ) : AbstractConeSubstitutor() {
override val typeInferenceContext: ConeInferenceContext
get() = useSiteSession.inferenceComponents.ctx
override fun substituteType(type: ConeKotlinType): ConeKotlinType? { override fun substituteType(type: ConeKotlinType): ConeKotlinType? {
if (type !is ConeTypeParameterType) return null if (type !is ConeTypeParameterType) return null
val result = substitution[type.lookupTag.symbol].updateNullabilityIfNeeded(type) ?: return null val result = substitution[type.lookupTag.symbol].updateNullabilityIfNeeded(type) ?: return null
@@ -171,8 +176,10 @@ data class ConeSubstitutorByMap(
fun createTypeSubstitutorByTypeConstructor(map: Map<TypeConstructorMarker, ConeKotlinType>, context: ConeTypeContext): ConeSubstitutor { fun createTypeSubstitutorByTypeConstructor(map: Map<TypeConstructorMarker, ConeKotlinType>, context: ConeTypeContext): ConeSubstitutor {
if (map.isEmpty()) return ConeSubstitutor.Empty if (map.isEmpty()) return ConeSubstitutor.Empty
return object : AbstractConeSubstitutor(), return object : AbstractConeSubstitutor(), TypeSubstitutorMarker {
TypeSubstitutorMarker { override val typeInferenceContext: ConeInferenceContext
get() = context.session.inferenceComponents.ctx
override fun substituteType(type: ConeKotlinType): ConeKotlinType? { override fun substituteType(type: ConeKotlinType): ConeKotlinType? {
if (type !is ConeLookupTagBasedType && type !is ConeStubType) return null if (type !is ConeLookupTagBasedType && type !is ConeStubType) return null
val new = map[type.typeConstructor(context)] ?: return null val new = map[type.typeConstructor(context)] ?: return null
@@ -228,12 +228,12 @@ interface ConeInferenceContext : TypeSystemInferenceExtensionContext, ConeTypeCo
override fun KotlinTypeMarker.makeDefinitelyNotNullOrNotNull(): KotlinTypeMarker { override fun KotlinTypeMarker.makeDefinitelyNotNullOrNotNull(): KotlinTypeMarker {
require(this is ConeKotlinType) require(this is ConeKotlinType)
return makeConeTypeDefinitelyNotNullOrNotNull() return makeConeTypeDefinitelyNotNullOrNotNull(this@ConeInferenceContext)
} }
override fun SimpleTypeMarker.makeSimpleTypeDefinitelyNotNullOrNotNull(): SimpleTypeMarker { override fun SimpleTypeMarker.makeSimpleTypeDefinitelyNotNullOrNotNull(): SimpleTypeMarker {
require(this is ConeKotlinType) require(this is ConeKotlinType)
return makeConeTypeDefinitelyNotNullOrNotNull() as SimpleTypeMarker return makeConeTypeDefinitelyNotNullOrNotNull(this@ConeInferenceContext) as SimpleTypeMarker
} }
override fun createCapturedType( override fun createCapturedType(
@@ -16,6 +16,7 @@ import org.jetbrains.kotlin.fir.expressions.FirVarargArgumentsExpression
import org.jetbrains.kotlin.fir.expressions.arguments import org.jetbrains.kotlin.fir.expressions.arguments
import org.jetbrains.kotlin.fir.resolve.correspondingSupertypesCache import org.jetbrains.kotlin.fir.resolve.correspondingSupertypesCache
import org.jetbrains.kotlin.fir.resolve.fullyExpandedType import org.jetbrains.kotlin.fir.resolve.fullyExpandedType
import org.jetbrains.kotlin.fir.resolve.inference.inferenceComponents
import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor
import org.jetbrains.kotlin.fir.resolve.substitution.substitutorByMap import org.jetbrains.kotlin.fir.resolve.substitution.substitutorByMap
import org.jetbrains.kotlin.fir.resolve.toSymbol import org.jetbrains.kotlin.fir.resolve.toSymbol
@@ -128,7 +129,7 @@ interface ConeTypeContext : TypeSystemContext, TypeSystemOptimizationContext, Ty
override fun SimpleTypeMarker.withNullability(nullable: Boolean): SimpleTypeMarker { override fun SimpleTypeMarker.withNullability(nullable: Boolean): SimpleTypeMarker {
require(this is ConeKotlinType) require(this is ConeKotlinType)
return withNullability(ConeNullability.create(nullable), this as? ConeInferenceContext) return withNullability(ConeNullability.create(nullable), session.inferenceComponents.ctx)
} }
override fun SimpleTypeMarker.typeConstructor(): TypeConstructorMarker { override fun SimpleTypeMarker.typeConstructor(): TypeConstructorMarker {
@@ -56,11 +56,11 @@ fun ConeDefinitelyNotNullType.Companion.create(original: ConeKotlinType): ConeDe
} }
} }
fun ConeKotlinType.makeConeTypeDefinitelyNotNullOrNotNull(): ConeKotlinType { fun ConeKotlinType.makeConeTypeDefinitelyNotNullOrNotNull(typeContext: ConeInferenceContext): ConeKotlinType {
if (this is ConeIntersectionType) { if (this is ConeIntersectionType) {
return ConeIntersectionType(intersectedTypes.map { it.makeConeTypeDefinitelyNotNullOrNotNull() }) return ConeIntersectionType(intersectedTypes.map { it.makeConeTypeDefinitelyNotNullOrNotNull(typeContext) })
} }
return ConeDefinitelyNotNullType.create(this) ?: this.withNullability(ConeNullability.NOT_NULL) return ConeDefinitelyNotNullType.create(this) ?: this.withNullability(ConeNullability.NOT_NULL, typeContext)
} }
fun <T : ConeKotlinType> T.withArguments(arguments: Array<out ConeTypeProjection>): T { fun <T : ConeKotlinType> T.withArguments(arguments: Array<out ConeTypeProjection>): T {
@@ -95,7 +95,7 @@ fun <T : ConeKotlinType> T.withAttributes(attributes: ConeAttributes): T {
fun <T : ConeKotlinType> T.withNullability( fun <T : ConeKotlinType> T.withNullability(
nullability: ConeNullability, nullability: ConeNullability,
typeContext: ConeInferenceContext? = null, typeContext: ConeInferenceContext,
attributes: ConeAttributes = this.attributes, attributes: ConeAttributes = this.attributes,
): T { ): T {
if (this.nullability == nullability && this.attributes == attributes) { if (this.nullability == nullability && this.attributes == attributes) {
@@ -123,7 +123,7 @@ fun <T : ConeKotlinType> T.withNullability(
is ConeCapturedType -> ConeCapturedType(captureStatus, lowerType, nullability, constructor, attributes) is ConeCapturedType -> ConeCapturedType(captureStatus, lowerType, nullability, constructor, attributes)
is ConeIntersectionType -> when (nullability) { is ConeIntersectionType -> when (nullability) {
ConeNullability.NULLABLE -> this.mapTypes { ConeNullability.NULLABLE -> this.mapTypes {
it.withNullability(nullability) it.withNullability(nullability, typeContext)
} }
ConeNullability.UNKNOWN -> this // TODO: is that correct? ConeNullability.UNKNOWN -> this // TODO: is that correct?
ConeNullability.NOT_NULL -> this ConeNullability.NOT_NULL -> this
@@ -140,7 +140,7 @@ fun <T : ConeKotlinType> T.withNullability(
} }
fun coneFlexibleOrSimpleType( fun coneFlexibleOrSimpleType(
typeContext: ConeInferenceContext?, typeContext: ConeInferenceContext,
lowerBound: ConeKotlinType, lowerBound: ConeKotlinType,
upperBound: ConeKotlinType, upperBound: ConeKotlinType,
): ConeKotlinType { ): ConeKotlinType {
@@ -151,15 +151,8 @@ fun coneFlexibleOrSimpleType(
return coneFlexibleOrSimpleType(typeContext, lowerBound, upperBound.upperBound) return coneFlexibleOrSimpleType(typeContext, lowerBound, upperBound.upperBound)
} }
return when { return when {
typeContext != null && AbstractStrictEqualityTypeChecker.strictEqualTypes(typeContext, lowerBound, upperBound) -> { AbstractStrictEqualityTypeChecker.strictEqualTypes(typeContext, lowerBound, upperBound) -> lowerBound
lowerBound else -> ConeFlexibleType(lowerBound, upperBound)
}
typeContext == null && lowerBound == upperBound -> {
lowerBound
}
else -> {
ConeFlexibleType(lowerBound, upperBound)
}
} }
} }
@@ -22,6 +22,7 @@ import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.backend.jvm.jvmTypeMapper import org.jetbrains.kotlin.fir.backend.jvm.jvmTypeMapper
import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.isPrimitiveType import org.jetbrains.kotlin.fir.isPrimitiveType
import org.jetbrains.kotlin.fir.resolve.inference.inferenceComponents
import org.jetbrains.kotlin.fir.resolve.substitution.AbstractConeSubstitutor import org.jetbrains.kotlin.fir.resolve.substitution.AbstractConeSubstitutor
import org.jetbrains.kotlin.fir.resolve.toSymbol import org.jetbrains.kotlin.fir.resolve.toSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirClassSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirClassSymbol
@@ -76,8 +77,13 @@ internal fun KtNamedClassOrObjectSymbol.typeForClassSymbol(psiElement: PsiElemen
return types.coneType.asPsiType(session, firRef.resolveState, TypeMappingMode.DEFAULT, psiElement) return types.coneType.asPsiType(session, firRef.resolveState, TypeMappingMode.DEFAULT, psiElement)
} }
private class AnonymousTypesSubstitutor(private val session: FirSession, private val state: FirModuleResolveState) : private class AnonymousTypesSubstitutor(
AbstractConeSubstitutor() { private val session: FirSession,
private val state: FirModuleResolveState
) : AbstractConeSubstitutor() {
override val typeInferenceContext: ConeInferenceContext
get() = session.inferenceComponents.ctx
override fun substituteType(type: ConeKotlinType): ConeKotlinType? { override fun substituteType(type: ConeKotlinType): ConeKotlinType? {
if (type !is ConeClassLikeType) return null if (type !is ConeClassLikeType) return null