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<KExtensionFunction0<A, Unit>>(x)
|
||||||
checkSubtype<KExtensionFunction1<A, Int, Unit>>(y)
|
checkSubtype<KExtensionFunction1<A, Int, Unit>>(y)
|
||||||
checkSubtype<KExtensionFunction0<A, String>>(z)
|
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<KMemberFunction0<A, Unit>>(x)
|
||||||
checkSubtype<KMemberFunction1<A, Int, Unit>>(y)
|
checkSubtype<KMemberFunction1<A, Int, Unit>>(y)
|
||||||
checkSubtype<KMemberFunction0<A, String>>(z)
|
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
|
override fun getSource() = SourceElement.NO_SOURCE
|
||||||
|
|
||||||
private inner class FunctionTypeConstructor : AbstractClassTypeConstructor() {
|
private inner class FunctionTypeConstructor : AbstractClassTypeConstructor() {
|
||||||
private val parameters = storageManager.createLazyValue {
|
private val parameters: List<TypeParameterDescriptor>
|
||||||
|
|
||||||
|
init {
|
||||||
val result = ArrayList<TypeParameterDescriptor>()
|
val result = ArrayList<TypeParameterDescriptor>()
|
||||||
|
|
||||||
fun typeParameter(variance: Variance, name: String) {
|
fun typeParameter(variance: Variance, name: String) {
|
||||||
@@ -121,26 +123,33 @@ public class FunctionClassDescriptor(
|
|||||||
|
|
||||||
typeParameter(Variance.OUT_VARIANCE, "R")
|
typeParameter(Variance.OUT_VARIANCE, "R")
|
||||||
|
|
||||||
result.toReadOnlyList()
|
parameters = result.toReadOnlyList()
|
||||||
}
|
}
|
||||||
|
|
||||||
private val supertypes = storageManager.createLazyValue {
|
private val supertypes = storageManager.createLazyValue {
|
||||||
val result = ArrayList<JetType>(2)
|
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
|
val descriptor = packageFragment.getMemberScope().getClassifier(name) as? ClassDescriptor
|
||||||
?: error("Class $name not found in $packageFragment")
|
?: 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 typeConstructor = descriptor.getTypeConstructor()
|
||||||
val superParameters = typeConstructor.getParameters()
|
val arguments = supertypeArguments(typeConstructor.getParameters())
|
||||||
val arguments = getParameters().takeLast(superParameters.size()).map { TypeProjectionImpl(it.getDefaultType()) }
|
|
||||||
|
|
||||||
result.add(JetTypeImpl(annotations, typeConstructor, false, arguments, descriptor.getMemberScope(arguments)))
|
result.add(JetTypeImpl(annotations, typeConstructor, false, arguments, descriptor.getMemberScope(arguments)))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add unnumbered base class, e.g. KMemberFunction for KMemberFunction5, or Function for Function0
|
// 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
|
// For K*Functions, add corresponding numbered Function class, e.g. Function2 for KMemberFunction1
|
||||||
if (functionKind in Kinds.KFunctions) {
|
if (functionKind in Kinds.KFunctions) {
|
||||||
@@ -158,13 +167,16 @@ public class FunctionClassDescriptor(
|
|||||||
AnnotationsImpl(listOf(KotlinBuiltIns.getInstance().createExtensionAnnotation()))
|
AnnotationsImpl(listOf(KotlinBuiltIns.getInstance().createExtensionAnnotation()))
|
||||||
else Annotations.EMPTY
|
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()
|
result.toReadOnlyList()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getParameters() = parameters()
|
override fun getParameters() = parameters
|
||||||
|
|
||||||
override fun getSupertypes(): Collection<JetType> = supertypes()
|
override fun getSupertypes(): Collection<JetType> = supertypes()
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user