[NI] Use NewTypeSubstitutor when create descriptor with fresh variables.

This commit is contained in:
Stanislav Erokhin
2017-05-04 15:46:52 +03:00
parent 652676dc71
commit 2602216039
2 changed files with 21 additions and 7 deletions
@@ -18,6 +18,7 @@ package org.jetbrains.kotlin.resolve.calls.components
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.resolve.calls.components.TypeArgumentsToParametersMapper.TypeArgumentsMapping.NoExplicitArguments
import org.jetbrains.kotlin.resolve.calls.inference.components.FreshVariableNewTypeSubstitutor
import org.jetbrains.kotlin.resolve.calls.inference.model.DeclaredUpperBoundConstraintPosition
import org.jetbrains.kotlin.resolve.calls.inference.model.ExplicitTypeParameterConstraintPosition
import org.jetbrains.kotlin.resolve.calls.inference.model.TypeVariableFromCallableDescriptor
@@ -26,13 +27,12 @@ import org.jetbrains.kotlin.resolve.calls.model.*
import org.jetbrains.kotlin.resolve.calls.smartcasts.getReceiverValueWithSmartCast
import org.jetbrains.kotlin.resolve.calls.tasks.ExplicitReceiverKind.*
import org.jetbrains.kotlin.resolve.calls.tower.ResolutionCandidateApplicability
import org.jetbrains.kotlin.resolve.calls.tower.ResolutionCandidateApplicability.*
import org.jetbrains.kotlin.resolve.calls.tower.ResolutionCandidateApplicability.IMPOSSIBLE_TO_GENERATE
import org.jetbrains.kotlin.resolve.calls.tower.ResolutionCandidateApplicability.RUNTIME_ERROR
import org.jetbrains.kotlin.resolve.calls.tower.VisibilityError
import org.jetbrains.kotlin.types.IndexedParametersSubstitution
import org.jetbrains.kotlin.types.TypeSubstitutor
import org.jetbrains.kotlin.types.UnwrappedType
import org.jetbrains.kotlin.types.Variance
import org.jetbrains.kotlin.types.typeUtil.asTypeProjection
internal object CheckInstantiationOfAbstractClass : ResolutionPart {
override fun SimpleKotlinResolutionCandidate.process(): List<KotlinCallDiagnostic> {
@@ -112,8 +112,8 @@ internal object CreateDescriptorWithFreshTypeVariables : ResolutionPart {
val freshTypeVariables = typeParameters.map { TypeVariableFromCallableDescriptor(kotlinCall, it) }
typeVariablesForFreshTypeParameters = freshTypeVariables
val toFreshVariables = IndexedParametersSubstitution(typeParameters,
freshTypeVariables.map { it.defaultType.asTypeProjection() }).buildSubstitutor()
val toFreshVariables = FreshVariableNewTypeSubstitutor(freshTypeVariables)
for (freshVariable in freshTypeVariables) {
csBuilder.registerVariable(freshVariable)
@@ -125,7 +125,7 @@ internal object CreateDescriptorWithFreshTypeVariables : ResolutionPart {
val position = DeclaredUpperBoundConstraintPosition(typeParameter)
for (upperBound in typeParameter.upperBounds) {
csBuilder.addSubtypeConstraint(freshVariable.defaultType, upperBound.unwrap().substitute(toFreshVariables), position)
csBuilder.addSubtypeConstraint(freshVariable.defaultType, toFreshVariables.safeSubstitute(upperBound.unwrap()), position)
}
}
@@ -137,7 +137,7 @@ internal object CreateDescriptorWithFreshTypeVariables : ResolutionPart {
// optimization
if (typeArgumentMappingByOriginal == NoExplicitArguments) {
descriptorWithFreshTypes = candidateDescriptor.safeSubstitute(toFreshVariables)
descriptorWithFreshTypes = candidateDescriptor.substitute(toFreshVariables)!!
csBuilder.simplify().let { assert(it.isEmpty) { "Substitutor should be empty: $it, call: $kotlinCall" } }
return emptyList()
}
@@ -16,6 +16,8 @@
package org.jetbrains.kotlin.resolve.calls.inference.components
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
import org.jetbrains.kotlin.resolve.calls.inference.model.TypeVariableFromCallableDescriptor
import org.jetbrains.kotlin.types.*
import org.jetbrains.kotlin.types.checker.NewCapturedType
import org.jetbrains.kotlin.types.checker.NewCapturedTypeConstructor
@@ -120,4 +122,16 @@ interface NewTypeSubstitutor {
class NewTypeSubstitutorByConstructorMap(val map: Map<TypeConstructor, UnwrappedType>) : NewTypeSubstitutor {
override val isEmpty get() = map.isEmpty()
override fun substituteNotNullTypeWithConstructor(constructor: TypeConstructor): UnwrappedType? = map[constructor]
}
class FreshVariableNewTypeSubstitutor(val freshVariables: List<TypeVariableFromCallableDescriptor>) : NewTypeSubstitutor {
override val isEmpty get() = freshVariables.isEmpty()
override fun substituteNotNullTypeWithConstructor(constructor: TypeConstructor): UnwrappedType? {
val indexProposal = (constructor.declarationDescriptor as? TypeParameterDescriptor)?.index ?: return null
val typeVariable = freshVariables.getOrNull(indexProposal) ?: return null
if (typeVariable.originalTypeParameter.typeConstructor != constructor) return null
return typeVariable.defaultType
}
}