[NI] Add missing substitution of known type parameters
Known type parameters appear after inheriting from class with type parameters. Their substitution matters for inner class constructor, because without substitution it's parameters will be type checked against incorrect (original) parameter descriptor with unsubstituted type parameters. Skip creation of composite substitutor, if old substitutor is empty. New substitutors return null in case they don't substitute a type, but old type substitutors have explicit isEmpty method. Composite substitutor with empty old substitutor leads to creation of incorrect descriptor copies.
This commit is contained in:
+4
@@ -23,6 +23,7 @@ import org.jetbrains.kotlin.resolve.calls.tower.InvokeConventionCallNoOperatorMo
|
||||
import org.jetbrains.kotlin.resolve.calls.tower.VisibilityError
|
||||
import org.jetbrains.kotlin.types.ErrorUtils
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.types.TypeSubstitutor
|
||||
import org.jetbrains.kotlin.types.UnwrappedType
|
||||
import org.jetbrains.kotlin.types.typeUtil.contains
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||
@@ -124,6 +125,8 @@ internal object NoArguments : ResolutionPart() {
|
||||
|
||||
internal object CreateFreshVariablesSubstitutor : ResolutionPart() {
|
||||
override fun KotlinResolutionCandidate.process(workIndex: Int) {
|
||||
resolvedCall.knownParametersSubstitutor = knownTypeParametersResultingSubstitutor ?: TypeSubstitutor.EMPTY
|
||||
|
||||
if (candidateDescriptor.typeParameters.isEmpty()) {
|
||||
resolvedCall.freshVariablesSubstitutor = FreshVariableNewTypeSubstitutor.Empty
|
||||
return
|
||||
@@ -415,6 +418,7 @@ internal object ErrorDescriptorResolutionPart : ResolutionPart() {
|
||||
resolvedCall.typeArgumentMappingByOriginal = TypeArgumentsToParametersMapper.TypeArgumentsMapping.NoExplicitArguments
|
||||
resolvedCall.argumentMappingByOriginal = emptyMap()
|
||||
resolvedCall.freshVariablesSubstitutor = FreshVariableNewTypeSubstitutor.Empty
|
||||
resolvedCall.knownParametersSubstitutor = TypeSubstitutor.EMPTY
|
||||
resolvedCall.argumentToCandidateParameter = emptyMap()
|
||||
|
||||
kotlinCall.explicitReceiver?.safeAs<SimpleKotlinCallArgument>()?.let {
|
||||
|
||||
+19
-4
@@ -7,8 +7,8 @@ package org.jetbrains.kotlin.resolve.calls.inference.components
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.annotations.CompositeAnnotations
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.model.NewTypeVariable
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.model.TypeVariableFromCallableDescriptor
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.substitute
|
||||
import org.jetbrains.kotlin.types.*
|
||||
import org.jetbrains.kotlin.types.checker.NewCapturedType
|
||||
import org.jetbrains.kotlin.types.checker.NewCapturedTypeConstructor
|
||||
@@ -190,7 +190,22 @@ class FreshVariableNewTypeSubstitutor(val freshVariables: List<TypeVariableFromC
|
||||
}
|
||||
}
|
||||
|
||||
fun UnwrappedType.substituteTypeVariable(typeVariable: NewTypeVariable, value: UnwrappedType): UnwrappedType {
|
||||
val substitutor = NewTypeSubstitutorByConstructorMap(mapOf(typeVariable.freshTypeConstructor to value))
|
||||
return substitutor.safeSubstitute(this)
|
||||
fun createCompositeSubstitutor(appliedFirst: NewTypeSubstitutor, appliedLast: TypeSubstitutor): NewTypeSubstitutor {
|
||||
if (appliedLast.isEmpty) return appliedFirst
|
||||
|
||||
return object : NewTypeSubstitutor {
|
||||
override fun substituteNotNullTypeWithConstructor(constructor: TypeConstructor): UnwrappedType? {
|
||||
val substitutedOnce = appliedFirst.substituteNotNullTypeWithConstructor(constructor)
|
||||
|
||||
return if (substitutedOnce != null) {
|
||||
appliedLast.substitute(substitutedOnce.unwrap())
|
||||
} else {
|
||||
constructor.declarationDescriptor?.defaultType?.let {
|
||||
appliedLast.substitute(it)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun NewTypeSubstitutor.composeWith(appliedAfter: TypeSubstitutor) = createCompositeSubstitutor(this, appliedAfter)
|
||||
|
||||
@@ -17,6 +17,7 @@ import org.jetbrains.kotlin.resolve.calls.inference.model.NewConstraintError
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.model.TypeVariableForLambdaReturnType
|
||||
import org.jetbrains.kotlin.resolve.calls.tasks.ExplicitReceiverKind
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.types.TypeSubstitutor
|
||||
import org.jetbrains.kotlin.types.UnwrappedType
|
||||
import org.jetbrains.kotlin.types.model.KotlinTypeMarker
|
||||
import org.jetbrains.kotlin.types.typeUtil.unCapture
|
||||
@@ -64,7 +65,7 @@ abstract class ResolvedCallAtom : ResolvedAtom() {
|
||||
abstract val typeArgumentMappingByOriginal: TypeArgumentsToParametersMapper.TypeArgumentsMapping
|
||||
abstract val argumentMappingByOriginal: Map<ValueParameterDescriptor, ResolvedCallArgument>
|
||||
abstract val freshVariablesSubstitutor: FreshVariableNewTypeSubstitutor
|
||||
|
||||
abstract val knownParametersSubstitutor: TypeSubstitutor
|
||||
abstract val argumentsWithConversion: Map<KotlinCallArgument, SamConversionDescription>
|
||||
}
|
||||
|
||||
|
||||
+1
@@ -179,6 +179,7 @@ class MutableResolvedCallAtom(
|
||||
override lateinit var typeArgumentMappingByOriginal: TypeArgumentsToParametersMapper.TypeArgumentsMapping
|
||||
override lateinit var argumentMappingByOriginal: Map<ValueParameterDescriptor, ResolvedCallArgument>
|
||||
override lateinit var freshVariablesSubstitutor: FreshVariableNewTypeSubstitutor
|
||||
override lateinit var knownParametersSubstitutor: TypeSubstitutor
|
||||
lateinit var argumentToCandidateParameter: Map<KotlinCallArgument, ValueParameterDescriptor>
|
||||
private var samAdapterMap: HashMap<KotlinCallArgument, SamConversionDescription>? = null
|
||||
|
||||
|
||||
Reference in New Issue
Block a user