Fixed 'subtype' for captured type
This commit is contained in:
+30
-5
@@ -22,9 +22,14 @@ import org.jetbrains.jet.lang.types.TypeConstructor
|
||||
import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptor
|
||||
import org.jetbrains.jet.lang.descriptors.annotations.Annotations
|
||||
import org.jetbrains.jet.lang.types.Variance
|
||||
import org.jetbrains.jet.lang.types.Variance.*
|
||||
import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns
|
||||
import org.jetbrains.jet.lang.types.JetTypeImpl
|
||||
import org.jetbrains.jet.lang.types.ErrorUtils
|
||||
import org.jetbrains.jet.lang.types.SubtypingRepresentatives
|
||||
import org.jetbrains.jet.lang.types.AbstractJetType
|
||||
import org.jetbrains.jet.lang.types.DelegatingType
|
||||
import org.jetbrains.jet.lang.types.JetTypeImpl
|
||||
import org.jetbrains.jet.lang.types.TypeUtils
|
||||
|
||||
public class CapturedTypeConstructor(
|
||||
public val typeProjection: TypeProjection
|
||||
@@ -56,10 +61,30 @@ public class CapturedTypeConstructor(
|
||||
override fun toString() = "Captured($typeProjection)"
|
||||
}
|
||||
|
||||
public fun createCapturedType(typeProjection: TypeProjection): JetType {
|
||||
val scope = ErrorUtils.createErrorScope("No member resolution should be done on captured type, " +
|
||||
"it used only during constraint system resolution", true)
|
||||
return JetTypeImpl(Annotations.EMPTY, CapturedTypeConstructor(typeProjection), false, listOf(), scope)
|
||||
public class CapturedType(
|
||||
private val typeProjection: TypeProjection
|
||||
): DelegatingType(), SubtypingRepresentatives {
|
||||
|
||||
private val delegateType = run {
|
||||
val scope = ErrorUtils.createErrorScope(
|
||||
"No member resolution should be done on captured type, it used only during constraint system resolution", true)
|
||||
JetTypeImpl(Annotations.EMPTY, CapturedTypeConstructor(typeProjection), false, listOf(), scope)
|
||||
}
|
||||
|
||||
override fun getDelegate(): JetType = delegateType
|
||||
|
||||
override val subTypeRepresentative: JetType
|
||||
get() = representative(OUT_VARIANCE, KotlinBuiltIns.getInstance().getNullableAnyType())
|
||||
|
||||
override val superTypeRepresentative: JetType
|
||||
get() = representative(IN_VARIANCE, KotlinBuiltIns.getInstance().getNothingType())
|
||||
|
||||
private fun representative(variance: Variance, default: JetType) =
|
||||
if (typeProjection.getProjectionKind() == variance) typeProjection.getType() else default
|
||||
|
||||
override fun sameTypeConstructor(type: JetType) = delegateType.getConstructor() === type.getConstructor()
|
||||
}
|
||||
|
||||
public fun createCapturedType(typeProjection: TypeProjection): JetType = CapturedType(typeProjection)
|
||||
|
||||
public fun JetType.isCaptured(): Boolean = getConstructor() is CapturedTypeConstructor
|
||||
@@ -31,9 +31,11 @@ public trait Specificity : TypeCapability {
|
||||
public fun getSpecificityRelationTo(otherType: JetType): Relation
|
||||
}
|
||||
|
||||
fun JetType.getSpecificityRelationTo(otherType: JetType) = this.getCapability(javaClass<Specificity>())?.getSpecificityRelationTo(otherType) ?: Specificity.Relation.DONT_KNOW
|
||||
fun JetType.getSpecificityRelationTo(otherType: JetType) =
|
||||
this.getCapability(javaClass<Specificity>())?.getSpecificityRelationTo(otherType) ?: Specificity.Relation.DONT_KNOW
|
||||
|
||||
fun oneMoreSpecificThanAnother(a: JetType, b: JetType) = a.getSpecificityRelationTo(b) != Specificity.Relation.DONT_KNOW || b.getSpecificityRelationTo(a) != Specificity.Relation.DONT_KNOW
|
||||
fun oneMoreSpecificThanAnother(a: JetType, b: JetType) =
|
||||
a.getSpecificityRelationTo(b) != Specificity.Relation.DONT_KNOW || b.getSpecificityRelationTo(a) != Specificity.Relation.DONT_KNOW
|
||||
|
||||
// To facilitate laziness, any JetType implementation may inherit from this trait,
|
||||
// even if it turns out that the type an instance represents is not actually a type variable
|
||||
@@ -52,4 +54,23 @@ public fun JetType.isCustomTypeVariable(): Boolean = this.getCapability(javaClas
|
||||
public fun JetType.getCustomTypeVariable(): CustomTypeVariable? =
|
||||
this.getCapability(javaClass<CustomTypeVariable>())?.let {
|
||||
if (it.isTypeVariable) it else null
|
||||
}
|
||||
}
|
||||
|
||||
public trait SubtypingRepresentatives : TypeCapability {
|
||||
public val subTypeRepresentative: JetType
|
||||
public val superTypeRepresentative: JetType
|
||||
|
||||
public fun sameTypeConstructor(type: JetType): Boolean
|
||||
}
|
||||
|
||||
public fun JetType.getSubtypeRepresentative(): JetType =
|
||||
this.getCapability(javaClass<SubtypingRepresentatives>())?.subTypeRepresentative ?: this
|
||||
|
||||
public fun JetType.getSupertypeRepresentative(): JetType =
|
||||
this.getCapability(javaClass<SubtypingRepresentatives>())?.superTypeRepresentative ?: this
|
||||
|
||||
public fun sameTypeConstructors(first: JetType, second: JetType): Boolean {
|
||||
val typeRangeCapability = javaClass<SubtypingRepresentatives>()
|
||||
return first.getCapability(typeRangeCapability)?.sameTypeConstructor(second) ?: false
|
||||
|| second.getCapability(typeRangeCapability)?.sameTypeConstructor(first) ?: false
|
||||
}
|
||||
|
||||
+11
-4
@@ -183,12 +183,19 @@ public class TypeCheckingProcedure {
|
||||
}
|
||||
|
||||
public boolean isSubtypeOf(@NotNull JetType subtype, @NotNull JetType supertype) {
|
||||
if (TypesPackage.isFlexible(subtype)) {
|
||||
return isSubtypeOf(TypesPackage.flexibility(subtype).getLowerBound(), supertype);
|
||||
if (TypesPackage.sameTypeConstructors(subtype, supertype)) {
|
||||
return !subtype.isMarkedNullable() || supertype.isMarkedNullable();
|
||||
}
|
||||
if (TypesPackage.isFlexible(supertype)) {
|
||||
return isSubtypeOf(subtype, TypesPackage.flexibility(supertype).getUpperBound());
|
||||
JetType subtypeRepresentative = TypesPackage.getSubtypeRepresentative(subtype);
|
||||
JetType supertypeRepresentative = TypesPackage.getSupertypeRepresentative(supertype);
|
||||
if (subtypeRepresentative != subtype || supertypeRepresentative != supertype) {
|
||||
// recursive invocation for possible chain of representatives
|
||||
return isSubtypeOf(subtypeRepresentative, supertypeRepresentative);
|
||||
}
|
||||
return isSubtypeOfForRepresentatives(subtype, supertype);
|
||||
}
|
||||
|
||||
private boolean isSubtypeOfForRepresentatives(JetType subtype, JetType supertype) {
|
||||
if (subtype.isError() || supertype.isError()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -34,7 +34,7 @@ public trait FlexibleTypeCapabilities {
|
||||
}
|
||||
}
|
||||
|
||||
public trait Flexibility : TypeCapability {
|
||||
public trait Flexibility : TypeCapability, SubtypingRepresentatives {
|
||||
class object {
|
||||
// This is a "magic" classifier: when type resolver sees it in the code, e.g. ft<Foo, Foo?>, instead of creating a normal type,
|
||||
// it creates a flexible type, e.g. (Foo..Foo?).
|
||||
@@ -48,6 +48,14 @@ public trait Flexibility : TypeCapability {
|
||||
public val upperBound: JetType
|
||||
|
||||
public val extraCapabilities: FlexibleTypeCapabilities
|
||||
|
||||
override val subTypeRepresentative: JetType
|
||||
get() = lowerBound
|
||||
|
||||
override val superTypeRepresentative: JetType
|
||||
get() = upperBound
|
||||
|
||||
override fun sameTypeConstructor(type: JetType) = false
|
||||
}
|
||||
|
||||
public fun JetType.isFlexible(): Boolean = this.getCapability(javaClass<Flexibility>()) != null
|
||||
|
||||
Reference in New Issue
Block a user