Skip to content

Commit 75e5120

Browse files
committed
Make PolyType a subtype of TypeLambda
1 parent 0264a0f commit 75e5120

File tree

2 files changed

+45
-30
lines changed

2 files changed

+45
-30
lines changed

src/dotty/tools/dotc/core/TypeComparer.scala

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -468,16 +468,6 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling {
468468
false
469469
}
470470
compareMethod
471-
case tp2: PolyType =>
472-
def comparePoly = tp1 match {
473-
case tp1: PolyType =>
474-
(tp1.signature consistentParams tp2.signature) &&
475-
matchingTypeParams(tp1, tp2) &&
476-
isSubType(tp1.resultType, tp2.resultType.subst(tp2, tp1))
477-
case _ =>
478-
false
479-
}
480-
comparePoly
481471
case tp2 @ ExprType(restpe2) =>
482472
def compareExpr = tp1 match {
483473
// We allow ()T to be a subtype of => T.

src/dotty/tools/dotc/core/Types.scala

Lines changed: 45 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -2512,8 +2512,6 @@ object Types {
25122512
(paramBoundsExp: GenericType => List[TypeBounds],
25132513
resultTypeExp: GenericType => Type)
25142514
extends CachedProxyType with BindingType with TermType {
2515-
type This <: GenericType
2516-
protected[this] def companion: GenericCompanion[This]
25172515

25182516
/** The bounds of the type parameters */
25192517
val paramBounds: List[TypeBounds] = paramBoundsExp(this)
@@ -2536,10 +2534,7 @@ object Types {
25362534
paramBounds.mapConserve(_.substParams(this, argTypes).bounds)
25372535

25382536
/** Unconditionally create a new generic type like this one with given elements */
2539-
def newLikeThis(paramNames: List[TypeName] = this.paramNames, paramBounds: List[TypeBounds] = this.paramBounds, resType: Type)(implicit ctx: Context): This =
2540-
companion.apply(paramNames, variances)(
2541-
x => paramBounds mapConserve (_.subst(this, x).bounds),
2542-
x => resType.subst(this, x))
2537+
def newLikeThis(paramNames: List[TypeName] = this.paramNames, paramBounds: List[TypeBounds] = this.paramBounds, resType: Type)(implicit ctx: Context): GenericType
25432538

25442539
def derivedGenericType(paramNames: List[TypeName] = this.paramNames,
25452540
paramBounds: List[TypeBounds] = this.paramBounds,
@@ -2584,23 +2579,20 @@ object Types {
25842579
}
25852580

25862581
/** A type for polymorphic methods */
2587-
class PolyType(paramNames: List[TypeName])(paramBoundsExp: GenericType => List[TypeBounds], resultTypeExp: GenericType => Type)
2588-
extends GenericType(paramNames)(paramBoundsExp, resultTypeExp) with MethodOrPoly {
2582+
class PolyType(paramNames: List[TypeName], variances: List[Int])(paramBoundsExp: GenericType => List[TypeBounds], resultTypeExp: GenericType => Type)
2583+
extends TypeLambda(paramNames, variances)(paramBoundsExp, resultTypeExp) with MethodOrPoly {
25892584

2590-
type This = PolyType
2591-
def companion = PolyType
2585+
protected override def computeSignature(implicit ctx: Context) = resultSignature
25922586

2593-
protected def computeSignature(implicit ctx: Context) = resultSignature
2594-
2595-
def isPolymorphicMethodType: Boolean = resType match {
2587+
override def isPolymorphicMethodType: Boolean = resType match {
25962588
case _: MethodType => true
25972589
case _ => false
25982590
}
25992591

26002592
/** Merge nested polytypes into one polytype. nested polytypes are normally not supported
26012593
* but can arise as temporary data structures.
26022594
*/
2603-
def flatten(implicit ctx: Context): PolyType = resType match {
2595+
override def flatten(implicit ctx: Context): PolyType = resType match {
26042596
case that: PolyType =>
26052597
val shift = new TypeMap {
26062598
def apply(t: Type) = t match {
@@ -2615,12 +2607,17 @@ object Types {
26152607
case _ => this
26162608
}
26172609

2610+
override def newLikeThis(paramNames: List[TypeName], paramBounds: List[TypeBounds], resType: Type)(implicit ctx: Context): PolyType =
2611+
PolyType.apply(paramNames, variances)(
2612+
x => paramBounds mapConserve (_.subst(this, x).bounds),
2613+
x => resType.subst(this, x))
2614+
26182615
override def toString = s"PolyType($paramNames, $paramBounds, $resType)"
26192616
}
26202617

26212618
object PolyType extends GenericCompanion[PolyType] {
26222619
def apply(paramNames: List[TypeName], variances: List[Int] = Nil)(paramBoundsExp: GenericType => List[TypeBounds], resultTypeExp: GenericType => Type)(implicit ctx: Context): PolyType = {
2623-
unique(new PolyType(paramNames)(paramBoundsExp, resultTypeExp))
2620+
unique(new PolyType(paramNames, paramNames.map(alwaysZero))(paramBoundsExp, resultTypeExp))
26242621
}
26252622
}
26262623

@@ -2629,17 +2626,26 @@ object Types {
26292626
/** A type lambda of the form `[v_0 X_0, ..., v_n X_n] => T` */
26302627
class TypeLambda(paramNames: List[TypeName], override val variances: List[Int])(
26312628
paramBoundsExp: GenericType => List[TypeBounds], resultTypeExp: GenericType => Type)
2632-
extends GenericType(paramNames)(paramBoundsExp, resultTypeExp) {
2629+
extends GenericType(paramNames)(paramBoundsExp, resultTypeExp) with MethodOrPoly {
26332630

26342631
assert(resType.isInstanceOf[TermType], this)
26352632
assert(paramNames.nonEmpty)
26362633

2637-
type This = TypeLambda
2638-
def companion = TypeLambda
2634+
protected def computeSignature(implicit ctx: Context) = resultSignature
2635+
2636+
def isPolymorphicMethodType: Boolean = resType match {
2637+
case _: MethodType => true
2638+
case _ => false
2639+
}
26392640

26402641
lazy val typeParams: List[LambdaParam] =
26412642
paramNames.indices.toList.map(new LambdaParam(this, _))
26422643

2644+
override def newLikeThis(paramNames: List[TypeName], paramBounds: List[TypeBounds], resType: Type)(implicit ctx: Context): TypeLambda =
2645+
TypeLambda.apply(paramNames, variances)(
2646+
x => paramBounds mapConserve (_.subst(this, x).bounds),
2647+
x => resType.subst(this, x))
2648+
26432649
def derivedLambdaAbstraction(paramNames: List[TypeName], paramBounds: List[TypeBounds], resType: Type)(implicit ctx: Context): Type =
26442650
resType match {
26452651
case resType @ TypeAlias(alias) =>
@@ -2652,14 +2658,33 @@ object Types {
26522658
derivedGenericType(paramNames, paramBounds, resType)
26532659
}
26542660

2661+
/** Merge nested polytypes into one polytype. nested polytypes are normally not supported
2662+
* but can arise as temporary data structures.
2663+
*/
2664+
def flatten(implicit ctx: Context): TypeLambda = resType match {
2665+
case that: PolyType =>
2666+
val shift = new TypeMap {
2667+
def apply(t: Type) = t match {
2668+
case PolyParam(`that`, n) => PolyParam(that, n + paramNames.length)
2669+
case t => mapOver(t)
2670+
}
2671+
}
2672+
PolyType(paramNames ++ that.paramNames)(
2673+
x => this.paramBounds.mapConserve(_.subst(this, x).bounds) ++
2674+
that.paramBounds.mapConserve(shift(_).subst(that, x).bounds),
2675+
x => shift(that.resultType).subst(that, x).subst(this, x))
2676+
case _ => this
2677+
}
2678+
26552679
override def toString = s"TypeLambda($variances, $paramNames, $paramBounds, $resType)"
26562680
}
26572681

26582682
object TypeLambda extends GenericCompanion[TypeLambda] {
2659-
def apply(paramNames: List[TypeName], variances: List[Int])(
2683+
def apply(paramNames: List[TypeName], variances: List[Int] = Nil)(
26602684
paramBoundsExp: GenericType => List[TypeBounds],
26612685
resultTypeExp: GenericType => Type)(implicit ctx: Context): TypeLambda = {
2662-
unique(new TypeLambda(paramNames, variances)(paramBoundsExp, resultTypeExp))
2686+
val vs = if (variances.isEmpty) paramNames.map(alwaysZero) else variances
2687+
unique(new TypeLambda(paramNames, vs)(paramBoundsExp, resultTypeExp))
26632688
}
26642689

26652690
def unapply(tl: TypeLambda): Some[(List[LambdaParam], Type)] =

0 commit comments

Comments
 (0)