diff options
32 files changed, 185 insertions, 260 deletions
diff --git a/dottydoc/src/dotty/tools/dottydoc/model/factories.scala b/dottydoc/src/dotty/tools/dottydoc/model/factories.scala index b19b836ee..f95474ef1 100644 --- a/dottydoc/src/dotty/tools/dottydoc/model/factories.scala +++ b/dottydoc/src/dotty/tools/dottydoc/model/factories.scala @@ -43,7 +43,7 @@ object factories { } def expandTpe(t: Type, params: List[Reference] = Nil): Reference = t match { - case tl: TypeLambda => + case tl: PolyType => //FIXME: should be handled correctly // example, in `Option`: // diff --git a/src/dotty/tools/backend/jvm/CollectEntryPoints.scala b/src/dotty/tools/backend/jvm/CollectEntryPoints.scala index 3ed232bc7..2ee1b6011 100644 --- a/src/dotty/tools/backend/jvm/CollectEntryPoints.scala +++ b/src/dotty/tools/backend/jvm/CollectEntryPoints.scala @@ -107,7 +107,7 @@ object CollectEntryPoints{ else (possibles exists(x=> isJavaMainMethod(x.symbol))) || { possibles exists { m => toDenot(m.symbol).info match { - case t:PolyType => + case t: PolyType => fail("main methods cannot be generic.") case t@MethodType(paramNames, paramTypes) => if (t.resultType :: paramTypes exists (_.typeSymbol.isAbstractType)) diff --git a/src/dotty/tools/dotc/ast/Trees.scala b/src/dotty/tools/dotc/ast/Trees.scala index ed3690795..1fb3557db 100644 --- a/src/dotty/tools/dotc/ast/Trees.scala +++ b/src/dotty/tools/dotc/ast/Trees.scala @@ -562,9 +562,9 @@ object Trees { } /** [typeparams] -> tpt */ - case class TypeLambdaTree[-T >: Untyped] private[ast] (tparams: List[TypeDef[T]], body: Tree[T]) + case class PolyTypeTree[-T >: Untyped] private[ast] (tparams: List[TypeDef[T]], body: Tree[T]) extends TypTree[T] { - type ThisTree[-T >: Untyped] = TypeLambdaTree[T] + type ThisTree[-T >: Untyped] = PolyTypeTree[T] } /** => T */ @@ -820,7 +820,7 @@ object Trees { type OrTypeTree = Trees.OrTypeTree[T] type RefinedTypeTree = Trees.RefinedTypeTree[T] type AppliedTypeTree = Trees.AppliedTypeTree[T] - type TypeLambdaTree = Trees.TypeLambdaTree[T] + type PolyTypeTree = Trees.PolyTypeTree[T] type ByNameTypeTree = Trees.ByNameTypeTree[T] type TypeBoundsTree = Trees.TypeBoundsTree[T] type Bind = Trees.Bind[T] @@ -984,9 +984,9 @@ object Trees { case tree: AppliedTypeTree if (tpt eq tree.tpt) && (args eq tree.args) => tree case _ => finalize(tree, untpd.AppliedTypeTree(tpt, args)) } - def TypeLambdaTree(tree: Tree)(tparams: List[TypeDef], body: Tree): TypeLambdaTree = tree match { - case tree: TypeLambdaTree if (tparams eq tree.tparams) && (body eq tree.body) => tree - case _ => finalize(tree, untpd.TypeLambdaTree(tparams, body)) + def PolyTypeTree(tree: Tree)(tparams: List[TypeDef], body: Tree): PolyTypeTree = tree match { + case tree: PolyTypeTree if (tparams eq tree.tparams) && (body eq tree.body) => tree + case _ => finalize(tree, untpd.PolyTypeTree(tparams, body)) } def ByNameTypeTree(tree: Tree)(result: Tree): ByNameTypeTree = tree match { case tree: ByNameTypeTree if result eq tree.result => tree @@ -1118,8 +1118,8 @@ object Trees { cpy.RefinedTypeTree(tree)(transform(tpt), transformSub(refinements)) case AppliedTypeTree(tpt, args) => cpy.AppliedTypeTree(tree)(transform(tpt), transform(args)) - case TypeLambdaTree(tparams, body) => - cpy.TypeLambdaTree(tree)(transformSub(tparams), transform(body)) + case PolyTypeTree(tparams, body) => + cpy.PolyTypeTree(tree)(transformSub(tparams), transform(body)) case ByNameTypeTree(result) => cpy.ByNameTypeTree(tree)(transform(result)) case TypeBoundsTree(lo, hi) => @@ -1222,7 +1222,7 @@ object Trees { this(this(x, tpt), refinements) case AppliedTypeTree(tpt, args) => this(this(x, tpt), args) - case TypeLambdaTree(tparams, body) => + case PolyTypeTree(tparams, body) => implicit val ctx: Context = localCtx this(this(x, tparams), body) case ByNameTypeTree(result) => diff --git a/src/dotty/tools/dotc/ast/untpd.scala b/src/dotty/tools/dotc/ast/untpd.scala index cc7cefbac..852c3a346 100644 --- a/src/dotty/tools/dotc/ast/untpd.scala +++ b/src/dotty/tools/dotc/ast/untpd.scala @@ -212,7 +212,7 @@ object untpd extends Trees.Instance[Untyped] with UntypedTreeInfo { def OrTypeTree(left: Tree, right: Tree): OrTypeTree = new OrTypeTree(left, right) def RefinedTypeTree(tpt: Tree, refinements: List[Tree]): RefinedTypeTree = new RefinedTypeTree(tpt, refinements) def AppliedTypeTree(tpt: Tree, args: List[Tree]): AppliedTypeTree = new AppliedTypeTree(tpt, args) - def TypeLambdaTree(tparams: List[TypeDef], body: Tree): TypeLambdaTree = new TypeLambdaTree(tparams, body) + def PolyTypeTree(tparams: List[TypeDef], body: Tree): PolyTypeTree = new PolyTypeTree(tparams, body) def ByNameTypeTree(result: Tree): ByNameTypeTree = new ByNameTypeTree(result) def TypeBoundsTree(lo: Tree, hi: Tree): TypeBoundsTree = new TypeBoundsTree(lo, hi) def Bind(name: Name, body: Tree): Bind = new Bind(name, body) diff --git a/src/dotty/tools/dotc/core/Constraint.scala b/src/dotty/tools/dotc/core/Constraint.scala index 91e70b7b5..c99b748b7 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: GenericType): Boolean + def contains(pt: PolyType): 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: GenericType, tvars: List[TypeVar])(implicit ctx: Context): This + def add(poly: PolyType, 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`. @@ -121,13 +121,13 @@ abstract class Constraint extends Showable { * all type parameters of the entry are associated with type variables * which have their `inst` fields set. */ - def isRemovable(pt: GenericType): Boolean + def isRemovable(pt: PolyType): Boolean /** A new constraint with all entries coming from `pt` removed. */ - def remove(pt: GenericType)(implicit ctx: Context): This + def remove(pt: PolyType)(implicit ctx: Context): This /** The polytypes constrained by this constraint */ - def domainPolys: List[GenericType] + def domainPolys: List[PolyType] /** The polytype parameters constrained by this constraint */ def domainParams: List[PolyParam] diff --git a/src/dotty/tools/dotc/core/ConstraintHandling.scala b/src/dotty/tools/dotc/core/ConstraintHandling.scala index 84f531385..3835d553c 100644 --- a/src/dotty/tools/dotc/core/ConstraintHandling.scala +++ b/src/dotty/tools/dotc/core/ConstraintHandling.scala @@ -44,10 +44,10 @@ trait ConstraintHandling { try op finally alwaysFluid = saved } - /** We are currently comparing lambdas. Used as a flag for + /** We are currently comparing polytypes. Used as a flag for * optimization: when `false`, no need to do an expensive `pruneLambdaParams` */ - protected var comparingLambdas = false + protected var comparedPolyTypes: Set[PolyType] = Set.empty private def addOneBound(param: PolyParam, bound: Type, isUpper: Boolean): Boolean = !constraint.contains(param) || { @@ -316,12 +316,12 @@ trait ConstraintHandling { * missing. */ def pruneLambdaParams(tp: Type) = - if (comparingLambdas && param.binder.isInstanceOf[PolyType]) { + if (comparedPolyTypes.nonEmpty) { val approx = new ApproximatingTypeMap { def apply(t: Type): Type = t match { - case t @ PolyParam(tl: TypeLambda, n) => + case t @ PolyParam(pt: PolyType, n) if comparedPolyTypes contains pt => val effectiveVariance = if (fromBelow) -variance else variance - val bounds = tl.paramBounds(n) + val bounds = pt.paramBounds(n) if (effectiveVariance > 0) bounds.lo else if (effectiveVariance < 0) bounds.hi else NoType diff --git a/src/dotty/tools/dotc/core/Definitions.scala b/src/dotty/tools/dotc/core/Definitions.scala index b1c2bc535..50746c61d 100644 --- a/src/dotty/tools/dotc/core/Definitions.scala +++ b/src/dotty/tools/dotc/core/Definitions.scala @@ -92,17 +92,17 @@ class Definitions { } private def newPolyMethod(cls: ClassSymbol, name: TermName, typeParamCount: Int, - resultTypeFn: GenericType => Type, flags: FlagSet = EmptyFlags) = { + resultTypeFn: PolyType => 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: GenericType => Type, flags: FlagSet) = + private def newT1ParameterlessMethod(cls: ClassSymbol, name: TermName, resultTypeFn: PolyType => Type, flags: FlagSet) = newPolyMethod(cls, name, 1, resultTypeFn, flags) - private def newT1EmptyParamsMethod(cls: ClassSymbol, name: TermName, resultTypeFn: GenericType => Type, flags: FlagSet) = + private def newT1EmptyParamsMethod(cls: ClassSymbol, name: TermName, resultTypeFn: PolyType => 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 93e9878e7..72c7a8e51 100644 --- a/src/dotty/tools/dotc/core/OrderingConstraint.scala +++ b/src/dotty/tools/dotc/core/OrderingConstraint.scala @@ -14,7 +14,7 @@ import annotation.tailrec object OrderingConstraint { - type ArrayValuedMap[T] = SimpleMap[GenericType, Array[T]] + type ArrayValuedMap[T] = SimpleMap[PolyType, Array[T]] /** The type of `OrderingConstraint#boundsMap` */ type ParamBounds = ArrayValuedMap[Type] @@ -32,11 +32,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: GenericType): Array[T] - def updateEntries(c: OrderingConstraint, poly: GenericType, entries: Array[T])(implicit ctx: Context): OrderingConstraint + def entries(c: OrderingConstraint, poly: PolyType): Array[T] + def updateEntries(c: OrderingConstraint, poly: PolyType, entries: Array[T])(implicit ctx: Context): OrderingConstraint def initial: T - def apply(c: OrderingConstraint, poly: GenericType, idx: Int) = { + def apply(c: OrderingConstraint, poly: PolyType, idx: Int) = { val es = entries(c, poly) if (es == null) initial else es(idx) } @@ -47,7 +47,7 @@ object OrderingConstraint { * parts of `current` which are not shared by `prev`. */ def update(prev: OrderingConstraint, current: OrderingConstraint, - poly: GenericType, idx: Int, entry: T)(implicit ctx: Context): OrderingConstraint = { + poly: PolyType, idx: Int, entry: T)(implicit ctx: Context): OrderingConstraint = { var es = entries(current, poly) if (es != null && (es(idx) eq entry)) current else { @@ -72,7 +72,7 @@ object OrderingConstraint { update(prev, current, param.binder, param.paramNum, entry) def map(prev: OrderingConstraint, current: OrderingConstraint, - poly: GenericType, idx: Int, f: T => T)(implicit ctx: Context): OrderingConstraint = + poly: PolyType, 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, @@ -81,25 +81,25 @@ object OrderingConstraint { } val boundsLens = new ConstraintLens[Type] { - def entries(c: OrderingConstraint, poly: GenericType): Array[Type] = + def entries(c: OrderingConstraint, poly: PolyType): Array[Type] = c.boundsMap(poly) - def updateEntries(c: OrderingConstraint, poly: GenericType, entries: Array[Type])(implicit ctx: Context): OrderingConstraint = + def updateEntries(c: OrderingConstraint, poly: PolyType, 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: GenericType): Array[List[PolyParam]] = + def entries(c: OrderingConstraint, poly: PolyType): Array[List[PolyParam]] = c.lowerMap(poly) - def updateEntries(c: OrderingConstraint, poly: GenericType, entries: Array[List[PolyParam]])(implicit ctx: Context): OrderingConstraint = + def updateEntries(c: OrderingConstraint, poly: PolyType, 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: GenericType): Array[List[PolyParam]] = + def entries(c: OrderingConstraint, poly: PolyType): Array[List[PolyParam]] = c.upperMap(poly) - def updateEntries(c: OrderingConstraint, poly: GenericType, entries: Array[List[PolyParam]])(implicit ctx: Context): OrderingConstraint = + def updateEntries(c: OrderingConstraint, poly: PolyType, entries: Array[List[PolyParam]])(implicit ctx: Context): OrderingConstraint = newConstraint(c.boundsMap, c.lowerMap, c.upperMap.updated(poly, entries)) def initial = Nil } @@ -149,7 +149,7 @@ class OrderingConstraint(private val boundsMap: ParamBounds, // ----------- Contains tests -------------------------------------------------- - def contains(pt: GenericType): Boolean = boundsMap(pt) != null + def contains(pt: PolyType): Boolean = boundsMap(pt) != null def contains(param: PolyParam): Boolean = { val entries = boundsMap(param.binder) @@ -280,7 +280,7 @@ class OrderingConstraint(private val boundsMap: ParamBounds, stripParams(tp, paramBuf, isUpper) .orElse(if (isUpper) defn.AnyType else defn.NothingType) - def add(poly: GenericType, tvars: List[TypeVar])(implicit ctx: Context): This = { + def add(poly: PolyType, tvars: List[TypeVar])(implicit ctx: Context): This = { assert(!contains(poly)) val nparams = poly.paramNames.length val entries1 = new Array[Type](nparams * 2) @@ -293,7 +293,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: GenericType)(implicit ctx: Context): This = { + private def init(poly: PolyType)(implicit ctx: Context): This = { var current = this val loBuf, hiBuf = new mutable.ListBuffer[PolyParam] var i = 0 @@ -400,7 +400,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: GenericType, atIdx: Int): Type = tp match { + def replaceParam(tp: Type, atPoly: PolyType, atIdx: Int): Type = tp match { case bounds @ TypeBounds(lo, hi) => def recombine(andor: AndOrType, op: (Type, Boolean) => Type, isUpper: Boolean): Type = { @@ -440,9 +440,9 @@ class OrderingConstraint(private val boundsMap: ParamBounds, } } - def remove(pt: GenericType)(implicit ctx: Context): This = { + def remove(pt: PolyType)(implicit ctx: Context): This = { def removeFromOrdering(po: ParamOrdering) = { - def removeFromBoundss(key: GenericType, bndss: Array[List[PolyParam]]): Array[List[PolyParam]] = { + def removeFromBoundss(key: PolyType, bndss: Array[List[PolyParam]]): Array[List[PolyParam]] = { val bndss1 = bndss.map(_.filterConserve(_.binder ne pt)) if (bndss.corresponds(bndss1)(_ eq _)) bndss else bndss1 } @@ -451,7 +451,7 @@ class OrderingConstraint(private val boundsMap: ParamBounds, newConstraint(boundsMap.remove(pt), removeFromOrdering(lowerMap), removeFromOrdering(upperMap)) } - def isRemovable(pt: GenericType): Boolean = { + def isRemovable(pt: PolyType): Boolean = { val entries = boundsMap(pt) @tailrec def allRemovable(last: Int): Boolean = if (last < 0) true @@ -464,7 +464,7 @@ class OrderingConstraint(private val boundsMap: ParamBounds, // ---------- Exploration -------------------------------------------------------- - def domainPolys: List[GenericType] = boundsMap.keys + def domainPolys: List[PolyType] = boundsMap.keys def domainParams: List[PolyParam] = for { @@ -481,7 +481,7 @@ class OrderingConstraint(private val boundsMap: ParamBounds, true } - def foreachParam(p: (GenericType, Int) => Unit): Unit = + def foreachParam(p: (PolyType, Int) => Unit): Unit = boundsMap.foreachBinding { (poly, entries) => 0.until(poly.paramNames.length).foreach(p(poly, _)) } @@ -541,7 +541,7 @@ class OrderingConstraint(private val boundsMap: ParamBounds, override def checkClosed()(implicit ctx: Context): Unit = { def isFreePolyParam(tp: Type) = tp match { - case PolyParam(binder: GenericType, _) => !contains(binder) + case PolyParam(binder: PolyType, _) => !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 05501011a..a98d6732a 100644 --- a/src/dotty/tools/dotc/core/SymDenotations.scala +++ b/src/dotty/tools/dotc/core/SymDenotations.scala @@ -1150,7 +1150,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: GenericType => tp.paramBounds.exists(hasSkolems) || hasSkolems(tp.resType) + case tp: PolyType => 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) diff --git a/src/dotty/tools/dotc/core/TypeApplications.scala b/src/dotty/tools/dotc/core/TypeApplications.scala index 8a4b47efb..8aaf77032 100644 --- a/src/dotty/tools/dotc/core/TypeApplications.scala +++ b/src/dotty/tools/dotc/core/TypeApplications.scala @@ -72,7 +72,7 @@ object TypeApplications { } def unapply(tp: Type)(implicit ctx: Context): Option[TypeRef] = tp match { - case tp @ TypeLambda(tparams, AppliedType(fn: TypeRef, args)) if (args == tparams.map(_.toArg)) => Some(fn) + case tp @ PolyType(tparams, AppliedType(fn: TypeRef, args)) if (args == tparams.map(_.toArg)) => Some(fn) case _ => None } } @@ -159,7 +159,7 @@ object TypeApplications { * result type. Using this mode, we can guarantee that `appliedTo` will never * produce a higher-kinded application with a type lambda as type constructor. */ - class Reducer(tycon: TypeLambda, args: List[Type])(implicit ctx: Context) extends TypeMap { + class Reducer(tycon: PolyType, args: List[Type])(implicit ctx: Context) extends TypeMap { private var available = (0 until args.length).toSet var allReplaced = true def hasWildcardArg(p: PolyParam) = @@ -212,7 +212,7 @@ class TypeApplications(val self: Type) extends AnyVal { self match { case self: ClassInfo => self.cls.typeParams - case self: TypeLambda => + case self: PolyType => self.typeParams case self: TypeRef => val tsym = self.symbol @@ -311,7 +311,7 @@ class TypeApplications(val self: Type) extends AnyVal { def isHK(implicit ctx: Context): Boolean = self.dealias match { case self: TypeRef => self.info.isHK case self: RefinedType => false - case self: TypeLambda => true + case self: PolyType => true case self: SingletonType => false case self: TypeVar => // Using `origin` instead of `underlying`, as is done for typeParams, @@ -339,7 +339,7 @@ class TypeApplications(val self: Type) extends AnyVal { */ def LambdaAbstract(tparams: List[TypeParamInfo])(implicit ctx: Context): Type = { def expand(tp: Type) = - TypeLambda( + PolyType( tpnme.syntheticLambdaParamNames(tparams.length), tparams.map(_.paramVariance))( tl => tparams.map(tparam => tl.lifted(tparams, tparam.paramBounds).bounds), tl => tl.lifted(tparams, tp)) @@ -421,10 +421,10 @@ class TypeApplications(val self: Type) extends AnyVal { if (hkParams.isEmpty) self else { def adaptArg(arg: Type): Type = arg match { - case arg @ TypeLambda(tparams, body) if + case arg @ PolyType(tparams, body) if !tparams.corresponds(hkParams)(_.paramVariance == _.paramVariance) && tparams.corresponds(hkParams)(varianceConforms) => - TypeLambda(tparams.map(_.paramName), hkParams.map(_.paramVariance))( + PolyType(tparams.map(_.paramName), hkParams.map(_.paramVariance))( tl => arg.paramBounds.map(_.subst(arg, tl).bounds), tl => arg.resultType.subst(arg, tl) ) @@ -466,7 +466,7 @@ class TypeApplications(val self: Type) extends AnyVal { val dealiased = stripped.safeDealias if (args.isEmpty || ctx.erasedTypes) self else dealiased match { - case dealiased: TypeLambda => + case dealiased: PolyType => def tryReduce = if (!args.exists(_.isInstanceOf[TypeBounds])) { val followAlias = Config.simplifyApplications && { @@ -485,7 +485,7 @@ class TypeApplications(val self: Type) extends AnyVal { // In this case we should always dealias since we cannot handle // higher-kinded applications to wildcard arguments. dealiased - .derivedGenericType(resType = tycon.safeDealias.appliedTo(args1)) + .derivedPolyType(resType = tycon.safeDealias.appliedTo(args1)) .appliedTo(args) case _ => val reducer = new Reducer(dealiased, args) @@ -494,8 +494,6 @@ class TypeApplications(val self: Type) extends AnyVal { else HKApply(dealiased, args) } tryReduce - case dealiased: PolyType => - dealiased.instantiate(args) case dealiased: AndOrType => dealiased.derivedAndOrType(dealiased.tp1.appliedTo(args), dealiased.tp2.appliedTo(args)) case dealiased: TypeAlias => diff --git a/src/dotty/tools/dotc/core/TypeComparer.scala b/src/dotty/tools/dotc/core/TypeComparer.scala index 7f60f0231..b495f00d0 100644 --- a/src/dotty/tools/dotc/core/TypeComparer.scala +++ b/src/dotty/tools/dotc/core/TypeComparer.scala @@ -412,9 +412,9 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling { compareRec case tp2 @ HKApply(tycon2, args2) => compareHkApply2(tp1, tp2, tycon2, args2) - case tp2 @ TypeLambda(tparams2, body2) => + case tp2 @ PolyType(tparams2, body2) => def compareHkLambda: Boolean = tp1.stripTypeVar match { - case tp1 @ TypeLambda(tparams1, body1) => + case tp1 @ PolyType(tparams1, body1) => /* Don't compare bounds of lambdas under language:Scala2, or t2994 will fail * The issue is that, logically, bounds should compare contravariantly, * but that would invalidate a pattern exploited in t2994: @@ -432,13 +432,14 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling { ctx.scala2Mode || tparams1.corresponds(tparams2)((tparam1, tparam2) => isSubType(tparam2.paramBounds.subst(tp2, tp1), tparam1.paramBounds)) - val saved = comparingLambdas - comparingLambdas = true + val saved = comparedPolyTypes + comparedPolyTypes += tp1 + comparedPolyTypes += tp2 try variancesConform(tparams1, tparams2) && boundsOK && isSubType(body1, body2.subst(tp2, tp1)) - finally comparingLambdas = saved + finally comparedPolyTypes = saved case _ => if (!tp1.isHK) { tp2 match { @@ -650,7 +651,7 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling { val tparams1 = tparams1a.drop(lengthDiff) variancesConform(tparams1, tparams) && { if (lengthDiff > 0) - tycon1b = TypeLambda(tparams1.map(_.paramName), tparams1.map(_.paramVariance))( + tycon1b = PolyType(tparams1.map(_.paramName), tparams1.map(_.paramVariance))( tl => tparams1.map(tparam => tl.lifted(tparams, tparam.paramBounds).bounds), tl => tycon1a.appliedTo(args1.take(lengthDiff) ++ tparams1.indices.toList.map(PolyParam(tl, _)))) @@ -1264,7 +1265,7 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling { else if (tparams2.isEmpty) original(tp1.appliedTo(tp1.typeParams.map(_.paramBoundsAsSeenFrom(tp1))), tp2) else - TypeLambda( + PolyType( paramNames = tpnme.syntheticLambdaParamNames(tparams1.length), variances = (tparams1, tparams2).zipped.map((tparam1, tparam2) => (tparam1.paramVariance + tparam2.paramVariance) / 2))( diff --git a/src/dotty/tools/dotc/core/TypeErasure.scala b/src/dotty/tools/dotc/core/TypeErasure.scala index bd1b9b1d3..fd5fcb921 100644 --- a/src/dotty/tools/dotc/core/TypeErasure.scala +++ b/src/dotty/tools/dotc/core/TypeErasure.scala @@ -169,7 +169,7 @@ object TypeErasure { val erase = erasureFn(isJava, semiEraseVCs, sym.isConstructor, wildcardOK = false) def eraseParamBounds(tp: PolyType): Type = - tp.derivedGenericType( + tp.derivedPolyType( tp.paramNames, tp.paramNames map (Function.const(TypeBounds.upper(defn.ObjectType))), tp.resultType) if (defn.isPolymorphicAfterErasure(sym)) eraseParamBounds(sym.info.asInstanceOf[PolyType]) @@ -370,11 +370,6 @@ class TypeErasure(isJava: Boolean, semiEraseVCs: Boolean, isConstructor: Boolean case rt => tp.derivedMethodType(tp.paramNames, formals, rt) } - case tp: PolyType => - this(tp.resultType) match { - case rt: MethodType => rt - case rt => MethodType(Nil, Nil, rt) - } case tp @ ClassInfo(pre, cls, classParents, decls, _) => if (cls is Package) tp else { @@ -409,9 +404,9 @@ class TypeErasure(isJava: Boolean, semiEraseVCs: Boolean, isConstructor: Boolean else JavaArrayType(arrayErasure(elemtp)) } - /** The erasure of a symbol's info. This is different from `apply` in the way `ExprType`s are - * treated. `eraseInfo` maps them them to nullary method types, whereas `apply` maps them - * to `Function0`. + /** The erasure of a symbol's info. This is different from `apply` in the way `ExprType`s and + * `PolyType`s are treated. `eraseInfo` maps them them to method types, whereas `apply` maps them + * to the underlying type. */ def eraseInfo(tp: Type, sym: Symbol)(implicit ctx: Context) = tp match { case ExprType(rt) => @@ -421,6 +416,11 @@ class TypeErasure(isJava: Boolean, semiEraseVCs: Boolean, isConstructor: Boolean // forwarders to mixin methods. // See doc comment for ElimByName for speculation how we could improve this. else MethodType(Nil, Nil, eraseResult(rt)) + case tp: PolyType => + this(tp.resultType) match { + case rt: MethodType => rt + case rt => MethodType(Nil, Nil, rt) + } case tp => this(tp) } diff --git a/src/dotty/tools/dotc/core/TyperState.scala b/src/dotty/tools/dotc/core/TyperState.scala index 7e332b412..5c476c1cb 100644 --- a/src/dotty/tools/dotc/core/TyperState.scala +++ b/src/dotty/tools/dotc/core/TyperState.scala @@ -152,7 +152,7 @@ extends TyperState(r) { } override def gc()(implicit ctx: Context): Unit = { - val toCollect = new mutable.ListBuffer[GenericType] + val toCollect = new mutable.ListBuffer[PolyType] 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 08b11e1cb..d242843e5 100644 --- a/src/dotty/tools/dotc/core/Types.scala +++ b/src/dotty/tools/dotc/core/Types.scala @@ -61,8 +61,7 @@ object Types { * | +- ExprType * | +- AnnotatedType * | +- TypeVar - * | +- GenericType ----+- PolyType - * | +- TypeLambda + * | +- PolyType * | * +- GroundType -+- AndType * +- OrType @@ -97,7 +96,7 @@ object Types { final def isValueType: Boolean = this.isInstanceOf[ValueType] /** Is the is value type or type lambda? */ - final def isValueTypeOrLambda: Boolean = isValueType || this.isInstanceOf[TypeLambda] + final def isValueTypeOrLambda: Boolean = isValueType || this.isInstanceOf[PolyType] /** Does this type denote a stable reference (i.e. singleton type)? */ final def isStable(implicit ctx: Context): Boolean = stripTypeVar match { @@ -522,7 +521,7 @@ object Types { } def goApply(tp: HKApply) = tp.tycon match { - case tl: TypeLambda => + case tl: PolyType => go(tl.resType).mapInfo(info => tl.derivedLambdaAbstraction(tl.paramNames, tl.paramBounds, info).appliedTo(tp.args)) case _ => @@ -1087,7 +1086,7 @@ object Types { /** 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: GenericType => pt.resultType.firstParamTypes + case pt: PolyType => pt.resultType.firstParamTypes case _ => Nil } @@ -2263,7 +2262,7 @@ object Types { // and therefore two different poly types would never be equal. /** A trait that mixes in functionality for signature caching */ - trait MethodicType extends Type { + trait MethodicType extends TermType { private[this] var mySignature: Signature = _ private[this] var mySignatureRunId: Int = NoRunId @@ -2503,11 +2502,10 @@ object Types { } } - /** A common supertrait of PolyType and TypeLambda */ - abstract class GenericType(val paramNames: List[TypeName]) - (paramBoundsExp: GenericType => List[TypeBounds], - resultTypeExp: GenericType => Type) - extends CachedProxyType with BindingType with TermType { + /** A type lambda of the form `[v_0 X_0, ..., v_n X_n] => T` */ + class PolyType(val paramNames: List[TypeName], val variances: List[Int])( + paramBoundsExp: PolyType => List[TypeBounds], resultTypeExp: PolyType => Type) + extends CachedProxyType with BindingType with MethodOrPoly { /** The bounds of the type parameters */ val paramBounds: List[TypeBounds] = paramBoundsExp(this) @@ -2515,115 +2513,6 @@ object Types { /** The result type of a PolyType / body of a type lambda */ val resType: Type = resultTypeExp(this) - /** If this is a type lambda, the variances of its parameters, otherwise Nil.*/ - def variances: List[Int] = Nil - - override def resultType(implicit ctx: Context) = resType - override def underlying(implicit ctx: Context) = resType - - /** Instantiate result type by substituting parameters with given arguments */ - final def instantiate(argTypes: List[Type])(implicit ctx: Context): Type = - resultType.substParams(this, argTypes) - - /** Instantiate parameter bounds by substituting parameters with given arguments */ - def instantiateBounds(argTypes: List[Type])(implicit ctx: Context): List[TypeBounds] = - 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): GenericType - - def derivedGenericType(paramNames: List[TypeName] = this.paramNames, - paramBounds: List[TypeBounds] = this.paramBounds, - resType: Type = this.resType)(implicit ctx: Context) = - if ((paramNames eq this.paramNames) && (paramBounds eq this.paramBounds) && (resType eq this.resType)) this - else newLikeThis(paramNames, paramBounds, resType) - - /** PolyParam references to all type parameters of this type */ - lazy val paramRefs: List[PolyParam] = paramNames.indices.toList.map(PolyParam(this, _)) - - /** The type `[tparams := paramRefs] tp`, where `tparams` can be - * either a list of type parameter symbols or a list of lambda parameters - */ - def lifted(tparams: List[TypeParamInfo], tp: Type)(implicit ctx: Context): Type = - tparams match { - case LambdaParam(poly, _) :: _ => tp.subst(poly, this) - case tparams: List[Symbol @unchecked] => tp.subst(tparams, paramRefs) - } - - override def equals(other: Any) = other match { - 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) - } - - abstract class GenericCompanion[GT <: GenericType] { - def apply(paramNames: List[TypeName], variances: List[Int])( - paramBoundsExp: GenericType => List[TypeBounds], - resultTypeExp: GenericType => Type)(implicit ctx: Context): GT - - def fromSymbols(tparams: List[Symbol], resultType: Type)(implicit ctx: Context): Type = - if (tparams.isEmpty) resultType - else apply(tparams map (_.name.asTypeName), tparams.map(_.variance))( - pt => tparams.map(tparam => pt.lifted(tparams, tparam.info).bounds), - pt => pt.lifted(tparams, resultType)) - } - - /** A type for polymorphic methods */ - class PolyType(paramNames: List[TypeName], variances: List[Int])(paramBoundsExp: GenericType => List[TypeBounds], resultTypeExp: GenericType => Type) - extends TypeLambda(paramNames, variances)(paramBoundsExp, resultTypeExp) with MethodOrPoly { - - protected override def computeSignature(implicit ctx: Context) = resultSignature - - override def isPolymorphicMethodType: Boolean = resType match { - case _: MethodType => true - case _ => false - } - - /** Merge nested polytypes into one polytype. nested polytypes are normally not supported - * but can arise as temporary data structures. - */ - override def flatten(implicit ctx: Context): PolyType = 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 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, paramNames.map(alwaysZero))(paramBoundsExp, resultTypeExp)) - } - } - - // ----- 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: GenericType => List[TypeBounds], resultTypeExp: GenericType => Type) - extends GenericType(paramNames)(paramBoundsExp, resultTypeExp) with MethodOrPoly { - assert(resType.isInstanceOf[TermType], this) assert(paramNames.nonEmpty) @@ -2634,14 +2523,34 @@ object Types { case _ => false } + /** PolyParam references to all type parameters of this type */ + lazy val paramRefs: List[PolyParam] = paramNames.indices.toList.map(PolyParam(this, _)) + 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)( + override def resultType(implicit ctx: Context) = resType + override def underlying(implicit ctx: Context) = resType + + /** Instantiate result type by substituting parameters with given arguments */ + final def instantiate(argTypes: List[Type])(implicit ctx: Context): Type = + resultType.substParams(this, argTypes) + + /** Instantiate parameter bounds by substituting parameters with given arguments */ + final def instantiateBounds(argTypes: List[Type])(implicit ctx: Context): List[TypeBounds] = + paramBounds.mapConserve(_.substParams(this, argTypes).bounds) + + 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)) + def derivedPolyType(paramNames: List[TypeName] = this.paramNames, + paramBounds: List[TypeBounds] = this.paramBounds, + resType: Type = this.resType)(implicit ctx: Context) = + if ((paramNames eq this.paramNames) && (paramBounds eq this.paramBounds) && (resType eq this.resType)) this + else newLikeThis(paramNames, paramBounds, resType) + def derivedLambdaAbstraction(paramNames: List[TypeName], paramBounds: List[TypeBounds], resType: Type)(implicit ctx: Context): Type = resType match { case resType @ TypeAlias(alias) => @@ -2651,13 +2560,13 @@ object Types { if (lo.isRef(defn.NothingClass)) lo else newLikeThis(paramNames, paramBounds, lo), newLikeThis(paramNames, paramBounds, hi)) case _ => - derivedGenericType(paramNames, paramBounds, resType) + derivedPolyType(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 { + def flatten(implicit ctx: Context): PolyType = resType match { case that: PolyType => val shift = new TypeMap { def apply(t: Type) = t match { @@ -2672,18 +2581,44 @@ object Types { case _ => this } - override def toString = s"TypeLambda($variances, $paramNames, $paramBounds, $resType)" + /** The type `[tparams := paramRefs] tp`, where `tparams` can be + * either a list of type parameter symbols or a list of lambda parameters + */ + def lifted(tparams: List[TypeParamInfo], tp: Type)(implicit ctx: Context): Type = + tparams match { + case LambdaParam(poly, _) :: _ => tp.subst(poly, this) + case tparams: List[Symbol @unchecked] => tp.subst(tparams, paramRefs) + } + + override def equals(other: Any) = other match { + case other: PolyType => + other.paramNames == this.paramNames && + other.paramBounds == this.paramBounds && + other.resType == this.resType && + other.variances == this.variances + case _ => false + } + + override def toString = s"PolyType($variances, $paramNames, $paramBounds, $resType)" + + override def computeHash = doHash(variances ::: paramNames, resType, paramBounds) } - object TypeLambda extends GenericCompanion[TypeLambda] { + object PolyType { def apply(paramNames: List[TypeName], variances: List[Int] = Nil)( - paramBoundsExp: GenericType => List[TypeBounds], - resultTypeExp: GenericType => Type)(implicit ctx: Context): TypeLambda = { + paramBoundsExp: PolyType => List[TypeBounds], + resultTypeExp: PolyType => Type)(implicit ctx: Context): PolyType = { val vs = if (variances.isEmpty) paramNames.map(alwaysZero) else variances - unique(new TypeLambda(paramNames, vs)(paramBoundsExp, resultTypeExp)) + unique(new PolyType(paramNames, vs)(paramBoundsExp, resultTypeExp)) } - def unapply(tl: TypeLambda): Some[(List[LambdaParam], Type)] = + def fromSymbols(tparams: List[Symbol], resultType: Type)(implicit ctx: Context): Type = + if (tparams.isEmpty) resultType + else apply(tparams map (_.name.asTypeName), tparams.map(_.variance))( + pt => tparams.map(tparam => pt.lifted(tparams, tparam.info).bounds), + pt => pt.lifted(tparams, resultType)) + + def unapply(tl: PolyType): Some[(List[LambdaParam], Type)] = Some((tl.typeParams, tl.resType)) def any(n: Int)(implicit ctx: Context) = @@ -2691,8 +2626,10 @@ object Types { pt => List.fill(n)(TypeBounds.empty), pt => defn.AnyType) } + // ----- HK types: LambdaParam, HKApply --------------------- + /** The parameter of a type lambda */ - case class LambdaParam(tl: TypeLambda, n: Int) extends TypeParamInfo { + case class LambdaParam(tl: PolyType, n: Int) extends TypeParamInfo { def isTypeParam(implicit ctx: Context) = true def paramName(implicit ctx: Context): TypeName = tl.paramNames(n) def paramBounds(implicit ctx: Context): TypeBounds = tl.paramBounds(n) @@ -2715,7 +2652,7 @@ object Types { override def superType(implicit ctx: Context): Type = { if (ctx.period != validSuper) { cachedSuper = tycon match { - case tp: TypeLambda => defn.AnyType + case tp: PolyType => defn.AnyType case tp: TypeVar if !tp.inst.exists => // supertype not stable, since underlying might change return tp.underlying.applyIfParameterized(args) @@ -2741,7 +2678,7 @@ object Types { def typeParams(implicit ctx: Context): List[TypeParamInfo] = { val tparams = tycon.typeParams - if (tparams.isEmpty) TypeLambda.any(args.length).typeParams else tparams + if (tparams.isEmpty) PolyType.any(args.length).typeParams else tparams } def derivedAppliedType(tycon: Type, args: List[Type])(implicit ctx: Context): Type = @@ -2754,7 +2691,7 @@ object Types { def check(tycon: Type): Unit = tycon.stripTypeVar match { case tycon: TypeRef if !tycon.symbol.isClass => case _: PolyParam | ErrorType | _: WildcardType => - case _: TypeLambda => + case _: PolyType => assert(args.exists(_.isInstanceOf[TypeBounds]), s"unreduced type apply: $this") case tycon: AnnotatedType => check(tycon.underlying) @@ -2820,8 +2757,8 @@ object Types { } /** TODO Some docs would be nice here! */ - case class PolyParam(binder: GenericType, paramNum: Int) extends ParamType { - type BT = GenericType + case class PolyParam(binder: PolyType, paramNum: Int) extends ParamType { + type BT = PolyType def copyBoundType(bt: BT) = PolyParam(bt, paramNum) /** Looking only at the structure of `bound`, is one of the following true? @@ -3427,8 +3364,8 @@ object Types { tp.derivedMethodType(tp.paramNames, formals, restpe) protected def derivedExprType(tp: ExprType, restpe: Type): Type = tp.derivedExprType(restpe) - protected def derivedGenericType(tp: GenericType, pbounds: List[TypeBounds], restpe: Type): Type = - tp.derivedGenericType(tp.paramNames, pbounds, restpe) + protected def derivedPolyType(tp: PolyType, pbounds: List[TypeBounds], restpe: Type): Type = + tp.derivedPolyType(tp.paramNames, pbounds, restpe) /** Map this function over given type */ def mapOver(tp: Type): Type = { @@ -3470,12 +3407,12 @@ object Types { case tp: ExprType => derivedExprType(tp, this(tp.resultType)) - case tp: GenericType => + case tp: PolyType => def mapOverPoly = { variance = -variance val bounds1 = tp.paramBounds.mapConserve(this).asInstanceOf[List[TypeBounds]] variance = -variance - derivedGenericType(tp, bounds1, this(tp.resultType)) + derivedPolyType(tp, bounds1, this(tp.resultType)) } mapOverPoly @@ -3688,7 +3625,7 @@ object Types { case ExprType(restpe) => this(x, restpe) - case tp: GenericType => + case tp: PolyType => variance = -variance val y = foldOver(x, tp.paramBounds) variance = -variance diff --git a/src/dotty/tools/dotc/core/tasty/TreePickler.scala b/src/dotty/tools/dotc/core/tasty/TreePickler.scala index b6f52c0ec..8889e8a5c 100644 --- a/src/dotty/tools/dotc/core/tasty/TreePickler.scala +++ b/src/dotty/tools/dotc/core/tasty/TreePickler.scala @@ -251,7 +251,7 @@ class TreePickler(pickler: TastyPickler) { case tpe: ExprType => writeByte(BYNAMEtype) pickleType(tpe.underlying) - case tpe: TypeLambda => + case tpe: PolyType => writeByte(LAMBDAtype) val paramNames = tpe.typeParams.map(tparam => varianceToPrefix(tparam.paramVariance) +: tparam.paramName) @@ -259,9 +259,6 @@ class TreePickler(pickler: TastyPickler) { case tpe: MethodType if richTypes => writeByte(METHODtype) pickleMethodic(tpe.resultType, tpe.paramNames, tpe.paramTypes) - case tpe: PolyType if richTypes => - writeByte(POLYtype) - pickleMethodic(tpe.resultType, tpe.paramNames, tpe.paramBounds) case tpe: PolyParam => if (!pickleParamType(tpe)) // TODO figure out why this case arises in e.g. pickling AbstractFileReader. diff --git a/src/dotty/tools/dotc/core/tasty/TreeUnpickler.scala b/src/dotty/tools/dotc/core/tasty/TreeUnpickler.scala index 09f2c0d1f..f67159808 100644 --- a/src/dotty/tools/dotc/core/tasty/TreeUnpickler.scala +++ b/src/dotty/tools/dotc/core/tasty/TreeUnpickler.scala @@ -270,7 +270,7 @@ class TreeUnpickler(reader: TastyReader, tastyName: TastyName.Table, posUnpickle val (rawNames, paramReader) = readNamesSkipParams val (variances, paramNames) = rawNames .map(name => (prefixToVariance(name.head), name.tail.toTypeName)).unzip - val result = TypeLambda(paramNames, variances)( + val result = PolyType(paramNames, variances)( pt => registeringType(pt, paramReader.readParamTypes[TypeBounds](end)), pt => readType()) goto(end) @@ -290,7 +290,7 @@ class TreeUnpickler(reader: TastyReader, tastyName: TastyName.Table, posUnpickle result case PARAMtype => readTypeRef() match { - case binder: GenericType => PolyParam(binder, readNat()) + case binder: PolyType => 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 0003459e0..70148b3e2 100644 --- a/src/dotty/tools/dotc/core/unpickleScala2/Scala2Unpickler.scala +++ b/src/dotty/tools/dotc/core/unpickleScala2/Scala2Unpickler.scala @@ -84,7 +84,7 @@ object Scala2Unpickler { paramTypes.init :+ defn.RepeatedParamType.appliedTo(elemtp), tp.resultType) case tp: PolyType => - tp.derivedGenericType(tp.paramNames, tp.paramBounds, arrayToRepeated(tp.resultType)) + 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/parsing/Parsers.scala b/src/dotty/tools/dotc/parsing/Parsers.scala index f22556f27..ab4e38638 100644 --- a/src/dotty/tools/dotc/parsing/Parsers.scala +++ b/src/dotty/tools/dotc/parsing/Parsers.scala @@ -702,7 +702,7 @@ object Parsers { val start = in.offset val tparams = typeParamClause(ParamOwner.TypeParam) if (isIdent && in.name.toString == "->") - atPos(start, in.skipToken())(TypeLambdaTree(tparams, typ())) + atPos(start, in.skipToken())(PolyTypeTree(tparams, typ())) else { syntaxErrorOrIncomplete(expectedMessage("`->'")); typ() } } else infixType() diff --git a/src/dotty/tools/dotc/printing/PlainPrinter.scala b/src/dotty/tools/dotc/printing/PlainPrinter.scala index a92095d9b..564ef21ef 100644 --- a/src/dotty/tools/dotc/printing/PlainPrinter.scala +++ b/src/dotty/tools/dotc/printing/PlainPrinter.scala @@ -114,7 +114,7 @@ class PlainPrinter(_ctx: Context) extends Printer { case _ => toTextGlobal(arg) } - /** The text for a TypeLambda + /** The text for a PolyType * * [v_1 p_1: B_1, ..., v_n p_n: B_n] -> T * @@ -124,7 +124,7 @@ class PlainPrinter(_ctx: Context) extends Printer { * @param argBoundss = B_1, ..., B_n * @param body = T */ - protected def typeLambdaText(paramNames: List[String], variances: List[Int], argBoundss: List[TypeBounds], body: Type): Text = { + protected def polyTypeText(paramNames: List[String], variances: List[Int], argBoundss: List[TypeBounds], body: Type): Text = { def lambdaParamText(variance: Int, name: String, bounds: TypeBounds): Text = varianceString(variance) ~ name ~ toText(bounds) changePrec(GlobalPrec) { @@ -185,16 +185,8 @@ class PlainPrinter(_ctx: Context) extends Printer { } case tp: ExprType => changePrec(GlobalPrec) { "=> " ~ toText(tp.resultType) } - case tp: TypeLambda => - typeLambdaText(tp.paramNames.map(_.toString), tp.variances, tp.paramBounds, tp.resultType) case tp: PolyType => - def paramText(name: TypeName, bounds: TypeBounds): Text = - polyParamNameString(name) ~ polyHash(tp) ~ toText(bounds) - changePrec(GlobalPrec) { - "[" ~ - Text((tp.paramNames, tp.paramBounds).zipped map paramText, ", ") ~ - "]" ~ toText(tp.resultType) - } + polyTypeText(tp.paramNames.map(_.toString), tp.variances, tp.paramBounds, tp.resultType) case tp: PolyParam => polyParamNameString(tp) ~ polyHash(tp.binder) case AnnotatedType(tpe, annot) => @@ -229,7 +221,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: GenericType): Text = + protected def polyHash(pt: PolyType): Text = if (ctx.settings.uniqid.value) "#" + pt.hashCode else "" /** If -uniqid is set, the unique id of symbol, after a # */ diff --git a/src/dotty/tools/dotc/printing/RefinedPrinter.scala b/src/dotty/tools/dotc/printing/RefinedPrinter.scala index b6deca52b..bcd12bc86 100644 --- a/src/dotty/tools/dotc/printing/RefinedPrinter.scala +++ b/src/dotty/tools/dotc/printing/RefinedPrinter.scala @@ -368,7 +368,7 @@ class RefinedPrinter(_ctx: Context) extends PlainPrinter(_ctx) { toTextLocal(tpt) ~ " " ~ blockText(refines) case AppliedTypeTree(tpt, args) => toTextLocal(tpt) ~ "[" ~ Text(args map argText, ", ") ~ "]" - case TypeLambdaTree(tparams, body) => + case PolyTypeTree(tparams, body) => changePrec(GlobalPrec) { tparamsText(tparams) ~ " -> " ~ toText(body) } diff --git a/src/dotty/tools/dotc/sbt/ExtractAPI.scala b/src/dotty/tools/dotc/sbt/ExtractAPI.scala index a7b18b6d6..bc8528c05 100644 --- a/src/dotty/tools/dotc/sbt/ExtractAPI.scala +++ b/src/dotty/tools/dotc/sbt/ExtractAPI.scala @@ -363,7 +363,7 @@ private class ExtractAPICollector(implicit val ctx: Context) extends ThunkHolder val apiTycon = simpleType(tycon) val apiArgs = args.map(processArg) new api.Parameterized(apiTycon, apiArgs.toArray) - case TypeLambda(tparams, res) => + case PolyType(tparams, res) => val apiTparams = tparams.map(apiTypeParameter) val apiRes = apiType(res) new api.Polymorphic(apiRes, apiTparams.toArray) diff --git a/src/dotty/tools/dotc/transform/ElimRepeated.scala b/src/dotty/tools/dotc/transform/ElimRepeated.scala index 1450ff832..258b7f234 100644 --- a/src/dotty/tools/dotc/transform/ElimRepeated.scala +++ b/src/dotty/tools/dotc/transform/ElimRepeated.scala @@ -44,7 +44,7 @@ class ElimRepeated extends MiniPhaseTransform with InfoTransformer with Annotati } else paramTypes tp.derivedMethodType(paramNames, paramTypes1, resultType1) case tp: PolyType => - tp.derivedGenericType(tp.paramNames, tp.paramBounds, elimRepeated(tp.resultType)) + tp.derivedPolyType(tp.paramNames, tp.paramBounds, elimRepeated(tp.resultType)) case tp => tp } @@ -126,7 +126,7 @@ class ElimRepeated extends MiniPhaseTransform with InfoTransformer with Annotati /** Convert type from Scala to Java varargs method */ private def toJavaVarArgs(tp: Type)(implicit ctx: Context): Type = tp match { case tp: PolyType => - tp.derivedGenericType(tp.paramNames, tp.paramBounds, toJavaVarArgs(tp.resultType)) + tp.derivedPolyType(tp.paramNames, tp.paramBounds, toJavaVarArgs(tp.resultType)) case tp: MethodType => val inits :+ last = tp.paramTypes val last1 = last.underlyingIfRepeated(isJava = true) diff --git a/src/dotty/tools/dotc/transform/FullParameterization.scala b/src/dotty/tools/dotc/transform/FullParameterization.scala index d2052d8cb..6c69c735b 100644 --- a/src/dotty/tools/dotc/transform/FullParameterization.scala +++ b/src/dotty/tools/dotc/transform/FullParameterization.scala @@ -111,13 +111,13 @@ trait FullParameterization { } /** Replace class type parameters by the added type parameters of the polytype `pt` */ - def mapClassParams(tp: Type, pt: GenericType): Type = { + def mapClassParams(tp: Type, pt: PolyType): 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: GenericType): List[TypeBounds] = + def mappedClassBounds(pt: PolyType): List[TypeBounds] = ctparams.map(tparam => mapClassParams(tparam.info, pt).bounds) info match { diff --git a/src/dotty/tools/dotc/transform/SuperAccessors.scala b/src/dotty/tools/dotc/transform/SuperAccessors.scala index 79dbd9fe7..10be6db65 100644 --- a/src/dotty/tools/dotc/transform/SuperAccessors.scala +++ b/src/dotty/tools/dotc/transform/SuperAccessors.scala @@ -175,7 +175,7 @@ class SuperAccessors(thisTransformer: DenotTransformer) { val accType = { def accTypeOf(tpe: Type): Type = tpe match { case tpe: PolyType => - tpe.derivedGenericType(tpe.paramNames, tpe.paramBounds, accTypeOf(tpe.resultType)) + tpe.derivedPolyType(tpe.paramNames, tpe.paramBounds, accTypeOf(tpe.resultType)) case _ => MethodType(receiverType :: Nil)(mt => tpe.substThis(sym.owner.asClass, MethodParam(mt, 0))) } @@ -227,7 +227,7 @@ class SuperAccessors(thisTransformer: DenotTransformer) { else clazz.classInfo.selfType def accTypeOf(tpe: Type): Type = tpe match { case tpe: PolyType => - tpe.derivedGenericType(tpe.paramNames, tpe.paramBounds, accTypeOf(tpe.resultType)) + tpe.derivedPolyType(tpe.paramNames, tpe.paramBounds, accTypeOf(tpe.resultType)) case _ => MethodType(receiverType :: Nil)(mt => tpe.substThis(sym.owner.asClass, MethodParam(mt, 0))) } diff --git a/src/dotty/tools/dotc/typer/Applications.scala b/src/dotty/tools/dotc/typer/Applications.scala index e2779e758..56595a637 100644 --- a/src/dotty/tools/dotc/typer/Applications.scala +++ b/src/dotty/tools/dotc/typer/Applications.scala @@ -1019,7 +1019,7 @@ trait Applications extends Compatibility { self: Typer with Dynamic => // todo: make sure implicit method types are not dependent? // but check test case in /tests/pos/depmet_implicit_chaining_zw.scala case pt: PolyType => - pt.derivedGenericType(pt.paramNames, pt.paramBounds, stripImplicit(pt.resultType)) + pt.derivedPolyType(pt.paramNames, pt.paramBounds, stripImplicit(pt.resultType)) case _ => tp } diff --git a/src/dotty/tools/dotc/typer/Checking.scala b/src/dotty/tools/dotc/typer/Checking.scala index 3461facc1..7899174f5 100644 --- a/src/dotty/tools/dotc/typer/Checking.scala +++ b/src/dotty/tools/dotc/typer/Checking.scala @@ -52,7 +52,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: GenericType)(implicit ctx: Context): Unit = + def checkBounds(args: List[tpd.Tree], poly: PolyType)(implicit ctx: Context): Unit = checkBounds(args, poly.paramBounds, _.substParams(poly, _)) /** If type is a higher-kinded application with wildcard arguments, @@ -63,7 +63,7 @@ object Checking { def checkWildcardHKApply(tp: Type, pos: Position)(implicit ctx: Context): Unit = tp match { case tp @ HKApply(tycon, args) if args.exists(_.isInstanceOf[TypeBounds]) => tycon match { - case tycon: TypeLambda => + case tycon: PolyType => ctx.errorOrMigrationWarning( ex"unreducible application of higher-kinded type $tycon to wildcard arguments", pos) diff --git a/src/dotty/tools/dotc/typer/Implicits.scala b/src/dotty/tools/dotc/typer/Implicits.scala index 6e3fe7630..d6cf7fb2b 100644 --- a/src/dotty/tools/dotc/typer/Implicits.scala +++ b/src/dotty/tools/dotc/typer/Implicits.scala @@ -302,7 +302,7 @@ trait ImplicitRunInfo { self: RunInfo => case _ => arg } (apply(tp.tycon) /: tp.args)((tc, arg) => AndType.make(tc, applyArg(arg))) - case tp: TypeLambda => + case tp: PolyType => apply(tp.resType) case _ => mapOver(tp) diff --git a/src/dotty/tools/dotc/typer/Inliner.scala b/src/dotty/tools/dotc/typer/Inliner.scala index d1c160a23..55008c0c5 100644 --- a/src/dotty/tools/dotc/typer/Inliner.scala +++ b/src/dotty/tools/dotc/typer/Inliner.scala @@ -108,7 +108,7 @@ object Inliner { // Add qualifier type as leading method argument to argument `tp` def addQualType(tp: Type): Type = tp match { - case tp: PolyType => tp.derivedGenericType(tp.paramNames, tp.paramBounds, addQualType(tp.resultType)) + case tp: PolyType => tp.derivedPolyType(tp.paramNames, tp.paramBounds, addQualType(tp.resultType)) case tp: ExprType => addQualType(tp.resultType) case tp => MethodType(qualType :: Nil, tp) } diff --git a/src/dotty/tools/dotc/typer/ProtoTypes.scala b/src/dotty/tools/dotc/typer/ProtoTypes.scala index 4fe2ea6bf..d451d6abd 100644 --- a/src/dotty/tools/dotc/typer/ProtoTypes.scala +++ b/src/dotty/tools/dotc/typer/ProtoTypes.scala @@ -316,7 +316,7 @@ object ProtoTypes { override def isMatchedBy(tp: Type)(implicit ctx: Context) = { def isInstantiatable(tp: Type) = tp.widen match { - case tp: GenericType => tp.paramNames.length == targs.length + case tp: PolyType => 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/TypeAssigner.scala b/src/dotty/tools/dotc/typer/TypeAssigner.scala index aecdcbee6..696ecfedb 100644 --- a/src/dotty/tools/dotc/typer/TypeAssigner.scala +++ b/src/dotty/tools/dotc/typer/TypeAssigner.scala @@ -360,7 +360,7 @@ trait TypeAssigner { if (gapBuf.isEmpty) resultType1 else { val gaps = gapBuf.toList - pt.derivedGenericType( + pt.derivedPolyType( gaps.map(paramNames), gaps.map(idx => transform(pt.paramBounds(idx)).bounds), resultType1) @@ -455,8 +455,8 @@ trait TypeAssigner { tree.withType(ownType) } - def assignType(tree: untpd.TypeLambdaTree, tparamDefs: List[TypeDef], body: Tree)(implicit ctx: Context) = - tree.withType(TypeLambda.fromSymbols(tparamDefs.map(_.symbol), body.tpe)) + def assignType(tree: untpd.PolyTypeTree, tparamDefs: List[TypeDef], body: Tree)(implicit ctx: Context) = + tree.withType(PolyType.fromSymbols(tparamDefs.map(_.symbol), body.tpe)) def assignType(tree: untpd.ByNameTypeTree, result: Tree)(implicit ctx: Context) = tree.withType(ExprType(result.tpe)) diff --git a/src/dotty/tools/dotc/typer/Typer.scala b/src/dotty/tools/dotc/typer/Typer.scala index e423082d5..6be119319 100644 --- a/src/dotty/tools/dotc/typer/Typer.scala +++ b/src/dotty/tools/dotc/typer/Typer.scala @@ -1061,12 +1061,12 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit } } - def typedTypeLambdaTree(tree: untpd.TypeLambdaTree)(implicit ctx: Context): Tree = track("typedTypeLambdaTree") { - val TypeLambdaTree(tparams, body) = tree + def typedPolyTypeTree(tree: untpd.PolyTypeTree)(implicit ctx: Context): Tree = track("typedPolyTypeTree") { + val PolyTypeTree(tparams, body) = tree index(tparams) val tparams1 = tparams.mapconserve(typed(_).asInstanceOf[TypeDef]) val body1 = typedType(tree.body) - assignType(cpy.TypeLambdaTree(tree)(tparams1, body1), tparams1, body1) + assignType(cpy.PolyTypeTree(tree)(tparams1, body1), tparams1, body1) } def typedByNameTypeTree(tree: untpd.ByNameTypeTree)(implicit ctx: Context): ByNameTypeTree = track("typedByNameTypeTree") { @@ -1469,7 +1469,7 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit case tree: untpd.OrTypeTree => typedOrTypeTree(tree) case tree: untpd.RefinedTypeTree => typedRefinedTypeTree(tree) case tree: untpd.AppliedTypeTree => typedAppliedTypeTree(tree) - case tree: untpd.TypeLambdaTree => typedTypeLambdaTree(tree)(localContext(tree, NoSymbol).setNewScope) + case tree: untpd.PolyTypeTree => typedPolyTypeTree(tree)(localContext(tree, NoSymbol).setNewScope) case tree: untpd.ByNameTypeTree => typedByNameTypeTree(tree) case tree: untpd.TypeBoundsTree => typedTypeBoundsTree(tree) case tree: untpd.Alternative => typedAlternative(tree, pt) @@ -1921,7 +1921,7 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit case _ => adaptOverloaded(ref) } - case poly: PolyType => + case poly: PolyType if !(ctx.mode is Mode.Type) => if (pt.isInstanceOf[PolyProto]) tree else { var typeArgs = tree match { diff --git a/src/dotty/tools/dotc/typer/Variances.scala b/src/dotty/tools/dotc/typer/Variances.scala index a8abe5e30..92bd9fd74 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: GenericType => + case tp: PolyType => flip(varianceInTypes(tp.paramBounds)(tparam)) & varianceInType(tp.resultType)(tparam) case AnnotatedType(tp, annot) => varianceInType(tp)(tparam) & varianceInAnnot(annot)(tparam) |