[FIR] Microoptimizations and clearing

This commit is contained in:
Ivan Kochurkin
2022-04-28 02:01:28 +03:00
parent ad7c213ab2
commit e69250a9fe
12 changed files with 61 additions and 157 deletions
@@ -220,11 +220,7 @@ class FirCallResolver(
origin = origin
)
towerResolver.reset()
val result = if (collector != null) {
towerResolver.runResolver(info, resolutionContext, collector)
} else {
towerResolver.runResolver(info, resolutionContext)
}
val result = towerResolver.runResolver(info, resolutionContext, collector)
val bestCandidates = result.bestCandidates()
fun chooseMostSpecific(): Set<Candidate> {
@@ -34,6 +34,7 @@ import org.jetbrains.kotlin.types.model.TypeConstructorMarker
import org.jetbrains.kotlin.types.model.TypeVariableMarker
import org.jetbrains.kotlin.utils.addIfNotNull
import org.jetbrains.kotlin.utils.addToStdlib.cast
import org.jetbrains.kotlin.utils.addToStdlib.filterIsInstanceWithChecker
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
class ConstraintSystemCompleter(components: BodyResolveComponents, private val context: BodyResolveContext) {
@@ -92,9 +93,10 @@ class ConstraintSystemCompleter(components: BodyResolveComponents, private val c
break
val postponedArgumentsWithRevisableType = postponedArguments
.filterIsInstance<PostponedAtomWithRevisableExpectedType>()
// NB: FE 1.0 does not perform this check
.filter { it.revisedExpectedType == null }
.filterIsInstanceWithChecker<PostponedAtomWithRevisableExpectedType> {
// NB: FE 1.0 does not perform this check
it.revisedExpectedType == null
}
val dependencyProvider =
TypeVariableDependencyInformationProvider(notFixedTypeVariables, postponedArguments, topLevelType, this)
@@ -170,6 +170,7 @@ class PostponedArgumentsAnalyzer(
returnArguments.forEach { c.addSubsystemFromExpression(it) }
val checkerSink: CheckerSink = CheckerSinkImpl(candidate)
val builder = c.getBuilder()
val lastExpression = lambda.atom.body?.statements?.lastOrNull() as? FirExpression
var hasExpressionInReturnArguments = false
@@ -183,9 +184,9 @@ class PostponedArgumentsAnalyzer(
val lastExpressionCoercedToUnit =
it == lastExpression && expectedReturnType?.isUnitOrFlexibleUnit == true && !it.typeRef.coneType.isUnitOrFlexibleUnit
// No constraint for the last expression of lambda if it will be coerced to Unit.
if (!lastExpressionCoercedToUnit && !c.getBuilder().hasContradiction) {
if (!lastExpressionCoercedToUnit && !builder.hasContradiction) {
candidate.resolveArgumentExpression(
c.getBuilder(),
builder,
it,
lambdaReturnType,
lambda.atom.returnTypeRef, // TODO: proper ref
@@ -198,7 +199,7 @@ class PostponedArgumentsAnalyzer(
}
if (!hasExpressionInReturnArguments && lambdaReturnType != null) {
c.getBuilder().addSubtypeConstraint(
builder.addSubtypeConstraint(
components.session.builtinTypes.unitType.type,
lambdaReturnType,
ConeLambdaArgumentConstraintPosition(lambda.atom)
@@ -209,20 +210,19 @@ class PostponedArgumentsAnalyzer(
lambda.returnStatements = returnArguments
if (inferenceSession != null) {
val constraintSystemBuilder = c.getBuilder()
val postponedVariables = inferenceSession.inferPostponedVariables(lambda, constraintSystemBuilder, completionMode)
val postponedVariables = inferenceSession.inferPostponedVariables(lambda, builder, completionMode)
if (postponedVariables == null) {
c.getBuilder().removePostponedVariables()
builder.removePostponedVariables()
return
}
for ((constructor, resultType) in postponedVariables) {
val variableWithConstraints = constraintSystemBuilder.currentStorage().notFixedTypeVariables[constructor] ?: continue
val variableWithConstraints = builder.currentStorage().notFixedTypeVariables[constructor] ?: continue
val variable = variableWithConstraints.typeVariable as ConeTypeVariable
c.getBuilder().unmarkPostponedVariable(variable)
c.getBuilder().addSubtypeConstraint(resultType, variable.defaultType(c), BuilderInferencePosition)
builder.unmarkPostponedVariable(variable)
builder.addSubtypeConstraint(resultType, variable.defaultType(c), BuilderInferencePosition)
}
c.removePostponedTypeVariablesFromConstraints(postponedVariables.keys)
@@ -548,15 +548,15 @@ class FirCallCompletionResultsWriterTransformer(
): List<ConeKotlinType> {
val declaration = candidate.symbol.fir as? FirCallableDeclaration ?: return emptyList()
return declaration.typeParameters.map { ConeTypeParameterTypeImpl(it.symbol.toLookupTag(), false) }
.map { candidate.substitutor.substituteOrSelf(it) }
.map {
finalSubstitutor.substituteOrSelf(it).let { substitutedType ->
typeApproximator.approximateToSuperType(
substitutedType, TypeApproximatorConfiguration.TypeArgumentApproximation,
) ?: substitutedType
}
return declaration.typeParameters.map {
val typeParameter = ConeTypeParameterTypeImpl(it.symbol.toLookupTag(), false)
val substitution = candidate.substitutor.substituteOrSelf(typeParameter)
finalSubstitutor.substituteOrSelf(substitution).let { substitutedType ->
typeApproximator.approximateToSuperType(
substitutedType, TypeApproximatorConfiguration.TypeArgumentApproximation,
) ?: substitutedType
}
}
}
override fun transformAnonymousFunctionExpression(
@@ -651,17 +651,16 @@ class FirCallCompletionResultsWriterTransformer(
expression.transform<FirElement, ExpectedArgumentType?>(this, finalType?.toExpectedType())
}
val resultFunction = result
if (resultFunction.returnTypeRef.coneTypeSafe<ConeIntegerLiteralType>() != null) {
if (result.returnTypeRef.coneTypeSafe<ConeIntegerLiteralType>() != null) {
val lastExpressionType =
(returnExpressionsOfAnonymousFunction.lastOrNull() as? FirExpression)
?.typeRef?.coneTypeSafe<ConeKotlinType>()
val newReturnTypeRef = resultFunction.returnTypeRef.withReplacedConeType(lastExpressionType)
resultFunction.replaceReturnTypeRef(newReturnTypeRef)
val newReturnTypeRef = result.returnTypeRef.withReplacedConeType(lastExpressionType)
result.replaceReturnTypeRef(newReturnTypeRef)
val resolvedTypeRef =
resultFunction.constructFunctionalTypeRef(isSuspend = expectedType?.isSuspendFunctionType(session) == true)
resultFunction.replaceTypeRef(resolvedTypeRef)
result.constructFunctionalTypeRef(isSuspend = expectedType?.isSuspendFunctionType(session) == true)
result.replaceTypeRef(resolvedTypeRef)
session.lookupTracker?.let {
it.recordTypeResolveAsLookup(newReturnTypeRef, anonymousFunction.source, context.file.source)
it.recordTypeResolveAsLookup(resolvedTypeRef, anonymousFunction.source, context.file.source)
@@ -570,18 +570,16 @@ open class FirDeclarationsResolveTransformer(transformer: FirBodyResolveTransfor
val returnType =
dataFlowAnalyzer.returnExpressionsOfAnonymousFunction(result)
.firstNotNullOfOrNull { (it as? FirExpression)?.resultType?.coneTypeSafe() }
if (returnType != null) {
result.transformReturnTypeRef(transformer, withExpectedType(returnType))
val resolutionMode = if (returnType != null) {
withExpectedType(returnType)
} else {
result.transformReturnTypeRef(
transformer,
withExpectedType(buildErrorTypeRef {
diagnostic =
ConeSimpleDiagnostic("Unresolved lambda return type", DiagnosticKind.InferenceError)
})
)
withExpectedType(buildErrorTypeRef {
diagnostic =
ConeSimpleDiagnostic("Unresolved lambda return type", DiagnosticKind.InferenceError)
})
}
result.transformReturnTypeRef(transformer, resolutionMode)
}
return result