FIR: Refine makesSenseToBeDefinitelyNotNull
Make it work just the same as the analogue from FE 1.0 This change is necessary since many tests start failing after we began reporting diagnostics after call completion
This commit is contained in:
committed by
teamcityserver
parent
a700fdc312
commit
42d387925d
@@ -34,12 +34,8 @@ import org.jetbrains.kotlin.fir.types.*
|
||||
import org.jetbrains.kotlin.fir.types.builder.buildErrorTypeRef
|
||||
import org.jetbrains.kotlin.fir.types.builder.buildResolvedTypeRef
|
||||
import org.jetbrains.kotlin.fir.types.impl.ConeClassLikeTypeImpl
|
||||
import org.jetbrains.kotlin.name.CallableId
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.resolve.ForbiddenNamedArgumentsTarget
|
||||
import org.jetbrains.kotlin.name.*
|
||||
import org.jetbrains.kotlin.resolve.ForbiddenNamedArgumentsTarget
|
||||
|
||||
fun List<FirQualifierPart>.toTypeProjections(): Array<ConeTypeProjection> =
|
||||
asReversed().flatMap { it.typeArgumentList.typeArguments.map { typeArgument -> typeArgument.toConeTypeProjection() } }.toTypedArray()
|
||||
@@ -326,9 +322,8 @@ fun FirCheckedSafeCallSubject.propagateTypeFromOriginalReceiver(nullableReceiver
|
||||
|
||||
val expandedReceiverType = if (receiverType is ConeClassLikeType) receiverType.fullyExpandedType(session) else receiverType
|
||||
|
||||
val resolvedTypeRef = typeRef.resolvedTypeFromPrototype(
|
||||
expandedReceiverType.makeConeTypeDefinitelyNotNullOrNotNull(session.inferenceComponents.ctx)
|
||||
)
|
||||
val resolvedTypeRef =
|
||||
typeRef.resolvedTypeFromPrototype(expandedReceiverType.makeConeTypeDefinitelyNotNullOrNotNull(session.typeContext))
|
||||
replaceTypeRef(resolvedTypeRef)
|
||||
session.lookupTracker?.recordTypeResolveAsLookup(resolvedTypeRef, source, null)
|
||||
}
|
||||
|
||||
@@ -8,7 +8,6 @@ package org.jetbrains.kotlin.fir.resolve
|
||||
import org.jetbrains.kotlin.fir.FirSession
|
||||
import org.jetbrains.kotlin.fir.declarations.FirTypeAlias
|
||||
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.symbols.impl.FirTypeAliasSymbol
|
||||
import org.jetbrains.kotlin.fir.typeContext
|
||||
@@ -85,10 +84,7 @@ private fun mapTypeAliasArguments(
|
||||
}
|
||||
val typeAliasMap = typeAlias.typeParameters.map { it.symbol }.zip(abbreviatedType.typeArguments).toMap()
|
||||
|
||||
val substitutor = object : AbstractConeSubstitutor() {
|
||||
override val typeInferenceContext: ConeInferenceContext
|
||||
get() = useSiteSession.inferenceComponents.ctx
|
||||
|
||||
val substitutor = object : AbstractConeSubstitutor(useSiteSession.typeContext) {
|
||||
override fun substituteType(type: ConeKotlinType): ConeKotlinType? {
|
||||
return null
|
||||
}
|
||||
|
||||
@@ -600,7 +600,7 @@ internal fun captureFromTypeParameterUpperBoundIfNeeded(
|
||||
|
||||
val capturedType = context.captureFromExpression(chosenSupertype) as ConeKotlinType? ?: return argumentType
|
||||
return if (argumentType is ConeDefinitelyNotNullType) {
|
||||
ConeDefinitelyNotNullType.create(capturedType) ?: capturedType
|
||||
ConeDefinitelyNotNullType.create(capturedType, session.typeContext) ?: capturedType
|
||||
} else {
|
||||
capturedType
|
||||
}
|
||||
|
||||
+9
-16
@@ -8,6 +8,7 @@ package org.jetbrains.kotlin.fir.resolve.substitution
|
||||
import org.jetbrains.kotlin.fir.FirSession
|
||||
import org.jetbrains.kotlin.fir.resolve.inference.inferenceComponents
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirTypeParameterSymbol
|
||||
import org.jetbrains.kotlin.fir.typeContext
|
||||
import org.jetbrains.kotlin.fir.types.*
|
||||
import org.jetbrains.kotlin.fir.types.impl.ConeClassLikeTypeImpl
|
||||
import org.jetbrains.kotlin.types.TypeApproximatorConfiguration
|
||||
@@ -15,9 +16,7 @@ import org.jetbrains.kotlin.types.model.TypeConstructorMarker
|
||||
import org.jetbrains.kotlin.types.model.TypeSubstitutorMarker
|
||||
import org.jetbrains.kotlin.types.model.typeConstructor
|
||||
|
||||
abstract class AbstractConeSubstitutor : ConeSubstitutor() {
|
||||
abstract val typeInferenceContext: ConeInferenceContext
|
||||
|
||||
abstract class AbstractConeSubstitutor(private val typeContext: ConeTypeContext) : ConeSubstitutor() {
|
||||
private fun wrapProjection(old: ConeTypeProjection, newType: ConeKotlinType): ConeTypeProjection {
|
||||
return when (old) {
|
||||
is ConeStarProjection -> old
|
||||
@@ -37,8 +36,8 @@ abstract class AbstractConeSubstitutor : ConeSubstitutor() {
|
||||
|
||||
fun ConeKotlinType?.updateNullabilityIfNeeded(originalType: ConeKotlinType): ConeKotlinType? {
|
||||
return when {
|
||||
originalType is ConeDefinitelyNotNullType -> this?.withNullability(ConeNullability.NOT_NULL, typeInferenceContext)
|
||||
originalType.isMarkedNullable -> this?.withNullability(ConeNullability.NULLABLE, typeInferenceContext)
|
||||
originalType is ConeDefinitelyNotNullType -> this?.withNullability(ConeNullability.NOT_NULL, typeContext)
|
||||
originalType.isMarkedNullable -> this?.withNullability(ConeNullability.NULLABLE, typeContext)
|
||||
else -> this
|
||||
}
|
||||
}
|
||||
@@ -46,7 +45,7 @@ abstract class AbstractConeSubstitutor : ConeSubstitutor() {
|
||||
override fun substituteOrNull(type: ConeKotlinType): ConeKotlinType? {
|
||||
val newType = substituteType(type)
|
||||
if (newType != null && type is ConeDefinitelyNotNullType) {
|
||||
return newType.makeConeTypeDefinitelyNotNullOrNotNull(typeInferenceContext)
|
||||
return newType.makeConeTypeDefinitelyNotNullOrNotNull(typeContext)
|
||||
}
|
||||
return (newType ?: type.substituteRecursive())
|
||||
}
|
||||
@@ -84,8 +83,8 @@ abstract class AbstractConeSubstitutor : ConeSubstitutor() {
|
||||
}
|
||||
|
||||
private fun ConeDefinitelyNotNullType.substituteOriginal(): ConeKotlinType? {
|
||||
val substituted = substituteOrNull(original)?.withNullability(ConeNullability.NOT_NULL, typeInferenceContext) ?: return null
|
||||
return ConeDefinitelyNotNullType.create(substituted) ?: substituted
|
||||
val substituted = substituteOrNull(original)?.withNullability(ConeNullability.NOT_NULL, typeContext) ?: return null
|
||||
return ConeDefinitelyNotNullType.create(substituted, typeContext) ?: substituted
|
||||
}
|
||||
|
||||
private fun ConeFlexibleType.substituteBounds(): ConeFlexibleType? {
|
||||
@@ -158,10 +157,7 @@ fun ConeSubstitutor.chain(other: ConeSubstitutor): ConeSubstitutor {
|
||||
data class ConeSubstitutorByMap(
|
||||
val substitution: Map<FirTypeParameterSymbol, ConeKotlinType>,
|
||||
val useSiteSession: FirSession
|
||||
) : AbstractConeSubstitutor() {
|
||||
override val typeInferenceContext: ConeInferenceContext
|
||||
get() = useSiteSession.inferenceComponents.ctx
|
||||
|
||||
) : AbstractConeSubstitutor(useSiteSession.typeContext) {
|
||||
override fun substituteType(type: ConeKotlinType): ConeKotlinType? {
|
||||
if (type !is ConeTypeParameterType) return null
|
||||
val result = substitution[type.lookupTag.symbol].updateNullabilityIfNeeded(type) ?: return null
|
||||
@@ -176,10 +172,7 @@ data class ConeSubstitutorByMap(
|
||||
|
||||
fun createTypeSubstitutorByTypeConstructor(map: Map<TypeConstructorMarker, ConeKotlinType>, context: ConeTypeContext): ConeSubstitutor {
|
||||
if (map.isEmpty()) return ConeSubstitutor.Empty
|
||||
return object : AbstractConeSubstitutor(), TypeSubstitutorMarker {
|
||||
override val typeInferenceContext: ConeInferenceContext
|
||||
get() = context.session.inferenceComponents.ctx
|
||||
|
||||
return object : AbstractConeSubstitutor(context), TypeSubstitutorMarker {
|
||||
override fun substituteType(type: ConeKotlinType): ConeKotlinType? {
|
||||
if (type !is ConeLookupTagBasedType && type !is ConeStubType) return null
|
||||
val new = map[type.typeConstructor(context)] ?: return null
|
||||
|
||||
+2
-1
@@ -298,7 +298,8 @@ class FirSyntheticCallGenerator(
|
||||
|
||||
val returnType = rightArgumentType.resolvedTypeFromPrototype(
|
||||
rightArgumentType.type.withAttributes(
|
||||
ConeAttributes.create(listOf(CompilerConeAttributes.Exact))
|
||||
ConeAttributes.create(listOf(CompilerConeAttributes.Exact)),
|
||||
session.typeContext,
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
+3
-1
@@ -517,6 +517,7 @@ open class FirDeclarationsResolveTransformer(transformer: FirBodyResolveTransfor
|
||||
returnExpression.resultType.approximatedIfNeededOrSelf(
|
||||
inferenceComponents.approximator,
|
||||
simpleFunction?.visibilityForApproximation(),
|
||||
transformer.session.typeContext,
|
||||
simpleFunction?.isInline == true
|
||||
)
|
||||
)
|
||||
@@ -843,7 +844,8 @@ open class FirDeclarationsResolveTransformer(transformer: FirBodyResolveTransfor
|
||||
withExpectedType(
|
||||
expectedType.approximatedIfNeededOrSelf(
|
||||
inferenceComponents.approximator,
|
||||
variable.visibilityForApproximation()
|
||||
variable.visibilityForApproximation(),
|
||||
inferenceComponents.session.typeContext,
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
@@ -17,9 +17,9 @@ import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor
|
||||
import org.jetbrains.kotlin.fir.resolve.substitution.createTypeSubstitutorByTypeConstructor
|
||||
import org.jetbrains.kotlin.fir.symbols.ConeClassLikeLookupTag
|
||||
import org.jetbrains.kotlin.fir.symbols.ConeTypeParameterLookupTag
|
||||
import org.jetbrains.kotlin.name.StandardClassIds
|
||||
import org.jetbrains.kotlin.fir.types.impl.ConeClassLikeTypeImpl
|
||||
import org.jetbrains.kotlin.fir.types.impl.ConeTypeParameterTypeImpl
|
||||
import org.jetbrains.kotlin.name.StandardClassIds
|
||||
import org.jetbrains.kotlin.types.AbstractTypeChecker
|
||||
import org.jetbrains.kotlin.types.model.*
|
||||
import org.jetbrains.kotlin.utils.DFS
|
||||
@@ -258,12 +258,12 @@ interface ConeInferenceContext : TypeSystemInferenceExtensionContext, ConeTypeCo
|
||||
|
||||
override fun KotlinTypeMarker.removeAnnotations(): KotlinTypeMarker {
|
||||
require(this is ConeKotlinType)
|
||||
return withAttributes(ConeAttributes.Empty)
|
||||
return withAttributes(ConeAttributes.Empty, this@ConeInferenceContext)
|
||||
}
|
||||
|
||||
override fun SimpleTypeMarker.replaceArguments(newArguments: List<TypeArgumentMarker>): SimpleTypeMarker {
|
||||
require(this is ConeKotlinType)
|
||||
return this.withArguments(newArguments.cast<List<ConeTypeProjection>>().toTypedArray())
|
||||
return this.withArguments(newArguments.cast<List<ConeTypeProjection>>().toTypedArray(), this@ConeInferenceContext)
|
||||
}
|
||||
|
||||
override fun KotlinTypeMarker.hasExactAnnotation(): Boolean {
|
||||
@@ -364,7 +364,7 @@ interface ConeInferenceContext : TypeSystemInferenceExtensionContext, ConeTypeCo
|
||||
|
||||
override fun KotlinTypeMarker.removeExactAnnotation(): KotlinTypeMarker {
|
||||
require(this is ConeKotlinType)
|
||||
return withAttributes(attributes.remove(CompilerConeAttributes.Exact))
|
||||
return withAttributes(attributes.remove(CompilerConeAttributes.Exact), this@ConeInferenceContext)
|
||||
}
|
||||
|
||||
override fun TypeConstructorMarker.toErrorType(): SimpleTypeMarker {
|
||||
|
||||
@@ -415,7 +415,7 @@ interface ConeTypeContext : TypeSystemContext, TypeSystemOptimizationContext, Ty
|
||||
}
|
||||
|
||||
private fun FirTypeParameterSymbol.allBoundsAreNullable(): Boolean {
|
||||
return fir.bounds.all { it.coneType.isMarkedNullable }
|
||||
return fir.bounds.all { it.coneType.isNullableType() }
|
||||
}
|
||||
|
||||
private fun TypeConstructorMarker.toFirRegularClass(): FirRegularClass? {
|
||||
|
||||
@@ -47,23 +47,32 @@ fun ConeInferenceContext.intersectTypesOrNull(types: List<ConeKotlinType>): Cone
|
||||
fun TypeCheckerProviderContext.equalTypes(a: ConeKotlinType, b: ConeKotlinType): Boolean =
|
||||
AbstractTypeChecker.equalTypes(this, a, b)
|
||||
|
||||
fun ConeDefinitelyNotNullType.Companion.create(original: ConeKotlinType): ConeDefinitelyNotNullType? {
|
||||
fun ConeDefinitelyNotNullType.Companion.create(
|
||||
original: ConeKotlinType,
|
||||
typeContext: ConeTypeContext,
|
||||
useCorrectedNullabilityForFlexibleTypeParameters: Boolean = false,
|
||||
): ConeDefinitelyNotNullType? {
|
||||
return when {
|
||||
original is ConeDefinitelyNotNullType -> original
|
||||
makesSenseToBeDefinitelyNotNull(original) ->
|
||||
ConeDefinitelyNotNullType(original.lowerBoundIfFlexible())
|
||||
typeContext
|
||||
.newBaseTypeCheckerContext(errorTypesEqualToAnything = false, stubTypesEqualToAnything = false)
|
||||
.makesSenseToBeDefinitelyNotNull(original, useCorrectedNullabilityForFlexibleTypeParameters) ->
|
||||
|
||||
ConeDefinitelyNotNullType(
|
||||
original.lowerBoundIfFlexible()
|
||||
)
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
|
||||
fun ConeKotlinType.makeConeTypeDefinitelyNotNullOrNotNull(typeContext: ConeInferenceContext): ConeKotlinType {
|
||||
fun ConeKotlinType.makeConeTypeDefinitelyNotNullOrNotNull(typeContext: ConeTypeContext): ConeKotlinType {
|
||||
if (this is ConeIntersectionType) {
|
||||
return ConeIntersectionType(intersectedTypes.map { it.makeConeTypeDefinitelyNotNullOrNotNull(typeContext) })
|
||||
}
|
||||
return ConeDefinitelyNotNullType.create(this) ?: this.withNullability(ConeNullability.NOT_NULL, typeContext)
|
||||
return ConeDefinitelyNotNullType.create(this, typeContext) ?: 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>, typeSystemContext: ConeTypeContext): T {
|
||||
if (this.typeArguments === arguments) {
|
||||
return this
|
||||
}
|
||||
@@ -72,12 +81,15 @@ fun <T : ConeKotlinType> T.withArguments(arguments: Array<out ConeTypeProjection
|
||||
return when (this) {
|
||||
is ConeClassErrorType -> this
|
||||
is ConeClassLikeTypeImpl -> ConeClassLikeTypeImpl(lookupTag, arguments, nullability.isNullable) as T
|
||||
is ConeDefinitelyNotNullType -> ConeDefinitelyNotNullType.create(original.withArguments(arguments))!! as T
|
||||
is ConeDefinitelyNotNullType -> ConeDefinitelyNotNullType.create(
|
||||
original.withArguments(arguments, typeSystemContext),
|
||||
typeSystemContext
|
||||
)!! as T
|
||||
else -> error("Not supported: $this: ${this.render()}")
|
||||
}
|
||||
}
|
||||
|
||||
fun <T : ConeKotlinType> T.withAttributes(attributes: ConeAttributes): T {
|
||||
fun <T : ConeKotlinType> T.withAttributes(attributes: ConeAttributes, typeSystemContext: ConeTypeContext): T {
|
||||
if (this.attributes == attributes) {
|
||||
return this
|
||||
}
|
||||
@@ -86,16 +98,22 @@ fun <T : ConeKotlinType> T.withAttributes(attributes: ConeAttributes): T {
|
||||
return when (this) {
|
||||
is ConeClassErrorType -> this
|
||||
is ConeClassLikeTypeImpl -> ConeClassLikeTypeImpl(lookupTag, typeArguments, nullability.isNullable, attributes)
|
||||
is ConeDefinitelyNotNullType -> ConeDefinitelyNotNullType.create(original.withAttributes(attributes))!!
|
||||
is ConeDefinitelyNotNullType -> ConeDefinitelyNotNullType.create(
|
||||
original.withAttributes(attributes, typeSystemContext),
|
||||
typeSystemContext
|
||||
)!!
|
||||
is ConeTypeParameterTypeImpl -> ConeTypeParameterTypeImpl(lookupTag, nullability.isNullable, attributes)
|
||||
is ConeFlexibleType -> ConeFlexibleType(lowerBound.withAttributes(attributes), upperBound.withAttributes(attributes))
|
||||
is ConeFlexibleType -> ConeFlexibleType(
|
||||
lowerBound.withAttributes(attributes, typeSystemContext),
|
||||
upperBound.withAttributes(attributes, typeSystemContext)
|
||||
)
|
||||
else -> error("Not supported: $this: ${this.render()}")
|
||||
} as T
|
||||
}
|
||||
|
||||
fun <T : ConeKotlinType> T.withNullability(
|
||||
nullability: ConeNullability,
|
||||
typeContext: ConeInferenceContext,
|
||||
typeContext: ConeTypeContext,
|
||||
attributes: ConeAttributes = this.attributes,
|
||||
): T {
|
||||
if (this.nullability == nullability && this.attributes == attributes) {
|
||||
@@ -140,7 +158,7 @@ fun <T : ConeKotlinType> T.withNullability(
|
||||
}
|
||||
|
||||
fun coneFlexibleOrSimpleType(
|
||||
typeContext: ConeInferenceContext,
|
||||
typeContext: ConeTypeContext,
|
||||
lowerBound: ConeKotlinType,
|
||||
upperBound: ConeKotlinType,
|
||||
): ConeKotlinType {
|
||||
@@ -197,7 +215,7 @@ fun FirTypeRef.isUnsafeVarianceType(session: FirSession): Boolean {
|
||||
fun FirTypeRef.hasEnhancedNullability(): Boolean =
|
||||
coneTypeSafe<ConeKotlinType>()?.hasEnhancedNullability == true
|
||||
|
||||
fun FirTypeRef.withoutEnhancedNullability(): FirTypeRef {
|
||||
fun FirTypeRef.withoutEnhancedNullability(typeSystemContext: ConeTypeContext): FirTypeRef {
|
||||
require(this is FirResolvedTypeRef)
|
||||
if (!hasEnhancedNullability()) return this
|
||||
return buildResolvedTypeRef {
|
||||
@@ -205,7 +223,8 @@ fun FirTypeRef.withoutEnhancedNullability(): FirTypeRef {
|
||||
type = this@withoutEnhancedNullability.type.withAttributes(
|
||||
ConeAttributes.create(
|
||||
this@withoutEnhancedNullability.type.attributes.filter { it != CompilerConeAttributes.EnhancedNullability }
|
||||
)
|
||||
),
|
||||
typeSystemContext,
|
||||
)
|
||||
annotations += this@withoutEnhancedNullability.annotations
|
||||
}
|
||||
@@ -263,13 +282,14 @@ fun FirTypeRef.approximated(
|
||||
fun FirTypeRef.approximatedIfNeededOrSelf(
|
||||
approximator: ConeTypeApproximator,
|
||||
containingCallableVisibility: Visibility?,
|
||||
isInlineFunction: Boolean = false
|
||||
typeSystemContext: ConeTypeContext,
|
||||
isInlineFunction: Boolean = false,
|
||||
): FirTypeRef {
|
||||
val approximated = if (containingCallableVisibility == Visibilities.Public || containingCallableVisibility == Visibilities.Protected)
|
||||
approximatedForPublicPosition(approximator)
|
||||
else
|
||||
this
|
||||
return approximated.hideLocalTypeIfNeeded(containingCallableVisibility, isInlineFunction).withoutEnhancedNullability()
|
||||
return approximated.hideLocalTypeIfNeeded(containingCallableVisibility, isInlineFunction).withoutEnhancedNullability(typeSystemContext)
|
||||
}
|
||||
|
||||
fun FirTypeRef.approximatedForPublicPosition(approximator: ConeTypeApproximator): FirTypeRef =
|
||||
@@ -334,11 +354,11 @@ fun ConeTypeContext.captureFromArgumentsInternal(type: ConeKotlinType, status: C
|
||||
val capturedArguments = captureArguments(type, status) ?: return null
|
||||
return if (type is ConeFlexibleType) {
|
||||
ConeFlexibleType(
|
||||
type.lowerBound.withArguments(capturedArguments),
|
||||
type.upperBound.withArguments(capturedArguments),
|
||||
type.lowerBound.withArguments(capturedArguments, this),
|
||||
type.upperBound.withArguments(capturedArguments, this),
|
||||
)
|
||||
} else {
|
||||
type.withArguments(capturedArguments)
|
||||
type.withArguments(capturedArguments, this)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -418,12 +438,12 @@ fun ConeTypeContext.captureFromExpressionInternal(type: ConeKotlinType): ConeKot
|
||||
typeToReplace.intersectedTypes.map { componentType ->
|
||||
val capturedArguments = findCorrespondingCapturedArgumentsForType(componentType)
|
||||
?: return@map componentType
|
||||
componentType.withArguments(capturedArguments)
|
||||
componentType.withArguments(capturedArguments, this)
|
||||
}
|
||||
} else {
|
||||
val capturedArguments = findCorrespondingCapturedArgumentsForType(typeToReplace)
|
||||
?: return listOf(typeToReplace)
|
||||
listOf(typeToReplace.withArguments(capturedArguments))
|
||||
listOf(typeToReplace.withArguments(capturedArguments, this))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user