aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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)