aboutsummaryrefslogtreecommitdiff
path: root/src/dotty
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2016-06-29 20:07:51 +0200
committerMartin Odersky <odersky@gmail.com>2016-07-11 13:35:03 +0200
commit02ce995f44c2252f7f7c0f07aa2a86f045b51ac2 (patch)
tree70768b1bf1aeec2e1f56acc6d0c390d9e9538cb5 /src/dotty
parent73dd03944cdfbc2588e9e41f407e0ad3a48abe96 (diff)
downloaddotty-02ce995f44c2252f7f7c0f07aa2a86f045b51ac2.tar.gz
dotty-02ce995f44c2252f7f7c0f07aa2a86f045b51ac2.tar.bz2
dotty-02ce995f44c2252f7f7c0f07aa2a86f045b51ac2.zip
Refactoring of PolyType and TypeLambda
Make them each inherit from common BaseType GenericType. That way we avoid inheriting accidentally stuff from PolyType in TypeLambda. Also, Fix adaptation of type lambdas. Don't confuse them with PolyTypes.
Diffstat (limited to 'src/dotty')
-rw-r--r--src/dotty/tools/dotc/core/Constraint.scala10
-rw-r--r--src/dotty/tools/dotc/core/Definitions.scala6
-rw-r--r--src/dotty/tools/dotc/core/OrderingConstraint.scala48
-rw-r--r--src/dotty/tools/dotc/core/SymDenotations.scala4
-rw-r--r--src/dotty/tools/dotc/core/TypeApplications.scala2
-rw-r--r--src/dotty/tools/dotc/core/TypeComparer.scala19
-rw-r--r--src/dotty/tools/dotc/core/TyperState.scala2
-rw-r--r--src/dotty/tools/dotc/core/Types.scala107
-rw-r--r--src/dotty/tools/dotc/core/tasty/TreeUnpickler.scala2
-rw-r--r--src/dotty/tools/dotc/core/unpickleScala2/Scala2Unpickler.scala4
-rw-r--r--src/dotty/tools/dotc/printing/PlainPrinter.scala2
-rw-r--r--src/dotty/tools/dotc/transform/FullParameterization.scala10
-rw-r--r--src/dotty/tools/dotc/transform/PostTyper.scala4
-rw-r--r--src/dotty/tools/dotc/typer/Checking.scala2
-rw-r--r--src/dotty/tools/dotc/typer/ProtoTypes.scala2
-rw-r--r--src/dotty/tools/dotc/typer/Variances.scala2
16 files changed, 124 insertions, 102 deletions
diff --git a/src/dotty/tools/dotc/core/Constraint.scala b/src/dotty/tools/dotc/core/Constraint.scala
index 19f93ce47..38f714131 100644
--- a/src/dotty/tools/dotc/core/Constraint.scala
+++ b/src/dotty/tools/dotc/core/Constraint.scala
@@ -23,7 +23,7 @@ abstract class Constraint extends Showable {
type This <: Constraint
/** Does the constraint's domain contain the type parameters of `pt`? */
- def contains(pt: PolyType): Boolean
+ def contains(pt: GenericType): Boolean
/** Does the constraint's domain contain the type parameter `param`? */
def contains(param: PolyParam): Boolean
@@ -79,7 +79,7 @@ abstract class Constraint extends Showable {
* satisfiability but will solved to give instances of
* type variables.
*/
- def add(poly: PolyType, tvars: List[TypeVar])(implicit ctx: Context): This
+ def add(poly: GenericType, tvars: List[TypeVar])(implicit ctx: Context): This
/** A new constraint which is derived from this constraint by updating
* the entry for parameter `param` to `tp`.
@@ -122,13 +122,13 @@ abstract class Constraint extends Showable {
* entry array, but is going to be removed at the same step,
* or -1 if no such parameter exists.
*/
- def isRemovable(pt: PolyType, removedParam: Int = -1): Boolean
+ def isRemovable(pt: GenericType, removedParam: Int = -1): Boolean
/** A new constraint with all entries coming from `pt` removed. */
- def remove(pt: PolyType)(implicit ctx: Context): This
+ def remove(pt: GenericType)(implicit ctx: Context): This
/** The polytypes constrained by this constraint */
- def domainPolys: List[PolyType]
+ def domainPolys: List[GenericType]
/** The polytype parameters constrained by this constraint */
def domainParams: List[PolyParam]
diff --git a/src/dotty/tools/dotc/core/Definitions.scala b/src/dotty/tools/dotc/core/Definitions.scala
index 5db9a6b0d..8d020a428 100644
--- a/src/dotty/tools/dotc/core/Definitions.scala
+++ b/src/dotty/tools/dotc/core/Definitions.scala
@@ -86,17 +86,17 @@ class Definitions {
}
private def newPolyMethod(cls: ClassSymbol, name: TermName, typeParamCount: Int,
- resultTypeFn: PolyType => Type, flags: FlagSet = EmptyFlags) = {
+ resultTypeFn: GenericType => Type, flags: FlagSet = EmptyFlags) = {
val tparamNames = tpnme.syntheticTypeParamNames(typeParamCount)
val tparamBounds = tparamNames map (_ => TypeBounds.empty)
val ptype = PolyType(tparamNames)(_ => tparamBounds, resultTypeFn)
newMethod(cls, name, ptype, flags)
}
- private def newT1ParameterlessMethod(cls: ClassSymbol, name: TermName, resultTypeFn: PolyType => Type, flags: FlagSet) =
+ private def newT1ParameterlessMethod(cls: ClassSymbol, name: TermName, resultTypeFn: GenericType => Type, flags: FlagSet) =
newPolyMethod(cls, name, 1, resultTypeFn, flags)
- private def newT1EmptyParamsMethod(cls: ClassSymbol, name: TermName, resultTypeFn: PolyType => Type, flags: FlagSet) =
+ private def newT1EmptyParamsMethod(cls: ClassSymbol, name: TermName, resultTypeFn: GenericType => Type, flags: FlagSet) =
newPolyMethod(cls, name, 1, pt => MethodType(Nil, resultTypeFn(pt)), flags)
private def mkArityArray(name: String, arity: Int, countFrom: Int): Array[TypeRef] = {
diff --git a/src/dotty/tools/dotc/core/OrderingConstraint.scala b/src/dotty/tools/dotc/core/OrderingConstraint.scala
index e818862cb..d9f6f5721 100644
--- a/src/dotty/tools/dotc/core/OrderingConstraint.scala
+++ b/src/dotty/tools/dotc/core/OrderingConstraint.scala
@@ -15,10 +15,10 @@ import reflect.ClassTag
object OrderingConstraint {
/** The type of `OrderingConstraint#boundsMap` */
- type ParamBounds = SimpleMap[PolyType, Array[Type]]
+ type ParamBounds = SimpleMap[GenericType, Array[Type]]
/** The type of `OrderingConstraint#lowerMap`, `OrderingConstraint#upperMap` */
- type ParamOrdering = SimpleMap[PolyType, Array[List[PolyParam]]]
+ type ParamOrdering = SimpleMap[GenericType, Array[List[PolyParam]]]
/** A new constraint with given maps */
private def newConstraint(boundsMap: ParamBounds, lowerMap: ParamOrdering, upperMap: ParamOrdering)(implicit ctx: Context) : OrderingConstraint = {
@@ -30,11 +30,11 @@ object OrderingConstraint {
/** A lens for updating a single entry array in one of the three constraint maps */
abstract class ConstraintLens[T <: AnyRef: ClassTag] {
- def entries(c: OrderingConstraint, poly: PolyType): Array[T]
- def updateEntries(c: OrderingConstraint, poly: PolyType, entries: Array[T])(implicit ctx: Context): OrderingConstraint
+ def entries(c: OrderingConstraint, poly: GenericType): Array[T]
+ def updateEntries(c: OrderingConstraint, poly: GenericType, entries: Array[T])(implicit ctx: Context): OrderingConstraint
def initial: T
- def apply(c: OrderingConstraint, poly: PolyType, idx: Int) = {
+ def apply(c: OrderingConstraint, poly: GenericType, idx: Int) = {
val es = entries(c, poly)
if (es == null) initial else es(idx)
}
@@ -45,7 +45,7 @@ object OrderingConstraint {
* parts of `current` which are not shared by `prev`.
*/
def update(prev: OrderingConstraint, current: OrderingConstraint,
- poly: PolyType, idx: Int, entry: T)(implicit ctx: Context): OrderingConstraint = {
+ poly: GenericType, idx: Int, entry: T)(implicit ctx: Context): OrderingConstraint = {
var es = entries(current, poly)
if (es != null && (es(idx) eq entry)) current
else {
@@ -70,7 +70,7 @@ object OrderingConstraint {
update(prev, current, param.binder, param.paramNum, entry)
def map(prev: OrderingConstraint, current: OrderingConstraint,
- poly: PolyType, idx: Int, f: T => T)(implicit ctx: Context): OrderingConstraint =
+ poly: GenericType, idx: Int, f: T => T)(implicit ctx: Context): OrderingConstraint =
update(prev, current, poly, idx, f(apply(current, poly, idx)))
def map(prev: OrderingConstraint, current: OrderingConstraint,
@@ -79,25 +79,25 @@ object OrderingConstraint {
}
val boundsLens = new ConstraintLens[Type] {
- def entries(c: OrderingConstraint, poly: PolyType): Array[Type] =
+ def entries(c: OrderingConstraint, poly: GenericType): Array[Type] =
c.boundsMap(poly)
- def updateEntries(c: OrderingConstraint, poly: PolyType, entries: Array[Type])(implicit ctx: Context): OrderingConstraint =
+ def updateEntries(c: OrderingConstraint, poly: GenericType, entries: Array[Type])(implicit ctx: Context): OrderingConstraint =
newConstraint(c.boundsMap.updated(poly, entries), c.lowerMap, c.upperMap)
def initial = NoType
}
val lowerLens = new ConstraintLens[List[PolyParam]] {
- def entries(c: OrderingConstraint, poly: PolyType): Array[List[PolyParam]] =
+ def entries(c: OrderingConstraint, poly: GenericType): Array[List[PolyParam]] =
c.lowerMap(poly)
- def updateEntries(c: OrderingConstraint, poly: PolyType, entries: Array[List[PolyParam]])(implicit ctx: Context): OrderingConstraint =
+ def updateEntries(c: OrderingConstraint, poly: GenericType, entries: Array[List[PolyParam]])(implicit ctx: Context): OrderingConstraint =
newConstraint(c.boundsMap, c.lowerMap.updated(poly, entries), c.upperMap)
def initial = Nil
}
val upperLens = new ConstraintLens[List[PolyParam]] {
- def entries(c: OrderingConstraint, poly: PolyType): Array[List[PolyParam]] =
+ def entries(c: OrderingConstraint, poly: GenericType): Array[List[PolyParam]] =
c.upperMap(poly)
- def updateEntries(c: OrderingConstraint, poly: PolyType, entries: Array[List[PolyParam]])(implicit ctx: Context): OrderingConstraint =
+ def updateEntries(c: OrderingConstraint, poly: GenericType, entries: Array[List[PolyParam]])(implicit ctx: Context): OrderingConstraint =
newConstraint(c.boundsMap, c.lowerMap, c.upperMap.updated(poly, entries))
def initial = Nil
}
@@ -147,7 +147,7 @@ class OrderingConstraint(private val boundsMap: ParamBounds,
// ----------- Contains tests --------------------------------------------------
- def contains(pt: PolyType): Boolean = boundsMap(pt) != null
+ def contains(pt: GenericType): Boolean = boundsMap(pt) != null
def contains(param: PolyParam): Boolean = {
val entries = boundsMap(param.binder)
@@ -278,7 +278,7 @@ class OrderingConstraint(private val boundsMap: ParamBounds,
stripParams(tp, paramBuf, isUpper)
.orElse(if (isUpper) defn.AnyType else defn.NothingType)
- def add(poly: PolyType, tvars: List[TypeVar])(implicit ctx: Context): This = {
+ def add(poly: GenericType, tvars: List[TypeVar])(implicit ctx: Context): This = {
assert(!contains(poly))
val nparams = poly.paramNames.length
val entries1 = new Array[Type](nparams * 2)
@@ -291,7 +291,7 @@ class OrderingConstraint(private val boundsMap: ParamBounds,
* Update all bounds to be normalized and update ordering to account for
* dependent parameters.
*/
- private def init(poly: PolyType)(implicit ctx: Context): This = {
+ private def init(poly: GenericType)(implicit ctx: Context): This = {
var current = this
val loBuf, hiBuf = new mutable.ListBuffer[PolyParam]
var i = 0
@@ -398,7 +398,7 @@ class OrderingConstraint(private val boundsMap: ParamBounds,
def removeParam(ps: List[PolyParam]) =
ps.filterNot(p => p.binder.eq(poly) && p.paramNum == idx)
- def replaceParam(tp: Type, atPoly: PolyType, atIdx: Int): Type = tp match {
+ def replaceParam(tp: Type, atPoly: GenericType, atIdx: Int): Type = tp match {
case bounds @ TypeBounds(lo, hi) =>
def recombine(andor: AndOrType, op: (Type, Boolean) => Type, isUpper: Boolean): Type = {
@@ -438,9 +438,9 @@ class OrderingConstraint(private val boundsMap: ParamBounds,
}
}
- def remove(pt: PolyType)(implicit ctx: Context): This = {
+ def remove(pt: GenericType)(implicit ctx: Context): This = {
def removeFromOrdering(po: ParamOrdering) = {
- def removeFromBoundss(key: PolyType, bndss: Array[List[PolyParam]]): Array[List[PolyParam]] = {
+ def removeFromBoundss(key: GenericType, bndss: Array[List[PolyParam]]): Array[List[PolyParam]] = {
val bndss1 = bndss.map(_.filterConserve(_.binder ne pt))
if (bndss.corresponds(bndss1)(_ eq _)) bndss else bndss1
}
@@ -449,7 +449,7 @@ class OrderingConstraint(private val boundsMap: ParamBounds,
newConstraint(boundsMap.remove(pt), removeFromOrdering(lowerMap), removeFromOrdering(upperMap))
}
- def isRemovable(pt: PolyType, removedParam: Int = -1): Boolean = {
+ def isRemovable(pt: GenericType, removedParam: Int = -1): Boolean = {
val entries = boundsMap(pt)
var noneLeft = true
var i = paramCount(entries)
@@ -467,13 +467,13 @@ class OrderingConstraint(private val boundsMap: ParamBounds,
// ---------- Exploration --------------------------------------------------------
- def domainPolys: List[PolyType] = boundsMap.keys
+ def domainPolys: List[GenericType] = boundsMap.keys
def domainParams: List[PolyParam] =
for {
(poly, entries) <- boundsMap.toList
n <- 0 until paramCount(entries)
- if isBounds(entries(n))
+ if true || isBounds(entries(n))
} yield PolyParam(poly, n)
def forallParams(p: PolyParam => Boolean): Boolean = {
@@ -484,7 +484,7 @@ class OrderingConstraint(private val boundsMap: ParamBounds,
true
}
- def foreachParam(p: (PolyType, Int) => Unit): Unit =
+ def foreachParam(p: (GenericType, Int) => Unit): Unit =
boundsMap.foreachBinding { (poly, entries) =>
0.until(poly.paramNames.length).foreach(p(poly, _))
}
@@ -501,7 +501,7 @@ class OrderingConstraint(private val boundsMap: ParamBounds,
override def checkClosed()(implicit ctx: Context): Unit = {
def isFreePolyParam(tp: Type) = tp match {
- case PolyParam(binder, _) => !contains(binder)
+ case PolyParam(binder: GenericType, _) => !contains(binder)
case _ => false
}
def checkClosedType(tp: Type, where: String) =
diff --git a/src/dotty/tools/dotc/core/SymDenotations.scala b/src/dotty/tools/dotc/core/SymDenotations.scala
index 2692f57a2..46d93b753 100644
--- a/src/dotty/tools/dotc/core/SymDenotations.scala
+++ b/src/dotty/tools/dotc/core/SymDenotations.scala
@@ -1127,7 +1127,7 @@ object SymDenotations {
case tp: NamedType => hasSkolems(tp.prefix)
case tp: RefinedType => hasSkolems(tp.parent) || hasSkolems(tp.refinedInfo)
case tp: RecType => hasSkolems(tp.parent)
- case tp: PolyType => tp.paramBounds.exists(hasSkolems) || hasSkolems(tp.resType)
+ case tp: GenericType => tp.paramBounds.exists(hasSkolems) || hasSkolems(tp.resType)
case tp: MethodType => tp.paramTypes.exists(hasSkolems) || hasSkolems(tp.resType)
case tp: ExprType => hasSkolems(tp.resType)
case tp: HKApply => hasSkolems(tp.tycon) || tp.args.exists(hasSkolems)
@@ -1658,6 +1658,8 @@ object SymDenotations {
case _ =>
baseTypeRefOf(tp.underlying)
}
+ case tp: HKApply =>
+ baseTypeRefOf(tp.upperBound) // TODO drop?
case tp: TypeProxy =>
baseTypeRefOf(tp.underlying)
case AndType(tp1, tp2) =>
diff --git a/src/dotty/tools/dotc/core/TypeApplications.scala b/src/dotty/tools/dotc/core/TypeApplications.scala
index 60d01c125..d7c73c63f 100644
--- a/src/dotty/tools/dotc/core/TypeApplications.scala
+++ b/src/dotty/tools/dotc/core/TypeApplications.scala
@@ -687,7 +687,7 @@ class TypeApplications(val self: Type) extends AnyVal {
final def appliedTo(args: List[Type])(implicit ctx: Context): Type = /*>|>*/ track("appliedTo") /*<|<*/ {
if (args.isEmpty || ctx.erasedTypes) self
else self.stripTypeVar match { // TODO investigate why we can't do safeDealias here
- case self: PolyType if !args.exists(_.isInstanceOf[TypeBounds]) =>
+ case self: GenericType if !args.exists(_.isInstanceOf[TypeBounds]) =>
self.instantiate(args)
case EtaExpansion(self1) =>
self1.appliedTo(args)
diff --git a/src/dotty/tools/dotc/core/TypeComparer.scala b/src/dotty/tools/dotc/core/TypeComparer.scala
index 9449787c1..68a263dfc 100644
--- a/src/dotty/tools/dotc/core/TypeComparer.scala
+++ b/src/dotty/tools/dotc/core/TypeComparer.scala
@@ -559,6 +559,7 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling {
*/
def compareHkApply2(tp1: Type, tp2: Type, tycon2: Type, args2: List[Type]): Boolean = {
val tparams = tycon2.typeParams
+ assert(tparams.nonEmpty)
def isMatchingApply(tp1: Type): Boolean = tp1 match {
case HKApply(tycon1, args1) =>
@@ -1087,10 +1088,10 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling {
formals2.isEmpty
}
- /** Do poly types `poly1` and `poly2` have type parameters that
+ /** Do generic types `poly1` and `poly2` have type parameters that
* have the same bounds (after renaming one set to the other)?
*/
- private def matchingTypeParams(poly1: PolyType, poly2: PolyType): Boolean =
+ private def matchingTypeParams(poly1: GenericType, poly2: GenericType): Boolean =
(poly1.paramBounds corresponds poly2.paramBounds)((b1, b2) =>
isSameType(b1, b2.subst(poly2, poly1)))
@@ -1312,7 +1313,7 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling {
else if (tparams1.length != tparams2.length) mergeConflict(tp1, tp2)
else if (Config.newHK) {
val numArgs = tparams1.length
- def argRefs(tl: PolyType) = List.range(0, numArgs).map(PolyParam(tl, _))
+ def argRefs(tl: GenericType) = List.range(0, numArgs).map(PolyParam(tl, _))
TypeLambda(
paramNames = tpnme.syntheticLambdaParamNames(numArgs),
variances = (tparams1, tparams2).zipped.map((tparam1, tparam2) =>
@@ -1382,10 +1383,10 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling {
case _ =>
mergeConflict(tp1, tp2)
}
- case tp1: PolyType =>
+ case tp1: GenericType =>
tp2 match {
- case tp2: PolyType if matchingTypeParams(tp1, tp2) =>
- tp1.derivedPolyType(
+ case tp2: GenericType if matchingTypeParams(tp1, tp2) =>
+ tp1.derivedGenericType(
mergeNames(tp1.paramNames, tp2.paramNames, tpnme.syntheticTypeParamName),
tp1.paramBounds, tp1.resultType & tp2.resultType.subst(tp2, tp1))
case _ =>
@@ -1438,10 +1439,10 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling {
case _ =>
mergeConflict(tp1, tp2)
}
- case tp1: PolyType =>
+ case tp1: GenericType =>
tp2 match {
- case tp2: PolyType if matchingTypeParams(tp1, tp2) =>
- tp1.derivedPolyType(
+ case tp2: GenericType if matchingTypeParams(tp1, tp2) =>
+ tp1.derivedGenericType(
mergeNames(tp1.paramNames, tp2.paramNames, tpnme.syntheticTypeParamName),
tp1.paramBounds, tp1.resultType | tp2.resultType.subst(tp2, tp1))
case _ =>
diff --git a/src/dotty/tools/dotc/core/TyperState.scala b/src/dotty/tools/dotc/core/TyperState.scala
index 36f026107..e64335218 100644
--- a/src/dotty/tools/dotc/core/TyperState.scala
+++ b/src/dotty/tools/dotc/core/TyperState.scala
@@ -127,7 +127,7 @@ extends TyperState(r) {
}
override def gc()(implicit ctx: Context): Unit = {
- val toCollect = new mutable.ListBuffer[PolyType]
+ val toCollect = new mutable.ListBuffer[GenericType]
constraint foreachTypeVar { tvar =>
if (!tvar.inst.exists) {
val inst = instType(tvar)
diff --git a/src/dotty/tools/dotc/core/Types.scala b/src/dotty/tools/dotc/core/Types.scala
index ca60f08a6..ac0048e16 100644
--- a/src/dotty/tools/dotc/core/Types.scala
+++ b/src/dotty/tools/dotc/core/Types.scala
@@ -67,7 +67,8 @@ object Types {
* +- MethodType -----+- ImplicitMethodType
* | +- JavaMethodType
* +- ClassInfo
- * +- PolyType --------- TypeLambda
+ * +- GenericType ----+- PolyType
+ * | +- TypeLambda
* |
* +- NoType
* +- NoPrefix
@@ -1082,10 +1083,10 @@ object Types {
}
- /** The parameter types in the first parameter section of a PolyType or MethodType, Empty list for others */
+ /** The parameter types in the first parameter section of a generic type or MethodType, Empty list for others */
final def firstParamTypes(implicit ctx: Context): List[Type] = this match {
case mt: MethodType => mt.paramTypes
- case pt: PolyType => pt.resultType.firstParamTypes
+ case pt: GenericType => pt.resultType.firstParamTypes
case _ => Nil
}
@@ -2572,8 +2573,9 @@ object Types {
}
}
- abstract case class PolyType(paramNames: List[TypeName])(paramBoundsExp: PolyType => List[TypeBounds], resultTypeExp: PolyType => Type)
- extends CachedGroundType with BindingType with TermType with MethodOrPoly {
+ /** A common superclass of PolyType and TypeLambda */
+ abstract class GenericType(val paramNames: List[TypeName])(paramBoundsExp: GenericType => List[TypeBounds], resultTypeExp: GenericType => Type)
+ extends CachedGroundType with BindingType with TermType {
val paramBounds = paramBoundsExp(this)
val resType = resultTypeExp(this)
@@ -2585,32 +2587,17 @@ object Types {
/** If this is a type lambda, the variances of its parameters, otherwise Nil.*/
def variances: List[Int] = Nil
- protected def computeSignature(implicit ctx: Context) = resultSignature
-
- def isPolymorphicMethodType: Boolean = resType match {
- case _: MethodType => true
- case _ => false
- }
-
final def instantiate(argTypes: List[Type])(implicit ctx: Context): Type =
resultType.substParams(this, argTypes)
def instantiateBounds(argTypes: List[Type])(implicit ctx: Context): List[TypeBounds] =
paramBounds.mapConserve(_.substParams(this, argTypes).bounds)
- def derivedPolyType(paramNames: List[TypeName], paramBounds: List[TypeBounds], resType: Type)(implicit ctx: Context) =
+ def derivedGenericType(paramNames: List[TypeName], paramBounds: List[TypeBounds], resType: Type)(implicit ctx: Context) =
if ((paramNames eq this.paramNames) && (paramBounds eq this.paramBounds) && (resType eq this.resType)) this
else duplicate(paramNames, paramBounds, resType)
- def duplicate(paramNames: List[TypeName] = this.paramNames, paramBounds: List[TypeBounds] = this.paramBounds, resType: Type)(implicit ctx: Context) =
- if (this.variances.isEmpty)
- PolyType(paramNames)(
- x => paramBounds mapConserve (_.subst(this, x).bounds),
- x => resType.subst(this, x))
- else
- TypeLambda(paramNames, variances)(
- x => paramBounds mapConserve (_.subst(this, x).bounds),
- x => resType.subst(this, x))
+ def duplicate(paramNames: List[TypeName] = this.paramNames, paramBounds: List[TypeBounds] = this.paramBounds, resType: Type)(implicit ctx: Context): GenericType
def lifted(tparams: List[MemberBinding], t: Type)(implicit ctx: Context): Type =
tparams match {
@@ -2621,26 +2608,44 @@ object Types {
}
override def equals(other: Any) = other match {
- case other: PolyType =>
+ case other: GenericType =>
other.paramNames == this.paramNames &&
other.paramBounds == this.paramBounds &&
other.resType == this.resType &&
other.variances == this.variances
case _ => false
}
+
override def computeHash = {
doHash(variances ::: paramNames, resType, paramBounds)
}
+ }
+
+ /** A type for polymorphic methods */
+ class PolyType(paramNames: List[TypeName])(paramBoundsExp: GenericType => List[TypeBounds], resultTypeExp: GenericType => Type)
+ extends GenericType(paramNames)(paramBoundsExp, resultTypeExp) with MethodOrPoly {
+
+ protected def computeSignature(implicit ctx: Context) = resultSignature
+
+ def isPolymorphicMethodType: Boolean = resType match {
+ case _: MethodType => true
+ case _ => false
+ }
+
+ def derivedPolyType(paramNames: List[TypeName], paramBounds: List[TypeBounds], resType: Type)(implicit ctx: Context) =
+ derivedGenericType(paramNames, paramBounds, resType)
+
+ def duplicate(paramNames: List[TypeName] = this.paramNames, paramBounds: List[TypeBounds] = this.paramBounds, resType: Type)(implicit ctx: Context): PolyType =
+ PolyType(paramNames)(
+ x => paramBounds mapConserve (_.subst(this, x).bounds),
+ x => resType.subst(this, x))
override def toString = s"PolyType($paramNames, $paramBounds, $resType)"
}
- class CachedPolyType(paramNames: List[TypeName])(paramBoundsExp: PolyType => List[TypeBounds], resultTypeExp: PolyType => Type)
- extends PolyType(paramNames)(paramBoundsExp, resultTypeExp)
-
object PolyType {
- def apply(paramNames: List[TypeName])(paramBoundsExp: PolyType => List[TypeBounds], resultTypeExp: PolyType => Type)(implicit ctx: Context): PolyType = {
- unique(new CachedPolyType(paramNames)(paramBoundsExp, resultTypeExp))
+ def apply(paramNames: List[TypeName])(paramBoundsExp: GenericType => List[TypeBounds], resultTypeExp: GenericType => Type)(implicit ctx: Context): PolyType = {
+ unique(new PolyType(paramNames)(paramBoundsExp, resultTypeExp))
}
def fromSymbols(tparams: List[Symbol], resultType: Type)(implicit ctx: Context) =
@@ -2653,16 +2658,24 @@ object Types {
// ----- HK types: TypeLambda, LambdaParam, HKApply ---------------------
/** 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: PolyType => List[TypeBounds], resultTypeExp: PolyType => Type)
- extends PolyType(paramNames)(paramBoundsExp, resultTypeExp) with ValueType {
+ class TypeLambda(paramNames: List[TypeName], override val variances: List[Int])(paramBoundsExp: GenericType => List[TypeBounds], resultTypeExp: GenericType => Type)
+ extends GenericType(paramNames)(paramBoundsExp, resultTypeExp) with ValueType {
assert(resType.isValueType, this)
+ assert(paramNames.nonEmpty)
lazy val typeParams: List[LambdaParam] =
paramNames.indices.toList.map(new LambdaParam(this, _))
- override def toString = s"TypeLambda($variances, $paramNames, $paramBounds, $resType)"
+ def derivedTypeLambda(paramNames: List[TypeName], paramBounds: List[TypeBounds], resType: Type)(implicit ctx: Context) =
+ derivedGenericType(paramNames, paramBounds, resType)
+ def duplicate(paramNames: List[TypeName] = this.paramNames, paramBounds: List[TypeBounds] = this.paramBounds, resType: Type)(implicit ctx: Context): TypeLambda =
+ TypeLambda(paramNames, variances)(
+ x => paramBounds mapConserve (_.subst(this, x).bounds),
+ x => resType.subst(this, x))
+
+ override def toString = s"TypeLambda($variances, $paramNames, $paramBounds, $resType)"
}
/** The parameter of a type lambda */
@@ -2676,7 +2689,7 @@ object Types {
}
object TypeLambda {
- def apply(paramNames: List[TypeName], variances: List[Int])(paramBoundsExp: PolyType => List[TypeBounds], resultTypeExp: PolyType => Type)(implicit ctx: Context): PolyType = {
+ def apply(paramNames: List[TypeName], variances: List[Int])(paramBoundsExp: GenericType => List[TypeBounds], resultTypeExp: GenericType => Type)(implicit ctx: Context): TypeLambda = {
unique(new TypeLambda(paramNames, variances)(paramBoundsExp, resultTypeExp))
}
def fromSymbols(tparams: List[Symbol], resultType: Type)(implicit ctx: Context) =
@@ -2720,9 +2733,14 @@ object Types {
*/
protected def checkInst(implicit ctx: Context): this.type = {
def check(tycon: Type): Unit = tycon.stripTypeVar match {
- case _: TypeRef | _: PolyParam | ErrorType =>
- case tycon: AnnotatedType => check(tycon.underlying)
- case _ => assert(false, s"illegal type constructor in $this")
+ case tycon: TypeRef if !tycon.symbol.isClass =>
+ case _: PolyParam | ErrorType =>
+ case _: TypeLambda =>
+ assert(args.exists(_.isInstanceOf[TypeBounds]), s"unreduced type apply: $this")
+ case tycon: AnnotatedType =>
+ check(tycon.underlying)
+ case _ =>
+ assert(false, s"illegal type constructor in $this")
}
check(tycon)
this
@@ -2783,8 +2801,8 @@ object Types {
}
/** TODO Some docs would be nice here! */
- case class PolyParam(binder: PolyType, paramNum: Int) extends ParamType {
- type BT = PolyType
+ case class PolyParam(binder: GenericType, paramNum: Int) extends ParamType {
+ type BT = GenericType
def copyBoundType(bt: BT) = PolyParam(bt, paramNum)
/** Looking only at the structure of `bound`, is one of the following true?
@@ -2804,7 +2822,7 @@ object Types {
override def underlying(implicit ctx: Context): Type = {
val bounds = binder.paramBounds
- if (bounds == null) NoType // this can happen if the PolyType is not initialized yet
+ if (bounds == null) NoType // this can happen if the references generic type is not initialized yet
else bounds(paramNum)
}
// no customized hashCode/equals needed because cycle is broken in PolyType
@@ -3436,7 +3454,8 @@ object Types {
protected def derivedSuperType(tp: SuperType, thistp: Type, supertp: Type): Type =
tp.derivedSuperType(thistp, supertp)
protected def derivedAppliedType(tp: HKApply, tycon: Type, args: List[Type]): Type =
- tp.derivedAppliedType(tycon, args)
+ if (tycon.typeParams.isEmpty) tycon
+ else tp.derivedAppliedType(tycon, args)
protected def derivedAndOrType(tp: AndOrType, tp1: Type, tp2: Type): Type =
tp.derivedAndOrType(tp1, tp2)
protected def derivedAnnotatedType(tp: AnnotatedType, underlying: Type, annot: Annotation): Type =
@@ -3451,8 +3470,8 @@ object Types {
tp.derivedMethodType(tp.paramNames, formals, restpe)
protected def derivedExprType(tp: ExprType, restpe: Type): Type =
tp.derivedExprType(restpe)
- protected def derivedPolyType(tp: PolyType, pbounds: List[TypeBounds], restpe: Type): Type =
- tp.derivedPolyType(tp.paramNames, pbounds, restpe)
+ protected def derivedGenericType(tp: GenericType, pbounds: List[TypeBounds], restpe: Type): Type =
+ tp.derivedGenericType(tp.paramNames, pbounds, restpe)
/** Map this function over given type */
def mapOver(tp: Type): Type = {
@@ -3494,12 +3513,12 @@ object Types {
case tp: ExprType =>
derivedExprType(tp, this(tp.resultType))
- case tp: PolyType =>
+ case tp: GenericType =>
def mapOverPoly = {
variance = -variance
val bounds1 = tp.paramBounds.mapConserve(this).asInstanceOf[List[TypeBounds]]
variance = -variance
- derivedPolyType(tp, bounds1, this(tp.resultType))
+ derivedGenericType(tp, bounds1, this(tp.resultType))
}
mapOverPoly
@@ -3713,7 +3732,7 @@ object Types {
case ExprType(restpe) =>
this(x, restpe)
- case tp @ PolyType(pnames) =>
+ case tp: GenericType =>
variance = -variance
val y = foldOver(x, tp.paramBounds)
variance = -variance
diff --git a/src/dotty/tools/dotc/core/tasty/TreeUnpickler.scala b/src/dotty/tools/dotc/core/tasty/TreeUnpickler.scala
index 6f0596ac0..c428ac8c0 100644
--- a/src/dotty/tools/dotc/core/tasty/TreeUnpickler.scala
+++ b/src/dotty/tools/dotc/core/tasty/TreeUnpickler.scala
@@ -311,7 +311,7 @@ class TreeUnpickler(reader: TastyReader, tastyName: TastyName.Table) {
result
case PARAMtype =>
readTypeRef() match {
- case binder: PolyType => PolyParam(binder, readNat())
+ case binder: GenericType => PolyParam(binder, readNat())
case binder: MethodType => MethodParam(binder, readNat())
}
case CLASSconst =>
diff --git a/src/dotty/tools/dotc/core/unpickleScala2/Scala2Unpickler.scala b/src/dotty/tools/dotc/core/unpickleScala2/Scala2Unpickler.scala
index aa660f73e..239dd4124 100644
--- a/src/dotty/tools/dotc/core/unpickleScala2/Scala2Unpickler.scala
+++ b/src/dotty/tools/dotc/core/unpickleScala2/Scala2Unpickler.scala
@@ -82,8 +82,8 @@ object Scala2Unpickler {
paramNames,
paramTypes.init :+ defn.RepeatedParamType.appliedTo(elemtp),
tp.resultType)
- case tp @ PolyType(paramNames) =>
- tp.derivedPolyType(paramNames, tp.paramBounds, arrayToRepeated(tp.resultType))
+ case tp: PolyType =>
+ tp.derivedPolyType(tp.paramNames, tp.paramBounds, arrayToRepeated(tp.resultType))
}
def ensureConstructor(cls: ClassSymbol, scope: Scope)(implicit ctx: Context) =
diff --git a/src/dotty/tools/dotc/printing/PlainPrinter.scala b/src/dotty/tools/dotc/printing/PlainPrinter.scala
index e86137c47..d1a0560f2 100644
--- a/src/dotty/tools/dotc/printing/PlainPrinter.scala
+++ b/src/dotty/tools/dotc/printing/PlainPrinter.scala
@@ -229,7 +229,7 @@ class PlainPrinter(_ctx: Context) extends Printer {
protected def simpleNameString(sym: Symbol): String = nameString(sym.name)
/** If -uniqid is set, the hashcode of the polytype, after a # */
- protected def polyHash(pt: PolyType): Text =
+ protected def polyHash(pt: GenericType): Text =
"#" + pt.hashCode provided ctx.settings.uniqid.value
/** If -uniqid is set, the unique id of symbol, after a # */
diff --git a/src/dotty/tools/dotc/transform/FullParameterization.scala b/src/dotty/tools/dotc/transform/FullParameterization.scala
index be64df384..d2052d8cb 100644
--- a/src/dotty/tools/dotc/transform/FullParameterization.scala
+++ b/src/dotty/tools/dotc/transform/FullParameterization.scala
@@ -95,7 +95,7 @@ trait FullParameterization {
*/
def fullyParameterizedType(info: Type, clazz: ClassSymbol, abstractOverClass: Boolean = true, liftThisType: Boolean = false)(implicit ctx: Context): Type = {
val (mtparamCount, origResult) = info match {
- case info @ PolyType(mtnames) => (mtnames.length, info.resultType)
+ case info: PolyType => (info.paramNames.length, info.resultType)
case info: ExprType => (0, info.resultType)
case _ => (0, info)
}
@@ -111,18 +111,18 @@ trait FullParameterization {
}
/** Replace class type parameters by the added type parameters of the polytype `pt` */
- def mapClassParams(tp: Type, pt: PolyType): Type = {
+ def mapClassParams(tp: Type, pt: GenericType): Type = {
val classParamsRange = (mtparamCount until mtparamCount + ctparams.length).toList
tp.substDealias(ctparams, classParamsRange map (PolyParam(pt, _)))
}
/** The bounds for the added type parameters of the polytype `pt` */
- def mappedClassBounds(pt: PolyType): List[TypeBounds] =
+ def mappedClassBounds(pt: GenericType): List[TypeBounds] =
ctparams.map(tparam => mapClassParams(tparam.info, pt).bounds)
info match {
- case info @ PolyType(mtnames) =>
- PolyType(mtnames ++ ctnames)(
+ case info: PolyType =>
+ PolyType(info.paramNames ++ ctnames)(
pt =>
(info.paramBounds.map(mapClassParams(_, pt).bounds) ++
mappedClassBounds(pt)).mapConserve(_.subst(info, pt).bounds),
diff --git a/src/dotty/tools/dotc/transform/PostTyper.scala b/src/dotty/tools/dotc/transform/PostTyper.scala
index fcde59b24..6b0b2b073 100644
--- a/src/dotty/tools/dotc/transform/PostTyper.scala
+++ b/src/dotty/tools/dotc/transform/PostTyper.scala
@@ -178,9 +178,9 @@ class PostTyper extends MacroTransform with IdentityDenotTransformer { thisTran
}
val (tycon, args) = decompose(tree)
tycon.tpe.widen match {
- case PolyType(pnames) =>
+ case tp: PolyType =>
val (namedArgs, otherArgs) = args.partition(isNamedArg)
- val args1 = reorderArgs(pnames, namedArgs.asInstanceOf[List[NamedArg]], otherArgs)
+ val args1 = reorderArgs(tp.paramNames, namedArgs.asInstanceOf[List[NamedArg]], otherArgs)
TypeApply(tycon, args1).withPos(tree.pos).withType(tree.tpe)
case _ =>
tree
diff --git a/src/dotty/tools/dotc/typer/Checking.scala b/src/dotty/tools/dotc/typer/Checking.scala
index cfad4e77e..9f218c3f1 100644
--- a/src/dotty/tools/dotc/typer/Checking.scala
+++ b/src/dotty/tools/dotc/typer/Checking.scala
@@ -51,7 +51,7 @@ object Checking {
* Note: This does not check the bounds of AppliedTypeTrees. These
* are handled by method checkBounds in FirstTransform
*/
- def checkBounds(args: List[tpd.Tree], poly: PolyType)(implicit ctx: Context): Unit =
+ def checkBounds(args: List[tpd.Tree], poly: GenericType)(implicit ctx: Context): Unit =
checkBounds(args, poly.paramBounds, _.substParams(poly, _))
/** Traverse type tree, performing the following checks:
diff --git a/src/dotty/tools/dotc/typer/ProtoTypes.scala b/src/dotty/tools/dotc/typer/ProtoTypes.scala
index 68fd99b3f..9a1337022 100644
--- a/src/dotty/tools/dotc/typer/ProtoTypes.scala
+++ b/src/dotty/tools/dotc/typer/ProtoTypes.scala
@@ -286,7 +286,7 @@ object ProtoTypes {
override def isMatchedBy(tp: Type)(implicit ctx: Context) = {
def isInstantiatable(tp: Type) = tp.widen match {
- case PolyType(paramNames) => paramNames.length == targs.length
+ case tp: GenericType => tp.paramNames.length == targs.length
case _ => false
}
isInstantiatable(tp) || tp.member(nme.apply).hasAltWith(d => isInstantiatable(d.info))
diff --git a/src/dotty/tools/dotc/typer/Variances.scala b/src/dotty/tools/dotc/typer/Variances.scala
index 9af11a0f4..a2f9a0f16 100644
--- a/src/dotty/tools/dotc/typer/Variances.scala
+++ b/src/dotty/tools/dotc/typer/Variances.scala
@@ -94,7 +94,7 @@ object Variances {
v
}
varianceInArgs(varianceInType(tycon)(tparam), args, tycon.typeParams)
- case tp @ PolyType(_) =>
+ case tp: GenericType =>
flip(varianceInTypes(tp.paramBounds)(tparam)) & varianceInType(tp.resultType)(tparam)
case AnnotatedType(tp, annot) =>
varianceInType(tp)(tparam) & varianceInAnnot(annot)(tparam)