FIR: use withNullability with type context whenever possible
It could simplify flexible type cases.
This commit is contained in:
committed by
TeamCityServer
parent
f94ed1a00c
commit
bb37728e4f
@@ -676,7 +676,7 @@ class HtmlFirDump internal constructor(private var linkResolver: FirLinkResolver
|
|||||||
AbstractStrictEqualityTypeChecker.strictEqualTypes(
|
AbstractStrictEqualityTypeChecker.strictEqualTypes(
|
||||||
session.typeContext,
|
session.typeContext,
|
||||||
flexibleType.lowerBound,
|
flexibleType.lowerBound,
|
||||||
flexibleType.upperBound.withNullability(ConeNullability.NOT_NULL)
|
flexibleType.upperBound.withNullability(ConeNullability.NOT_NULL, session.typeContext)
|
||||||
)
|
)
|
||||||
) {
|
) {
|
||||||
generate(flexibleType.lowerBound)
|
generate(flexibleType.lowerBound)
|
||||||
|
|||||||
@@ -582,7 +582,7 @@ class Fir2IrVisitor(
|
|||||||
IrGetValueImpl(startOffset, endOffset, irLhsVariable.type, irLhsVariable.symbol)
|
IrGetValueImpl(startOffset, endOffset, irLhsVariable.type, irLhsVariable.symbol)
|
||||||
|
|
||||||
val originalType = firLhsVariable.returnTypeRef.coneType
|
val originalType = firLhsVariable.returnTypeRef.coneType
|
||||||
val notNullType = originalType.withNullability(ConeNullability.NOT_NULL)
|
val notNullType = originalType.withNullability(ConeNullability.NOT_NULL, session.typeContext)
|
||||||
val irBranches = listOf(
|
val irBranches = listOf(
|
||||||
IrBranchImpl(
|
IrBranchImpl(
|
||||||
startOffset, endOffset, primitiveOp2(
|
startOffset, endOffset, primitiveOp2(
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ 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.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.types.*
|
import org.jetbrains.kotlin.fir.types.*
|
||||||
import org.jetbrains.kotlin.fir.types.impl.ConeClassLikeTypeImpl
|
import org.jetbrains.kotlin.fir.types.impl.ConeClassLikeTypeImpl
|
||||||
import org.jetbrains.kotlin.fir.utils.WeakPair
|
import org.jetbrains.kotlin.fir.utils.WeakPair
|
||||||
@@ -58,14 +59,17 @@ fun ConeClassLikeType.directExpansionType(
|
|||||||
val typeAliasSymbol = lookupTag.toSymbol(useSiteSession) as? FirTypeAliasSymbol ?: return null
|
val typeAliasSymbol = lookupTag.toSymbol(useSiteSession) as? FirTypeAliasSymbol ?: return null
|
||||||
val typeAlias = typeAliasSymbol.fir
|
val typeAlias = typeAliasSymbol.fir
|
||||||
|
|
||||||
val resultType = expandedConeType(typeAlias)?.applyNullabilityFrom(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) as? ConeClassLikeType
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun ConeClassLikeType.applyNullabilityFrom(abbreviation: ConeClassLikeType): ConeClassLikeType {
|
private fun ConeClassLikeType.applyNullabilityFrom(
|
||||||
if (abbreviation.isMarkedNullable) return withNullability(ConeNullability.NULLABLE)
|
session: FirSession,
|
||||||
|
abbreviation: ConeClassLikeType
|
||||||
|
): ConeClassLikeType {
|
||||||
|
if (abbreviation.isMarkedNullable) return withNullability(ConeNullability.NULLABLE, session.typeContext)
|
||||||
return this
|
return this
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+6
-5
@@ -16,6 +16,7 @@ import org.jetbrains.kotlin.fir.resolve.inference.model.ConeDeclaredUpperBoundCo
|
|||||||
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.symbols.ConeTypeParameterLookupTag
|
import org.jetbrains.kotlin.fir.symbols.ConeTypeParameterLookupTag
|
||||||
|
import org.jetbrains.kotlin.fir.typeContext
|
||||||
import org.jetbrains.kotlin.name.StandardClassIds
|
import org.jetbrains.kotlin.name.StandardClassIds
|
||||||
import org.jetbrains.kotlin.fir.types.*
|
import org.jetbrains.kotlin.fir.types.*
|
||||||
import org.jetbrains.kotlin.fir.types.impl.FirTypePlaceholderProjection
|
import org.jetbrains.kotlin.fir.types.impl.FirTypePlaceholderProjection
|
||||||
@@ -68,7 +69,7 @@ internal object CreateFreshTypeVariableSubstitutorStage : ResolutionStage() {
|
|||||||
getTypePreservingFlexibilityWrtTypeVariable(
|
getTypePreservingFlexibilityWrtTypeVariable(
|
||||||
typeArgument.typeRef.coneType,
|
typeArgument.typeRef.coneType,
|
||||||
typeParameter,
|
typeParameter,
|
||||||
context.session.inferenceComponents.ctx
|
context.session
|
||||||
).fullyExpandedType(context.session),
|
).fullyExpandedType(context.session),
|
||||||
SimpleConstraintSystemConstraintPosition // TODO
|
SimpleConstraintSystemConstraintPosition // TODO
|
||||||
)
|
)
|
||||||
@@ -88,11 +89,11 @@ internal object CreateFreshTypeVariableSubstitutorStage : ResolutionStage() {
|
|||||||
private fun getTypePreservingFlexibilityWrtTypeVariable(
|
private fun getTypePreservingFlexibilityWrtTypeVariable(
|
||||||
type: ConeKotlinType,
|
type: ConeKotlinType,
|
||||||
typeParameter: FirTypeParameterRef,
|
typeParameter: FirTypeParameterRef,
|
||||||
context: ConeTypeContext
|
session: FirSession,
|
||||||
): ConeKotlinType {
|
): ConeKotlinType {
|
||||||
return if (typeParameter.shouldBeFlexible(context)) {
|
return if (typeParameter.shouldBeFlexible(session.typeContext)) {
|
||||||
val notNullType = type.withNullability(ConeNullability.NOT_NULL)
|
val notNullType = type.withNullability(ConeNullability.NOT_NULL, session.typeContext)
|
||||||
ConeFlexibleType(notNullType, notNullType.withNullability(ConeNullability.NULLABLE))
|
ConeFlexibleType(notNullType, notNullType.withNullability(ConeNullability.NULLABLE, session.typeContext))
|
||||||
} else {
|
} else {
|
||||||
type
|
type
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -91,8 +91,8 @@ class FirSyntheticPropertiesScope(
|
|||||||
// I think details here are worth designing
|
// I think details here are worth designing
|
||||||
if (!AbstractTypeChecker.isSubtypeOf(
|
if (!AbstractTypeChecker.isSubtypeOf(
|
||||||
session.typeContext,
|
session.typeContext,
|
||||||
getterReturnType.withNullability(NOT_NULL),
|
getterReturnType.withNullability(NOT_NULL, session.typeContext),
|
||||||
parameterType.withNullability(NOT_NULL)
|
parameterType.withNullability(NOT_NULL, session.typeContext)
|
||||||
)
|
)
|
||||||
) {
|
) {
|
||||||
return
|
return
|
||||||
|
|||||||
+6
-6
@@ -6,8 +6,7 @@
|
|||||||
package org.jetbrains.kotlin.fir.resolve.dfa
|
package org.jetbrains.kotlin.fir.resolve.dfa
|
||||||
|
|
||||||
import org.jetbrains.kotlin.config.LanguageFeature
|
import org.jetbrains.kotlin.config.LanguageFeature
|
||||||
import org.jetbrains.kotlin.fir.FirSession
|
import org.jetbrains.kotlin.fir.*
|
||||||
import org.jetbrains.kotlin.fir.PrivateForInline
|
|
||||||
import org.jetbrains.kotlin.fir.contracts.FirResolvedContractDescription
|
import org.jetbrains.kotlin.fir.contracts.FirResolvedContractDescription
|
||||||
import org.jetbrains.kotlin.fir.contracts.description.ConeBooleanConstantReference
|
import org.jetbrains.kotlin.fir.contracts.description.ConeBooleanConstantReference
|
||||||
import org.jetbrains.kotlin.fir.contracts.description.ConeConditionalEffectDeclaration
|
import org.jetbrains.kotlin.fir.contracts.description.ConeConditionalEffectDeclaration
|
||||||
@@ -15,7 +14,6 @@ import org.jetbrains.kotlin.fir.contracts.description.ConeConstantReference
|
|||||||
import org.jetbrains.kotlin.fir.contracts.description.ConeReturnsEffectDeclaration
|
import org.jetbrains.kotlin.fir.contracts.description.ConeReturnsEffectDeclaration
|
||||||
import org.jetbrains.kotlin.fir.declarations.*
|
import org.jetbrains.kotlin.fir.declarations.*
|
||||||
import org.jetbrains.kotlin.fir.expressions.*
|
import org.jetbrains.kotlin.fir.expressions.*
|
||||||
import org.jetbrains.kotlin.fir.languageVersionSettings
|
|
||||||
import org.jetbrains.kotlin.fir.references.FirControlFlowGraphReference
|
import org.jetbrains.kotlin.fir.references.FirControlFlowGraphReference
|
||||||
import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference
|
import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference
|
||||||
import org.jetbrains.kotlin.fir.resolve.*
|
import org.jetbrains.kotlin.fir.resolve.*
|
||||||
@@ -33,7 +31,6 @@ import org.jetbrains.kotlin.name.CallableId
|
|||||||
import org.jetbrains.kotlin.name.StandardClassIds
|
import org.jetbrains.kotlin.name.StandardClassIds
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.FirVariableSymbol
|
import org.jetbrains.kotlin.fir.symbols.impl.FirVariableSymbol
|
||||||
import org.jetbrains.kotlin.fir.types.*
|
import org.jetbrains.kotlin.fir.types.*
|
||||||
import org.jetbrains.kotlin.fir.visibilityChecker
|
|
||||||
import org.jetbrains.kotlin.fir.visitors.transformSingle
|
import org.jetbrains.kotlin.fir.visitors.transformSingle
|
||||||
import org.jetbrains.kotlin.name.FqName
|
import org.jetbrains.kotlin.name.FqName
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
@@ -777,7 +774,7 @@ abstract class FirDataFlowAnalyzer<FLOW : Flow>(
|
|||||||
|
|
||||||
safeCall.receiver.let { receiver ->
|
safeCall.receiver.let { receiver ->
|
||||||
val type = receiver.coneType.takeIf { it.isMarkedNullable }
|
val type = receiver.coneType.takeIf { it.isMarkedNullable }
|
||||||
?.withNullability(ConeNullability.NOT_NULL)
|
?.withNullability(ConeNullability.NOT_NULL, components.session.typeContext)
|
||||||
?: return@let
|
?: return@let
|
||||||
|
|
||||||
val variable = variableStorage.getOrCreateVariable(flow, receiver)
|
val variable = variableStorage.getOrCreateVariable(flow, receiver)
|
||||||
@@ -998,7 +995,10 @@ abstract class FirDataFlowAnalyzer<FLOW : Flow>(
|
|||||||
|
|
||||||
if (isAssignment) {
|
if (isAssignment) {
|
||||||
if (initializer is FirConstExpression<*> && initializer.kind == ConstantValueKind.Null) {
|
if (initializer is FirConstExpression<*> && initializer.kind == ConstantValueKind.Null) {
|
||||||
flow.addTypeStatement(propertyVariable typeEq property.returnTypeRef.coneType.withNullability(ConeNullability.NULLABLE))
|
flow.addTypeStatement(
|
||||||
|
propertyVariable typeEq
|
||||||
|
property.returnTypeRef.coneType.withNullability(ConeNullability.NULLABLE, components.session.typeContext)
|
||||||
|
)
|
||||||
} else {
|
} else {
|
||||||
flow.addTypeStatement(propertyVariable typeEq initializer.typeRef.coneType)
|
flow.addTypeStatement(propertyVariable typeEq initializer.typeRef.coneType)
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-1
@@ -17,6 +17,7 @@ import org.jetbrains.kotlin.fir.resolve.transformers.FirSyntheticCallGenerator
|
|||||||
import org.jetbrains.kotlin.fir.resolve.transformers.FirWhenExhaustivenessTransformer
|
import org.jetbrains.kotlin.fir.resolve.transformers.FirWhenExhaustivenessTransformer
|
||||||
import org.jetbrains.kotlin.fir.resolve.withExpectedType
|
import org.jetbrains.kotlin.fir.resolve.withExpectedType
|
||||||
import org.jetbrains.kotlin.fir.resolvedTypeFromPrototype
|
import org.jetbrains.kotlin.fir.resolvedTypeFromPrototype
|
||||||
|
import org.jetbrains.kotlin.fir.typeContext
|
||||||
import org.jetbrains.kotlin.fir.types.*
|
import org.jetbrains.kotlin.fir.types.*
|
||||||
import org.jetbrains.kotlin.fir.types.builder.buildErrorTypeRef
|
import org.jetbrains.kotlin.fir.types.builder.buildErrorTypeRef
|
||||||
import org.jetbrains.kotlin.fir.visitors.transformSingle
|
import org.jetbrains.kotlin.fir.visitors.transformSingle
|
||||||
@@ -217,7 +218,7 @@ class FirControlFlowStatementsResolveTransformer(transformer: FirBodyResolveTran
|
|||||||
elvisExpression.transformAnnotations(transformer, data)
|
elvisExpression.transformAnnotations(transformer, data)
|
||||||
|
|
||||||
val expectedType = data.expectedType?.coneTypeSafe<ConeKotlinType>()
|
val expectedType = data.expectedType?.coneTypeSafe<ConeKotlinType>()
|
||||||
val resolutionModeForLhs = withExpectedType(expectedType?.withNullability(ConeNullability.NULLABLE))
|
val resolutionModeForLhs = withExpectedType(expectedType?.withNullability(ConeNullability.NULLABLE, session.typeContext))
|
||||||
elvisExpression.transformLhs(transformer, resolutionModeForLhs)
|
elvisExpression.transformLhs(transformer, resolutionModeForLhs)
|
||||||
dataFlowAnalyzer.exitElvisLhs(elvisExpression)
|
dataFlowAnalyzer.exitElvisLhs(elvisExpression)
|
||||||
|
|
||||||
|
|||||||
@@ -113,7 +113,11 @@ fun <T : ConeKotlinType> T.withNullability(
|
|||||||
return this
|
return this
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
coneFlexibleOrSimpleType(typeContext, lowerBound.withNullability(nullability), upperBound.withNullability(nullability))
|
coneFlexibleOrSimpleType(
|
||||||
|
typeContext,
|
||||||
|
lowerBound.withNullability(nullability, typeContext),
|
||||||
|
upperBound.withNullability(nullability, typeContext)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
is ConeTypeVariableType -> ConeTypeVariableType(nullability, lookupTag)
|
is ConeTypeVariableType -> ConeTypeVariableType(nullability, lookupTag)
|
||||||
is ConeCapturedType -> ConeCapturedType(captureStatus, lowerType, nullability, constructor, attributes)
|
is ConeCapturedType -> ConeCapturedType(captureStatus, lowerType, nullability, constructor, attributes)
|
||||||
@@ -127,8 +131,8 @@ fun <T : ConeKotlinType> T.withNullability(
|
|||||||
is ConeStubType -> ConeStubType(variable, nullability)
|
is ConeStubType -> ConeStubType(variable, nullability)
|
||||||
is ConeDefinitelyNotNullType -> when (nullability) {
|
is ConeDefinitelyNotNullType -> when (nullability) {
|
||||||
ConeNullability.NOT_NULL -> this
|
ConeNullability.NOT_NULL -> this
|
||||||
ConeNullability.NULLABLE -> original.withNullability(nullability)
|
ConeNullability.NULLABLE -> original.withNullability(nullability, typeContext)
|
||||||
ConeNullability.UNKNOWN -> original.withNullability(nullability)
|
ConeNullability.UNKNOWN -> original.withNullability(nullability, typeContext)
|
||||||
}
|
}
|
||||||
is ConeIntegerLiteralType -> ConeIntegerLiteralTypeImpl(value, isUnsigned, nullability)
|
is ConeIntegerLiteralType -> ConeIntegerLiteralTypeImpl(value, isUnsigned, nullability)
|
||||||
else -> error("sealed: ${this::class}")
|
else -> error("sealed: ${this::class}")
|
||||||
|
|||||||
+5
-1
@@ -412,7 +412,11 @@ class FirVisualizer(private val firFile: FirFile) : BaseRenderer() {
|
|||||||
val lowerRendered = lowerBound.tryToRenderConeAsFunctionType()
|
val lowerRendered = lowerBound.tryToRenderConeAsFunctionType()
|
||||||
if (lowerBound.nullability == ConeNullability.NOT_NULL && upperBound.nullability == ConeNullability.NULLABLE &&
|
if (lowerBound.nullability == ConeNullability.NOT_NULL && upperBound.nullability == ConeNullability.NULLABLE &&
|
||||||
AbstractStrictEqualityTypeChecker
|
AbstractStrictEqualityTypeChecker
|
||||||
.strictEqualTypes(session.typeContext, lowerBound, upperBound.withNullability(ConeNullability.NOT_NULL))
|
.strictEqualTypes(
|
||||||
|
session.typeContext,
|
||||||
|
lowerBound,
|
||||||
|
upperBound.withNullability(ConeNullability.NOT_NULL, session.typeContext)
|
||||||
|
)
|
||||||
) {
|
) {
|
||||||
"$lowerRendered!"
|
"$lowerRendered!"
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
Reference in New Issue
Block a user