aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2016-10-08 12:51:21 +0200
committerGuillaume Martres <smarter@ubuntu.com>2016-10-12 03:36:57 +0200
commit5456c8b944056584ad7295d7e4d2a3b7a16362f8 (patch)
tree562683369ed6440f24540eaead986993ba91facb /src
parent695afc5651da0fae0ff2cf0467820b6503dd0f6d (diff)
downloaddotty-5456c8b944056584ad7295d7e4d2a3b7a16362f8.tar.gz
dotty-5456c8b944056584ad7295d7e4d2a3b7a16362f8.tar.bz2
dotty-5456c8b944056584ad7295d7e4d2a3b7a16362f8.zip
Make PolyType a subtype of TypeLambda
Diffstat (limited to 'src')
-rw-r--r--src/dotty/tools/dotc/core/TypeComparer.scala10
-rw-r--r--src/dotty/tools/dotc/core/Types.scala65
2 files changed, 45 insertions, 30 deletions
diff --git a/src/dotty/tools/dotc/core/TypeComparer.scala b/src/dotty/tools/dotc/core/TypeComparer.scala
index 4c962747a..91a3dd2b9 100644
--- a/src/dotty/tools/dotc/core/TypeComparer.scala
+++ b/src/dotty/tools/dotc/core/TypeComparer.scala
@@ -478,16 +478,6 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling {
false
}
compareMethod
- case tp2: PolyType =>
- def comparePoly = tp1 match {
- case tp1: PolyType =>
- (tp1.signature consistentParams tp2.signature) &&
- matchingTypeParams(tp1, tp2) &&
- isSubType(tp1.resultType, tp2.resultType.subst(tp2, tp1))
- case _ =>
- false
- }
- comparePoly
case tp2 @ ExprType(restpe2) =>
def compareExpr = tp1 match {
// We allow ()T to be a subtype of => T.
diff --git a/src/dotty/tools/dotc/core/Types.scala b/src/dotty/tools/dotc/core/Types.scala
index 30bffd2eb..08b11e1cb 100644
--- a/src/dotty/tools/dotc/core/Types.scala
+++ b/src/dotty/tools/dotc/core/Types.scala
@@ -2508,8 +2508,6 @@ object Types {
(paramBoundsExp: GenericType => List[TypeBounds],
resultTypeExp: GenericType => Type)
extends CachedProxyType with BindingType with TermType {
- type This <: GenericType
- protected[this] def companion: GenericCompanion[This]
/** The bounds of the type parameters */
val paramBounds: List[TypeBounds] = paramBoundsExp(this)
@@ -2532,10 +2530,7 @@ object Types {
paramBounds.mapConserve(_.substParams(this, argTypes).bounds)
/** Unconditionally create a new generic type like this one with given elements */
- def newLikeThis(paramNames: List[TypeName] = this.paramNames, paramBounds: List[TypeBounds] = this.paramBounds, resType: Type)(implicit ctx: Context): This =
- companion.apply(paramNames, variances)(
- x => paramBounds mapConserve (_.subst(this, x).bounds),
- x => resType.subst(this, x))
+ def newLikeThis(paramNames: List[TypeName] = this.paramNames, paramBounds: List[TypeBounds] = this.paramBounds, resType: Type)(implicit ctx: Context): GenericType
def derivedGenericType(paramNames: List[TypeName] = this.paramNames,
paramBounds: List[TypeBounds] = this.paramBounds,
@@ -2580,15 +2575,12 @@ object Types {
}
/** A type for polymorphic methods */
- class PolyType(paramNames: List[TypeName])(paramBoundsExp: GenericType => List[TypeBounds], resultTypeExp: GenericType => Type)
- extends GenericType(paramNames)(paramBoundsExp, resultTypeExp) with MethodOrPoly {
+ class PolyType(paramNames: List[TypeName], variances: List[Int])(paramBoundsExp: GenericType => List[TypeBounds], resultTypeExp: GenericType => Type)
+ extends TypeLambda(paramNames, variances)(paramBoundsExp, resultTypeExp) with MethodOrPoly {
- type This = PolyType
- def companion = PolyType
+ protected override def computeSignature(implicit ctx: Context) = resultSignature
- protected def computeSignature(implicit ctx: Context) = resultSignature
-
- def isPolymorphicMethodType: Boolean = resType match {
+ override def isPolymorphicMethodType: Boolean = resType match {
case _: MethodType => true
case _ => false
}
@@ -2596,7 +2588,7 @@ object Types {
/** Merge nested polytypes into one polytype. nested polytypes are normally not supported
* but can arise as temporary data structures.
*/
- def flatten(implicit ctx: Context): PolyType = resType match {
+ override def flatten(implicit ctx: Context): PolyType = resType match {
case that: PolyType =>
val shift = new TypeMap {
def apply(t: Type) = t match {
@@ -2611,12 +2603,17 @@ object Types {
case _ => this
}
+ override def newLikeThis(paramNames: List[TypeName], paramBounds: List[TypeBounds], resType: Type)(implicit ctx: Context): PolyType =
+ PolyType.apply(paramNames, variances)(
+ x => paramBounds mapConserve (_.subst(this, x).bounds),
+ x => resType.subst(this, x))
+
override def toString = s"PolyType($paramNames, $paramBounds, $resType)"
}
object PolyType extends GenericCompanion[PolyType] {
def apply(paramNames: List[TypeName], variances: List[Int] = Nil)(paramBoundsExp: GenericType => List[TypeBounds], resultTypeExp: GenericType => Type)(implicit ctx: Context): PolyType = {
- unique(new PolyType(paramNames)(paramBoundsExp, resultTypeExp))
+ unique(new PolyType(paramNames, paramNames.map(alwaysZero))(paramBoundsExp, resultTypeExp))
}
}
@@ -2625,17 +2622,26 @@ object Types {
/** A type lambda of the form `[v_0 X_0, ..., v_n X_n] => T` */
class TypeLambda(paramNames: List[TypeName], override val variances: List[Int])(
paramBoundsExp: GenericType => List[TypeBounds], resultTypeExp: GenericType => Type)
- extends GenericType(paramNames)(paramBoundsExp, resultTypeExp) {
+ extends GenericType(paramNames)(paramBoundsExp, resultTypeExp) with MethodOrPoly {
assert(resType.isInstanceOf[TermType], this)
assert(paramNames.nonEmpty)
- type This = TypeLambda
- def companion = TypeLambda
+ protected def computeSignature(implicit ctx: Context) = resultSignature
+
+ def isPolymorphicMethodType: Boolean = resType match {
+ case _: MethodType => true
+ case _ => false
+ }
lazy val typeParams: List[LambdaParam] =
paramNames.indices.toList.map(new LambdaParam(this, _))
+ override def newLikeThis(paramNames: List[TypeName], paramBounds: List[TypeBounds], resType: Type)(implicit ctx: Context): TypeLambda =
+ TypeLambda.apply(paramNames, variances)(
+ x => paramBounds mapConserve (_.subst(this, x).bounds),
+ x => resType.subst(this, x))
+
def derivedLambdaAbstraction(paramNames: List[TypeName], paramBounds: List[TypeBounds], resType: Type)(implicit ctx: Context): Type =
resType match {
case resType @ TypeAlias(alias) =>
@@ -2648,14 +2654,33 @@ object Types {
derivedGenericType(paramNames, paramBounds, resType)
}
+ /** Merge nested polytypes into one polytype. nested polytypes are normally not supported
+ * but can arise as temporary data structures.
+ */
+ def flatten(implicit ctx: Context): TypeLambda = resType match {
+ case that: PolyType =>
+ val shift = new TypeMap {
+ def apply(t: Type) = t match {
+ case PolyParam(`that`, n) => PolyParam(that, n + paramNames.length)
+ case t => mapOver(t)
+ }
+ }
+ PolyType(paramNames ++ that.paramNames)(
+ x => this.paramBounds.mapConserve(_.subst(this, x).bounds) ++
+ that.paramBounds.mapConserve(shift(_).subst(that, x).bounds),
+ x => shift(that.resultType).subst(that, x).subst(this, x))
+ case _ => this
+ }
+
override def toString = s"TypeLambda($variances, $paramNames, $paramBounds, $resType)"
}
object TypeLambda extends GenericCompanion[TypeLambda] {
- def apply(paramNames: List[TypeName], variances: List[Int])(
+ def apply(paramNames: List[TypeName], variances: List[Int] = Nil)(
paramBoundsExp: GenericType => List[TypeBounds],
resultTypeExp: GenericType => Type)(implicit ctx: Context): TypeLambda = {
- unique(new TypeLambda(paramNames, variances)(paramBoundsExp, resultTypeExp))
+ val vs = if (variances.isEmpty) paramNames.map(alwaysZero) else variances
+ unique(new TypeLambda(paramNames, vs)(paramBoundsExp, resultTypeExp))
}
def unapply(tl: TypeLambda): Some[(List[LambdaParam], Type)] =