[NI] Avoid computing few things for simple calls without type variables

This commit is contained in:
Mikhail Zarechenskiy
2019-09-17 18:47:39 +03:00
parent 7bd65c0bcd
commit 1a50a3cbb1
10 changed files with 38 additions and 10 deletions
@@ -256,7 +256,7 @@ interface ConeInferenceContext : TypeSystemInferenceExtensionContext,
} }
override fun typeSubstitutorByTypeConstructor(map: Map<TypeConstructorMarker, KotlinTypeMarker>): TypeSubstitutorMarker { override fun typeSubstitutorByTypeConstructor(map: Map<TypeConstructorMarker, KotlinTypeMarker>): TypeSubstitutorMarker {
if (map.isEmpty()) return ConeSubstitutor.Empty if (map.isEmpty()) return createEmptySubstitutor()
return object : AbstractConeSubstitutor(), return object : AbstractConeSubstitutor(),
TypeSubstitutorMarker { TypeSubstitutorMarker {
override fun substituteType(type: ConeKotlinType): ConeKotlinType? { override fun substituteType(type: ConeKotlinType): ConeKotlinType? {
@@ -266,6 +266,10 @@ interface ConeInferenceContext : TypeSystemInferenceExtensionContext,
} }
} }
override fun createEmptySubstitutor(): TypeSubstitutorMarker {
return ConeSubstitutor.Empty
}
override fun TypeSubstitutorMarker.safeSubstitute(type: KotlinTypeMarker): KotlinTypeMarker { override fun TypeSubstitutorMarker.safeSubstitute(type: KotlinTypeMarker): KotlinTypeMarker {
if (this === NoSubstitutor) return type if (this === NoSubstitutor) return type
require(this is ConeSubstitutor) require(this is ConeSubstitutor)
@@ -27,6 +27,7 @@ import org.jetbrains.kotlin.fir.types.impl.FirResolvedTypeRefImpl
import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.resolve.calls.components.InferenceSession import org.jetbrains.kotlin.resolve.calls.components.InferenceSession
import org.jetbrains.kotlin.resolve.calls.inference.buildAbstractResultingSubstitutor import org.jetbrains.kotlin.resolve.calls.inference.buildAbstractResultingSubstitutor
import org.jetbrains.kotlin.resolve.calls.inference.components.EmptySubstitutor
import org.jetbrains.kotlin.resolve.calls.inference.components.KotlinConstraintSystemCompleter import org.jetbrains.kotlin.resolve.calls.inference.components.KotlinConstraintSystemCompleter
import org.jetbrains.kotlin.resolve.calls.inference.model.SimpleConstraintSystemConstraintPosition import org.jetbrains.kotlin.resolve.calls.inference.model.SimpleConstraintSystemConstraintPosition
import org.jetbrains.kotlin.types.model.StubTypeMarker import org.jetbrains.kotlin.types.model.StubTypeMarker
@@ -7,6 +7,7 @@ package org.jetbrains.kotlin.resolve.calls.components
import org.jetbrains.kotlin.builtins.KotlinBuiltIns import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.resolve.calls.inference.components.ConstraintInjector import org.jetbrains.kotlin.resolve.calls.inference.components.ConstraintInjector
import org.jetbrains.kotlin.resolve.calls.inference.components.EmptySubstitutor
import org.jetbrains.kotlin.resolve.calls.inference.components.NewTypeSubstitutor import org.jetbrains.kotlin.resolve.calls.inference.components.NewTypeSubstitutor
import org.jetbrains.kotlin.resolve.calls.inference.components.NewTypeSubstitutorByConstructorMap import org.jetbrains.kotlin.resolve.calls.inference.components.NewTypeSubstitutorByConstructorMap
import org.jetbrains.kotlin.resolve.calls.inference.model.NewConstraintSystemImpl import org.jetbrains.kotlin.resolve.calls.inference.model.NewConstraintSystemImpl
@@ -60,9 +61,14 @@ class ClassicTypeSystemContextForCS(override val builtIns: KotlinBuiltIns) : Typ
} }
override fun typeSubstitutorByTypeConstructor(map: Map<TypeConstructorMarker, KotlinTypeMarker>): TypeSubstitutorMarker { override fun typeSubstitutorByTypeConstructor(map: Map<TypeConstructorMarker, KotlinTypeMarker>): TypeSubstitutorMarker {
if (map.isEmpty()) return createEmptySubstitutor()
return NewTypeSubstitutorByConstructorMap(map.cast()) return NewTypeSubstitutorByConstructorMap(map.cast())
} }
override fun createEmptySubstitutor(): TypeSubstitutorMarker {
return EmptySubstitutor
}
override fun TypeSubstitutorMarker.safeSubstitute(type: KotlinTypeMarker): KotlinTypeMarker { override fun TypeSubstitutorMarker.safeSubstitute(type: KotlinTypeMarker): KotlinTypeMarker {
require(type is UnwrappedType, type::errorMessage) require(type is UnwrappedType, type::errorMessage)
return when (this) { return when (this) {
@@ -51,8 +51,8 @@ private fun checkExpressionArgument(
diagnosticsHolder: KotlinDiagnosticsHolder, diagnosticsHolder: KotlinDiagnosticsHolder,
isReceiver: Boolean isReceiver: Boolean
): ResolvedAtom { ): ResolvedAtom {
val resolvedKtExpression = ResolvedExpressionAtom(expressionArgument) val resolvedExpression = ResolvedExpressionAtom(expressionArgument)
if (expectedType == null) return resolvedKtExpression if (expectedType == null) return resolvedExpression
// todo run this approximation only once for call // todo run this approximation only once for call
val argumentType = captureFromTypeParameterUpperBoundIfNeeded(expressionArgument.receiver.stableType, expectedType) val argumentType = captureFromTypeParameterUpperBoundIfNeeded(expressionArgument.receiver.stableType, expectedType)
@@ -77,7 +77,6 @@ private fun checkExpressionArgument(
return null return null
} }
val expectedNullableType = expectedType.makeNullableAsSpecified(true)
val position = if (isReceiver) ReceiverConstraintPosition(expressionArgument) else ArgumentConstraintPosition(expressionArgument) val position = if (isReceiver) ReceiverConstraintPosition(expressionArgument) else ArgumentConstraintPosition(expressionArgument)
// Used only for arguments with @NotNull annotation // Used only for arguments with @NotNull annotation
@@ -86,12 +85,13 @@ private fun checkExpressionArgument(
} }
if (expressionArgument.isSafeCall) { if (expressionArgument.isSafeCall) {
val expectedNullableType = expectedType.makeNullableAsSpecified(true)
if (!csBuilder.addSubtypeConstraintIfCompatible(argumentType, expectedNullableType, position)) { if (!csBuilder.addSubtypeConstraintIfCompatible(argumentType, expectedNullableType, position)) {
diagnosticsHolder.addDiagnosticIfNotNull( diagnosticsHolder.addDiagnosticIfNotNull(
unstableSmartCastOrSubtypeError(expressionArgument.receiver.unstableType, expectedNullableType, position) unstableSmartCastOrSubtypeError(expressionArgument.receiver.unstableType, expectedNullableType, position)
) )
} }
return resolvedKtExpression return resolvedExpression
} }
if (!csBuilder.addSubtypeConstraintIfCompatible(argumentType, expectedType, position)) { if (!csBuilder.addSubtypeConstraintIfCompatible(argumentType, expectedType, position)) {
@@ -103,10 +103,12 @@ private fun checkExpressionArgument(
position position
) )
) )
return resolvedKtExpression return resolvedExpression
} }
val unstableType = expressionArgument.receiver.unstableType val unstableType = expressionArgument.receiver.unstableType
val expectedNullableType = expectedType.makeNullableAsSpecified(true)
if (unstableType != null && csBuilder.addSubtypeConstraintIfCompatible(unstableType, expectedType, position)) { if (unstableType != null && csBuilder.addSubtypeConstraintIfCompatible(unstableType, expectedType, position)) {
diagnosticsHolder.addDiagnostic(UnstableSmartCast(expressionArgument, unstableType)) diagnosticsHolder.addDiagnostic(UnstableSmartCast(expressionArgument, unstableType))
} else if (csBuilder.addSubtypeConstraintIfCompatible(argumentType, expectedNullableType, position)) { } else if (csBuilder.addSubtypeConstraintIfCompatible(argumentType, expectedNullableType, position)) {
@@ -116,7 +118,7 @@ private fun checkExpressionArgument(
} }
} }
return resolvedKtExpression return resolvedExpression
} }
/** /**
@@ -21,9 +21,10 @@ import org.jetbrains.kotlin.resolve.calls.inference.components.NewTypeSubstituto
import org.jetbrains.kotlin.resolve.calls.inference.model.ConstraintStorage import org.jetbrains.kotlin.resolve.calls.inference.model.ConstraintStorage
import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns
import org.jetbrains.kotlin.types.* import org.jetbrains.kotlin.types.*
import org.jetbrains.kotlin.types.checker.ClassicTypeSystemContext import org.jetbrains.kotlin.types.model.StubTypeMarker
import org.jetbrains.kotlin.types.model.* import org.jetbrains.kotlin.types.model.TypeConstructorMarker
import java.util.* import org.jetbrains.kotlin.types.model.TypeSubstitutorMarker
import org.jetbrains.kotlin.types.model.TypeSystemInferenceExtensionContext
fun ConstraintStorage.buildCurrentSubstitutor( fun ConstraintStorage.buildCurrentSubstitutor(
context: TypeSystemInferenceExtensionContext, context: TypeSystemInferenceExtensionContext,
@@ -34,6 +35,8 @@ fun ConstraintStorage.buildCurrentSubstitutor(
fun ConstraintStorage.buildAbstractResultingSubstitutor(context: TypeSystemInferenceExtensionContext): TypeSubstitutorMarker = fun ConstraintStorage.buildAbstractResultingSubstitutor(context: TypeSystemInferenceExtensionContext): TypeSubstitutorMarker =
with(context) { with(context) {
if (allTypeVariables.isEmpty()) return createEmptySubstitutor()
val currentSubstitutorMap = fixedTypeVariables.entries.associate { val currentSubstitutorMap = fixedTypeVariables.entries.associate {
it.key to it.value it.key to it.value
} }
@@ -159,6 +159,10 @@ interface NewTypeSubstitutor: TypeSubstitutorMarker {
} }
} }
object EmptySubstitutor : NewTypeSubstitutor {
override fun substituteNotNullTypeWithConstructor(constructor: TypeConstructor): UnwrappedType? = null
}
class NewTypeSubstitutorByConstructorMap(val map: Map<TypeConstructor, UnwrappedType>) : NewTypeSubstitutor { class NewTypeSubstitutorByConstructorMap(val map: Map<TypeConstructor, UnwrappedType>) : NewTypeSubstitutor {
override fun substituteNotNullTypeWithConstructor(constructor: TypeConstructor): UnwrappedType? = map[constructor] override fun substituteNotNullTypeWithConstructor(constructor: TypeConstructor): UnwrappedType? = map[constructor]
} }
@@ -77,6 +77,8 @@ class VariableFixationFinder(
completionMode: ConstraintSystemCompletionMode, completionMode: ConstraintSystemCompletionMode,
topLevelType: KotlinTypeMarker topLevelType: KotlinTypeMarker
): VariableForFixation? { ): VariableForFixation? {
if (allTypeVariables.isEmpty()) return null
val dependencyProvider = TypeVariableDependencyInformationProvider( val dependencyProvider = TypeVariableDependencyInformationProvider(
notFixedTypeVariables, postponedArguments, topLevelType.takeIf { completionMode == PARTIAL }, this notFixedTypeVariables, postponedArguments, topLevelType.takeIf { completionMode == PARTIAL }, this
) )
@@ -179,6 +179,7 @@ class NewConstraintSystemImpl(
// ResultTypeResolver.Context, ConstraintSystemBuilder // ResultTypeResolver.Context, ConstraintSystemBuilder
override fun isProperType(type: KotlinTypeMarker): Boolean { override fun isProperType(type: KotlinTypeMarker): Boolean {
checkState(State.BUILDING, State.COMPLETION, State.TRANSACTION) checkState(State.BUILDING, State.COMPLETION, State.TRANSACTION)
if (storage.allTypeVariables.isEmpty()) return true
return !type.contains { return !type.contains {
val capturedType = it.asSimpleType()?.asCapturedType() val capturedType = it.asSimpleType()?.asCapturedType()
// TODO: change NewCapturedType to markered one for FE-IR // TODO: change NewCapturedType to markered one for FE-IR
@@ -456,6 +456,10 @@ interface ClassicTypeSystemContext : TypeSystemInferenceExtensionContext, TypeSy
errorSupportedOnlyInTypeInference() errorSupportedOnlyInTypeInference()
} }
override fun createEmptySubstitutor(): TypeSubstitutorMarker {
errorSupportedOnlyInTypeInference()
}
override fun TypeSubstitutorMarker.safeSubstitute(type: KotlinTypeMarker): KotlinTypeMarker { override fun TypeSubstitutorMarker.safeSubstitute(type: KotlinTypeMarker): KotlinTypeMarker {
require(type is UnwrappedType, type::errorMessage) require(type is UnwrappedType, type::errorMessage)
require(this is TypeSubstitutor, this::errorMessage) require(this is TypeSubstitutor, this::errorMessage)
@@ -146,6 +146,7 @@ interface TypeSystemInferenceExtensionContext : TypeSystemContext, TypeSystemBui
fun DefinitelyNotNullTypeMarker.original(): SimpleTypeMarker fun DefinitelyNotNullTypeMarker.original(): SimpleTypeMarker
fun typeSubstitutorByTypeConstructor(map: Map<TypeConstructorMarker, KotlinTypeMarker>): TypeSubstitutorMarker fun typeSubstitutorByTypeConstructor(map: Map<TypeConstructorMarker, KotlinTypeMarker>): TypeSubstitutorMarker
fun createEmptySubstitutor(): TypeSubstitutorMarker
fun TypeSubstitutorMarker.safeSubstitute(type: KotlinTypeMarker): KotlinTypeMarker fun TypeSubstitutorMarker.safeSubstitute(type: KotlinTypeMarker): KotlinTypeMarker