Fix type argument substitution bug in KFunction construction
For example,
KMemberFunction2<T, P1, P2, R> : KMemberFunction<T, R>
So for this inheritance the heuristic that was present ("take the last K type
parameters of the subclass, and substitute for K parameters of the superclass")
was wrong. The new heuristic for this case is: take type parameters with the
same names.
Also don't store "parameters" in a lazy value, since it's easy to compute and
it's computed practically every time anyway
This commit is contained in:
+4
@@ -16,4 +16,8 @@ fun main() {
|
||||
checkSubtype<KExtensionFunction0<A, Unit>>(x)
|
||||
checkSubtype<KExtensionFunction1<A, Int, Unit>>(y)
|
||||
checkSubtype<KExtensionFunction0<A, String>>(z)
|
||||
|
||||
checkSubtype<KExtensionFunction<A, Unit>>(x)
|
||||
checkSubtype<KExtensionFunction<A, Unit>>(y)
|
||||
checkSubtype<KExtensionFunction<A, String>>(z)
|
||||
}
|
||||
|
||||
+4
@@ -16,4 +16,8 @@ fun main() {
|
||||
checkSubtype<KMemberFunction0<A, Unit>>(x)
|
||||
checkSubtype<KMemberFunction1<A, Int, Unit>>(y)
|
||||
checkSubtype<KMemberFunction0<A, String>>(z)
|
||||
|
||||
checkSubtype<KMemberFunction<A, Unit>>(x)
|
||||
checkSubtype<KMemberFunction<A, Unit>>(y)
|
||||
checkSubtype<KMemberFunction<A, String>>(z)
|
||||
}
|
||||
|
||||
+21
-9
@@ -99,7 +99,9 @@ public class FunctionClassDescriptor(
|
||||
override fun getSource() = SourceElement.NO_SOURCE
|
||||
|
||||
private inner class FunctionTypeConstructor : AbstractClassTypeConstructor() {
|
||||
private val parameters = storageManager.createLazyValue {
|
||||
private val parameters: List<TypeParameterDescriptor>
|
||||
|
||||
init {
|
||||
val result = ArrayList<TypeParameterDescriptor>()
|
||||
|
||||
fun typeParameter(variance: Variance, name: String) {
|
||||
@@ -121,26 +123,33 @@ public class FunctionClassDescriptor(
|
||||
|
||||
typeParameter(Variance.OUT_VARIANCE, "R")
|
||||
|
||||
result.toReadOnlyList()
|
||||
parameters = result.toReadOnlyList()
|
||||
}
|
||||
|
||||
private val supertypes = storageManager.createLazyValue {
|
||||
val result = ArrayList<JetType>(2)
|
||||
|
||||
fun add(packageFragment: PackageFragmentDescriptor, name: Name, annotations: Annotations) {
|
||||
fun add(
|
||||
packageFragment: PackageFragmentDescriptor,
|
||||
name: Name,
|
||||
annotations: Annotations,
|
||||
supertypeArguments: (superParameters: List<TypeParameterDescriptor>) -> List<TypeProjection>
|
||||
) {
|
||||
val descriptor = packageFragment.getMemberScope().getClassifier(name) as? ClassDescriptor
|
||||
?: error("Class $name not found in $packageFragment")
|
||||
|
||||
// Substitute K type parameters of the super class with our last K type parameters
|
||||
val typeConstructor = descriptor.getTypeConstructor()
|
||||
val superParameters = typeConstructor.getParameters()
|
||||
val arguments = getParameters().takeLast(superParameters.size()).map { TypeProjectionImpl(it.getDefaultType()) }
|
||||
val arguments = supertypeArguments(typeConstructor.getParameters())
|
||||
|
||||
result.add(JetTypeImpl(annotations, typeConstructor, false, arguments, descriptor.getMemberScope(arguments)))
|
||||
}
|
||||
|
||||
// Add unnumbered base class, e.g. KMemberFunction for KMemberFunction5, or Function for Function0
|
||||
add(containingDeclaration, Name.identifier(functionKind.classNamePrefix), Annotations.EMPTY)
|
||||
add(containingDeclaration, Name.identifier(functionKind.classNamePrefix), Annotations.EMPTY) { superParameters ->
|
||||
// Substitute type parameters of the super class with our type parameters with the same names
|
||||
val parametersByName = getParameters().toMap { it.getName() }
|
||||
superParameters.map { TypeProjectionImpl(parametersByName[it.getName()]!!.getDefaultType()) }
|
||||
}
|
||||
|
||||
// For K*Functions, add corresponding numbered Function class, e.g. Function2 for KMemberFunction1
|
||||
if (functionKind in Kinds.KFunctions) {
|
||||
@@ -158,13 +167,16 @@ public class FunctionClassDescriptor(
|
||||
AnnotationsImpl(listOf(KotlinBuiltIns.getInstance().createExtensionAnnotation()))
|
||||
else Annotations.EMPTY
|
||||
|
||||
add(kotlinPackageFragment, Kind.Function.numberedClassName(functionArity), annotations)
|
||||
add(kotlinPackageFragment, Kind.Function.numberedClassName(functionArity), annotations) {
|
||||
// Substitute all type parameters of the super class with all our type parameters
|
||||
getParameters().map { TypeProjectionImpl(it.getDefaultType()) }
|
||||
}
|
||||
}
|
||||
|
||||
result.toReadOnlyList()
|
||||
}
|
||||
|
||||
override fun getParameters() = parameters()
|
||||
override fun getParameters() = parameters
|
||||
|
||||
override fun getSupertypes(): Collection<JetType> = supertypes()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user