aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorodersky <odersky@gmail.com>2017-04-06 14:12:22 +0200
committerGitHub <noreply@github.com>2017-04-06 14:12:22 +0200
commit09cc23726069fa04cbfeec55a9fa4bb8e4a02ff9 (patch)
tree604b5580371851334c05566986538f209ad55544
parent62c2a1e2d6265cf7f096e4c4e51e4e883bce1514 (diff)
parente800987c671c101a3643bfbaf93873db80ced9f3 (diff)
downloaddotty-09cc23726069fa04cbfeec55a9fa4bb8e4a02ff9.tar.gz
dotty-09cc23726069fa04cbfeec55a9fa4bb8e4a02ff9.tar.bz2
dotty-09cc23726069fa04cbfeec55a9fa4bb8e4a02ff9.zip
Merge pull request #2121 from dotty-staging/change-merge-method-poly
Refactor lambda types
-rw-r--r--compiler/src/dotty/tools/backend/jvm/scalaPrimitives.scala2
-rw-r--r--compiler/src/dotty/tools/dotc/ast/Desugar.scala4
-rw-r--r--compiler/src/dotty/tools/dotc/ast/TreeInfo.scala2
-rw-r--r--compiler/src/dotty/tools/dotc/ast/Trees.scala18
-rw-r--r--compiler/src/dotty/tools/dotc/ast/tpd.scala14
-rw-r--r--compiler/src/dotty/tools/dotc/ast/untpd.scala4
-rw-r--r--compiler/src/dotty/tools/dotc/config/Config.scala2
-rw-r--r--compiler/src/dotty/tools/dotc/core/Constants.scala4
-rw-r--r--compiler/src/dotty/tools/dotc/core/Constraint.scala60
-rw-r--r--compiler/src/dotty/tools/dotc/core/ConstraintHandling.scala58
-rw-r--r--compiler/src/dotty/tools/dotc/core/Definitions.scala12
-rw-r--r--compiler/src/dotty/tools/dotc/core/Denotations.scala56
-rw-r--r--compiler/src/dotty/tools/dotc/core/Mode.scala2
-rw-r--r--compiler/src/dotty/tools/dotc/core/NameOps.scala26
-rw-r--r--compiler/src/dotty/tools/dotc/core/OrderingConstraint.scala154
-rw-r--r--compiler/src/dotty/tools/dotc/core/ParamInfo.scala (renamed from compiler/src/dotty/tools/dotc/core/TypeParamInfo.scala)22
-rw-r--r--compiler/src/dotty/tools/dotc/core/StdNames.scala7
-rw-r--r--compiler/src/dotty/tools/dotc/core/Substituters.scala6
-rw-r--r--compiler/src/dotty/tools/dotc/core/SymDenotations.scala7
-rw-r--r--compiler/src/dotty/tools/dotc/core/Symbols.scala12
-rw-r--r--compiler/src/dotty/tools/dotc/core/TypeApplications.scala65
-rw-r--r--compiler/src/dotty/tools/dotc/core/TypeComparer.scala146
-rw-r--r--compiler/src/dotty/tools/dotc/core/TypeErasure.scala22
-rw-r--r--compiler/src/dotty/tools/dotc/core/TypeOps.scala2
-rw-r--r--compiler/src/dotty/tools/dotc/core/TyperState.scala8
-rw-r--r--compiler/src/dotty/tools/dotc/core/Types.scala760
-rw-r--r--compiler/src/dotty/tools/dotc/core/classfile/ClassfileParser.scala6
-rw-r--r--compiler/src/dotty/tools/dotc/core/tasty/TastyFormat.scala21
-rw-r--r--compiler/src/dotty/tools/dotc/core/tasty/TastyPrinter.scala2
-rw-r--r--compiler/src/dotty/tools/dotc/core/tasty/TreePickler.scala34
-rw-r--r--compiler/src/dotty/tools/dotc/core/tasty/TreeUnpickler.scala39
-rw-r--r--compiler/src/dotty/tools/dotc/core/unpickleScala2/Scala2Unpickler.scala16
-rw-r--r--compiler/src/dotty/tools/dotc/parsing/Parsers.scala2
-rw-r--r--compiler/src/dotty/tools/dotc/printing/Formatting.scala10
-rw-r--r--compiler/src/dotty/tools/dotc/printing/PlainPrinter.scala26
-rw-r--r--compiler/src/dotty/tools/dotc/printing/RefinedPrinter.scala6
-rw-r--r--compiler/src/dotty/tools/dotc/reporting/diagnostic/messages.scala4
-rw-r--r--compiler/src/dotty/tools/dotc/sbt/ExtractAPI.scala18
-rw-r--r--compiler/src/dotty/tools/dotc/sbt/ExtractDependencies.scala4
-rw-r--r--compiler/src/dotty/tools/dotc/transform/CollectEntryPoints.scala2
-rw-r--r--compiler/src/dotty/tools/dotc/transform/ElimByName.scala2
-rw-r--r--compiler/src/dotty/tools/dotc/transform/ElimErasedValueType.scala4
-rw-r--r--compiler/src/dotty/tools/dotc/transform/ElimRepeated.scala10
-rw-r--r--compiler/src/dotty/tools/dotc/transform/Erasure.scala12
-rw-r--r--compiler/src/dotty/tools/dotc/transform/ExplicitOuter.scala2
-rw-r--r--compiler/src/dotty/tools/dotc/transform/FullParameterization.scala14
-rw-r--r--compiler/src/dotty/tools/dotc/transform/FunctionalInterfaces.scala6
-rw-r--r--compiler/src/dotty/tools/dotc/transform/MixinOps.scala2
-rw-r--r--compiler/src/dotty/tools/dotc/transform/PatternMatcher.scala2
-rw-r--r--compiler/src/dotty/tools/dotc/transform/ShortcutImplicits.scala4
-rw-r--r--compiler/src/dotty/tools/dotc/transform/SuperAccessors.scala8
-rw-r--r--compiler/src/dotty/tools/dotc/transform/TreeChecker.scala4
-rw-r--r--compiler/src/dotty/tools/dotc/transform/VCInlineMethods.scala2
-rw-r--r--compiler/src/dotty/tools/dotc/typer/Applications.scala36
-rw-r--r--compiler/src/dotty/tools/dotc/typer/Checking.scala14
-rw-r--r--compiler/src/dotty/tools/dotc/typer/Dynamic.scala2
-rw-r--r--compiler/src/dotty/tools/dotc/typer/ErrorReporting.scala12
-rw-r--r--compiler/src/dotty/tools/dotc/typer/EtaExpansion.scala8
-rw-r--r--compiler/src/dotty/tools/dotc/typer/Implicits.scala15
-rw-r--r--compiler/src/dotty/tools/dotc/typer/Inferencing.scala14
-rw-r--r--compiler/src/dotty/tools/dotc/typer/Inliner.scala9
-rw-r--r--compiler/src/dotty/tools/dotc/typer/Namer.scala16
-rw-r--r--compiler/src/dotty/tools/dotc/typer/ProtoTypes.scala58
-rw-r--r--compiler/src/dotty/tools/dotc/typer/ReTyper.scala2
-rw-r--r--compiler/src/dotty/tools/dotc/typer/TypeAssigner.scala20
-rw-r--r--compiler/src/dotty/tools/dotc/typer/Typer.scala44
-rw-r--r--compiler/src/dotty/tools/dotc/typer/VarianceChecker.scala6
-rw-r--r--compiler/src/dotty/tools/dotc/typer/Variances.scala8
-rw-r--r--doc-tool/src/dotty/tools/dottydoc/core/DocASTPhase.scala5
-rw-r--r--doc-tool/src/dotty/tools/dottydoc/model/factories.scala14
70 files changed, 1032 insertions, 988 deletions
diff --git a/compiler/src/dotty/tools/backend/jvm/scalaPrimitives.scala b/compiler/src/dotty/tools/backend/jvm/scalaPrimitives.scala
index 89831e56b..7beae90c4 100644
--- a/compiler/src/dotty/tools/backend/jvm/scalaPrimitives.scala
+++ b/compiler/src/dotty/tools/backend/jvm/scalaPrimitives.scala
@@ -142,7 +142,7 @@ class DottyPrimitives(ctx: Context) {
ctx.error(s"Unknown primitive method $cls.$method")
else alts foreach (s =>
addPrimitive(s,
- s.info.paramTypess match {
+ s.info.paramInfoss match {
case List(tp :: _) if code == ADD && tp =:= ctx.definitions.StringType => CONCAT
case _ => code
}
diff --git a/compiler/src/dotty/tools/dotc/ast/Desugar.scala b/compiler/src/dotty/tools/dotc/ast/Desugar.scala
index 8499330fb..66fc6bf84 100644
--- a/compiler/src/dotty/tools/dotc/ast/Desugar.scala
+++ b/compiler/src/dotty/tools/dotc/ast/Desugar.scala
@@ -154,8 +154,8 @@ object desugar {
case ContextBounds(tbounds, cxbounds) =>
epbuf ++= makeImplicitParameters(cxbounds, isPrimaryConstructor)
tbounds
- case PolyTypeTree(tparams, body) =>
- cpy.PolyTypeTree(rhs)(tparams, desugarContextBounds(body))
+ case LambdaTypeTree(tparams, body) =>
+ cpy.LambdaTypeTree(rhs)(tparams, desugarContextBounds(body))
case _ =>
rhs
}
diff --git a/compiler/src/dotty/tools/dotc/ast/TreeInfo.scala b/compiler/src/dotty/tools/dotc/ast/TreeInfo.scala
index b00d7df71..037ab73af 100644
--- a/compiler/src/dotty/tools/dotc/ast/TreeInfo.scala
+++ b/compiler/src/dotty/tools/dotc/ast/TreeInfo.scala
@@ -262,7 +262,7 @@ trait UntypedTreeInfo extends TreeInfo[Untyped] { self: Trees.Instance[Untyped]
case mdef: TypeDef =>
def isBounds(rhs: Tree): Boolean = rhs match {
case _: TypeBoundsTree => true
- case PolyTypeTree(_, body) => isBounds(body)
+ case LambdaTypeTree(_, body) => isBounds(body)
case _ => false
}
mdef.rhs.isEmpty || isBounds(mdef.rhs)
diff --git a/compiler/src/dotty/tools/dotc/ast/Trees.scala b/compiler/src/dotty/tools/dotc/ast/Trees.scala
index 669e5429c..0fc47a8a4 100644
--- a/compiler/src/dotty/tools/dotc/ast/Trees.scala
+++ b/compiler/src/dotty/tools/dotc/ast/Trees.scala
@@ -578,9 +578,9 @@ object Trees {
}
/** [typeparams] -> tpt */
- case class PolyTypeTree[-T >: Untyped] private[ast] (tparams: List[TypeDef[T]], body: Tree[T])
+ case class LambdaTypeTree[-T >: Untyped] private[ast] (tparams: List[TypeDef[T]], body: Tree[T])
extends TypTree[T] {
- type ThisTree[-T >: Untyped] = PolyTypeTree[T]
+ type ThisTree[-T >: Untyped] = LambdaTypeTree[T]
}
/** => T */
@@ -833,7 +833,7 @@ object Trees {
type OrTypeTree = Trees.OrTypeTree[T]
type RefinedTypeTree = Trees.RefinedTypeTree[T]
type AppliedTypeTree = Trees.AppliedTypeTree[T]
- type PolyTypeTree = Trees.PolyTypeTree[T]
+ type LambdaTypeTree = Trees.LambdaTypeTree[T]
type ByNameTypeTree = Trees.ByNameTypeTree[T]
type TypeBoundsTree = Trees.TypeBoundsTree[T]
type Bind = Trees.Bind[T]
@@ -998,9 +998,9 @@ object Trees {
case tree: AppliedTypeTree if (tpt eq tree.tpt) && (args eq tree.args) => tree
case _ => finalize(tree, untpd.AppliedTypeTree(tpt, args))
}
- 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 LambdaTypeTree(tree: Tree)(tparams: List[TypeDef], body: Tree): LambdaTypeTree = tree match {
+ case tree: LambdaTypeTree if (tparams eq tree.tparams) && (body eq tree.body) => tree
+ case _ => finalize(tree, untpd.LambdaTypeTree(tparams, body))
}
def ByNameTypeTree(tree: Tree)(result: Tree): ByNameTypeTree = tree match {
case tree: ByNameTypeTree if result eq tree.result => tree
@@ -1144,8 +1144,8 @@ object Trees {
cpy.RefinedTypeTree(tree)(transform(tpt), transformSub(refinements))
case AppliedTypeTree(tpt, args) =>
cpy.AppliedTypeTree(tree)(transform(tpt), transform(args))
- case PolyTypeTree(tparams, body) =>
- cpy.PolyTypeTree(tree)(transformSub(tparams), transform(body))
+ case LambdaTypeTree(tparams, body) =>
+ cpy.LambdaTypeTree(tree)(transformSub(tparams), transform(body))
case ByNameTypeTree(result) =>
cpy.ByNameTypeTree(tree)(transform(result))
case TypeBoundsTree(lo, hi) =>
@@ -1248,7 +1248,7 @@ object Trees {
this(this(x, tpt), refinements)
case AppliedTypeTree(tpt, args) =>
this(this(x, tpt), args)
- case PolyTypeTree(tparams, body) =>
+ case LambdaTypeTree(tparams, body) =>
implicit val ctx = localCtx
this(this(x, tparams), body)
case ByNameTypeTree(result) =>
diff --git a/compiler/src/dotty/tools/dotc/ast/tpd.scala b/compiler/src/dotty/tools/dotc/ast/tpd.scala
index cbb256dd0..ff66c8c8e 100644
--- a/compiler/src/dotty/tools/dotc/ast/tpd.scala
+++ b/compiler/src/dotty/tools/dotc/ast/tpd.scala
@@ -145,8 +145,8 @@ object tpd extends Trees.Instance[Type] with TypedTreeInfo {
def ByNameTypeTree(result: Tree)(implicit ctx: Context): ByNameTypeTree =
ta.assignType(untpd.ByNameTypeTree(result), result)
- def PolyTypeTree(tparams: List[TypeDef], body: Tree)(implicit ctx: Context): PolyTypeTree =
- ta.assignType(untpd.PolyTypeTree(tparams, body), tparams, body)
+ def LambdaTypeTree(tparams: List[TypeDef], body: Tree)(implicit ctx: Context): LambdaTypeTree =
+ ta.assignType(untpd.LambdaTypeTree(tparams, body), tparams, body)
def TypeBoundsTree(lo: Tree, hi: Tree)(implicit ctx: Context): TypeBoundsTree =
ta.assignType(untpd.TypeBoundsTree(lo, hi), lo, hi)
@@ -190,7 +190,7 @@ object tpd extends Trees.Instance[Type] with TypedTreeInfo {
val maybeImplicit = if (tp.isInstanceOf[ImplicitMethodType]) Implicit else EmptyFlags
ctx.newSymbol(sym, name, TermParam | maybeImplicit, info)
}
- val params = (tp.paramNames, tp.paramTypes).zipped.map(valueParam)
+ val params = (tp.paramNames, tp.paramInfos).zipped.map(valueParam)
val (paramss, rtp) = valueParamss(tp.instantiate(params map (_.termRef)))
(params :: paramss, rtp)
case tp => (Nil, tp.widenExpr)
@@ -221,7 +221,7 @@ object tpd extends Trees.Instance[Type] with TypedTreeInfo {
case ctpe: PolyType =>
isApplicable(ctpe.instantiate(firstParent.argTypes))
case ctpe: MethodType =>
- (superArgs corresponds ctpe.paramTypes)(_.tpe <:< _)
+ (superArgs corresponds ctpe.paramInfos)(_.tpe <:< _)
case _ =>
false
}
@@ -836,7 +836,7 @@ object tpd extends Trees.Instance[Type] with TypedTreeInfo {
val selected =
if (denot.isOverloaded) {
def typeParamCount(tp: Type) = tp.widen match {
- case tp: PolyType => tp.paramBounds.length
+ case tp: PolyType => tp.paramInfos.length
case _ => 0
}
var allAlts = denot.alternatives
@@ -859,7 +859,7 @@ object tpd extends Trees.Instance[Type] with TypedTreeInfo {
def adaptLastArg(lastParam: Tree, expectedType: Type) = {
if (isAnnotConstructor && !(lastParam.tpe <:< expectedType)) {
val defn = ctx.definitions
- val prefix = args.take(selected.widen.paramTypess.head.size - 1)
+ val prefix = args.take(selected.widen.paramInfoss.head.size - 1)
expectedType match {
case defn.ArrayOf(el) =>
lastParam.tpe match {
@@ -878,7 +878,7 @@ object tpd extends Trees.Instance[Type] with TypedTreeInfo {
}
val callArgs: List[Tree] = if (args.isEmpty) Nil else {
- val expectedType = selected.widen.paramTypess.head.last
+ val expectedType = selected.widen.paramInfoss.head.last
val lastParam = args.last
adaptLastArg(lastParam, expectedType)
}
diff --git a/compiler/src/dotty/tools/dotc/ast/untpd.scala b/compiler/src/dotty/tools/dotc/ast/untpd.scala
index a5feecc77..7a9f2fe66 100644
--- a/compiler/src/dotty/tools/dotc/ast/untpd.scala
+++ b/compiler/src/dotty/tools/dotc/ast/untpd.scala
@@ -270,7 +270,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 PolyTypeTree(tparams: List[TypeDef], body: Tree): PolyTypeTree = new PolyTypeTree(tparams, body)
+ def LambdaTypeTree(tparams: List[TypeDef], body: Tree): LambdaTypeTree = new LambdaTypeTree(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)
@@ -361,7 +361,7 @@ object untpd extends Trees.Instance[Untyped] with UntypedTreeInfo {
ValDef(nme.syntheticParamName(n), tpt, EmptyTree).withFlags(SyntheticTermParam)
def lambdaAbstract(tparams: List[TypeDef], tpt: Tree)(implicit ctx: Context) =
- if (tparams.isEmpty) tpt else PolyTypeTree(tparams, tpt)
+ if (tparams.isEmpty) tpt else LambdaTypeTree(tparams, tpt)
/** A reference to given definition. If definition is a repeated
* parameter, the reference will be a repeated argument.
diff --git a/compiler/src/dotty/tools/dotc/config/Config.scala b/compiler/src/dotty/tools/dotc/config/Config.scala
index 903efd794..46b1896f1 100644
--- a/compiler/src/dotty/tools/dotc/config/Config.scala
+++ b/compiler/src/dotty/tools/dotc/config/Config.scala
@@ -40,7 +40,7 @@ object Config {
* accesses javac's settings.)
*
* It is recommended to turn this option on only when chasing down
- * a PolyParam instantiation error. See comment in Types.TypeVar.instantiate.
+ * a TypeParamRef instantiation error. See comment in Types.TypeVar.instantiate.
*/
final val debugCheckConstraintsClosed = false
diff --git a/compiler/src/dotty/tools/dotc/core/Constants.scala b/compiler/src/dotty/tools/dotc/core/Constants.scala
index 1892e4bdc..ed388b7ec 100644
--- a/compiler/src/dotty/tools/dotc/core/Constants.scala
+++ b/compiler/src/dotty/tools/dotc/core/Constants.scala
@@ -169,12 +169,12 @@ object Constants {
def convertTo(pt: Type)(implicit ctx: Context): Constant = {
def classBound(pt: Type): Type = pt.dealias.stripTypeVar match {
case tref: TypeRef if !tref.symbol.isClass => classBound(tref.info.bounds.lo)
- case param: PolyParam =>
+ case param: TypeParamRef =>
ctx.typerState.constraint.entry(param) match {
case TypeBounds(lo, hi) =>
if (hi.classSymbol.isPrimitiveValueClass) hi //constrain further with high bound
else classBound(lo)
- case NoType => classBound(param.binder.paramBounds(param.paramNum).lo)
+ case NoType => classBound(param.binder.paramInfos(param.paramNum).lo)
case inst => classBound(inst)
}
case pt => pt
diff --git a/compiler/src/dotty/tools/dotc/core/Constraint.scala b/compiler/src/dotty/tools/dotc/core/Constraint.scala
index 50136a26c..a6c21c0d1 100644
--- a/compiler/src/dotty/tools/dotc/core/Constraint.scala
+++ b/compiler/src/dotty/tools/dotc/core/Constraint.scala
@@ -13,20 +13,20 @@ import config.Printers.constr
/** Constraint over undetermined type parameters. Constraints are built
* over values of the following types:
*
- * - PolyType A constraint constrains the type parameters of a set of PolyTypes
- * - PolyParam The parameters of the constrained polytypes
- * - TypeVar Every constrained parameter might be associated with a TypeVar
- * that has the PolyParam as origin.
+ * - TypeLambda A constraint constrains the type parameters of a set of TypeLambdas
+ * - TypeParamRef The parameters of the constrained type lambdas
+ * - TypeVar Every constrained parameter might be associated with a TypeVar
+ * that has the TypeParamRef as origin.
*/
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: TypeLambda): Boolean
/** Does the constraint's domain contain the type parameter `param`? */
- def contains(param: PolyParam): Boolean
+ def contains(param: TypeParamRef): Boolean
/** Does this constraint contain the type variable `tvar` and is it uninstantiated? */
def contains(tvar: TypeVar): Boolean
@@ -34,43 +34,43 @@ abstract class Constraint extends Showable {
/** The constraint entry for given type parameter `param`, or NoType if `param` is not part of
* the constraint domain. Note: Low level, implementation dependent.
*/
- def entry(param: PolyParam): Type
+ def entry(param: TypeParamRef): Type
/** The type variable corresponding to parameter `param`, or
* NoType, if `param` is not in constrained or is not paired with a type variable.
*/
- def typeVarOfParam(param: PolyParam): Type
+ def typeVarOfParam(param: TypeParamRef): Type
/** Is it known that `param1 <:< param2`? */
- def isLess(param1: PolyParam, param2: PolyParam): Boolean
+ def isLess(param1: TypeParamRef, param2: TypeParamRef): Boolean
/** The parameters that are known to be smaller wrt <: than `param` */
- def lower(param: PolyParam): List[PolyParam]
+ def lower(param: TypeParamRef): List[TypeParamRef]
/** The parameters that are known to be greater wrt <: than `param` */
- def upper(param: PolyParam): List[PolyParam]
+ def upper(param: TypeParamRef): List[TypeParamRef]
/** lower(param) \ lower(butNot) */
- def exclusiveLower(param: PolyParam, butNot: PolyParam): List[PolyParam]
+ def exclusiveLower(param: TypeParamRef, butNot: TypeParamRef): List[TypeParamRef]
/** upper(param) \ upper(butNot) */
- def exclusiveUpper(param: PolyParam, butNot: PolyParam): List[PolyParam]
+ def exclusiveUpper(param: TypeParamRef, butNot: TypeParamRef): List[TypeParamRef]
/** The constraint bounds for given type parameter `param`.
* Poly params that are known to be smaller or greater than `param`
* are not contained in the return bounds.
* @pre `param` is not part of the constraint domain.
*/
- def nonParamBounds(param: PolyParam): TypeBounds
+ def nonParamBounds(param: TypeParamRef): TypeBounds
/** The lower bound of `param` including all known-to-be-smaller parameters */
- def fullLowerBound(param: PolyParam)(implicit ctx: Context): Type
+ def fullLowerBound(param: TypeParamRef)(implicit ctx: Context): Type
/** The upper bound of `param` including all known-to-be-greater parameters */
- def fullUpperBound(param: PolyParam)(implicit ctx: Context): Type
+ def fullUpperBound(param: TypeParamRef)(implicit ctx: Context): Type
/** The bounds of `param` including all known-to-be-smaller and -greater parameters */
- def fullBounds(param: PolyParam)(implicit ctx: Context): TypeBounds
+ def fullBounds(param: TypeParamRef)(implicit ctx: Context): TypeBounds
/** A new constraint which is derived from this constraint by adding
* entries for all type parameters of `poly`.
@@ -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: TypeLambda, 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`.
@@ -90,18 +90,18 @@ abstract class Constraint extends Showable {
*
* @pre `this contains param`.
*/
- def updateEntry(param: PolyParam, tp: Type)(implicit ctx: Context): This
+ def updateEntry(param: TypeParamRef, tp: Type)(implicit ctx: Context): This
/** A constraint that includes the relationship `p1 <: p2`.
* `<:` relationships between parameters ("edges") are propagated, but
* non-parameter bounds are left alone.
*/
- def addLess(p1: PolyParam, p2: PolyParam)(implicit ctx: Context): This
+ def addLess(p1: TypeParamRef, p2: TypeParamRef)(implicit ctx: Context): This
/** A constraint resulting from adding p2 = p1 to this constraint, and at the same
* time transferring all bounds of p2 to p1
*/
- def unify(p1: PolyParam, p2: PolyParam)(implicit ctx: Context): This
+ def unify(p1: TypeParamRef, p2: TypeParamRef)(implicit ctx: Context): This
/** A new constraint which is derived from this constraint by removing
* the type parameter `param` from the domain and replacing all top-level occurrences
@@ -109,25 +109,25 @@ abstract class Constraint extends Showable {
* approximation of it if that is needed to avoid cycles.
* Occurrences nested inside a refinement or prefix are not affected.
*/
- def replace(param: PolyParam, tp: Type)(implicit ctx: Context): This
+ def replace(param: TypeParamRef, tp: Type)(implicit ctx: Context): This
/** Is entry associated with `pt` removable? This is the case if
* all type parameters of the entry are associated with type variables
* which have their `inst` fields set.
*/
- def isRemovable(pt: PolyType): Boolean
+ def isRemovable(pt: TypeLambda): Boolean
/** A new constraint with all entries coming from `pt` removed. */
- def remove(pt: PolyType)(implicit ctx: Context): This
+ def remove(pt: TypeLambda)(implicit ctx: Context): This
- /** The polytypes constrained by this constraint */
- def domainPolys: List[PolyType]
+ /** The type lambdas constrained by this constraint */
+ def domainLambdas: List[TypeLambda]
- /** The polytype parameters constrained by this constraint */
- def domainParams: List[PolyParam]
+ /** The type lambda parameters constrained by this constraint */
+ def domainParams: List[TypeParamRef]
/** Check whether predicate holds for all parameters in constraint */
- def forallParams(p: PolyParam => Boolean): Boolean
+ def forallParams(p: TypeParamRef => Boolean): Boolean
/** Perform operation `op` on all typevars, or only on uninstantiated
* typevars, depending on whether `uninstOnly` is set or not.
@@ -143,6 +143,6 @@ abstract class Constraint extends Showable {
/** Check that no constrained parameter contains itself as a bound */
def checkNonCyclic()(implicit ctx: Context): Unit
- /** Check that constraint only refers to PolyParams bound by itself */
+ /** Check that constraint only refers to TypeParamRefs bound by itself */
def checkClosed()(implicit ctx: Context): Unit
}
diff --git a/compiler/src/dotty/tools/dotc/core/ConstraintHandling.scala b/compiler/src/dotty/tools/dotc/core/ConstraintHandling.scala
index a12936c58..de96f644a 100644
--- a/compiler/src/dotty/tools/dotc/core/ConstraintHandling.scala
+++ b/compiler/src/dotty/tools/dotc/core/ConstraintHandling.scala
@@ -42,12 +42,12 @@ trait ConstraintHandling {
*/
protected var homogenizeArgs = false
- /** We are currently comparing polytypes. Used as a flag for
+ /** We are currently comparing type lambdas. Used as a flag for
* optimization: when `false`, no need to do an expensive `pruneLambdaParams`
*/
- protected var comparedPolyTypes: Set[PolyType] = Set.empty
+ protected var comparedTypeLambdas: Set[TypeLambda] = Set.empty
- private def addOneBound(param: PolyParam, bound: Type, isUpper: Boolean): Boolean =
+ private def addOneBound(param: TypeParamRef, bound: Type, isUpper: Boolean): Boolean =
!constraint.contains(param) || {
def occursIn(bound: Type): Boolean = {
val b = bound.dealias
@@ -75,7 +75,7 @@ trait ConstraintHandling {
* If `isUpper` is true, ensure that `param <: `bound`, otherwise ensure
* that `param >: bound`.
*/
- def narrowedBound(param: PolyParam, bound: Type, isUpper: Boolean)(implicit ctx: Context): TypeBounds = {
+ def narrowedBound(param: TypeParamRef, bound: Type, isUpper: Boolean)(implicit ctx: Context): TypeBounds = {
val oldBounds @ TypeBounds(lo, hi) = constraint.nonParamBounds(param)
val saved = homogenizeArgs
homogenizeArgs = Config.alignArgsInAnd
@@ -85,7 +85,7 @@ trait ConstraintHandling {
finally homogenizeArgs = saved
}
- protected def addUpperBound(param: PolyParam, bound: Type): Boolean = {
+ protected def addUpperBound(param: TypeParamRef, bound: Type): Boolean = {
def description = i"constraint $param <: $bound to\n$constraint"
if (bound.isRef(defn.NothingClass) && ctx.typerState.isGlobalCommittable) {
def msg = s"!!! instantiated to Nothing: $param, constraint = ${constraint.show}"
@@ -101,7 +101,7 @@ trait ConstraintHandling {
res
}
- protected def addLowerBound(param: PolyParam, bound: Type): Boolean = {
+ protected def addLowerBound(param: TypeParamRef, bound: Type): Boolean = {
def description = i"constraint $param >: $bound to\n$constraint"
constr.println(i"adding $description")
val upper = constraint.upper(param)
@@ -112,7 +112,7 @@ trait ConstraintHandling {
res
}
- protected def addLess(p1: PolyParam, p2: PolyParam): Boolean = {
+ protected def addLess(p1: TypeParamRef, p2: TypeParamRef): Boolean = {
def description = i"ordering $p1 <: $p2 to\n$constraint"
val res =
if (constraint.isLess(p2, p1)) unify(p2, p1)
@@ -133,7 +133,7 @@ trait ConstraintHandling {
/** Make p2 = p1, transfer all bounds of p2 to p1
* @pre less(p1)(p2)
*/
- private def unify(p1: PolyParam, p2: PolyParam): Boolean = {
+ private def unify(p1: TypeParamRef, p2: TypeParamRef): Boolean = {
constr.println(s"unifying $p1 $p2")
assert(constraint.isLess(p1, p2))
val down = constraint.exclusiveLower(p2, p1)
@@ -191,7 +191,7 @@ trait ConstraintHandling {
* @return the instantiating type
* @pre `param` is in the constraint's domain.
*/
- final def approximation(param: PolyParam, fromBelow: Boolean): Type = {
+ final def approximation(param: TypeParamRef, fromBelow: Boolean): Type = {
val avoidParam = new TypeMap {
override def stopAtStatic = true
def apply(tp: Type) = mapOver {
@@ -235,7 +235,7 @@ trait ConstraintHandling {
* a lower bound instantiation can be a singleton type only if the upper bound
* is also a singleton type.
*/
- def instanceType(param: PolyParam, fromBelow: Boolean): Type = {
+ def instanceType(param: TypeParamRef, fromBelow: Boolean): Type = {
def upperBound = constraint.fullUpperBound(param)
def isSingleton(tp: Type): Boolean = tp match {
case tp: SingletonType => true
@@ -301,26 +301,26 @@ trait ConstraintHandling {
}
/** The current bounds of type parameter `param` */
- final def bounds(param: PolyParam): TypeBounds = {
+ final def bounds(param: TypeParamRef): TypeBounds = {
val e = constraint.entry(param)
- if (e.exists) e.bounds else param.binder.paramBounds(param.paramNum)
+ if (e.exists) e.bounds else param.binder.paramInfos(param.paramNum)
}
- /** Add polytype `pt`, possibly with type variables `tvars`, to current constraint
+ /** Add type lambda `tl`, possibly with type variables `tvars`, to current constraint
* and propagate all bounds.
* @param tvars See Constraint#add
*/
- def addToConstraint(pt: PolyType, tvars: List[TypeVar]): Unit =
+ def addToConstraint(tl: TypeLambda, tvars: List[TypeVar]): Unit =
assert {
- checkPropagated(i"initialized $pt") {
- constraint = constraint.add(pt, tvars)
- pt.paramNames.indices.forall { i =>
- val param = PolyParam(pt, i)
+ checkPropagated(i"initialized $tl") {
+ constraint = constraint.add(tl, tvars)
+ tl.paramNames.indices.forall { i =>
+ val param = TypeParamRef(tl, i)
val bounds = constraint.nonParamBounds(param)
val lower = constraint.lower(param)
val upper = constraint.upper(param)
if (lower.nonEmpty && !bounds.lo.isRef(defn.NothingClass) ||
- upper.nonEmpty && !bounds.hi.isRef(defn.AnyClass)) constr.println(i"INIT*** $pt")
+ upper.nonEmpty && !bounds.hi.isRef(defn.AnyClass)) constr.println(i"INIT*** $tl")
lower.forall(addOneBound(_, bounds.hi, isUpper = true)) &&
upper.forall(addOneBound(_, bounds.lo, isUpper = false))
}
@@ -328,7 +328,7 @@ trait ConstraintHandling {
}
/** Can `param` be constrained with new bounds? */
- final def canConstrain(param: PolyParam): Boolean =
+ final def canConstrain(param: TypeParamRef): Boolean =
!frozenConstraint && (constraint contains param)
/** Add constraint `param <: bound` if `fromBelow` is false, `param >: bound` otherwise.
@@ -338,7 +338,7 @@ trait ConstraintHandling {
* not be AndTypes and lower bounds may not be OrTypes. This is assured by the
* way isSubType is organized.
*/
- protected def addConstraint(param: PolyParam, bound: Type, fromBelow: Boolean): Boolean = {
+ protected def addConstraint(param: TypeParamRef, bound: Type, fromBelow: Boolean): Boolean = {
def description = i"constr $param ${if (fromBelow) ">:" else "<:"} $bound:\n$constraint"
//checkPropagated(s"adding $description")(true) // DEBUG in case following fails
checkPropagated(s"added $description") {
@@ -357,12 +357,12 @@ trait ConstraintHandling {
* missing.
*/
def pruneLambdaParams(tp: Type) =
- if (comparedPolyTypes.nonEmpty) {
+ if (comparedTypeLambdas.nonEmpty) {
val approx = new ApproximatingTypeMap {
def apply(t: Type): Type = t match {
- case t @ PolyParam(pt: PolyType, n) if comparedPolyTypes contains pt =>
+ case t @ TypeParamRef(tl: TypeLambda, n) if comparedTypeLambdas contains tl =>
val effectiveVariance = if (fromBelow) -variance else variance
- val bounds = pt.paramBounds(n)
+ val bounds = tl.paramInfos(n)
if (effectiveVariance > 0) bounds.lo
else if (effectiveVariance < 0) bounds.hi
else NoType
@@ -374,7 +374,7 @@ trait ConstraintHandling {
}
else tp
- def addParamBound(bound: PolyParam) =
+ def addParamBound(bound: TypeParamRef) =
if (fromBelow) addLess(bound, param) else addLess(param, bound)
/** Drop all constrained parameters that occur at the toplevel in `bound` and
@@ -419,7 +419,7 @@ trait ConstraintHandling {
else NoType
case bound: TypeVar if constraint contains bound.origin =>
prune(bound.underlying)
- case bound: PolyParam =>
+ case bound: TypeParamRef =>
constraint.entry(bound) match {
case NoType => pruneLambdaParams(bound)
case _: TypeBounds =>
@@ -434,7 +434,7 @@ trait ConstraintHandling {
}
try bound match {
- case bound: PolyParam if constraint contains bound =>
+ case bound: TypeParamRef if constraint contains bound =>
addParamBound(bound)
case _ =>
val pbound = prune(bound)
@@ -446,7 +446,7 @@ trait ConstraintHandling {
}
/** Instantiate `param` to `tp` if the constraint stays satisfiable */
- protected def tryInstantiate(param: PolyParam, tp: Type): Boolean = {
+ protected def tryInstantiate(param: TypeParamRef, tp: Type): Boolean = {
val saved = constraint
constraint =
if (addConstraint(param, tp, fromBelow = true) &&
@@ -461,7 +461,7 @@ trait ConstraintHandling {
val saved = frozenConstraint
frozenConstraint = true
for (p <- constraint.domainParams) {
- def check(cond: => Boolean, q: PolyParam, ordering: String, explanation: String): Unit =
+ def check(cond: => Boolean, q: TypeParamRef, ordering: String, explanation: String): Unit =
assert(cond, i"propagation failure for $p $ordering $q: $explanation\n$msg")
for (u <- constraint.upper(p))
check(bounds(p).hi <:< bounds(u).hi, u, "<:", "upper bound not propagated")
diff --git a/compiler/src/dotty/tools/dotc/core/Definitions.scala b/compiler/src/dotty/tools/dotc/core/Definitions.scala
index 39b46cbfe..b70fcb093 100644
--- a/compiler/src/dotty/tools/dotc/core/Definitions.scala
+++ b/compiler/src/dotty/tools/dotc/core/Definitions.scala
@@ -150,9 +150,9 @@ class Definitions {
private def enterPolyMethod(cls: ClassSymbol, name: TermName, typeParamCount: Int,
resultTypeFn: PolyType => Type, flags: FlagSet = EmptyFlags) = {
- val tparamNames = tpnme.syntheticTypeParamNames(typeParamCount)
- val tparamBounds = tparamNames map (_ => TypeBounds.empty)
- val ptype = PolyType(tparamNames, tparamNames.map(alwaysZero))(_ => tparamBounds, resultTypeFn)
+ val tparamNames = PolyType.syntheticParamNames(typeParamCount)
+ val tparamInfos = tparamNames map (_ => TypeBounds.empty)
+ val ptype = PolyType(tparamNames)(_ => tparamInfos, resultTypeFn)
enterMethod(cls, name, ptype, flags)
}
@@ -242,7 +242,7 @@ class Definitions {
lazy val Any_## = enterMethod(AnyClass, nme.HASHHASH, ExprType(IntType), Final)
lazy val Any_getClass = enterMethod(AnyClass, nme.getClass_, MethodType(Nil, ClassClass.typeRef.appliedTo(TypeBounds.empty)), Final)
lazy val Any_isInstanceOf = enterT1ParameterlessMethod(AnyClass, nme.isInstanceOf_, _ => BooleanType, Final)
- lazy val Any_asInstanceOf = enterT1ParameterlessMethod(AnyClass, nme.asInstanceOf_, PolyParam(_, 0), Final)
+ lazy val Any_asInstanceOf = enterT1ParameterlessMethod(AnyClass, nme.asInstanceOf_, TypeParamRef(_, 0), Final)
def AnyMethods = List(Any_==, Any_!=, Any_equals, Any_hashCode,
Any_toString, Any_##, Any_getClass, Any_isInstanceOf, Any_asInstanceOf)
@@ -268,7 +268,7 @@ class Definitions {
lazy val Object_eq = enterMethod(ObjectClass, nme.eq, methOfAnyRef(BooleanType), Final)
lazy val Object_ne = enterMethod(ObjectClass, nme.ne, methOfAnyRef(BooleanType), Final)
lazy val Object_synchronized = enterPolyMethod(ObjectClass, nme.synchronized_, 1,
- pt => MethodType(List(PolyParam(pt, 0)), PolyParam(pt, 0)), Final)
+ pt => MethodType(List(TypeParamRef(pt, 0)), TypeParamRef(pt, 0)), Final)
lazy val Object_clone = enterMethod(ObjectClass, nme.clone_, MethodType(Nil, ObjectType), Protected)
lazy val Object_finalize = enterMethod(ObjectClass, nme.finalize_, MethodType(Nil, UnitType), Protected)
lazy val Object_notify = enterMethod(ObjectClass, nme.notify_, MethodType(Nil, UnitType))
@@ -283,7 +283,7 @@ class Definitions {
/** Dummy method needed by elimByName */
lazy val dummyApply = enterPolyMethod(
OpsPackageClass, nme.dummyApply, 1,
- pt => MethodType(List(FunctionOf(Nil, PolyParam(pt, 0))), PolyParam(pt, 0)))
+ pt => MethodType(List(FunctionOf(Nil, TypeParamRef(pt, 0))), TypeParamRef(pt, 0)))
/** Method representing a throw */
lazy val throwMethod = enterMethod(OpsPackageClass, nme.THROWkw,
diff --git a/compiler/src/dotty/tools/dotc/core/Denotations.scala b/compiler/src/dotty/tools/dotc/core/Denotations.scala
index f726cd0d1..7341b96af 100644
--- a/compiler/src/dotty/tools/dotc/core/Denotations.scala
+++ b/compiler/src/dotty/tools/dotc/core/Denotations.scala
@@ -213,7 +213,7 @@ object Denotations {
def requiredMethod(name: PreName, argTypes: List[Type])(implicit ctx: Context): TermSymbol =
info.member(name.toTermName).requiredSymbol(x=>
- (x is Method) && x.info.paramTypess == List(argTypes)
+ (x is Method) && x.info.paramInfoss == List(argTypes)
).asTerm
def requiredMethodRef(name: PreName, argTypes: List[Type])(implicit ctx: Context): TermRef =
requiredMethod(name, argTypes).termRef
@@ -252,13 +252,12 @@ object Denotations {
else throw new Error(s"cannot merge ${showType(tp1)} with ${showType(tp2)}") // flip condition for debugging
}
- /** Merge two lists of names. If names in corresponding positions match, keep them,
+ /** Merge parameter names of lambda types. If names in corresponding positions match, keep them,
* otherwise generate new synthetic names.
*/
- def mergeNames[N <: Name](names1: List[N], names2: List[N], syntheticName: Int => N): List[N] = {
- for ((name1, name2, idx) <- (names1, names2, 0 until names1.length).zipped)
- yield if (name1 == name2) name1 else syntheticName(idx)
- }.toList
+ private def mergeParamNames(tp1: LambdaType, tp2: LambdaType): List[tp1.ThisName] =
+ (for ((name1, name2, idx) <- (tp1.paramNames, tp2.paramNames, tp1.paramNames.indices).zipped)
+ yield if (name1 == name2) name1 else tp1.companion.syntheticParamName(idx)).toList
/** Form a denotation by conjoining with denotation `that`.
*
@@ -308,27 +307,17 @@ object Denotations {
case tp2: TypeBounds if tp2 contains tp1 => tp1
case _ => mergeConflict(tp1, tp2)
}
- case tp1: MethodType if isTerm =>
+ case tp1: MethodOrPoly =>
tp2 match {
- case tp2: MethodType if ctx.typeComparer.matchingParams(tp1.paramTypes, tp2.paramTypes, tp1.isJava, tp2.isJava) &&
- tp1.isImplicit == tp2.isImplicit =>
- tp1.derivedMethodType(
- mergeNames(tp1.paramNames, tp2.paramNames, nme.syntheticParamName),
- tp1.paramTypes,
+ case tp2: MethodOrPoly
+ if ctx.typeComparer.matchingParams(tp1, tp2) &&
+ tp1.isImplicit == tp2.isImplicit =>
+ tp1.derivedLambdaType(
+ mergeParamNames(tp1, tp2), tp1.paramInfos,
infoMeet(tp1.resultType, tp2.resultType.subst(tp2, tp1)))
case _ =>
mergeConflict(tp1, tp2)
}
- case tp1: PolyType if isTerm =>
- tp2 match {
- case tp2: PolyType if ctx.typeComparer.matchingTypeParams(tp1, tp2) =>
- tp1.derivedPolyType(
- mergeNames(tp1.paramNames, tp2.paramNames, tpnme.syntheticTypeParamName),
- tp1.paramBounds,
- infoMeet(tp1.resultType, tp2.resultType.subst(tp2, tp1)))
- case _: MethodicType =>
- mergeConflict(tp1, tp2)
- }
case _ =>
tp1 & tp2
}
@@ -471,23 +460,14 @@ object Denotations {
case tp2: TypeBounds if tp2 contains tp1 => tp2
case _ => mergeConflict(tp1, tp2)
}
- case tp1: MethodType =>
- tp2 match {
- case tp2: MethodType
- if ctx.typeComparer.matchingParams(tp1.paramTypes, tp2.paramTypes, tp1.isJava, tp2.isJava) &&
- tp1.isImplicit == tp2.isImplicit =>
- tp1.derivedMethodType(
- mergeNames(tp1.paramNames, tp2.paramNames, nme.syntheticParamName),
- tp1.paramTypes, tp1.resultType | tp2.resultType.subst(tp2, tp1))
- case _ =>
- mergeConflict(tp1, tp2)
- }
- case tp1: PolyType =>
+ case tp1: MethodOrPoly =>
tp2 match {
- case tp2: PolyType if ctx.typeComparer.matchingTypeParams(tp1, tp2) =>
- tp1.derivedPolyType(
- mergeNames(tp1.paramNames, tp2.paramNames, tpnme.syntheticTypeParamName),
- tp1.paramBounds, tp1.resultType | tp2.resultType.subst(tp2, tp1))
+ case tp2: MethodOrPoly
+ if ctx.typeComparer.matchingParams(tp1, tp2) &&
+ tp1.isImplicit == tp2.isImplicit =>
+ tp1.derivedLambdaType(
+ mergeParamNames(tp1, tp2), tp1.paramInfos,
+ tp1.resultType | tp2.resultType.subst(tp2, tp1))
case _ =>
mergeConflict(tp1, tp2)
}
diff --git a/compiler/src/dotty/tools/dotc/core/Mode.scala b/compiler/src/dotty/tools/dotc/core/Mode.scala
index 406a84af6..c835f677e 100644
--- a/compiler/src/dotty/tools/dotc/core/Mode.scala
+++ b/compiler/src/dotty/tools/dotc/core/Mode.scala
@@ -34,7 +34,7 @@ object Mode {
* context with typerstate and constraint. This is typically done when we
* cache the eligibility of implicits. Caching needs to be done across different constraints.
* Therefore, if TypevarsMissContext is set, subtyping becomes looser, and assumes
- * that PolyParams can be sub- and supertypes of anything. See TypeComparer.
+ * that TypeParamRefs can be sub- and supertypes of anything. See TypeComparer.
*/
val TypevarsMissContext = newMode(4, "TypevarsMissContext")
val CheckCyclic = newMode(5, "CheckCyclic")
diff --git a/compiler/src/dotty/tools/dotc/core/NameOps.scala b/compiler/src/dotty/tools/dotc/core/NameOps.scala
index ea905c19f..240ad359b 100644
--- a/compiler/src/dotty/tools/dotc/core/NameOps.scala
+++ b/compiler/src/dotty/tools/dotc/core/NameOps.scala
@@ -196,6 +196,31 @@ object NameOps {
if (name.isModuleClassName) name.stripModuleClassSuffix.freshened.moduleClassName
else likeTyped(ctx.freshName(name ++ NameTransformer.NAME_JOIN_STRING)))
+ /** Name with variance prefix: `+` for covariant, `-` for contravariant */
+ def withVariance(v: Int): N =
+ if (hasVariance) dropVariance.withVariance(v)
+ else v match {
+ case -1 => likeTyped('-' +: name)
+ case 1 => likeTyped('+' +: name)
+ case 0 => name
+ }
+
+ /** Does name have a `+`/`-` variance prefix? */
+ def hasVariance: Boolean =
+ name.nonEmpty && name.head == '+' || name.head == '-'
+
+ /** Drop variance prefix if name has one */
+ def dropVariance: N = if (hasVariance) likeTyped(name.tail) else name
+
+ /** The variance as implied by the variance prefix, or 0 if there is
+ * no variance prefix.
+ */
+ def variance = name.head match {
+ case '-' => -1
+ case '+' => 1
+ case _ => 0
+ }
+
/** Translate a name into a list of simple TypeNames and TermNames.
* In all segments before the last, type/term is determined by whether
* the following separator char is '.' or '#'. The last segment
@@ -271,7 +296,6 @@ object NameOps {
else -1
}
-
/** The number of hops specified in an outer-select name */
def outerSelectHops: Int = {
require(isOuterSelect)
diff --git a/compiler/src/dotty/tools/dotc/core/OrderingConstraint.scala b/compiler/src/dotty/tools/dotc/core/OrderingConstraint.scala
index 61dd5a445..84b0bfc6d 100644
--- a/compiler/src/dotty/tools/dotc/core/OrderingConstraint.scala
+++ b/compiler/src/dotty/tools/dotc/core/OrderingConstraint.scala
@@ -14,13 +14,13 @@ import annotation.tailrec
object OrderingConstraint {
- type ArrayValuedMap[T] = SimpleMap[PolyType, Array[T]]
+ type ArrayValuedMap[T] = SimpleMap[TypeLambda, Array[T]]
/** The type of `OrderingConstraint#boundsMap` */
type ParamBounds = ArrayValuedMap[Type]
/** The type of `OrderingConstraint#lowerMap`, `OrderingConstraint#upperMap` */
- type ParamOrdering = ArrayValuedMap[List[PolyParam]]
+ type ParamOrdering = ArrayValuedMap[List[TypeParamRef]]
/** A new constraint with given maps */
private def newConstraint(boundsMap: ParamBounds, lowerMap: ParamOrdering, upperMap: ParamOrdering)(implicit ctx: Context) : OrderingConstraint = {
@@ -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: PolyType): Array[T]
- def updateEntries(c: OrderingConstraint, poly: PolyType, entries: Array[T])(implicit ctx: Context): OrderingConstraint
+ def entries(c: OrderingConstraint, poly: TypeLambda): Array[T]
+ def updateEntries(c: OrderingConstraint, poly: TypeLambda, entries: Array[T])(implicit ctx: Context): OrderingConstraint
def initial: T
- def apply(c: OrderingConstraint, poly: PolyType, idx: Int) = {
+ def apply(c: OrderingConstraint, poly: TypeLambda, 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: PolyType, idx: Int, entry: T)(implicit ctx: Context): OrderingConstraint = {
+ poly: TypeLambda, idx: Int, entry: T)(implicit ctx: Context): OrderingConstraint = {
var es = entries(current, poly)
if (es != null && (es(idx) eq entry)) current
else {
@@ -68,38 +68,38 @@ object OrderingConstraint {
}
def update(prev: OrderingConstraint, current: OrderingConstraint,
- param: PolyParam, entry: T)(implicit ctx: Context): OrderingConstraint =
+ param: TypeParamRef, entry: T)(implicit ctx: Context): 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: TypeLambda, 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,
- param: PolyParam, f: T => T)(implicit ctx: Context): OrderingConstraint =
+ param: TypeParamRef, f: T => T)(implicit ctx: Context): OrderingConstraint =
map(prev, current, param.binder, param.paramNum, f)
}
val boundsLens = new ConstraintLens[Type] {
- def entries(c: OrderingConstraint, poly: PolyType): Array[Type] =
+ def entries(c: OrderingConstraint, poly: TypeLambda): Array[Type] =
c.boundsMap(poly)
- def updateEntries(c: OrderingConstraint, poly: PolyType, entries: Array[Type])(implicit ctx: Context): OrderingConstraint =
+ def updateEntries(c: OrderingConstraint, poly: TypeLambda, 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]] =
+ val lowerLens = new ConstraintLens[List[TypeParamRef]] {
+ def entries(c: OrderingConstraint, poly: TypeLambda): Array[List[TypeParamRef]] =
c.lowerMap(poly)
- def updateEntries(c: OrderingConstraint, poly: PolyType, entries: Array[List[PolyParam]])(implicit ctx: Context): OrderingConstraint =
+ def updateEntries(c: OrderingConstraint, poly: TypeLambda, entries: Array[List[TypeParamRef]])(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]] =
+ val upperLens = new ConstraintLens[List[TypeParamRef]] {
+ def entries(c: OrderingConstraint, poly: TypeLambda): Array[List[TypeParamRef]] =
c.upperMap(poly)
- def updateEntries(c: OrderingConstraint, poly: PolyType, entries: Array[List[PolyParam]])(implicit ctx: Context): OrderingConstraint =
+ def updateEntries(c: OrderingConstraint, poly: TypeLambda, entries: Array[List[TypeParamRef]])(implicit ctx: Context): OrderingConstraint =
newConstraint(c.boundsMap, c.lowerMap, c.upperMap.updated(poly, entries))
def initial = Nil
}
@@ -109,20 +109,20 @@ import OrderingConstraint._
/** Constraint over undetermined type parameters that keeps separate maps to
* reflect parameter orderings.
- * @param boundsMap a map from PolyType to arrays.
+ * @param boundsMap a map from TypeLambda to arrays.
* Each array contains twice the number of entries as there a type parameters
- * in the PolyType. The first half of the array contains the type bounds that constrain the
- * polytype's type parameters. The second half might contain type variables that
+ * in the TypeLambda. The first half of the array contains the type bounds that constrain the
+ * lambda's type parameters. The second half might contain type variables that
* track the corresponding parameters, or is left empty (filled with nulls).
* An instantiated type parameter is represented by having its instance type in
* the corresponding array entry. The dual use of arrays for poly params
* and typevars is to save space and hopefully gain some speed.
*
- * @param lowerMap a map from PolyTypes to arrays. Each array entry corresponds
- * to a parameter P of the polytype; it contains all constrained parameters
+ * @param lowerMap a map from TypeLambdas to arrays. Each array entry corresponds
+ * to a parameter P of the type lambda; it contains all constrained parameters
* Q that are known to be smaller than P, i.e. Q <: P.
- * @param upperMap a map from PolyTypes to arrays. Each array entry corresponds
- * to a parameter P of the polytype; it contains all constrained parameters
+ * @param upperMap a map from TypeLambdas to arrays. Each array entry corresponds
+ * to a parameter P of the type lambda; it contains all constrained parameters
* Q that are known to be greater than P, i.e. P <: Q.
*/
class OrderingConstraint(private val boundsMap: ParamBounds,
@@ -141,7 +141,7 @@ class OrderingConstraint(private val boundsMap: ParamBounds,
entries(paramCount(entries) + n)
/** The `boundsMap` entry corresponding to `param` */
- def entry(param: PolyParam): Type = {
+ def entry(param: TypeParamRef): Type = {
val entries = boundsMap(param.binder)
if (entries == null) NoType
else entries(param.paramNum)
@@ -149,9 +149,9 @@ class OrderingConstraint(private val boundsMap: ParamBounds,
// ----------- Contains tests --------------------------------------------------
- def contains(pt: PolyType): Boolean = boundsMap(pt) != null
+ def contains(pt: TypeLambda): Boolean = boundsMap(pt) != null
- def contains(param: PolyParam): Boolean = {
+ def contains(param: TypeParamRef): Boolean = {
val entries = boundsMap(param.binder)
entries != null && isBounds(entries(param.paramNum))
}
@@ -167,43 +167,43 @@ class OrderingConstraint(private val boundsMap: ParamBounds,
// ---------- Dependency handling ----------------------------------------------
- def lower(param: PolyParam): List[PolyParam] = lowerLens(this, param.binder, param.paramNum)
- def upper(param: PolyParam): List[PolyParam] = upperLens(this, param.binder, param.paramNum)
+ def lower(param: TypeParamRef): List[TypeParamRef] = lowerLens(this, param.binder, param.paramNum)
+ def upper(param: TypeParamRef): List[TypeParamRef] = upperLens(this, param.binder, param.paramNum)
- def minLower(param: PolyParam): List[PolyParam] = {
+ def minLower(param: TypeParamRef): List[TypeParamRef] = {
val all = lower(param)
all.filterNot(p => all.exists(isLess(p, _)))
}
- def minUpper(param: PolyParam): List[PolyParam] = {
+ def minUpper(param: TypeParamRef): List[TypeParamRef] = {
val all = upper(param)
all.filterNot(p => all.exists(isLess(_, p)))
}
- def exclusiveLower(param: PolyParam, butNot: PolyParam): List[PolyParam] =
+ def exclusiveLower(param: TypeParamRef, butNot: TypeParamRef): List[TypeParamRef] =
lower(param).filterNot(isLess(_, butNot))
- def exclusiveUpper(param: PolyParam, butNot: PolyParam): List[PolyParam] =
+ def exclusiveUpper(param: TypeParamRef, butNot: TypeParamRef): List[TypeParamRef] =
upper(param).filterNot(isLess(butNot, _))
-// ---------- Info related to PolyParams -------------------------------------------
+// ---------- Info related to TypeParamRefs -------------------------------------------
- def isLess(param1: PolyParam, param2: PolyParam): Boolean =
+ def isLess(param1: TypeParamRef, param2: TypeParamRef): Boolean =
upper(param1).contains(param2)
- def nonParamBounds(param: PolyParam): TypeBounds =
+ def nonParamBounds(param: TypeParamRef): TypeBounds =
entry(param).asInstanceOf[TypeBounds]
- def fullLowerBound(param: PolyParam)(implicit ctx: Context): Type =
+ def fullLowerBound(param: TypeParamRef)(implicit ctx: Context): Type =
(nonParamBounds(param).lo /: minLower(param))(_ | _)
- def fullUpperBound(param: PolyParam)(implicit ctx: Context): Type =
+ def fullUpperBound(param: TypeParamRef)(implicit ctx: Context): Type =
(nonParamBounds(param).hi /: minUpper(param))(_ & _)
- def fullBounds(param: PolyParam)(implicit ctx: Context): TypeBounds =
+ def fullBounds(param: TypeParamRef)(implicit ctx: Context): TypeBounds =
nonParamBounds(param).derivedTypeBounds(fullLowerBound(param), fullUpperBound(param))
- def typeVarOfParam(param: PolyParam): Type = {
+ def typeVarOfParam(param: TypeParamRef): Type = {
val entries = boundsMap(param.binder)
if (entries == null) NoType
else {
@@ -212,15 +212,15 @@ class OrderingConstraint(private val boundsMap: ParamBounds,
}
}
-// ---------- Adding PolyTypes --------------------------------------------------
+// ---------- Adding TypeLambdas --------------------------------------------------
/** The list of parameters P such that, for a fresh type parameter Q:
*
* Q <: tp implies Q <: P and isUpper = true, or
* tp <: Q implies P <: Q and isUpper = false
*/
- def dependentParams(tp: Type, isUpper: Boolean): List[PolyParam] = tp match {
- case param: PolyParam if contains(param) =>
+ def dependentParams(tp: Type, isUpper: Boolean): List[TypeParamRef] = tp match {
+ case param: TypeParamRef if contains(param) =>
param :: (if (isUpper) upper(param) else lower(param))
case tp: AndOrType =>
val ps1 = dependentParams(tp.tp1, isUpper)
@@ -255,9 +255,9 @@ class OrderingConstraint(private val boundsMap: ParamBounds,
*
* @param isUpper If true, `bound` is an upper bound, else a lower bound.
*/
- private def stripParams(tp: Type, paramBuf: mutable.ListBuffer[PolyParam],
+ private def stripParams(tp: Type, paramBuf: mutable.ListBuffer[TypeParamRef],
isUpper: Boolean)(implicit ctx: Context): Type = tp match {
- case param: PolyParam if contains(param) =>
+ case param: TypeParamRef if contains(param) =>
if (!paramBuf.contains(param)) paramBuf += param
NoType
case tp: AndOrType if isUpper == tp.isAnd =>
@@ -275,16 +275,16 @@ class OrderingConstraint(private val boundsMap: ParamBounds,
* A top or bottom type if type consists only of dependent parameters.
* @param isUpper If true, `bound` is an upper bound, else a lower bound.
*/
- private def normalizedType(tp: Type, paramBuf: mutable.ListBuffer[PolyParam],
+ private def normalizedType(tp: Type, paramBuf: mutable.ListBuffer[TypeParamRef],
isUpper: Boolean)(implicit ctx: Context): Type =
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: TypeLambda, tvars: List[TypeVar])(implicit ctx: Context): This = {
assert(!contains(poly))
val nparams = poly.paramNames.length
val entries1 = new Array[Type](nparams * 2)
- poly.paramBounds.copyToArray(entries1, 0)
+ poly.paramInfos.copyToArray(entries1, 0)
tvars.copyToArray(entries1, nparams)
newConstraint(boundsMap.updated(poly, entries1), lowerMap, upperMap).init(poly)
}
@@ -293,12 +293,12 @@ 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: TypeLambda)(implicit ctx: Context): This = {
var current = this
- val loBuf, hiBuf = new mutable.ListBuffer[PolyParam]
+ val loBuf, hiBuf = new mutable.ListBuffer[TypeParamRef]
var i = 0
while (i < poly.paramNames.length) {
- val param = PolyParam(poly, i)
+ val param = TypeParamRef(poly, i)
val bounds = nonParamBounds(param)
val lo = normalizedType(bounds.lo, loBuf, isUpper = false)
val hi = normalizedType(bounds.hi, hiBuf, isUpper = true)
@@ -318,7 +318,7 @@ class OrderingConstraint(private val boundsMap: ParamBounds,
/** Add the fact `param1 <: param2` to the constraint `current` and propagate
* `<:<` relationships between parameters ("edges") but not bounds.
*/
- private def order(current: This, param1: PolyParam, param2: PolyParam)(implicit ctx: Context): This =
+ private def order(current: This, param1: TypeParamRef, param2: TypeParamRef)(implicit ctx: Context): This =
if (param1 == param2 || current.isLess(param1, param2)) this
else {
assert(contains(param1))
@@ -330,10 +330,10 @@ class OrderingConstraint(private val boundsMap: ParamBounds,
current2
}
- def addLess(param1: PolyParam, param2: PolyParam)(implicit ctx: Context): This =
+ def addLess(param1: TypeParamRef, param2: TypeParamRef)(implicit ctx: Context): This =
order(this, param1, param2)
- def updateEntry(current: This, param: PolyParam, tp: Type)(implicit ctx: Context): This = {
+ def updateEntry(current: This, param: TypeParamRef, tp: Type)(implicit ctx: Context): This = {
var current1 = boundsLens.update(this, current, param, tp)
tp match {
case TypeBounds(lo, hi) =>
@@ -346,10 +346,10 @@ class OrderingConstraint(private val boundsMap: ParamBounds,
current1
}
- def updateEntry(param: PolyParam, tp: Type)(implicit ctx: Context): This =
+ def updateEntry(param: TypeParamRef, tp: Type)(implicit ctx: Context): This =
updateEntry(this, param, tp)
- def unify(p1: PolyParam, p2: PolyParam)(implicit ctx: Context): This = {
+ def unify(p1: TypeParamRef, p2: TypeParamRef)(implicit ctx: Context): This = {
val p1Bounds = (nonParamBounds(p1) & nonParamBounds(p2)).substParam(p2, p1)
updateEntry(p1, p1Bounds).replace(p2, p1)
}
@@ -381,7 +381,7 @@ class OrderingConstraint(private val boundsMap: ParamBounds,
* would not find out where we need to approximate. Occurrences of parameters
* that are not top-level are not affected.
*/
- def replace(param: PolyParam, tp: Type)(implicit ctx: Context): OrderingConstraint = {
+ def replace(param: TypeParamRef, tp: Type)(implicit ctx: Context): OrderingConstraint = {
val replacement = tp.dealias.stripTypeVar
if (param == replacement) this
else {
@@ -389,10 +389,10 @@ class OrderingConstraint(private val boundsMap: ParamBounds,
val poly = param.binder
val idx = param.paramNum
- def removeParam(ps: List[PolyParam]) =
+ def removeParam(ps: List[TypeParamRef]) =
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: TypeLambda, atIdx: Int): Type = tp match {
case bounds @ TypeBounds(lo, hi) =>
def recombine(andor: AndOrType, op: (Type, Boolean) => Type, isUpper: Boolean): Type = {
@@ -404,7 +404,7 @@ class OrderingConstraint(private val boundsMap: ParamBounds,
}
def normalize(tp: Type, isUpper: Boolean): Type = tp match {
- case p: PolyParam if p.binder == atPoly && p.paramNum == atIdx =>
+ case p: TypeParamRef if p.binder == atPoly && p.paramNum == atIdx =>
if (isUpper) defn.AnyType else defn.NothingType
case tp: AndOrType if isUpper == tp.isAnd => recombine(tp, normalize, isUpper)
case _ => tp
@@ -432,9 +432,9 @@ class OrderingConstraint(private val boundsMap: ParamBounds,
}
}
- def remove(pt: PolyType)(implicit ctx: Context): This = {
+ def remove(pt: TypeLambda)(implicit ctx: Context): This = {
def removeFromOrdering(po: ParamOrdering) = {
- def removeFromBoundss(key: PolyType, bndss: Array[List[PolyParam]]): Array[List[PolyParam]] = {
+ def removeFromBoundss(key: TypeLambda, bndss: Array[List[TypeParamRef]]): Array[List[TypeParamRef]] = {
val bndss1 = bndss.map(_.filterConserve(_.binder ne pt))
if (bndss.corresponds(bndss1)(_ eq _)) bndss else bndss1
}
@@ -443,7 +443,7 @@ class OrderingConstraint(private val boundsMap: ParamBounds,
newConstraint(boundsMap.remove(pt), removeFromOrdering(lowerMap), removeFromOrdering(upperMap))
}
- def isRemovable(pt: PolyType): Boolean = {
+ def isRemovable(pt: TypeLambda): Boolean = {
val entries = boundsMap(pt)
@tailrec def allRemovable(last: Int): Boolean =
if (last < 0) true
@@ -456,24 +456,24 @@ class OrderingConstraint(private val boundsMap: ParamBounds,
// ---------- Exploration --------------------------------------------------------
- def domainPolys: List[PolyType] = boundsMap.keys
+ def domainLambdas: List[TypeLambda] = boundsMap.keys
- def domainParams: List[PolyParam] =
+ def domainParams: List[TypeParamRef] =
for {
(poly, entries) <- boundsMap.toList
n <- 0 until paramCount(entries)
if entries(n).exists
- } yield PolyParam(poly, n)
+ } yield TypeParamRef(poly, n)
- def forallParams(p: PolyParam => Boolean): Boolean = {
+ def forallParams(p: TypeParamRef => Boolean): Boolean = {
boundsMap.foreachBinding { (poly, entries) =>
for (i <- 0 until paramCount(entries))
- if (isBounds(entries(i)) && !p(PolyParam(poly, i))) return false
+ if (isBounds(entries(i)) && !p(TypeParamRef(poly, i))) return false
}
true
}
- def foreachParam(p: (PolyType, Int) => Unit): Unit =
+ def foreachParam(p: (TypeLambda, Int) => Unit): Unit =
boundsMap.foreachBinding { (poly, entries) =>
0.until(poly.paramNames.length).foreach(p(poly, _))
}
@@ -503,7 +503,7 @@ class OrderingConstraint(private val boundsMap: ParamBounds,
merged
}
- def mergeParams(ps1: List[PolyParam], ps2: List[PolyParam]) =
+ def mergeParams(ps1: List[TypeParamRef], ps2: List[TypeParamRef]) =
(ps1 /: ps2)((ps1, p2) => if (ps1.contains(p2)) ps1 else p2 :: ps1)
def mergeEntries(e1: Type, e2: Type): Type = e1 match {
@@ -532,13 +532,13 @@ class OrderingConstraint(private val boundsMap: ParamBounds,
}
override def checkClosed()(implicit ctx: Context): Unit = {
- def isFreePolyParam(tp: Type) = tp match {
- case PolyParam(binder: PolyType, _) => !contains(binder)
+ def isFreeTypeParamRef(tp: Type) = tp match {
+ case TypeParamRef(binder: TypeLambda, _) => !contains(binder)
case _ => false
}
def checkClosedType(tp: Type, where: String) =
if (tp != null)
- assert(!tp.existsPart(isFreePolyParam), i"unclosed constraint: $this refers to $tp in $where")
+ assert(!tp.existsPart(isFreeTypeParamRef), i"unclosed constraint: $this refers to $tp in $where")
boundsMap.foreachBinding((_, tps) => tps.foreach(checkClosedType(_, "bounds")))
lowerMap.foreachBinding((_, paramss) => paramss.foreach(_.foreach(checkClosedType(_, "lower"))))
upperMap.foreachBinding((_, paramss) => paramss.foreach(_.foreach(checkClosedType(_, "upper"))))
@@ -567,7 +567,7 @@ class OrderingConstraint(private val boundsMap: ParamBounds,
def checkNonCyclic()(implicit ctx: Context): Unit =
domainParams.foreach(checkNonCyclic)
- private def checkNonCyclic(param: PolyParam)(implicit ctx: Context): Unit =
+ private def checkNonCyclic(param: TypeParamRef)(implicit ctx: Context): Unit =
assert(!isLess(param, param), i"cyclic constraint involving $param in $this")
// ---------- toText -----------------------------------------------------
@@ -584,7 +584,7 @@ class OrderingConstraint(private val boundsMap: ParamBounds,
val uninstVarsText = " uninstVars = " ~
Text(uninstVars map (_.toText(printer)), ", ") ~ ";"
val constrainedText =
- " constrained types = " ~ Text(domainPolys map (_.toText(printer)), ", ")
+ " constrained types = " ~ Text(domainLambdas map (_.toText(printer)), ", ")
val boundsText =
" bounds = " ~ {
val assocs =
@@ -614,8 +614,8 @@ class OrderingConstraint(private val boundsMap: ParamBounds,
case _ =>" := " + tp
}
val constrainedText =
- " constrained types = " + domainPolys.mkString("\n")
- val boundsText =
+ " constrained types = " + domainLambdas.mkString("\n")
+ val boundsText = domainLambdas
" bounds = " + {
val assocs =
for (param <- domainParams)
diff --git a/compiler/src/dotty/tools/dotc/core/TypeParamInfo.scala b/compiler/src/dotty/tools/dotc/core/ParamInfo.scala
index 647c895db..46e378fc2 100644
--- a/compiler/src/dotty/tools/dotc/core/TypeParamInfo.scala
+++ b/compiler/src/dotty/tools/dotc/core/ParamInfo.scala
@@ -1,13 +1,15 @@
package dotty.tools.dotc.core
-import Names.TypeName
+import Names.Name
import Contexts.Context
-import Types.{Type, TypeBounds}
+import Types.Type
/** A common super trait of Symbol and LambdaParam.
* Used to capture the attributes of type parameters which can be implemented as either.
*/
-trait TypeParamInfo {
+trait ParamInfo {
+
+ type ThisName <: Name
/** Is this the info of a type parameter? Will return `false` for symbols
* that are not type parameters.
@@ -15,26 +17,30 @@ trait TypeParamInfo {
def isTypeParam(implicit ctx: Context): Boolean
/** The name of the type parameter */
- def paramName(implicit ctx: Context): TypeName
+ def paramName(implicit ctx: Context): ThisName
/** The info of the type parameter */
- def paramBounds(implicit ctx: Context): TypeBounds
+ def paramInfo(implicit ctx: Context): Type
/** The info of the type parameter as seen from a prefix type.
* For type parameter symbols, this is the `memberInfo` as seen from `prefix`.
- * For type lambda parameters, it's the same as `paramBounds` as
+ * For type lambda parameters, it's the same as `paramInfos` as
* `asSeenFrom` has already been applied to the whole type lambda.
*/
- def paramBoundsAsSeenFrom(pre: Type)(implicit ctx: Context): TypeBounds
+ def paramInfoAsSeenFrom(pre: Type)(implicit ctx: Context): Type
/** The parameter bounds, or the completer if the type parameter
* is an as-yet uncompleted symbol.
*/
- def paramBoundsOrCompleter(implicit ctx: Context): Type
+ def paramInfoOrCompleter(implicit ctx: Context): Type
/** The variance of the type parameter */
def paramVariance(implicit ctx: Context): Int
/** A type that refers to the parameter */
def paramRef(implicit ctx: Context): Type
+}
+
+object ParamInfo {
+ type Of[N] = ParamInfo { type ThisName = N }
} \ No newline at end of file
diff --git a/compiler/src/dotty/tools/dotc/core/StdNames.scala b/compiler/src/dotty/tools/dotc/core/StdNames.scala
index bc3f96d91..e7928fd09 100644
--- a/compiler/src/dotty/tools/dotc/core/StdNames.scala
+++ b/compiler/src/dotty/tools/dotc/core/StdNames.scala
@@ -722,9 +722,6 @@ object StdNames {
case _ => termName("_" + j)
}
- def syntheticParamNames(num: Int): List[TermName] =
- (0 until num).map(syntheticParamName)(breakOut)
-
def localDummyName(clazz: Symbol)(implicit ctx: Context): TermName =
LOCALDUMMY_PREFIX ++ clazz.name ++ ">"
@@ -747,9 +744,6 @@ object StdNames {
def syntheticTypeParamName(i: Int): TypeName = "X" + i
- def syntheticTypeParamNames(num: Int): List[TypeName] =
- (0 until num).map(syntheticTypeParamName)(breakOut)
-
final val Conforms = encode("<:<")
final val Uninstantiated: TypeName = "?$"
@@ -850,5 +844,4 @@ object StdNames {
val tpnme = new ScalaTypeNames
val jnme = new JavaTermNames
val jtpnme = new JavaTypeNames
-
}
diff --git a/compiler/src/dotty/tools/dotc/core/Substituters.scala b/compiler/src/dotty/tools/dotc/core/Substituters.scala
index 23683608a..d565ec229 100644
--- a/compiler/src/dotty/tools/dotc/core/Substituters.scala
+++ b/compiler/src/dotty/tools/dotc/core/Substituters.scala
@@ -196,7 +196,7 @@ trait Substituters { this: Context =>
.mapOver(tp)
}
- final def substParam(tp: Type, from: ParamType, to: Type, theMap: SubstParamMap): Type =
+ final def substParam(tp: Type, from: ParamRef, to: Type, theMap: SubstParamMap): Type =
tp match {
case tp: BoundType =>
if (tp == from) to else tp
@@ -216,7 +216,7 @@ trait Substituters { this: Context =>
final def substParams(tp: Type, from: BindingType, to: List[Type], theMap: SubstParamsMap): Type =
tp match {
- case tp: ParamType =>
+ case tp: ParamRef =>
if (tp.binder == from) to(tp.paramNum) else tp
case tp: NamedType =>
if (tp.currentSymbol.isStatic) tp
@@ -269,7 +269,7 @@ trait Substituters { this: Context =>
def apply(tp: Type): Type = substRecThis(tp, from, to, this)
}
- final class SubstParamMap(from: ParamType, to: Type) extends DeepTypeMap {
+ final class SubstParamMap(from: ParamRef, to: Type) extends DeepTypeMap {
def apply(tp: Type) = substParam(tp, from, to, this)
}
diff --git a/compiler/src/dotty/tools/dotc/core/SymDenotations.scala b/compiler/src/dotty/tools/dotc/core/SymDenotations.scala
index 27782698d..602848a50 100644
--- a/compiler/src/dotty/tools/dotc/core/SymDenotations.scala
+++ b/compiler/src/dotty/tools/dotc/core/SymDenotations.scala
@@ -1146,14 +1146,13 @@ 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: MethodType => tp.paramTypes.exists(hasSkolems) || hasSkolems(tp.resType)
+ case tp: TypeBounds => hasSkolems(tp.lo) || hasSkolems(tp.hi)
+ case tp: TypeVar => hasSkolems(tp.inst)
case tp: ExprType => hasSkolems(tp.resType)
case tp: HKApply => hasSkolems(tp.tycon) || tp.args.exists(hasSkolems)
+ case tp: LambdaType => tp.paramInfos.exists(hasSkolems) || hasSkolems(tp.resType)
case tp: AndOrType => hasSkolems(tp.tp1) || hasSkolems(tp.tp2)
- case tp: TypeBounds => hasSkolems(tp.lo) || hasSkolems(tp.hi)
case tp: AnnotatedType => hasSkolems(tp.tpe)
- case tp: TypeVar => hasSkolems(tp.inst)
case _ => false
}
diff --git a/compiler/src/dotty/tools/dotc/core/Symbols.scala b/compiler/src/dotty/tools/dotc/core/Symbols.scala
index 33aba4d13..95ff1cb75 100644
--- a/compiler/src/dotty/tools/dotc/core/Symbols.scala
+++ b/compiler/src/dotty/tools/dotc/core/Symbols.scala
@@ -384,7 +384,7 @@ object Symbols {
* @param coord The coordinates of the symbol (a position or an index)
* @param id A unique identifier of the symbol (unique per ContextBase)
*/
- class Symbol private[Symbols] (val coord: Coord, val id: Int) extends DotClass with TypeParamInfo with printing.Showable {
+ class Symbol private[Symbols] (val coord: Coord, val id: Int) extends DotClass with ParamInfo with printing.Showable {
type ThisName <: Name
@@ -513,12 +513,12 @@ object Symbols {
*/
def pos: Position = if (coord.isPosition) coord.toPosition else NoPosition
- // TypeParamInfo methods
+ // ParamInfo types and methods
def isTypeParam(implicit ctx: Context) = denot.is(TypeParam)
- def paramName(implicit ctx: Context) = name.asTypeName
- def paramBounds(implicit ctx: Context) = denot.info.bounds
- def paramBoundsAsSeenFrom(pre: Type)(implicit ctx: Context) = pre.memberInfo(this).bounds
- def paramBoundsOrCompleter(implicit ctx: Context): Type = denot.infoOrCompleter
+ def paramName(implicit ctx: Context) = name.asInstanceOf[ThisName]
+ def paramInfo(implicit ctx: Context) = denot.info
+ def paramInfoAsSeenFrom(pre: Type)(implicit ctx: Context) = pre.memberInfo(this)
+ def paramInfoOrCompleter(implicit ctx: Context): Type = denot.infoOrCompleter
def paramVariance(implicit ctx: Context) = denot.variance
def paramRef(implicit ctx: Context) = denot.typeRef
diff --git a/compiler/src/dotty/tools/dotc/core/TypeApplications.scala b/compiler/src/dotty/tools/dotc/core/TypeApplications.scala
index ba3e6a461..23c3f96cc 100644
--- a/compiler/src/dotty/tools/dotc/core/TypeApplications.scala
+++ b/compiler/src/dotty/tools/dotc/core/TypeApplications.scala
@@ -21,6 +21,8 @@ import java.util.NoSuchElementException
object TypeApplications {
+ type TypeParamInfo = ParamInfo.Of[TypeName]
+
/** Assert type is not a TypeBounds instance and return it unchanged */
val noBounds = (tp: Type) => tp match {
case tp: TypeBounds => throw new AssertionError("no TypeBounds allowed")
@@ -73,7 +75,7 @@ object TypeApplications {
}
def unapply(tp: Type)(implicit ctx: Context): Option[TypeRef] = tp match {
- case tp @ PolyType(tparams, AppliedType(fn: TypeRef, args)) if (args == tparams.map(_.toArg)) => Some(fn)
+ case tp @ HKTypeLambda(tparams, AppliedType(fn: TypeRef, args)) if (args == tparams.map(_.toArg)) => Some(fn)
case _ => None
}
}
@@ -119,7 +121,7 @@ object TypeApplications {
*/
def EtaExpandIfHK(tparams: List[TypeParamInfo], args: List[Type])(implicit ctx: Context): List[Type] =
if (tparams.isEmpty) args
- else args.zipWithConserve(tparams)((arg, tparam) => arg.EtaExpandIfHK(tparam.paramBoundsOrCompleter))
+ else args.zipWithConserve(tparams)((arg, tparam) => arg.EtaExpandIfHK(tparam.paramInfoOrCompleter))
/** A type map that tries to reduce (part of) the result type of the type lambda `tycon`
* with the given `args`(some of which are wildcard arguments represented by type bounds).
@@ -160,18 +162,18 @@ 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: PolyType, args: List[Type])(implicit ctx: Context) extends TypeMap {
+ class Reducer(tycon: TypeLambda, args: List[Type])(implicit ctx: Context) extends TypeMap {
private var available = (0 until args.length).toSet
var allReplaced = true
- def hasWildcardArg(p: PolyParam) =
+ def hasWildcardArg(p: TypeParamRef) =
p.binder == tycon && args(p.paramNum).isInstanceOf[TypeBounds]
- def canReduceWildcard(p: PolyParam) =
+ def canReduceWildcard(p: TypeParamRef) =
!ctx.mode.is(Mode.AllowLambdaWildcardApply) || available.contains(p.paramNum)
def apply(t: Type) = t match {
- case t @ TypeAlias(p: PolyParam) if hasWildcardArg(p) && canReduceWildcard(p) =>
+ case t @ TypeAlias(p: TypeParamRef) if hasWildcardArg(p) && canReduceWildcard(p) =>
available -= p.paramNum
args(p.paramNum)
- case p: PolyParam if p.binder == tycon =>
+ case p: TypeParamRef if p.binder == tycon =>
args(p.paramNum) match {
case TypeBounds(lo, hi) =>
if (ctx.mode.is(Mode.AllowLambdaWildcardApply)) { allReplaced = false; p }
@@ -213,7 +215,7 @@ class TypeApplications(val self: Type) extends AnyVal {
self match {
case self: ClassInfo =>
self.cls.typeParams
- case self: PolyType =>
+ case self: HKTypeLambda =>
self.typeParams
case self: TypeRef =>
val tsym = self.symbol
@@ -251,7 +253,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: PolyType => true
+ case self: HKTypeLambda => true
case self: SingletonType => false
case self: TypeVar =>
// Using `origin` instead of `underlying`, as is done for typeParams,
@@ -270,31 +272,6 @@ class TypeApplications(val self: Type) extends AnyVal {
self
}
- /** Lambda abstract `self` with given type parameters. Examples:
- *
- * type T[X] = U becomes type T = [X] -> U
- * type T[X] >: L <: U becomes type T >: L <: ([X] -> U)
- *
- * TODO: Handle parameterized lower bounds
- */
- def LambdaAbstract(tparams: List[TypeParamInfo])(implicit ctx: Context): Type = {
- def expand(tp: Type) =
- PolyType(
- tparams.map(_.paramName), tparams.map(_.paramVariance))(
- tl => tparams.map(tparam => tl.lifted(tparams, tparam.paramBounds).bounds),
- tl => tl.lifted(tparams, tp))
- if (tparams.isEmpty) self
- else self match {
- case self: TypeAlias =>
- self.derivedTypeAlias(expand(self.alias))
- case self @ TypeBounds(lo, hi) =>
- self.derivedTypeBounds(
- if (lo.isRef(defn.NothingClass)) lo else expand(lo),
- expand(hi))
- case _ => expand(self)
- }
- }
-
/** Convert a type constructor `TC` which has type parameters `T1, ..., Tn`
* in a context where type parameters `U1,...,Un` are expected to
*
@@ -307,7 +284,7 @@ class TypeApplications(val self: Type) extends AnyVal {
*/
def EtaExpand(tparams: List[TypeSymbol])(implicit ctx: Context): Type = {
val tparamsToUse = if (variancesConform(typeParams, tparams)) tparams else typeParamSymbols
- self.appliedTo(tparams map (_.typeRef)).LambdaAbstract(tparamsToUse)
+ HKTypeLambda.fromParams(tparamsToUse, self.appliedTo(tparams map (_.typeRef)))
//.ensuring(res => res.EtaReduce =:= self, s"res = $res, core = ${res.EtaReduce}, self = $self, hc = ${res.hashCode}")
}
@@ -362,11 +339,13 @@ class TypeApplications(val self: Type) extends AnyVal {
if (hkParams.isEmpty) self
else {
def adaptArg(arg: Type): Type = arg match {
- case arg @ PolyType(tparams, body) if
+ case arg @ HKTypeLambda(tparams, body) if
!tparams.corresponds(hkParams)(_.paramVariance == _.paramVariance) &&
tparams.corresponds(hkParams)(varianceConforms) =>
- PolyType(tparams.map(_.paramName), hkParams.map(_.paramVariance))(
- tl => arg.paramBounds.map(_.subst(arg, tl).bounds),
+ HKTypeLambda(
+ (tparams, hkParams).zipped.map((tparam, hkparam) =>
+ tparam.paramName.withVariance(hkparam.paramVariance)))(
+ tl => arg.paramInfos.map(_.subst(arg, tl).bounds),
tl => arg.resultType.subst(arg, tl)
)
case arg @ TypeAlias(alias) =>
@@ -390,7 +369,7 @@ class TypeApplications(val self: Type) extends AnyVal {
*/
final def appliedTo(args: List[Type])(implicit ctx: Context): Type = /*>|>*/ track("appliedTo") /*<|<*/ {
val typParams = self.typeParams
- def matchParams(t: Type, tparams: List[TypeParamInfo], args: List[Type])(implicit ctx: Context): Type = args match {
+ def matchParams(t: Type, tparams: List[ParamInfo], args: List[Type])(implicit ctx: Context): Type = args match {
case arg :: args1 =>
try {
val tparam :: tparams1 = tparams
@@ -407,7 +386,7 @@ class TypeApplications(val self: Type) extends AnyVal {
val dealiased = stripped.safeDealias
if (args.isEmpty || ctx.erasedTypes) self
else dealiased match {
- case dealiased: PolyType =>
+ case dealiased: HKTypeLambda =>
def tryReduce =
if (!args.exists(_.isInstanceOf[TypeBounds])) {
val followAlias = Config.simplifyApplications && {
@@ -426,7 +405,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
- .derivedPolyType(resType = tycon.safeDealias.appliedTo(args1))
+ .derivedLambdaType(resType = tycon.safeDealias.appliedTo(args1))
.appliedTo(args)
case _ =>
val reducer = new Reducer(dealiased, args)
@@ -435,6 +414,8 @@ 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 =>
@@ -475,7 +456,7 @@ class TypeApplications(val self: Type) extends AnyVal {
/** Turn this type, which is used as an argument for
* type parameter `tparam`, into a TypeBounds RHS
*/
- final def toBounds(tparam: TypeParamInfo)(implicit ctx: Context): TypeBounds = self match {
+ final def toBounds(tparam: ParamInfo)(implicit ctx: Context): TypeBounds = self match {
case self: TypeBounds => // this can happen for wildcard args
self
case _ =>
diff --git a/compiler/src/dotty/tools/dotc/core/TypeComparer.scala b/compiler/src/dotty/tools/dotc/core/TypeComparer.scala
index 57dde3288..da6d63387 100644
--- a/compiler/src/dotty/tools/dotc/core/TypeComparer.scala
+++ b/compiler/src/dotty/tools/dotc/core/TypeComparer.scala
@@ -280,7 +280,7 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling {
case _ =>
}
thirdTry(tp1, tp2)
- case tp1: PolyParam =>
+ case tp1: TypeParamRef =>
def flagNothingBound = {
if (!frozenConstraint && tp2.isRef(defn.NothingClass) && state.isGlobalCommittable) {
def msg = s"!!! instantiated to Nothing: $tp1, constraint = ${constraint.show}"
@@ -289,13 +289,13 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling {
}
true
}
- def comparePolyParam =
+ def compareTypeParamRef =
ctx.mode.is(Mode.TypevarsMissContext) ||
isSubTypeWhenFrozen(bounds(tp1).hi, tp2) || {
if (canConstrain(tp1)) addConstraint(tp1, tp2, fromBelow = false) && flagNothingBound
else thirdTry(tp1, tp2)
}
- comparePolyParam
+ compareTypeParamRef
case tp1: ThisType =>
val cls1 = tp1.cls
tp2 match {
@@ -373,8 +373,8 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling {
private def thirdTry(tp1: Type, tp2: Type): Boolean = tp2 match {
case tp2: NamedType =>
thirdTryNamed(tp1, tp2)
- case tp2: PolyParam =>
- def comparePolyParam =
+ case tp2: TypeParamRef =>
+ def compareTypeParamRef =
(ctx.mode is Mode.TypevarsMissContext) || {
val alwaysTrue =
// The following condition is carefully formulated to catch all cases
@@ -391,7 +391,7 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling {
else fourthTry(tp1, tp2)
}
}
- comparePolyParam
+ compareTypeParamRef
case tp2: RefinedType =>
def compareRefinedSlow: Boolean = {
val name2 = tp2.refinedName
@@ -428,9 +428,9 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling {
compareRec
case tp2 @ HKApply(tycon2, args2) =>
compareHkApply2(tp1, tp2, tycon2, args2)
- case tp2 @ PolyType(tparams2, body2) =>
- def compareHkLambda: Boolean = tp1.stripTypeVar match {
- case tp1 @ PolyType(tparams1, body1) =>
+ case tp2: HKTypeLambda =>
+ def compareTypeLambda: Boolean = tp1.stripTypeVar match {
+ case tp1: HKTypeLambda =>
/* 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:
@@ -446,16 +446,16 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling {
*/
def boundsOK =
ctx.scala2Mode ||
- tparams1.corresponds(tparams2)((tparam1, tparam2) =>
- isSubType(tparam2.paramBounds.subst(tp2, tp1), tparam1.paramBounds))
- val saved = comparedPolyTypes
- comparedPolyTypes += tp1
- comparedPolyTypes += tp2
+ tp1.typeParams.corresponds(tp2.typeParams)((tparam1, tparam2) =>
+ isSubType(tparam2.paramInfo.subst(tp2, tp1), tparam1.paramInfo))
+ val saved = comparedTypeLambdas
+ comparedTypeLambdas += tp1
+ comparedTypeLambdas += tp2
try
- variancesConform(tparams1, tparams2) &&
+ variancesConform(tp1.typeParams, tp2.typeParams) &&
boundsOK &&
- isSubType(body1, body2.subst(tp2, tp1))
- finally comparedPolyTypes = saved
+ isSubType(tp1.resType, tp2.resType.subst(tp2, tp1))
+ finally comparedTypeLambdas = saved
case _ =>
if (!tp1.isHK) {
tp2 match {
@@ -466,7 +466,7 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling {
}
fourthTry(tp1, tp2)
}
- compareHkLambda
+ compareTypeLambda
case OrType(tp21, tp22) =>
// Rewrite T1 <: (T211 & T212) | T22 to T1 <: (T211 | T22) and T1 <: (T212 | T22)
// and analogously for T1 <: T21 | (T221 & T222)
@@ -484,12 +484,12 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling {
case _ =>
}
either(isSubType(tp1, tp21), isSubType(tp1, tp22)) || fourthTry(tp1, tp2)
- case tp2: MethodType =>
+ case tp2: MethodOrPoly =>
def compareMethod = tp1 match {
- case tp1: MethodType =>
+ case tp1: MethodOrPoly =>
(tp1.signature consistentParams tp2.signature) &&
- matchingParams(tp1.paramTypes, tp2.paramTypes, tp1.isJava, tp2.isJava) &&
- (tp1.isImplicit == tp2.isImplicit) &&
+ matchingParams(tp1, tp2) &&
+ tp1.isImplicit == tp2.isImplicit &&
isSubType(tp1.resultType, tp2.resultType.subst(tp2, tp1))
case _ =>
false
@@ -618,7 +618,7 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling {
def isMatchingApply(tp1: Type): Boolean = tp1 match {
case HKApply(tycon1, args1) =>
tycon1.dealias match {
- case tycon1: PolyParam =>
+ case tycon1: TypeParamRef =>
(tycon1 == tycon2 ||
canConstrain(tycon1) && tryInstantiate(tycon1, tycon2)) &&
isSubArgs(args1, args2, tparams)
@@ -646,7 +646,7 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling {
* and the resulting type application is a supertype of `tp1`,
* or fallback to fourthTry.
*/
- def canInstantiate(tycon2: PolyParam): Boolean = {
+ def canInstantiate(tycon2: TypeParamRef): Boolean = {
/** Let
*
@@ -669,10 +669,10 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling {
val tparams1 = tparams1a.drop(lengthDiff)
variancesConform(tparams1, tparams) && {
if (lengthDiff > 0)
- tycon1b = PolyType(tparams1.map(_.paramName), tparams1.map(_.paramVariance))(
- tl => tparams1.map(tparam => tl.lifted(tparams, tparam.paramBounds).bounds),
+ tycon1b = HKTypeLambda(tparams1.map(_.paramName))(
+ tl => tparams1.map(tparam => tl.integrate(tparams, tparam.paramInfo).bounds),
tl => tycon1a.appliedTo(args1.take(lengthDiff) ++
- tparams1.indices.toList.map(PolyParam(tl, _))))
+ tparams1.indices.toList.map(TypeParamRef(tl, _))))
(ctx.mode.is(Mode.TypevarsMissContext) ||
tryInstantiate(tycon2, tycon1b.ensureHK)) &&
isSubType(tp1, tycon1b.appliedTo(args2))
@@ -725,7 +725,7 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling {
fallback(tycon2bounds.lo)
tycon2 match {
- case param2: PolyParam =>
+ case param2: TypeParamRef =>
isMatchingApply(tp1) || {
if (canConstrain(param2)) canInstantiate(param2)
else compareLower(bounds(param2), tyconIsTypeRef = false)
@@ -746,7 +746,7 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling {
*/
def compareHkApply1(tp1: HKApply, tycon1: Type, args1: List[Type], tp2: Type): Boolean =
tycon1 match {
- case param1: PolyParam =>
+ case param1: TypeParamRef =>
def canInstantiate = tp2 match {
case AppliedType(tycon2, args2) =>
tryInstantiate(param1, tycon2.ensureHK) && isSubArgs(args1, args2, tycon2.typeParams)
@@ -764,7 +764,7 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling {
/** Subtype test for corresponding arguments in `args1`, `args2` according to
* variances in type parameters `tparams`.
*/
- def isSubArgs(args1: List[Type], args2: List[Type], tparams: List[TypeParamInfo]): Boolean =
+ def isSubArgs(args1: List[Type], args2: List[Type], tparams: List[ParamInfo]): Boolean =
if (args1.isEmpty) args2.isEmpty
else args2.nonEmpty && {
val v = tparams.head.paramVariance
@@ -806,7 +806,7 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling {
def fix(tp: Type): Type = tp.stripTypeVar match {
case tp: RecType => fix(tp.parent).substRecThis(tp, anchor)
case tp @ RefinedType(parent, rname, rinfo) => tp.derivedRefinedType(fix(parent), rname, rinfo)
- case tp: PolyParam => fixOrElse(bounds(tp).hi, tp)
+ case tp: TypeParamRef => fixOrElse(bounds(tp).hi, tp)
case tp: TypeProxy => fixOrElse(tp.underlying, tp)
case tp: AndOrType => tp.derivedAndOrType(fix(tp.tp1), fix(tp.tp2))
case tp => tp
@@ -967,7 +967,7 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling {
/** Defer constraining type variables when compared against prototypes */
def isMatchedByProto(proto: ProtoType, tp: Type) = tp.stripTypeVar match {
- case tp: PolyParam if constraint contains tp => true
+ case tp: TypeParamRef if constraint contains tp => true
case _ => proto.isMatchedBy(tp)
}
@@ -978,7 +978,7 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling {
* type variable with (the corresponding type in) `tp2` instead.
*/
private def isCappable(tp: Type): Boolean = tp match {
- case tp: PolyParam => constraint contains tp
+ case tp: TypeParamRef => constraint contains tp
case tp: TypeProxy => isCappable(tp.underlying)
case tp: AndOrType => isCappable(tp.tp1) || isCappable(tp.tp2)
case _ => false
@@ -1021,7 +1021,7 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling {
tp2.widen match {
case tp2: MethodType =>
// implicitness is ignored when matching
- matchingParams(tp1.paramTypes, tp2.paramTypes, tp1.isJava, tp2.isJava) &&
+ matchingParams(tp1, tp2) &&
matchesType(tp1.resultType, tp2.resultType.subst(tp2, tp1), relaxed)
case tp2 =>
relaxed && tp1.paramNames.isEmpty &&
@@ -1031,7 +1031,7 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling {
tp2.widen match {
case tp2: PolyType =>
sameLength(tp1.paramNames, tp2.paramNames) &&
- matchesType(tp1.resultType, tp2.resultType.subst(tp2, tp1), relaxed)
+ matchesType(tp1.resultType, tp2.resultType.subst(tp2, tp1), relaxed)
case _ =>
false
}
@@ -1047,28 +1047,28 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling {
}
}
- /** Are `syms1` and `syms2` parameter lists with pairwise equivalent types? */
- def matchingParams(formals1: List[Type], formals2: List[Type], isJava1: Boolean, isJava2: Boolean): Boolean = formals1 match {
- case formal1 :: rest1 =>
- formals2 match {
- case formal2 :: rest2 =>
- (isSameTypeWhenFrozen(formal1, formal2)
- || isJava1 && (formal2 isRef ObjectClass) && (formal1 isRef AnyClass)
- || isJava2 && (formal1 isRef ObjectClass) && (formal2 isRef AnyClass)) &&
- matchingParams(rest1, rest2, isJava1, isJava2)
- case nil =>
- false
- }
- case nil =>
- formals2.isEmpty
- }
-
- /** Do generic types `poly1` and `poly2` have type parameters that
- * have the same bounds (after renaming one set to the other)?
+ /** Do lambda types `lam1` and `lam2` have parameters that have the same types
+ * and the same implicit status? (after renaming one set to the other)
*/
- def matchingTypeParams(poly1: PolyType, poly2: PolyType): Boolean =
- (poly1.paramBounds corresponds poly2.paramBounds)((b1, b2) =>
- isSameType(b1, b2.subst(poly2, poly1)))
+ def matchingParams(lam1: MethodOrPoly, lam2: MethodOrPoly): Boolean = {
+ /** Are `syms1` and `syms2` parameter lists with pairwise equivalent types? */
+ def loop(formals1: List[Type], formals2: List[Type]): Boolean = formals1 match {
+ case formal1 :: rest1 =>
+ formals2 match {
+ case formal2 :: rest2 =>
+ val formal2a = if (lam2.isParamDependent) formal2.subst(lam2, lam1) else formal2
+ (isSameTypeWhenFrozen(formal1, formal2a)
+ || lam1.isJava && (formal2 isRef ObjectClass) && (formal1 isRef AnyClass)
+ || lam2.isJava && (formal1 isRef ObjectClass) && (formal2 isRef AnyClass)) &&
+ loop(rest1, rest2)
+ case nil =>
+ false
+ }
+ case nil =>
+ formals2.isEmpty
+ }
+ loop(lam1.paramInfos, lam2.paramInfos)
+ }
// Type equality =:=
@@ -1216,7 +1216,7 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling {
/** Form a normalized conjunction of two types.
* Note: For certain types, `&` is distributed inside the type. This holds for
* all types which are not value types (e.g. TypeBounds, ClassInfo,
- * ExprType, MethodType, PolyType). Also, when forming an `&`,
+ * ExprType, LambdaType). Also, when forming an `&`,
* instantiated TypeVars are dereferenced and annotations are stripped.
* Finally, refined types with the same refined name are
* opportunistically merged.
@@ -1245,7 +1245,7 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling {
/** Form a normalized conjunction of two types.
* Note: For certain types, `|` is distributed inside the type. This holds for
* all types which are not value types (e.g. TypeBounds, ClassInfo,
- * ExprType, MethodType, PolyType). Also, when forming an `|`,
+ * ExprType, LambdaType). Also, when forming an `|`,
* instantiated TypeVars are dereferenced and annotations are stripped.
*
* Sometimes, the disjunction of two types cannot be formed because
@@ -1276,20 +1276,20 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling {
val tparams2 = tp2.typeParams
if (tparams1.isEmpty)
if (tparams2.isEmpty) op(tp1, tp2)
- else original(tp1, tp2.appliedTo(tp2.typeParams.map(_.paramBoundsAsSeenFrom(tp2))))
+ else original(tp1, tp2.appliedTo(tp2.typeParams.map(_.paramInfoAsSeenFrom(tp2))))
else if (tparams2.isEmpty)
- original(tp1.appliedTo(tp1.typeParams.map(_.paramBoundsAsSeenFrom(tp1))), tp2)
+ original(tp1.appliedTo(tp1.typeParams.map(_.paramInfoAsSeenFrom(tp1))), tp2)
else
- PolyType(
- paramNames = tpnme.syntheticTypeParamNames(tparams1.length),
- variances = (tparams1, tparams2).zipped.map((tparam1, tparam2) =>
- (tparam1.paramVariance + tparam2.paramVariance) / 2))(
- paramBoundsExp = tl => (tparams1, tparams2).zipped.map((tparam1, tparam2) =>
- tl.lifted(tparams1, tparam1.paramBoundsAsSeenFrom(tp1)).bounds &
- tl.lifted(tparams2, tparam2.paramBoundsAsSeenFrom(tp2)).bounds),
+ HKTypeLambda(
+ paramNames = (HKTypeLambda.syntheticParamNames(tparams1.length), tparams1, tparams2)
+ .zipped.map((pname, tparam1, tparam2) =>
+ pname.withVariance((tparam1.paramVariance + tparam2.paramVariance) / 2)))(
+ paramInfosExp = tl => (tparams1, tparams2).zipped.map((tparam1, tparam2) =>
+ tl.integrate(tparams1, tparam1.paramInfoAsSeenFrom(tp1)).bounds &
+ tl.integrate(tparams2, tparam2.paramInfoAsSeenFrom(tp2)).bounds),
resultTypeExp = tl =>
- original(tl.lifted(tparams1, tp1).appliedTo(tl.paramRefs),
- tl.lifted(tparams2, tp2).appliedTo(tl.paramRefs)))
+ original(tl.integrate(tparams1, tp1).appliedTo(tl.paramRefs),
+ tl.integrate(tparams2, tp2).appliedTo(tl.paramRefs)))
}
/** Try to distribute `&` inside type, detect and handle conflicts
@@ -1392,8 +1392,8 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling {
case tp2: MethodType =>
def asGoodParams(formals1: List[Type], formals2: List[Type]) =
(formals2 corresponds formals1)(isSubTypeWhenFrozen)
- asGoodParams(tp1.paramTypes, tp2.paramTypes) &&
- (!asGoodParams(tp2.paramTypes, tp1.paramTypes) ||
+ asGoodParams(tp1.paramInfos, tp2.paramInfos) &&
+ (!asGoodParams(tp2.paramInfos, tp1.paramInfos) ||
isAsGood(tp1.resultType, tp2.resultType))
case _ =>
false
@@ -1424,7 +1424,7 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling {
def showGoal(tp1: Type, tp2: Type)(implicit ctx: Context) = {
println(ex"assertion failure for $tp1 <:< $tp2, frozen = $frozenConstraint")
def explainPoly(tp: Type) = tp match {
- case tp: PolyParam => ctx.echo(s"polyparam ${tp.show} found in ${tp.binder.show}")
+ case tp: TypeParamRef => ctx.echo(s"TypeParamRef ${tp.show} found in ${tp.binder.show}")
case tp: TypeRef if tp.symbol.exists => ctx.echo(s"typeref ${tp.show} found in ${tp.symbol.owner.show}")
case tp: TypeVar => ctx.echo(s"typevar ${tp.show}, origin = ${tp.origin}")
case _ => ctx.echo(s"${tp.show} is a ${tp.getClass}")
@@ -1503,7 +1503,7 @@ class ExplainingTypeComparer(initctx: Context) extends TypeComparer(initctx) {
super.glb(tp1, tp2)
}
- override def addConstraint(param: PolyParam, bound: Type, fromBelow: Boolean): Boolean =
+ override def addConstraint(param: TypeParamRef, bound: Type, fromBelow: Boolean): Boolean =
traceIndented(i"add constraint $param ${if (fromBelow) ">:" else "<:"} $bound $frozenConstraint, constraint = ${ctx.typerState.constraint}") {
super.addConstraint(param, bound, fromBelow)
}
diff --git a/compiler/src/dotty/tools/dotc/core/TypeErasure.scala b/compiler/src/dotty/tools/dotc/core/TypeErasure.scala
index fe3396fcb..f35752644 100644
--- a/compiler/src/dotty/tools/dotc/core/TypeErasure.scala
+++ b/compiler/src/dotty/tools/dotc/core/TypeErasure.scala
@@ -28,7 +28,7 @@ import scala.annotation.tailrec
* WildcardType
* ErrorType
*
- * only for isInstanceOf, asInstanceOf: PolyType, PolyParam, TypeBounds
+ * only for isInstanceOf, asInstanceOf: PolyType, TypeParamRef, TypeBounds
*
*/
object TypeErasure {
@@ -55,7 +55,7 @@ object TypeErasure {
case ThisType(tref) =>
isErasedType(tref)
case tp: MethodType =>
- tp.paramTypes.forall(isErasedType) && isErasedType(tp.resultType)
+ tp.paramInfos.forall(isErasedType) && isErasedType(tp.resultType)
case tp @ ClassInfo(pre, _, parents, decls, _) =>
isErasedType(pre) && parents.forall(isErasedType) //&& decls.forall(sym => isErasedType(sym.info)) && isErasedType(tp.selfType)
case NoType | NoPrefix | WildcardType | _: ErrorType | SuperType(_, _) =>
@@ -176,7 +176,7 @@ object TypeErasure {
val erase = erasureFn(isJava, semiEraseVCs, sym.isConstructor, wildcardOK = false)
def eraseParamBounds(tp: PolyType): Type =
- tp.derivedPolyType(
+ tp.derivedLambdaType(
tp.paramNames, tp.paramNames map (Function.const(TypeBounds.upper(defn.ObjectType))), tp.resultType)
if (defn.isPolymorphicAfterErasure(sym)) eraseParamBounds(sym.info.asInstanceOf[PolyType])
@@ -186,7 +186,7 @@ object TypeErasure {
case einfo: MethodType =>
if (sym.isGetter && einfo.resultType.isRef(defn.UnitClass))
MethodType(Nil, defn.BoxedUnitType)
- else if (sym.isAnonymousFunction && einfo.paramTypes.length > MaxImplementedFunctionArity)
+ else if (sym.isAnonymousFunction && einfo.paramInfos.length > MaxImplementedFunctionArity)
MethodType(nme.ALLARGS :: Nil, JavaArrayType(defn.ObjectType) :: Nil, einfo.resultType)
else
einfo
@@ -204,7 +204,7 @@ object TypeErasure {
!tp.symbol.isClass &&
!tp.derivesFrom(defn.ObjectClass) &&
!tp.symbol.is(JavaDefined)
- case tp: PolyParam =>
+ case tp: TypeParamRef =>
!tp.derivesFrom(defn.ObjectClass) &&
!tp.binder.resultType.isInstanceOf[JavaMethodType]
case tp: TypeAlias => isUnboundedGeneric(tp.alias)
@@ -304,7 +304,7 @@ object TypeErasure {
case _: ClassInfo => true
case _ => false
}
- case tp: PolyParam => false
+ case tp: TypeParamRef => false
case tp: TypeProxy => hasStableErasure(tp.superType)
case tp: AndOrType => hasStableErasure(tp.tp1) && hasStableErasure(tp.tp2)
case _ => false
@@ -382,13 +382,15 @@ class TypeErasure(isJava: Boolean, semiEraseVCs: Boolean, isConstructor: Boolean
case tp: MethodType =>
def paramErasure(tpToErase: Type) =
erasureFn(tp.isJava, semiEraseVCs, isConstructor, wildcardOK)(tpToErase)
- val formals = tp.paramTypes.mapConserve(paramErasure)
+ val formals = tp.paramInfos.mapConserve(paramErasure)
eraseResult(tp.resultType) match {
case rt: MethodType =>
- tp.derivedMethodType(tp.paramNames ++ rt.paramNames, formals ++ rt.paramTypes, rt.resultType)
+ tp.derivedLambdaType(tp.paramNames ++ rt.paramNames, formals ++ rt.paramInfos, rt.resultType)
case rt =>
- tp.derivedMethodType(tp.paramNames, formals, rt)
+ tp.derivedLambdaType(tp.paramNames, formals, rt)
}
+ case tp: PolyType =>
+ this(tp.resultType)
case tp @ ClassInfo(pre, cls, classParents, decls, _) =>
if (cls is Package) tp
else {
@@ -517,6 +519,8 @@ class TypeErasure(isJava: Boolean, semiEraseVCs: Boolean, isConstructor: Boolean
if (inst.exists) sigName(inst) else tpnme.Uninstantiated
case tp: TypeProxy =>
sigName(tp.underlying)
+ case tp: PolyType =>
+ sigName(tp.resultType)
case _: ErrorType | WildcardType =>
tpnme.WILDCARD
case tp: WildcardType =>
diff --git a/compiler/src/dotty/tools/dotc/core/TypeOps.scala b/compiler/src/dotty/tools/dotc/core/TypeOps.scala
index 3d2906320..9593bfe93 100644
--- a/compiler/src/dotty/tools/dotc/core/TypeOps.scala
+++ b/compiler/src/dotty/tools/dotc/core/TypeOps.scala
@@ -157,7 +157,7 @@ trait TypeOps { this: Context => // TODO: Make standalone object.
tp2
case tp1 => tp1
}
- case tp: PolyParam =>
+ case tp: TypeParamRef =>
typerState.constraint.typeVarOfParam(tp) orElse tp
case _: ThisType | _: BoundType | NoPrefix =>
tp
diff --git a/compiler/src/dotty/tools/dotc/core/TyperState.scala b/compiler/src/dotty/tools/dotc/core/TyperState.scala
index 206438d86..b33b3aa29 100644
--- a/compiler/src/dotty/tools/dotc/core/TyperState.scala
+++ b/compiler/src/dotty/tools/dotc/core/TyperState.scala
@@ -42,7 +42,7 @@ class TyperState(r: Reporter) extends DotClass with Showable {
*/
def instType(tvar: TypeVar)(implicit ctx: Context): Type = constraint.entry(tvar.origin) match {
case _: TypeBounds => NoType
- case tp: PolyParam =>
+ case tp: TypeParamRef =>
var tvar1 = constraint.typeVarOfParam(tp)
if (tvar1.exists) tvar1 else tp
case tp => tp
@@ -155,14 +155,14 @@ extends TyperState(r) {
}
override def gc()(implicit ctx: Context): Unit = {
- val toCollect = new mutable.ListBuffer[PolyType]
+ val toCollect = new mutable.ListBuffer[TypeLambda]
constraint foreachTypeVar { tvar =>
if (!tvar.inst.exists) {
val inst = instType(tvar)
if (inst.exists && (tvar.owningState eq this)) {
tvar.inst = inst
- val poly = tvar.origin.binder
- if (constraint.isRemovable(poly)) toCollect += poly
+ val lam = tvar.origin.binder
+ if (constraint.isRemovable(lam)) toCollect += lam
}
}
}
diff --git a/compiler/src/dotty/tools/dotc/core/Types.scala b/compiler/src/dotty/tools/dotc/core/Types.scala
index c80107f93..83fb70aa1 100644
--- a/compiler/src/dotty/tools/dotc/core/Types.scala
+++ b/compiler/src/dotty/tools/dotc/core/Types.scala
@@ -54,10 +54,10 @@ object Types {
* | | +--- ThisType
* | | +--- SuperType
* | | +--- ConstantType
- * | | +--- MethodParam
+ * | | +--- TermParamRef
* | | +----RecThis
* | | +--- SkolemType
- * | +- PolyParam
+ * | +- TypeParamRef
* | +- RefinedOrRecType -+-- RefinedType
* | | -+-- RecType
* | +- HKApply
@@ -65,12 +65,13 @@ object Types {
* | +- ExprType
* | +- AnnotatedType
* | +- TypeVar
- * | +- PolyType
+ * | +- HKTypeLambda
* |
* +- GroundType -+- AndType
* +- OrType
- * +- MethodType -----+- ImplicitMethodType
- * | +- JavaMethodType
+ * +- MethodOrPoly ---+-- PolyType
+ * +-- MethodType ---+- ImplicitMethodType
+ * | +- JavaMethodType
* +- ClassInfo
* |
* +- NoType
@@ -103,7 +104,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[PolyType]
+ final def isValueTypeOrLambda: Boolean = isValueType || this.isInstanceOf[TypeLambda]
/** Does this type denote a stable reference (i.e. singleton type)? */
@tailrec final def isStable(implicit ctx: Context): Boolean = stripTypeVar match {
@@ -215,17 +216,15 @@ object Types {
/** Is this the type of a method that has a repeated parameter type as
* last parameter type?
*/
- def isVarArgsMethod(implicit ctx: Context): Boolean = this match {
- case tp: PolyType => tp.resultType.isVarArgsMethod
- case mt: MethodType => mt.paramTypes.nonEmpty && mt.paramTypes.last.isRepeatedParam
+ def isVarArgsMethod(implicit ctx: Context): Boolean = stripPoly match {
+ case mt: MethodType => mt.paramInfos.nonEmpty && mt.paramInfos.last.isRepeatedParam
case _ => false
}
/** Is this the type of a method with a leading empty parameter list?
*/
- def isNullaryMethod(implicit ctx: Context): Boolean = this match {
+ def isNullaryMethod(implicit ctx: Context): Boolean = stripPoly match {
case MethodType(Nil) => true
- case tp: PolyType => tp.resultType.isNullaryMethod
case _ => false
}
@@ -443,10 +442,10 @@ object Types {
case tp: TermRef =>
go (tp.underlying match {
case mt: MethodType
- if mt.paramTypes.isEmpty && (tp.symbol is Stable) => mt.resultType
+ if mt.paramInfos.isEmpty && (tp.symbol is Stable) => mt.resultType
case tp1 => tp1
})
- case tp: PolyParam =>
+ case tp: TypeParamRef =>
goParam(tp)
case tp: RecType =>
goRec(tp)
@@ -541,9 +540,9 @@ object Types {
}
def goApply(tp: HKApply) = tp.tycon match {
- case tl: PolyType =>
+ case tl: HKTypeLambda =>
go(tl.resType).mapInfo(info =>
- tl.derivedLambdaAbstraction(tl.paramNames, tl.paramBounds, info).appliedTo(tp.args))
+ tl.derivedLambdaAbstraction(tl.paramNames, tl.paramInfos, info).appliedTo(tp.args))
case _ =>
go(tp.superType)
}
@@ -563,7 +562,7 @@ object Types {
// loadClassWithPrivateInnerAndSubSelf in ShowClassTests
go(tp.cls.typeRef) orElse d
}
- def goParam(tp: PolyParam) = {
+ def goParam(tp: TypeParamRef) = {
val next = tp.underlying
ctx.typerState.constraint.entry(tp) match {
case bounds: TypeBounds if bounds ne next =>
@@ -814,6 +813,12 @@ object Types {
*/
def stripAnnots(implicit ctx: Context): Type = this
+ /** Strip PolyType prefix */
+ def stripPoly(implicit ctx: Context): Type = this match {
+ case tp: PolyType => tp.resType.stripPoly
+ case _ => this
+ }
+
/** Widen from singleton type to its underlying non-singleton
* base type by applying one or more `underlying` dereferences,
* Also go from => T to T.
@@ -1088,43 +1093,38 @@ object Types {
}
/** The parameter types of a PolyType or MethodType, Empty list for others */
- final def paramTypess(implicit ctx: Context): List[List[Type]] = this match {
- case mt: MethodType => mt.paramTypes :: mt.resultType.paramTypess
- case pt: PolyType => pt.resultType.paramTypess
+ final def paramInfoss(implicit ctx: Context): List[List[Type]] = stripPoly match {
+ case mt: MethodType => mt.paramInfos :: mt.resultType.paramInfoss
case _ => Nil
}
/** The parameter names of a PolyType or MethodType, Empty list for others */
- final def paramNamess(implicit ctx: Context): List[List[TermName]] = this match {
+ final def paramNamess(implicit ctx: Context): List[List[TermName]] = stripPoly match {
case mt: MethodType => mt.paramNames :: mt.resultType.paramNamess
- case pt: PolyType => pt.resultType.paramNamess
case _ => Nil
}
/** The parameter types in the first parameter section of a generic type or MethodType, Empty list for others */
- @tailrec final def firstParamTypes(implicit ctx: Context): List[Type] = this match {
- case mt: MethodType => mt.paramTypes
- case pt: PolyType => pt.resultType.firstParamTypes
+ final def firstParamTypes(implicit ctx: Context): List[Type] = stripPoly match {
+ case mt: MethodType => mt.paramInfos
case _ => Nil
}
/** Is this either not a method at all, or a parameterless method? */
- @tailrec final def isParameterless(implicit ctx: Context): Boolean = this match {
+ final def isParameterless(implicit ctx: Context): Boolean = stripPoly match {
case mt: MethodType => false
- case pt: PolyType => pt.resultType.isParameterless
case _ => true
}
- /** The resultType of a PolyType, MethodType, or ExprType, the type itself for others */
+ /** The resultType of a LambdaType, or ExprType, the type itself for others */
def resultType(implicit ctx: Context): Type = this
/** The final result type of a PolyType, MethodType, or ExprType, after skipping
* all parameter sections, the type itself for all others.
*/
- def finalResultType(implicit ctx: Context): Type = resultType match {
+ def finalResultType(implicit ctx: Context): Type = resultType.stripPoly match {
case mt: MethodType => mt.resultType.finalResultType
- case pt: PolyType => pt.resultType.finalResultType
case _ => resultType
}
@@ -1180,8 +1180,8 @@ object Types {
final def substDealias(from: List[Symbol], to: List[Type])(implicit ctx: Context): Type =
ctx.substDealias(this, from, to, null)
- /** Substitute all types of the form `PolyParam(from, N)` by
- * `PolyParam(to, N)`.
+ /** Substitute all types of the form `TypeParamRef(from, N)` by
+ * `TypeParamRef(to, N)`.
*/
final def subst(from: BindingType, to: BindingType)(implicit ctx: Context): Type =
ctx.subst(this, from, to, null)
@@ -1199,7 +1199,7 @@ object Types {
ctx.substRecThis(this, binder, tp, null)
/** Substitute a bound type by some other type */
- final def substParam(from: ParamType, to: Type)(implicit ctx: Context): Type =
+ final def substParam(from: ParamRef, to: Type)(implicit ctx: Context): Type =
ctx.substParam(this, from, to, null)
/** Substitute bound types by some other types */
@@ -1220,7 +1220,7 @@ object Types {
*/
def toFunctionType(dropLast: Int = 0)(implicit ctx: Context): Type = this match {
case mt: MethodType if !mt.isDependent || ctx.mode.is(Mode.AllowDependentFunctions) =>
- val formals1 = if (dropLast == 0) mt.paramTypes else mt.paramTypes dropRight dropLast
+ val formals1 = if (dropLast == 0) mt.paramInfos else mt.paramInfos dropRight dropLast
defn.FunctionOf(
formals1 mapConserve (_.underlyingIfRepeated(mt.isJava)), mt.resultType, mt.isImplicit && !ctx.erasedTypes)
}
@@ -1360,7 +1360,7 @@ object Types {
}
/** A marker trait for types that bind other types that refer to them.
- * Instances are: PolyType, MethodType, RefinedType.
+ * Instances are: LambdaType, RecType.
*/
trait BindingType extends Type
@@ -2280,7 +2280,7 @@ object Types {
if (tp1 eq tp2) tp1 else apply(tp1, tp2)
}
- // ----- Method types: MethodType/ExprType/PolyType -------------------------------
+ // ----- ExprType and LambdaTypes -----------------------------------
// Note: method types are cached whereas poly types are not. The reason
// is that most poly types are cyclic via poly params,
@@ -2315,20 +2315,126 @@ object Types {
}
}
- trait MethodOrPoly extends MethodicType
+ /** A by-name parameter type of the form `=> T`, or the type of a method with no parameter list. */
+ abstract case class ExprType(resType: Type)
+ extends CachedProxyType with TermType with MethodicType {
+ override def resultType(implicit ctx: Context): Type = resType
+ override def underlying(implicit ctx: Context): Type = resType
+ protected def computeSignature(implicit ctx: Context): Signature = resultSignature
+ def derivedExprType(resType: Type)(implicit ctx: Context) =
+ if (resType eq this.resType) this else ExprType(resType)
+ override def computeHash = doHash(resType)
+ }
- abstract case class MethodType(paramNames: List[TermName])(
- paramTypesExp: MethodType => List[Type],
- resultTypeExp: MethodType => Type)
- extends CachedGroundType with BindingType with TermType with MethodOrPoly with NarrowCached { thisMethodType =>
- import MethodType._
+ final class CachedExprType(resultType: Type) extends ExprType(resultType)
+
+ object ExprType {
+ def apply(resultType: Type)(implicit ctx: Context) = {
+ assertUnerased()
+ unique(new CachedExprType(resultType))
+ }
+ }
- def isJava = false
+ /** The lambda type square:
+ *
+ * LambdaType | TermLambda | TypeLambda
+ * -------------+-------------------+------------------
+ * HKLambda | HKTermLambda | HKTypeLambda
+ * MethodOrPoly | MethodType | PolyType
+ */
+ trait LambdaType extends BindingType with MethodicType { self =>
+ type ThisName <: Name
+ type PInfo <: Type
+ type This <: LambdaType{type PInfo = self.PInfo}
+
+ def paramNames: List[ThisName]
+ def paramInfos: List[PInfo]
+ def resType: Type
+ def newParamRef(n: Int): ParamRef
+
+ override def resultType(implicit ctx: Context) = resType
+
+ def isJava: Boolean = false
def isImplicit = false
- val paramTypes = paramTypesExp(this)
- private[core] val resType = resultTypeExp(this)
- assert(resType.exists)
+ def isDependent(implicit ctx: Context): Boolean
+ def isParamDependent(implicit ctx: Context): Boolean
+
+ final def isTermLambda = isInstanceOf[TermLambda]
+ final def isTypeLambda = isInstanceOf[TypeLambda]
+ final def isHigherKinded = isInstanceOf[TypeProxy]
+
+ lazy val paramRefs: List[ParamRef] = paramNames.indices.toList.map(newParamRef)
+
+ protected def computeSignature(implicit ctx: Context) = resultSignature
+
+ final def instantiate(argTypes: => List[Type])(implicit ctx: Context): Type =
+ if (isDependent) resultType.substParams(this, argTypes)
+ else resultType
+
+ def companion: LambdaTypeCompanion[ThisName, PInfo, This]
+
+ /** The type `[tparams := paramRefs] tp`, where `tparams` can be
+ * either a list of type parameter symbols or a list of lambda parameters
+ */
+ def integrate(tparams: List[ParamInfo], tp: Type)(implicit ctx: Context): Type =
+ tparams match {
+ case LambdaParam(lam, _) :: _ => tp.subst(lam, this)
+ case tparams: List[Symbol @unchecked] => tp.subst(tparams, paramRefs)
+ }
+
+ final def derivedLambdaType(paramNames: List[ThisName] = this.paramNames,
+ paramInfos: List[PInfo] = this.paramInfos,
+ resType: Type = this.resType)(implicit ctx: Context) =
+ if ((paramNames eq this.paramNames) && (paramInfos eq this.paramInfos) && (resType eq this.resType)) this
+ else newLikeThis(paramNames, paramInfos, resType)
+
+ final def newLikeThis(paramNames: List[ThisName], paramInfos: List[PInfo], resType: Type)(implicit ctx: Context): This =
+ companion(paramNames)(
+ x => paramInfos.mapConserve(_.subst(this, x).asInstanceOf[PInfo]),
+ x => resType.subst(this, x))
+
+ protected def prefixString: String
+ final override def toString = s"$prefixString($paramNames, $paramInfos, $resType)"
+ }
+
+ abstract class HKLambda extends CachedProxyType with LambdaType {
+ final override def underlying(implicit ctx: Context) = resType
+
+ final override def computeHash = doHash(paramNames, resType, paramInfos)
+
+ // Defined here instead of in LambdaType for efficiency
+ final override def equals(that: Any) = that match {
+ case that: HKLambda =>
+ this.paramNames == that.paramNames &&
+ this.paramInfos == that.paramInfos &&
+ this.resType == that.resType &&
+ (this.companion eq that.companion)
+ case _ =>
+ false
+ }
+ }
+
+ abstract class MethodOrPoly extends CachedGroundType with LambdaType with TermType {
+ final override def computeHash = doHash(paramNames, resType, paramInfos)
+
+ // Defined here instead of in LambdaType for efficiency
+ final override def equals(that: Any) = that match {
+ case that: MethodOrPoly =>
+ this.paramNames == that.paramNames &&
+ this.paramInfos == that.paramInfos &&
+ this.resType == that.resType &&
+ (this.companion eq that.companion)
+ case _ =>
+ false
+ }
+ }
+
+ trait TermLambda extends LambdaType { thisLambdaType =>
+ import DepStatus._
+ type ThisName = TermName
+ type PInfo = Type
+ type This <: TermLambda
override def resultType(implicit ctx: Context): Type =
if (dependencyStatus == FalseDeps) { // dealias all false dependencies
@@ -2347,8 +2453,8 @@ object Types {
}
else resType
- var myDependencyStatus: DependencyStatus = Unknown
- var myParamDependencyStatus: DependencyStatus = Unknown
+ private var myDependencyStatus: DependencyStatus = Unknown
+ private var myParamDependencyStatus: DependencyStatus = Unknown
private def depStatus(initial: DependencyStatus, tp: Type)(implicit ctx: Context): DependencyStatus = {
def combine(x: DependencyStatus, y: DependencyStatus) = {
@@ -2361,7 +2467,7 @@ object Types {
if (status == TrueDeps) status
else
tp match {
- case MethodParam(`thisMethodType`, _) => TrueDeps
+ case TermParamRef(`thisLambdaType`, _) => TrueDeps
case tp: TypeRef =>
val status1 = foldOver(status, tp)
tp.info match { // follow type alias to avoid dependency
@@ -2401,8 +2507,8 @@ object Types {
if (myParamDependencyStatus != Unknown) myParamDependencyStatus
else {
val result =
- if (paramTypes.isEmpty) NoDeps
- else (NoDeps /: paramTypes.tail)(depStatus(_, _))
+ if (paramInfos.isEmpty) NoDeps
+ else (NoDeps /: paramInfos.tail)(depStatus(_, _))
if ((result & Provisional) == 0) myParamDependencyStatus = result
(result & StatusMask).toByte
}
@@ -2418,75 +2524,90 @@ object Types {
*/
def isParamDependent(implicit ctx: Context): Boolean = paramDependencyStatus == TrueDeps
- protected def computeSignature(implicit ctx: Context): Signature =
- resultSignature.prepend(paramTypes, isJava)
+ def newParamRef(n: Int) = TermParamRef(this, n)
+ }
- def derivedMethodType(paramNames: List[TermName] = this.paramNames,
- paramTypes: List[Type] = this.paramTypes,
- resType: Type = this.resType)(implicit ctx: Context) =
- if ((paramNames eq this.paramNames) && (paramTypes eq this.paramTypes) && (resType eq this.resType)) this
- else {
- val paramTypesFn = (x: MethodType) => paramTypes.map(_.subst(this, x))
- val resTypeFn = (x: MethodType) => resType.subst(this, x)
- if (isJava) JavaMethodType(paramNames)(paramTypesFn, resTypeFn)
- else if (isImplicit) ImplicitMethodType(paramNames)(paramTypesFn, resTypeFn)
- else MethodType(paramNames)(paramTypesFn, resTypeFn)
- }
+ abstract case class MethodType(paramNames: List[TermName])(
+ paramInfosExp: MethodType => List[Type],
+ resultTypeExp: MethodType => Type)
+ extends MethodOrPoly with TermLambda with NarrowCached { thisMethodType =>
+ import MethodType._
- def instantiate(argTypes: => List[Type])(implicit ctx: Context): Type =
- if (isDependent) resultType.substParams(this, argTypes)
- else resultType
+ type This = MethodType
- override def equals(that: Any) = that match {
- case that: MethodType =>
- this.paramNames == that.paramNames &&
- this.paramTypes == that.paramTypes &&
- this.resType == that.resType
- case _ =>
- false
- }
+ val paramInfos = paramInfosExp(this)
+ val resType = resultTypeExp(this)
+ assert(resType.exists)
- override def computeHash = doHash(paramNames, resType, paramTypes)
+ override def computeSignature(implicit ctx: Context): Signature =
+ resultSignature.prepend(paramInfos, isJava)
protected def prefixString = "MethodType"
- override def toString = s"$prefixString($paramNames, $paramTypes, $resType)"
}
- final class CachedMethodType(paramNames: List[TermName])(paramTypesExp: MethodType => List[Type], resultTypeExp: MethodType => Type)
- extends MethodType(paramNames)(paramTypesExp, resultTypeExp) {
- override def equals(that: Any) = super.equals(that) && that.isInstanceOf[CachedMethodType]
+ final class CachedMethodType(paramNames: List[TermName])(paramInfosExp: MethodType => List[Type], resultTypeExp: MethodType => Type)
+ extends MethodType(paramNames)(paramInfosExp, resultTypeExp) {
+ def companion = MethodType
}
- final class JavaMethodType(paramNames: List[TermName])(paramTypesExp: MethodType => List[Type], resultTypeExp: MethodType => Type)
- extends MethodType(paramNames)(paramTypesExp, resultTypeExp) {
+ final class JavaMethodType(paramNames: List[TermName])(paramInfosExp: MethodType => List[Type], resultTypeExp: MethodType => Type)
+ extends MethodType(paramNames)(paramInfosExp, resultTypeExp) {
+ def companion = JavaMethodType
override def isJava = true
- override def equals(that: Any) = super.equals(that) && that.isInstanceOf[JavaMethodType]
- override def computeHash = addDelta(super.computeHash, 1)
override protected def prefixString = "JavaMethodType"
}
- final class ImplicitMethodType(paramNames: List[TermName])(paramTypesExp: MethodType => List[Type], resultTypeExp: MethodType => Type)
- extends MethodType(paramNames)(paramTypesExp, resultTypeExp) {
+ final class ImplicitMethodType(paramNames: List[TermName])(paramInfosExp: MethodType => List[Type], resultTypeExp: MethodType => Type)
+ extends MethodType(paramNames)(paramInfosExp, resultTypeExp) {
+ def companion = ImplicitMethodType
override def isImplicit = true
- override def equals(that: Any) = super.equals(that) && that.isInstanceOf[ImplicitMethodType]
- override def computeHash = addDelta(super.computeHash, 2)
override protected def prefixString = "ImplicitMethodType"
}
- abstract class MethodTypeCompanion {
- def apply(paramNames: List[TermName])(paramTypesExp: MethodType => List[Type], resultTypeExp: MethodType => Type)(implicit ctx: Context): MethodType
- def apply(paramNames: List[TermName], paramTypes: List[Type], resultType: Type)(implicit ctx: Context): MethodType =
- apply(paramNames)(_ => paramTypes, _ => resultType)
- def apply(paramTypes: List[Type])(resultTypeExp: MethodType => Type)(implicit ctx: Context): MethodType =
- apply(nme.syntheticParamNames(paramTypes.length))(_ => paramTypes, resultTypeExp)
- def apply(paramTypes: List[Type], resultType: Type)(implicit ctx: Context): MethodType =
- apply(nme.syntheticParamNames(paramTypes.length), paramTypes, resultType)
+ abstract class LambdaTypeCompanion[N <: Name, PInfo <: Type, LT <: LambdaType] {
+ def syntheticParamName(n: Int): N
+
+ @sharable private val memoizedNames = new mutable.HashMap[Int, List[N]]
+ def syntheticParamNames(n: Int): List[N] = synchronized {
+ memoizedNames.getOrElseUpdate(n, (0 until n).map(syntheticParamName).toList)
+ }
+
+ def apply(paramNames: List[N])(paramInfosExp: LT => List[PInfo], resultTypeExp: LT => Type)(implicit ctx: Context): LT
+ def apply(paramNames: List[N], paramInfos: List[PInfo], resultType: Type)(implicit ctx: Context): LT =
+ apply(paramNames)(_ => paramInfos, _ => resultType)
+ def apply(paramInfos: List[PInfo])(resultTypeExp: LT => Type)(implicit ctx: Context): LT =
+ apply(syntheticParamNames(paramInfos.length))(_ => paramInfos, resultTypeExp)
+ def apply(paramInfos: List[PInfo], resultType: Type)(implicit ctx: Context): LT =
+ apply(syntheticParamNames(paramInfos.length), paramInfos, resultType)
+
+ protected def paramName(param: ParamInfo.Of[N])(implicit ctx: Context): N =
+ param.paramName
+
+ def fromParams[PI <: ParamInfo.Of[N]](params: List[PI], resultType: Type)(implicit ctx: Context): Type =
+ if (params.isEmpty) resultType
+ else apply(params.map(paramName))(
+ tl => params.map(param => tl.integrate(params, param.paramInfo).asInstanceOf[PInfo]),
+ tl => tl.integrate(params, resultType))
+ }
+
+ abstract class TermLambdaCompanion[LT <: TermLambda]
+ extends LambdaTypeCompanion[TermName, Type, LT] {
+ def syntheticParamName(n: Int) = nme.syntheticParamName(n)
+ }
+
+ abstract class TypeLambdaCompanion[LT <: TypeLambda]
+ extends LambdaTypeCompanion[TypeName, TypeBounds, LT] {
+ def syntheticParamName(n: Int) = tpnme.syntheticTypeParamName(n)
+ }
+
+ abstract class MethodTypeCompanion extends TermLambdaCompanion[MethodType] {
/** Produce method type from parameter symbols, with special mappings for repeated
- * and inline parameters.
+ * and inline parameters:
+ * - replace @repeated annotations on Seq or Array types by <repeated> types
+ * - add @inlineParam to inline call-by-value parameters
*/
def fromSymbols(params: List[Symbol], resultType: Type)(implicit ctx: Context) = {
- /** Replace @repeated annotations on Seq or Array types by <repeated> types */
def translateRepeated(tp: Type): Type = tp match {
case tp @ ExprType(tp1) => tp.derivedExprType(translateRepeated(tp1))
case AnnotatedType(tp, annot) if annot matches defn.RepeatedAnnot =>
@@ -2496,27 +2617,25 @@ object Types {
case tp =>
tp
}
- /** Add @inlineParam to inline call-by-value parameters */
def translateInline(tp: Type): Type = tp match {
case _: ExprType => tp
case _ => AnnotatedType(tp, Annotation(defn.InlineParamAnnot))
}
- def integrate(tp: Type, mt: MethodType) =
- tp.subst(params, (0 until params.length).toList.map(MethodParam(mt, _)))
- def paramInfo(param: Symbol): Type = {
+ def paramInfo(param: Symbol) = {
val paramType = translateRepeated(param.info)
if (param.is(Inline)) translateInline(paramType) else paramType
}
+
apply(params.map(_.name.asTermName))(
- mt => params.map(param => integrate(paramInfo(param), mt)),
- mt => integrate(resultType, mt))
+ tl => params.map(p => tl.integrate(params, paramInfo(p))),
+ tl => tl.integrate(params, resultType))
}
def checkValid(mt: MethodType)(implicit ctx: Context): mt.type = {
if (Config.checkMethodTypes)
- for ((paramType, idx) <- mt.paramTypes.zipWithIndex)
- paramType.foreachPart {
- case MethodParam(`mt`, j) => assert(j < idx, mt)
+ for ((paramInfo, idx) <- mt.paramInfos.zipWithIndex)
+ paramInfo.foreachPart {
+ case TermParamRef(`mt`, j) => assert(j < idx, mt)
case _ =>
}
mt
@@ -2524,114 +2643,97 @@ object Types {
}
object MethodType extends MethodTypeCompanion {
- def apply(paramNames: List[TermName])(paramTypesExp: MethodType => List[Type], resultTypeExp: MethodType => Type)(implicit ctx: Context): MethodType =
- checkValid(unique(new CachedMethodType(paramNames)(paramTypesExp, resultTypeExp)))
-
- private type DependencyStatus = Byte
- private final val Unknown: DependencyStatus = 0 // not yet computed
- private final val NoDeps: DependencyStatus = 1 // no dependent parameters found
- private final val FalseDeps: DependencyStatus = 2 // all dependent parameters are prefixes of non-depended alias types
- private final val TrueDeps: DependencyStatus = 3 // some truly dependent parameters exist
- private final val StatusMask: DependencyStatus = 3 // the bits indicating actual dependency status
- private final val Provisional: DependencyStatus = 4 // set if dependency status can still change due to type variable instantiations
+ def apply(paramNames: List[TermName])(paramInfosExp: MethodType => List[Type], resultTypeExp: MethodType => Type)(implicit ctx: Context): MethodType =
+ checkValid(unique(new CachedMethodType(paramNames)(paramInfosExp, resultTypeExp)))
}
object JavaMethodType extends MethodTypeCompanion {
- def apply(paramNames: List[TermName])(paramTypesExp: MethodType => List[Type], resultTypeExp: MethodType => Type)(implicit ctx: Context): MethodType =
- unique(new JavaMethodType(paramNames)(paramTypesExp, resultTypeExp))
+ def apply(paramNames: List[TermName])(paramInfosExp: MethodType => List[Type], resultTypeExp: MethodType => Type)(implicit ctx: Context): MethodType =
+ unique(new JavaMethodType(paramNames)(paramInfosExp, resultTypeExp))
}
object ImplicitMethodType extends MethodTypeCompanion {
- def apply(paramNames: List[TermName])(paramTypesExp: MethodType => List[Type], resultTypeExp: MethodType => Type)(implicit ctx: Context): MethodType =
- checkValid(unique(new ImplicitMethodType(paramNames)(paramTypesExp, resultTypeExp)))
+ def apply(paramNames: List[TermName])(paramInfosExp: MethodType => List[Type], resultTypeExp: MethodType => Type)(implicit ctx: Context): MethodType =
+ checkValid(unique(new ImplicitMethodType(paramNames)(paramInfosExp, resultTypeExp)))
}
/** A ternary extractor for MethodType */
object MethodTpe {
def unapply(mt: MethodType)(implicit ctx: Context) =
- Some((mt.paramNames, mt.paramTypes, mt.resultType))
- }
-
- /** A by-name parameter type of the form `=> T`, or the type of a method with no parameter list. */
- abstract case class ExprType(resType: Type)
- extends CachedProxyType with TermType with MethodicType {
- override def resultType(implicit ctx: Context): Type = resType
- override def underlying(implicit ctx: Context): Type = resType
- protected def computeSignature(implicit ctx: Context): Signature = resultSignature
- def derivedExprType(resType: Type)(implicit ctx: Context) =
- if (resType eq this.resType) this else ExprType(resType)
- override def computeHash = doHash(resType)
+ Some((mt.paramNames, mt.paramInfos, mt.resultType))
}
- final class CachedExprType(resultType: Type) extends ExprType(resultType)
-
- object ExprType {
- def apply(resultType: Type)(implicit ctx: Context) = {
- assertUnerased()
- unique(new CachedExprType(resultType))
- }
- }
-
- /** 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)
-
- /** The result type of a PolyType / body of a type lambda */
- val resType: Type = resultTypeExp(this)
-
- assert(resType.isInstanceOf[TermType], this)
- assert(paramNames.nonEmpty)
-
- protected def computeSignature(implicit ctx: Context) = resultSignature
+ trait TypeLambda extends LambdaType {
+ type ThisName = TypeName
+ type PInfo = TypeBounds
+ type This <: TypeLambda
- def isPolymorphicMethodType: Boolean = resType match {
- case _: MethodType => true
- case _ => false
- }
+ def isDependent(implicit ctx: Context): Boolean = true
+ def isParamDependent(implicit ctx: Context): Boolean = true
- /** PolyParam references to all type parameters of this type */
- lazy val paramRefs: List[PolyParam] = paramNames.indices.toList.map(PolyParam(this, _))
+ def newParamRef(n: Int) = TypeParamRef(this, n)
lazy val typeParams: List[LambdaParam] =
paramNames.indices.toList.map(new LambdaParam(this, _))
- 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)
+ final def instantiateBounds(argTypes: List[Type])(implicit ctx: Context): List[Type] =
+ paramInfos.mapConserve(_.substParams(this, argTypes))
- def derivedLambdaAbstraction(paramNames: List[TypeName], paramBounds: List[TypeBounds], resType: Type)(implicit ctx: Context): Type =
+ def derivedLambdaAbstraction(paramNames: List[TypeName], paramInfos: List[TypeBounds], resType: Type)(implicit ctx: Context): Type =
resType match {
case resType @ TypeAlias(alias) =>
- resType.derivedTypeAlias(newLikeThis(paramNames, paramBounds, alias))
+ resType.derivedTypeAlias(newLikeThis(paramNames, paramInfos, alias))
case resType @ TypeBounds(lo, hi) =>
resType.derivedTypeBounds(
- if (lo.isRef(defn.NothingClass)) lo else newLikeThis(paramNames, paramBounds, lo),
- newLikeThis(paramNames, paramBounds, hi))
+ if (lo.isRef(defn.NothingClass)) lo else newLikeThis(paramNames, paramInfos, lo),
+ newLikeThis(paramNames, paramInfos, hi))
case _ =>
- derivedPolyType(paramNames, paramBounds, resType)
+ derivedLambdaType(paramNames, paramInfos, resType)
}
+ }
+
+ /** A type lambda of the form `[X_0 B_0, ..., X_n B_n] => T`
+ * Variances are encoded in parameter names. A name starting with `+`
+ * designates a covariant parameter, a name starting with `-` designates
+ * a contravariant parameter, and every other name designates a non-variant parameter.
+ *
+ * @param paramNames The names `X_0`, ..., `X_n`
+ * @param paramInfosExp A function that, given the polytype itself, returns the
+ * parameter bounds `B_1`, ..., `B_n`
+ * @param resultTypeExp A function that, given the polytype itself, returns the
+ * result type `T`.
+ */
+ class HKTypeLambda(val paramNames: List[TypeName])(
+ paramInfosExp: HKTypeLambda => List[TypeBounds], resultTypeExp: HKTypeLambda => Type)
+ extends HKLambda with TypeLambda {
+ type This = HKTypeLambda
+ def companion = HKTypeLambda
+
+ val paramInfos: List[TypeBounds] = paramInfosExp(this)
+ val resType: Type = resultTypeExp(this)
+
+ assert(resType.isInstanceOf[TermType], this)
+ assert(paramNames.nonEmpty)
+
+ protected def prefixString = "HKTypeLambda"
+ }
+
+ /** The type of a polymorphic method. It has the same form as HKTypeLambda,
+ * except it applies to terms and parameters do not have variances.
+ */
+ class PolyType(val paramNames: List[TypeName])(
+ paramInfosExp: PolyType => List[TypeBounds], resultTypeExp: PolyType => Type)
+ extends MethodOrPoly with TypeLambda {
+
+ type This = PolyType
+ def companion = PolyType
+
+ val paramInfos: List[TypeBounds] = paramInfosExp(this)
+ val resType: Type = resultTypeExp(this)
+
+ assert(resType.isInstanceOf[TermType], this)
+ assert(paramNames.nonEmpty)
/** Merge nested polytypes into one polytype. nested polytypes are normally not supported
* but can arise as temporary data structures.
@@ -2640,67 +2742,95 @@ object Types {
case that: PolyType =>
val shift = new TypeMap {
def apply(t: Type) = t match {
- case PolyParam(`that`, n) => PolyParam(that, n + paramNames.length)
+ case TypeParamRef(`that`, n) => TypeParamRef(that, n + paramNames.length)
case t => mapOver(t)
}
}
- PolyType(paramNames ++ that.paramNames, variances ++ that.variances)(
- x => this.paramBounds.mapConserve(_.subst(this, x).bounds) ++
- that.paramBounds.mapConserve(shift(_).subst(that, x).bounds),
+ PolyType(paramNames ++ that.paramNames)(
+ x => this.paramInfos.mapConserve(_.subst(this, x).bounds) ++
+ that.paramInfos.mapConserve(shift(_).subst(that, x).bounds),
x => shift(that.resultType).subst(that, x).subst(this, x))
case _ => 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)
- }
+ protected def prefixString = "PolyType"
+ }
- 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
+ object HKTypeLambda extends TypeLambdaCompanion[HKTypeLambda] {
+ def apply(paramNames: List[TypeName])(
+ paramInfosExp: HKTypeLambda => List[TypeBounds],
+ resultTypeExp: HKTypeLambda => Type)(implicit ctx: Context): HKTypeLambda = {
+ unique(new HKTypeLambda(paramNames)(paramInfosExp, resultTypeExp))
}
- override def toString = s"PolyType($variances, $paramNames, $paramBounds, $resType)"
+ def unapply(tl: HKTypeLambda): Some[(List[LambdaParam], Type)] =
+ Some((tl.typeParams, tl.resType))
+
+ def any(n: Int)(implicit ctx: Context) =
+ apply(syntheticParamNames(n))(
+ pt => List.fill(n)(TypeBounds.empty), pt => defn.AnyType)
- override def computeHash = doHash(variances ::: paramNames, resType, paramBounds)
+ override def paramName(param: ParamInfo.Of[TypeName])(implicit ctx: Context): TypeName =
+ param.paramName.withVariance(param.paramVariance)
+
+ /** Distributes Lambda inside type bounds. Examples:
+ *
+ * type T[X] = U becomes type T = [X] -> U
+ * type T[X] <: U becomes type T >: Nothign <: ([X] -> U)
+ * type T[X] >: L <: U becomes type T >: ([X] -> L) <: ([X] -> U)
+ */
+ override def fromParams[PI <: ParamInfo.Of[TypeName]](params: List[PI], resultType: Type)(implicit ctx: Context): Type = {
+ def expand(tp: Type) = super.fromParams(params, tp)
+ resultType match {
+ case rt: TypeAlias =>
+ rt.derivedTypeAlias(expand(rt.alias))
+ case rt @ TypeBounds(lo, hi) =>
+ rt.derivedTypeBounds(
+ if (lo.isRef(defn.NothingClass)) lo else expand(lo), expand(hi))
+ case rt =>
+ expand(rt)
+ }
+ }
}
- object PolyType {
- def apply(paramNames: List[TypeName], variances: List[Int])(
- paramBoundsExp: PolyType => List[TypeBounds],
+ object PolyType extends TypeLambdaCompanion[PolyType] {
+ def apply(paramNames: List[TypeName])(
+ paramInfosExp: PolyType => List[TypeBounds],
resultTypeExp: PolyType => Type)(implicit ctx: Context): PolyType = {
- unique(new PolyType(paramNames, variances)(paramBoundsExp, resultTypeExp))
+ unique(new PolyType(paramNames)(paramInfosExp, resultTypeExp))
}
def unapply(tl: PolyType): Some[(List[LambdaParam], Type)] =
Some((tl.typeParams, tl.resType))
def any(n: Int)(implicit ctx: Context) =
- apply(tpnme.syntheticTypeParamNames(n), List.fill(n)(0))(
+ apply(syntheticParamNames(n))(
pt => List.fill(n)(TypeBounds.empty), pt => defn.AnyType)
}
+ private object DepStatus {
+ type DependencyStatus = Byte
+ final val Unknown: DependencyStatus = 0 // not yet computed
+ final val NoDeps: DependencyStatus = 1 // no dependent parameters found
+ final val FalseDeps: DependencyStatus = 2 // all dependent parameters are prefixes of non-depended alias types
+ final val TrueDeps: DependencyStatus = 3 // some truly dependent parameters exist
+ final val StatusMask: DependencyStatus = 3 // the bits indicating actual dependency status
+ final val Provisional: DependencyStatus = 4 // set if dependency status can still change due to type variable instantiations
+ }
+
// ----- HK types: LambdaParam, HKApply ---------------------
/** The parameter of a type lambda */
- 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)
- def paramBoundsAsSeenFrom(pre: Type)(implicit ctx: Context): TypeBounds = paramBounds
- def paramBoundsOrCompleter(implicit ctx: Context): Type = paramBounds
- def paramVariance(implicit ctx: Context): Int = tl.variances(n)
- def toArg: Type = PolyParam(tl, n)
- def paramRef(implicit ctx: Context): Type = PolyParam(tl, n)
+ case class LambdaParam(tl: TypeLambda, n: Int) extends ParamInfo {
+ type ThisName = TypeName
+ def isTypeParam(implicit ctx: Context) = tl.paramNames.head.isTypeName
+ def paramName(implicit ctx: Context) = tl.paramNames(n)
+ def paramInfo(implicit ctx: Context) = tl.paramInfos(n)
+ def paramInfoAsSeenFrom(pre: Type)(implicit ctx: Context) = paramInfo
+ def paramInfoOrCompleter(implicit ctx: Context): Type = paramInfo
+ def paramVariance(implicit ctx: Context): Int = tl.paramNames(n).variance
+ def toArg: Type = TypeParamRef(tl, n)
+ def paramRef(implicit ctx: Context): Type = TypeParamRef(tl, n)
}
/** A higher kinded type application `C[T_1, ..., T_n]` */
@@ -2715,7 +2845,7 @@ object Types {
override def superType(implicit ctx: Context): Type = {
if (ctx.period != validSuper) {
cachedSuper = tycon match {
- case tp: PolyType => defn.AnyType
+ case tp: HKTypeLambda => defn.AnyType
case tp: TypeVar if !tp.inst.exists =>
// supertype not stable, since underlying might change
return tp.underlying.applyIfParameterized(args)
@@ -2739,9 +2869,9 @@ object Types {
NoType
}
- def typeParams(implicit ctx: Context): List[TypeParamInfo] = {
+ def typeParams(implicit ctx: Context): List[ParamInfo] = {
val tparams = tycon.typeParams
- if (tparams.isEmpty) PolyType.any(args.length).typeParams else tparams
+ if (tparams.isEmpty) HKTypeLambda.any(args.length).typeParams else tparams
}
def derivedAppliedType(tycon: Type, args: List[Type])(implicit ctx: Context): Type =
@@ -2753,8 +2883,8 @@ object Types {
protected def checkInst(implicit ctx: Context): this.type = {
def check(tycon: Type): Unit = tycon.stripTypeVar match {
case tycon: TypeRef if !tycon.symbol.isClass =>
- case _: PolyParam | _: ErrorType | _: WildcardType =>
- case _: PolyType =>
+ case _: TypeParamRef | _: ErrorType | _: WildcardType =>
+ case _: TypeLambda =>
assert(args.exists(_.isInstanceOf[TypeBounds]), s"unreduced type apply: $this")
case tycon: AnnotatedType =>
check(tycon.underlying)
@@ -2773,92 +2903,61 @@ object Types {
unique(new CachedHKApply(tycon, args)).checkInst
}
- // ----- Bound types: MethodParam, PolyParam --------------------------
+ // ----- BoundTypes: ParamRef, RecThis ----------------------------------------
abstract class BoundType extends CachedProxyType with ValueType {
type BT <: Type
- def binder: BT
- // Dotty deviation: copyBoundType was copy, but
- // dotty generates copy methods always automatically, and therefore
- // does not accept same-named method definitions in subclasses.
- // Scala2x, on the other hand, requires them (not sure why!)
+ val binder: BT
def copyBoundType(bt: BT): Type
}
- abstract class ParamType extends BoundType {
+ abstract class ParamRef extends BoundType {
+ type BT <: LambdaType
def paramNum: Int
- def paramName: Name
- }
-
- abstract case class MethodParam(binder: MethodType, paramNum: Int) extends ParamType with SingletonType {
- type BT = MethodType
-
- def paramName = binder.paramNames(paramNum)
+ def paramName: binder.ThisName = binder.paramNames(paramNum)
- override def underlying(implicit ctx: Context): Type = binder.paramTypes(paramNum)
- def copyBoundType(bt: BT) = new MethodParamImpl(bt, paramNum)
+ override def underlying(implicit ctx: Context): Type = {
+ val infos = binder.paramInfos
+ if (infos == null) NoType // this can happen if the referenced generic type is not initialized yet
+ else infos(paramNum)
+ }
- // need to customize hashCode and equals to prevent infinite recursion for dep meth types.
- override def computeHash = addDelta(binder.identityHash, paramNum)
+ override def computeHash = doHash(paramNum, binder.identityHash)
override def equals(that: Any) = that match {
- case that: MethodParam =>
+ case that: ParamRef =>
(this.binder eq that.binder) && this.paramNum == that.paramNum
case _ =>
false
}
- override def toString = s"MethodParam($paramName)"
+ override def toString =
+ try s"ParamRef($paramName)"
+ catch {
+ case ex: IndexOutOfBoundsException => s"ParamRef(<bad index: $paramNum>)"
+ }
}
- class MethodParamImpl(binder: MethodType, paramNum: Int) extends MethodParam(binder, paramNum)
-
- object MethodParam {
- def apply(binder: MethodType, paramNum: Int)(implicit ctx: Context): MethodParam = {
- assertUnerased()
- new MethodParamImpl(binder, paramNum)
- }
+ case class TermParamRef(binder: TermLambda, paramNum: Int) extends ParamRef {
+ type BT = TermLambda
+ def copyBoundType(bt: BT) = TermParamRef(bt, paramNum)
}
- /** TODO Some docs would be nice here! */
- case class PolyParam(binder: PolyType, paramNum: Int) extends ParamType {
- type BT = PolyType
- def copyBoundType(bt: BT) = PolyParam(bt, paramNum)
+ case class TypeParamRef(binder: TypeLambda, paramNum: Int) extends ParamRef {
+ type BT = TypeLambda
+ def copyBoundType(bt: BT) = TypeParamRef(bt, paramNum)
/** Looking only at the structure of `bound`, is one of the following true?
* - fromBelow and param <:< bound
* - !fromBelow and param >:> bound
*/
def occursIn(bound: Type, fromBelow: Boolean)(implicit ctx: Context): Boolean = bound.stripTypeVar match {
- case bound: PolyParam => bound == this
+ case bound: ParamRef => bound == this
case bound: AndOrType =>
def occ1 = occursIn(bound.tp1, fromBelow)
def occ2 = occursIn(bound.tp2, fromBelow)
if (fromBelow == bound.isAnd) occ1 && occ2 else occ1 || occ2
case _ => false
}
-
- def paramName = binder.paramNames(paramNum)
-
- override def underlying(implicit ctx: Context): Type = {
- val bounds = binder.paramBounds
- if (bounds == null) NoType // this can happen if the referenced generic type is not initialized yet
- else bounds(paramNum)
- }
- // no customized hashCode/equals needed because cycle is broken in PolyType
- override def toString =
- try s"PolyParam($paramName)"
- catch {
- case ex: IndexOutOfBoundsException => s"PolyParam(<bad index: $paramNum>)"
- }
-
- override def computeHash = doHash(paramNum, binder.identityHash)
-
- override def equals(that: Any) = that match {
- case that: PolyParam =>
- (this.binder eq that.binder) && this.paramNum == that.paramNum
- case _ =>
- false
- }
}
/** a self-reference to an enclosing recursive type. */
@@ -2929,7 +3028,7 @@ object Types {
* `owningTree` and `owner` are used to determine whether a type-variable can be instantiated
* at some given point. See `Inferencing#interpolateUndetVars`.
*/
- final class TypeVar(val origin: PolyParam, creatorState: TyperState, val bindingTree: untpd.Tree, val owner: Symbol) extends CachedProxyType with ValueType {
+ final class TypeVar(val origin: TypeParamRef, creatorState: TyperState, val bindingTree: untpd.Tree, val owner: Symbol) extends CachedProxyType with ValueType {
/** The permanent instance type of the variable, or NoType is none is given yet */
private[core] var inst: Type = NoType
@@ -3341,9 +3440,8 @@ object Types {
object SAMType {
def zeroParamClass(tp: Type)(implicit ctx: Context): Type = tp match {
case tp: ClassInfo =>
- def zeroParams(tp: Type): Boolean = tp match {
- case pt: PolyType => zeroParams(pt.resultType)
- case mt: MethodType => mt.paramTypes.isEmpty && !mt.resultType.isInstanceOf[MethodType]
+ def zeroParams(tp: Type): Boolean = tp.stripPoly match {
+ case mt: MethodType => mt.paramInfos.isEmpty && !mt.resultType.isInstanceOf[MethodType]
case et: ExprType => true
case _ => false
}
@@ -3426,12 +3524,11 @@ object Types {
tp.derivedClassInfo(pre)
protected def derivedJavaArrayType(tp: JavaArrayType, elemtp: Type): Type =
tp.derivedJavaArrayType(elemtp)
- protected def derivedMethodType(tp: MethodType, formals: List[Type], restpe: Type): Type =
- 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)
+ // note: currying needed because Scala2 does not support param-dependencies
+ protected def derivedLambdaType(tp: LambdaType)(formals: List[tp.PInfo], restpe: Type): Type =
+ tp.derivedLambdaType(tp.paramNames, formals, restpe)
/** Map this function over given type */
def mapOver(tp: Type): Type = {
@@ -3461,29 +3558,34 @@ object Types {
variance = -variance
derivedTypeBounds(tp, lo1, this(tp.hi))
- case tp: MethodType =>
- def mapOverMethod = {
- variance = -variance
- val ptypes1 = tp.paramTypes mapConserve this
- variance = -variance
- derivedMethodType(tp, ptypes1, this(tp.resultType))
+ case tp: RecType =>
+ derivedRecType(tp, this(tp.parent))
+
+ case tp: TypeVar =>
+ val inst = tp.instanceOpt
+ if (inst.exists) apply(inst) else tp
+
+ case tp: HKApply =>
+ def mapArg(arg: Type, tparam: ParamInfo): Type = {
+ val saved = variance
+ variance *= tparam.paramVariance
+ try this(arg)
+ finally variance = saved
}
- mapOverMethod
+ derivedAppliedType(tp, this(tp.tycon),
+ tp.args.zipWithConserve(tp.typeParams)(mapArg))
case tp: ExprType =>
derivedExprType(tp, this(tp.resultType))
- case tp: PolyType =>
- def mapOverPoly = {
+ case tp: LambdaType =>
+ def mapOverLambda = {
variance = -variance
- val bounds1 = tp.paramBounds.mapConserve(this).asInstanceOf[List[TypeBounds]]
+ val ptypes1 = tp.paramInfos.mapConserve(this).asInstanceOf[List[tp.PInfo]]
variance = -variance
- derivedPolyType(tp, bounds1, this(tp.resultType))
+ derivedLambdaType(tp)(ptypes1, this(tp.resultType))
}
- mapOverPoly
-
- case tp: RecType =>
- derivedRecType(tp, this(tp.parent))
+ mapOverLambda
case tp @ SuperType(thistp, supertp) =>
derivedSuperType(tp, this(thistp), this(supertp))
@@ -3494,21 +3596,7 @@ object Types {
case tp: ClassInfo =>
mapClassInfo(tp)
- case tp: TypeVar =>
- val inst = tp.instanceOpt
- if (inst.exists) apply(inst) else tp
-
- case tp: HKApply =>
- def mapArg(arg: Type, tparam: TypeParamInfo): Type = {
- val saved = variance
- variance *= tparam.paramVariance
- try this(arg)
- finally variance = saved
- }
- derivedAppliedType(tp, this(tp.tycon),
- tp.args.zipWithConserve(tp.typeParams)(mapArg))
-
- case tp: AndOrType =>
+ case tp: AndOrType =>
derivedAndOrType(tp, this(tp.tp1), this(tp.tp2))
case tp: SkolemType =>
@@ -3689,23 +3777,14 @@ object Types {
this(y, hi)
}
- case tp: MethodType =>
- variance = -variance
- val y = foldOver(x, tp.paramTypes)
- variance = -variance
- this(y, tp.resultType)
+ case tp: RecType =>
+ this(x, tp.parent)
case ExprType(restpe) =>
this(x, restpe)
- case tp: PolyType =>
- variance = -variance
- val y = foldOver(x, tp.paramBounds)
- variance = -variance
- this(y, tp.resultType)
-
- case tp: RecType =>
- this(x, tp.parent)
+ case tp: TypeVar =>
+ this(x, tp.underlying)
case SuperType(thistp, supertp) =>
this(this(x, thistp), supertp)
@@ -3714,7 +3793,7 @@ object Types {
this(x, prefix)
case tp @ HKApply(tycon, args) =>
- @tailrec def foldArgs(x: T, tparams: List[TypeParamInfo], args: List[Type]): T =
+ @tailrec def foldArgs(x: T, tparams: List[ParamInfo], args: List[Type]): T =
if (args.isEmpty) {
assert(tparams.isEmpty)
x
@@ -3730,6 +3809,12 @@ object Types {
}
foldArgs(this(x, tycon), tp.typeParams, args)
+ case tp: LambdaType =>
+ variance = -variance
+ val y = foldOver(x, tp.paramInfos)
+ variance = -variance
+ this(y, tp.resultType)
+
case tp: AndOrType =>
this(this(x, tp.tp1), tp.tp2)
@@ -3739,9 +3824,6 @@ object Types {
case AnnotatedType(underlying, annot) =>
this(applyToAnnot(x, annot), underlying)
- case tp: TypeVar =>
- this(x, tp.underlying)
-
case tp: WildcardType =>
this(x, tp.optBounds)
@@ -3804,9 +3886,7 @@ object Types {
apply(x, tp.tref)
case tp: ConstantType =>
apply(x, tp.underlying)
- case tp: MethodParam =>
- apply(x, tp.underlying)
- case tp: PolyParam =>
+ case tp: ParamRef =>
apply(x, tp.underlying)
case _ =>
foldOver(x, tp)
diff --git a/compiler/src/dotty/tools/dotc/core/classfile/ClassfileParser.scala b/compiler/src/dotty/tools/dotc/core/classfile/ClassfileParser.scala
index e0b233ce8..da875c906 100644
--- a/compiler/src/dotty/tools/dotc/core/classfile/ClassfileParser.scala
+++ b/compiler/src/dotty/tools/dotc/core/classfile/ClassfileParser.scala
@@ -199,7 +199,7 @@ class ClassfileParser(
def stripOuterParamFromConstructor() = innerClasses.get(currentClassName) match {
case Some(entry) if !isStatic(entry.jflags) =>
val mt @ MethodTpe(paramNames, paramTypes, resultType) = denot.info
- denot.info = mt.derivedMethodType(paramNames.tail, paramTypes.tail, resultType)
+ denot.info = mt.derivedLambdaType(paramNames.tail, paramTypes.tail, resultType)
case _ =>
}
@@ -209,7 +209,7 @@ class ClassfileParser(
def normalizeConstructorInfo() = {
val mt @ MethodType(paramNames) = denot.info
val rt = classRoot.typeRef appliedTo (classRoot.typeParams map (_.typeRef))
- denot.info = mt.derivedMethodType(paramNames, mt.paramTypes, rt)
+ denot.info = mt.derivedLambdaType(paramNames, mt.paramInfos, rt)
addConstructorTypeParams(denot)
}
@@ -975,7 +975,7 @@ class ClassfileParser(
if (name == nme.CONSTRUCTOR)
tpe match {
case tp: MethodType =>
- tp.derivedMethodType(tp.paramNames, tp.paramTypes, ownerTpe)
+ tp.derivedLambdaType(tp.paramNames, tp.paramInfos, ownerTpe)
}
p = (name, tpe)
values(index) = p
diff --git a/compiler/src/dotty/tools/dotc/core/tasty/TastyFormat.scala b/compiler/src/dotty/tools/dotc/core/tasty/TastyFormat.scala
index cb1b56c3c..8b2255e94 100644
--- a/compiler/src/dotty/tools/dotc/core/tasty/TastyFormat.scala
+++ b/compiler/src/dotty/tools/dotc/core/tasty/TastyFormat.scala
@@ -151,8 +151,9 @@ Standard-Section: "ASTs" TopLevelStat*
BIND Length boundName_NameRef bounds_Type
// for type-variables defined in a type pattern
BYNAMEtype underlying_Type
- POLYtype Length result_Type NamesTypes // variance encoded in front of name: +/-/=
+ POLYtype Length result_Type NamesTypes
METHODtype Length result_Type NamesTypes // needed for refinements
+ TYPELAMBDAtype Length result_Type NamesTypes // variance encoded in front of name: +/-/(nothing)
PARAMtype Length binder_ASTref paramNum_Nat // needed for refinements
SHARED type_ASTRef
NamesTypes = NameType*
@@ -345,9 +346,10 @@ object TastyFormat {
final val ORtpt = 169
final val METHODtype = 170
final val POLYtype = 171
- final val POLYtpt = 172
- final val PARAMtype = 173
- final val ANNOTATION = 174
+ final val TYPELAMBDAtype = 172
+ final val LAMBDAtpt = 173
+ final val PARAMtype = 174
+ final val ANNOTATION = 175
final val firstSimpleTreeTag = UNITconst
final val firstNatTreeTag = SHARED
@@ -397,7 +399,7 @@ object TastyFormat {
| SINGLETONtpt
| REFINEDtpt
| APPLIEDtpt
- | POLYtpt
+ | LAMBDAtpt
| TYPEBOUNDStpt
| ANNOTATEDtpt
| ANDtpt
@@ -528,8 +530,9 @@ object TastyFormat {
case BYNAMEtype => "BYNAMEtype"
case BYNAMEtpt => "BYNAMEtpt"
case POLYtype => "POLYtype"
- case POLYtpt => "POLYtpt"
case METHODtype => "METHODtype"
+ case TYPELAMBDAtype => "TYPELAMBDAtype"
+ case LAMBDAtpt => "LAMBDAtpt"
case PARAMtype => "PARAMtype"
case ANNOTATION => "ANNOTATION"
case PRIVATEqualified => "PRIVATEqualified"
@@ -543,11 +546,7 @@ object TastyFormat {
case VALDEF | DEFDEF | TYPEDEF | TYPEPARAM | PARAM | NAMEDARG | RETURN | BIND |
SELFDEF | REFINEDtype => 1
case RENAMED | PARAMtype => 2
- case POLYtype | METHODtype => -1
+ case POLYtype | METHODtype | TYPELAMBDAtype => -1
case _ => 0
}
-
- /** Map between variances and name prefixes */
- val varianceToPrefix = Map(-1 -> '-', 0 -> '=', 1 -> '+')
- val prefixToVariance = Map('-' -> -1, '=' -> 0, '+' -> 1)
}
diff --git a/compiler/src/dotty/tools/dotc/core/tasty/TastyPrinter.scala b/compiler/src/dotty/tools/dotc/core/tasty/TastyPrinter.scala
index fb37c9e7d..ce3722ff1 100644
--- a/compiler/src/dotty/tools/dotc/core/tasty/TastyPrinter.scala
+++ b/compiler/src/dotty/tools/dotc/core/tasty/TastyPrinter.scala
@@ -77,7 +77,7 @@ class TastyPrinter(bytes: Array[Byte])(implicit ctx: Context) {
printName(); printTree(); printTrees()
case RETURN =>
printNat(); printTrees()
- case METHODtype | POLYtype =>
+ case METHODtype | POLYtype | TYPELAMBDAtype =>
printTree()
until(end) { printName(); printTree() }
case PARAMtype =>
diff --git a/compiler/src/dotty/tools/dotc/core/tasty/TreePickler.scala b/compiler/src/dotty/tools/dotc/core/tasty/TreePickler.scala
index 80270aa25..902d01c21 100644
--- a/compiler/src/dotty/tools/dotc/core/tasty/TreePickler.scala
+++ b/compiler/src/dotty/tools/dotc/core/tasty/TreePickler.scala
@@ -253,23 +253,21 @@ class TreePickler(pickler: TastyPickler) {
case tpe: ExprType =>
writeByte(BYNAMEtype)
pickleType(tpe.underlying)
- case tpe: PolyType =>
- writeByte(POLYtype)
- val paramNames = tpe.typeParams.map(tparam =>
- varianceToPrefix(tparam.paramVariance) +: tparam.paramName)
- pickleMethodic(tpe.resultType, paramNames, tpe.paramBounds)
+ case tpe: HKTypeLambda =>
+ pickleMethodic(TYPELAMBDAtype, tpe)
+ case tpe: PolyType if richTypes =>
+ pickleMethodic(POLYtype, tpe)
case tpe: MethodType if richTypes =>
- writeByte(METHODtype)
- pickleMethodic(tpe.resultType, tpe.paramNames, tpe.paramTypes)
- case tpe: PolyParam =>
- if (!pickleParamType(tpe))
+ pickleMethodic(METHODtype, tpe)
+ case tpe: TypeParamRef =>
+ if (!pickleParamRef(tpe))
// TODO figure out why this case arises in e.g. pickling AbstractFileReader.
ctx.typerState.constraint.entry(tpe) match {
case TypeBounds(lo, hi) if lo eq hi => pickleNewType(lo, richTypes)
case _ => assert(false, s"orphan poly parameter: $tpe")
}
- case tpe: MethodParam =>
- assert(pickleParamType(tpe), s"orphan method parameter: $tpe")
+ case tpe: TermParamRef =>
+ assert(pickleParamRef(tpe), s"orphan method parameter: $tpe")
case tpe: LazyRef =>
pickleType(tpe.ref)
}} catch {
@@ -283,15 +281,17 @@ class TreePickler(pickler: TastyPickler) {
pickleName(qualifiedName(pkg))
}
- def pickleMethodic(result: Type, names: List[Name], types: List[Type])(implicit ctx: Context) =
+ def pickleMethodic(tag: Int, tpe: LambdaType)(implicit ctx: Context) = {
+ writeByte(tag)
withLength {
- pickleType(result, richTypes = true)
- (names, types).zipped.foreach { (name, tpe) =>
+ pickleType(tpe.resultType, richTypes = true)
+ (tpe.paramNames, tpe.paramInfos).zipped.foreach { (name, tpe) =>
pickleName(name); pickleType(tpe)
}
}
+ }
- def pickleParamType(tpe: ParamType)(implicit ctx: Context): Boolean = {
+ def pickleParamRef(tpe: ParamRef)(implicit ctx: Context): Boolean = {
val binder = pickledTypes.get(tpe.binder)
val pickled = binder != null
if (pickled) {
@@ -555,8 +555,8 @@ class TreePickler(pickler: TastyPickler) {
case Annotated(tree, annot) =>
writeByte(ANNOTATEDtpt)
withLength { pickleTree(tree); pickleTree(annot.tree) }
- case PolyTypeTree(tparams, body) =>
- writeByte(POLYtpt)
+ case LambdaTypeTree(tparams, body) =>
+ writeByte(LAMBDAtpt)
withLength { pickleParams(tparams); pickleTree(body) }
case TypeBoundsTree(lo, hi) =>
writeByte(TYPEBOUNDStpt)
diff --git a/compiler/src/dotty/tools/dotc/core/tasty/TreeUnpickler.scala b/compiler/src/dotty/tools/dotc/core/tasty/TreeUnpickler.scala
index 88b6eef7a..4db995e10 100644
--- a/compiler/src/dotty/tools/dotc/core/tasty/TreeUnpickler.scala
+++ b/compiler/src/dotty/tools/dotc/core/tasty/TreeUnpickler.scala
@@ -38,7 +38,7 @@ class TreeUnpickler(reader: TastyReader, tastyName: TastyName.Table, posUnpickle
/** A map from addresses of type entries to the types they define.
* Currently only populated for types that might be recursively referenced
- * from within themselves (i.e. RefinedTypes, PolyTypes, MethodTypes).
+ * from within themselves (i.e. RecTypes, LambdaTypes).
*/
private val typeAtAddr = new mutable.HashMap[Addr, Type]
@@ -227,11 +227,17 @@ class TreeUnpickler(reader: TastyReader, tastyName: TastyName.Table, posUnpickle
def readLengthType(): Type = {
val end = readEnd()
- def readNamesSkipParams: (List[Name], TreeReader) = {
+ def readMethodic[N <: Name, PInfo <: Type, LT <: LambdaType]
+ (companion: LambdaTypeCompanion[N, PInfo, LT], nameMap: Name => N): LT = {
val nameReader = fork
nameReader.skipTree() // skip result
val paramReader = nameReader.fork
- (nameReader.readParamNames(end), paramReader)
+ val paramNames = nameReader.readParamNames(end).map(nameMap)
+ val result = companion(paramNames)(
+ pt => registeringType(pt, paramReader.readParamTypes[PInfo](end)),
+ pt => readType())
+ goto(end)
+ result
}
val result =
@@ -268,25 +274,14 @@ class TreeUnpickler(reader: TastyReader, tastyName: TastyName.Table, posUnpickle
registerSym(start, sym)
TypeRef.withFixedSym(NoPrefix, sym.name, sym)
case POLYtype =>
- val (rawNames, paramReader) = readNamesSkipParams
- val (variances, paramNames) = rawNames
- .map(name => (prefixToVariance(name.head), name.tail.toTypeName)).unzip
- val result = PolyType(paramNames, variances)(
- pt => registeringType(pt, paramReader.readParamTypes[TypeBounds](end)),
- pt => readType())
- goto(end)
- result
+ readMethodic(PolyType, _.toTypeName)
case METHODtype =>
- val (names, paramReader) = readNamesSkipParams
- val result = MethodType(names.map(_.toTermName))(
- mt => registeringType(mt, paramReader.readParamTypes[Type](end)),
- mt => readType())
- goto(end)
- result
+ readMethodic(MethodType, _.toTermName)
+ case TYPELAMBDAtype =>
+ readMethodic(HKTypeLambda, _.toTypeName)
case PARAMtype =>
readTypeRef() match {
- case binder: PolyType => PolyParam(binder, readNat())
- case binder: MethodType => MethodParam(binder, readNat())
+ case binder: LambdaType => binder.newParamRef(readNat())
}
case CLASSconst =>
ConstantType(Constant(readType()))
@@ -412,7 +407,7 @@ class TreeUnpickler(reader: TastyReader, tastyName: TastyName.Table, posUnpickle
}
def isAbstractType(ttag: Int)(implicit ctx: Context): Boolean = nextUnsharedTag match {
- case POLYtpt =>
+ case LAMBDAtpt =>
val rdr = fork
rdr.reader.readByte() // tag
rdr.reader.readNat() // length
@@ -1035,11 +1030,11 @@ class TreeUnpickler(reader: TastyReader, tastyName: TastyName.Table, posUnpickle
OrTypeTree(readTpt(), readTpt())
case ANNOTATEDtpt =>
Annotated(readTpt(), readTerm())
- case POLYtpt =>
+ case LAMBDAtpt =>
val localCtx = localNonClassCtx
val tparams = readParams[TypeDef](TYPEPARAM)(localCtx)
val body = readTpt()(localCtx)
- PolyTypeTree(tparams, body)
+ LambdaTypeTree(tparams, body)
case TYPEBOUNDStpt =>
TypeBoundsTree(readTpt(), readTpt())
case _ =>
diff --git a/compiler/src/dotty/tools/dotc/core/unpickleScala2/Scala2Unpickler.scala b/compiler/src/dotty/tools/dotc/core/unpickleScala2/Scala2Unpickler.scala
index 688a2d007..cf99bb022 100644
--- a/compiler/src/dotty/tools/dotc/core/unpickleScala2/Scala2Unpickler.scala
+++ b/compiler/src/dotty/tools/dotc/core/unpickleScala2/Scala2Unpickler.scala
@@ -42,13 +42,15 @@ object Scala2Unpickler {
/** Convert temp poly type to poly type and leave other types alone. */
def translateTempPoly(tp: Type)(implicit ctx: Context): Type = tp match {
- case TempPolyType(tparams, restpe) => restpe.LambdaAbstract(tparams)
+ case TempPolyType(tparams, restpe) =>
+ (if (tparams.head.owner.isTerm) PolyType else HKTypeLambda)
+ .fromParams(tparams, restpe)
case tp => tp
}
def addConstructorTypeParams(denot: SymDenotation)(implicit ctx: Context) = {
assert(denot.isConstructor)
- denot.info = denot.info.LambdaAbstract(denot.owner.typeParams)
+ denot.info = PolyType.fromParams(denot.owner.typeParams, denot.info)
}
/** Convert array parameters denoting a repeated parameter of a Java method
@@ -56,7 +58,7 @@ object Scala2Unpickler {
*/
def arrayToRepeated(tp: Type)(implicit ctx: Context): Type = tp match {
case tp: MethodType =>
- val lastArg = tp.paramTypes.last
+ val lastArg = tp.paramInfos.last
assert(lastArg isRef defn.ArrayClass)
val elemtp0 :: Nil = lastArg.baseArgInfos(defn.ArrayClass)
val elemtp = elemtp0 match {
@@ -65,12 +67,12 @@ object Scala2Unpickler {
case _ =>
elemtp0
}
- tp.derivedMethodType(
+ tp.derivedLambdaType(
tp.paramNames,
- tp.paramTypes.init :+ defn.RepeatedParamType.appliedTo(elemtp),
+ tp.paramInfos.init :+ defn.RepeatedParamType.appliedTo(elemtp),
tp.resultType)
case tp: PolyType =>
- tp.derivedPolyType(tp.paramNames, tp.paramBounds, arrayToRepeated(tp.resultType))
+ tp.derivedLambdaType(tp.paramNames, tp.paramInfos, arrayToRepeated(tp.resultType))
}
def ensureConstructor(cls: ClassSymbol, scope: Scope)(implicit ctx: Context) =
@@ -745,7 +747,7 @@ class Scala2Unpickler(bytes: Array[Byte], classRoot: ClassDenotation, moduleClas
TempClassInfoType(until(end, readTypeRef), symScope(clazz), clazz)
case METHODtpe | IMPLICITMETHODtpe =>
val restpe = readTypeRef()
- val params = until(end, readSymbolRef)
+ val params = until(end, readSymbolRef).asInstanceOf[List[TermSymbol]]
def isImplicit =
tag == IMPLICITMETHODtpe ||
params.nonEmpty && (params.head is Implicit)
diff --git a/compiler/src/dotty/tools/dotc/parsing/Parsers.scala b/compiler/src/dotty/tools/dotc/parsing/Parsers.scala
index 9864281a5..3e3673e5e 100644
--- a/compiler/src/dotty/tools/dotc/parsing/Parsers.scala
+++ b/compiler/src/dotty/tools/dotc/parsing/Parsers.scala
@@ -728,7 +728,7 @@ object Parsers {
val start = in.offset
val tparams = typeParamClause(ParamOwner.TypeParam)
if (in.token == ARROW)
- atPos(start, in.skipToken())(PolyTypeTree(tparams, typ()))
+ atPos(start, in.skipToken())(LambdaTypeTree(tparams, typ()))
else { accept(ARROW); typ() }
}
else infixType()
diff --git a/compiler/src/dotty/tools/dotc/printing/Formatting.scala b/compiler/src/dotty/tools/dotc/printing/Formatting.scala
index 760b22689..e8fa45403 100644
--- a/compiler/src/dotty/tools/dotc/printing/Formatting.scala
+++ b/compiler/src/dotty/tools/dotc/printing/Formatting.scala
@@ -107,7 +107,7 @@ object Formatting {
else nonSensicalStartTag + str + nonSensicalEndTag
}
- private type Recorded = AnyRef /*Symbol | PolyParam*/
+ private type Recorded = AnyRef /*Symbol | TypeParamRef*/
private class Seen extends mutable.HashMap[String, List[Recorded]] {
@@ -135,8 +135,8 @@ object Formatting {
if ((sym is ModuleClass) && sym.sourceModule.exists) simpleNameString(sym.sourceModule)
else seen.record(super.simpleNameString(sym), sym)
- override def polyParamNameString(param: PolyParam): String =
- seen.record(super.polyParamNameString(param), param)
+ override def TypeParamRefNameString(param: TypeParamRef): String =
+ seen.record(super.TypeParamRefNameString(param), param)
}
/** Create explanation for single `Recorded` type or symbol */
@@ -161,7 +161,7 @@ object Formatting {
}
entry match {
- case param: PolyParam =>
+ case param: TypeParamRef =>
s"is a type variable${addendum("constraint", ctx.typeComparer.bounds(param))}"
case sym: Symbol =>
s"is a ${ctx.printer.kindString(sym)}${sym.showExtendedLocation}${addendum("bounds", sym.info)}"
@@ -175,7 +175,7 @@ object Formatting {
*/
private def explanations(seen: Seen)(implicit ctx: Context): String = {
def needsExplanation(entry: Recorded) = entry match {
- case param: PolyParam => ctx.typerState.constraint.contains(param)
+ case param: TypeParamRef => ctx.typerState.constraint.contains(param)
case _ => false
}
diff --git a/compiler/src/dotty/tools/dotc/printing/PlainPrinter.scala b/compiler/src/dotty/tools/dotc/printing/PlainPrinter.scala
index 67d44daa1..d5014b547 100644
--- a/compiler/src/dotty/tools/dotc/printing/PlainPrinter.scala
+++ b/compiler/src/dotty/tools/dotc/printing/PlainPrinter.scala
@@ -170,21 +170,20 @@ class PlainPrinter(_ctx: Context) extends Printer {
def paramText(name: TermName, tp: Type) = toText(name) ~ ": " ~ toText(tp)
changePrec(GlobalPrec) {
(if (tp.isImplicit) "(implicit " else "(") ~
- Text((tp.paramNames, tp.paramTypes).zipped map paramText, ", ") ~
+ Text((tp.paramNames, tp.paramInfos).zipped map paramText, ", ") ~
")" ~ toText(tp.resultType)
}
case tp: ExprType =>
changePrec(GlobalPrec) { "=> " ~ toText(tp.resultType) }
- case tp: PolyType =>
- def paramText(variance: Int, name: Name, bounds: TypeBounds): Text =
- varianceString(variance) ~ name.toString ~ toText(bounds)
+ case tp: TypeLambda =>
+ def paramText(name: Name, bounds: TypeBounds): Text = name.toString ~ toText(bounds)
changePrec(GlobalPrec) {
- "[" ~ Text((tp.variances, tp.paramNames, tp.paramBounds).zipped.map(paramText), ", ") ~
+ "[" ~ Text((tp.paramNames, tp.paramInfos).zipped.map(paramText), ", ") ~
"]" ~ (" => " provided !tp.resultType.isInstanceOf[MethodType]) ~
toTextGlobal(tp.resultType)
}
- case tp: PolyParam =>
- polyParamNameString(tp) ~ polyHash(tp.binder)
+ case tp: TypeParamRef =>
+ TypeParamRefNameString(tp) ~ lambdaHash(tp.binder)
case AnnotatedType(tpe, annot) =>
toTextLocal(tpe) ~ " " ~ toText(annot)
case HKApply(tycon, args) =>
@@ -207,17 +206,18 @@ class PlainPrinter(_ctx: Context) extends Printer {
}
}.close
- protected def polyParamNameString(name: TypeName): String = name.toString
+ protected def TypeParamRefNameString(name: TypeName): String = name.toString
- protected def polyParamNameString(param: PolyParam): String = polyParamNameString(param.binder.paramNames(param.paramNum))
+ protected def TypeParamRefNameString(param: TypeParamRef): String =
+ TypeParamRefNameString(param.binder.paramNames(param.paramNum))
/** The name of the symbol without a unique id. Under refined printing,
* the decoded original name.
*/
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 =
+ /** If -uniqid is set, the hashcode of the lambda type, after a # */
+ protected def lambdaHash(pt: LambdaType): Text =
if (ctx.settings.uniqid.value) "#" + pt.hashCode else ""
/** If -uniqid is set, the unique id of symbol, after a # */
@@ -259,8 +259,8 @@ class PlainPrinter(_ctx: Context) extends Printer {
"Super(" ~ toTextGlobal(thistpe) ~ ")"
case tp @ ConstantType(value) =>
toText(value)
- case MethodParam(mt, idx) =>
- nameString(mt.paramNames(idx))
+ case pref: TermParamRef =>
+ nameString(pref.binder.paramNames(pref.paramNum))
case tp: RecThis =>
val idx = openRecs.reverse.indexOf(tp.binder)
if (idx >= 0) selfRecName(idx + 1)
diff --git a/compiler/src/dotty/tools/dotc/printing/RefinedPrinter.scala b/compiler/src/dotty/tools/dotc/printing/RefinedPrinter.scala
index 8a33472b8..76bce7920 100644
--- a/compiler/src/dotty/tools/dotc/printing/RefinedPrinter.scala
+++ b/compiler/src/dotty/tools/dotc/printing/RefinedPrinter.scala
@@ -401,7 +401,7 @@ class RefinedPrinter(_ctx: Context) extends PlainPrinter(_ctx) {
toTextLocal(tpt) ~ " " ~ blockText(refines)
case AppliedTypeTree(tpt, args) =>
toTextLocal(tpt) ~ "[" ~ Text(args map argText, ", ") ~ "]"
- case PolyTypeTree(tparams, body) =>
+ case LambdaTypeTree(tparams, body) =>
changePrec(GlobalPrec) {
tparamsText(tparams) ~ " -> " ~ toText(body)
}
@@ -451,7 +451,7 @@ class RefinedPrinter(_ctx: Context) extends PlainPrinter(_ctx) {
(if (tree.hasType && ctx.settings.verbose.value) i"[decls = ${tree.symbol.info.decls}]" else "")
case rhs: TypeBoundsTree =>
typeDefText(tparamsTxt, toText(rhs))
- case PolyTypeTree(tparams, body) =>
+ case LambdaTypeTree(tparams, body) =>
recur(body, tparamsText(tparams))
case rhs =>
typeDefText(tparamsTxt, optText(rhs)(" = " ~ _))
@@ -604,7 +604,7 @@ class RefinedPrinter(_ctx: Context) extends PlainPrinter(_ctx) {
def optText[T >: Untyped](tree: List[Tree[T]])(encl: Text => Text): Text =
if (tree.exists(!_.isEmpty)) encl(blockText(tree)) else ""
- override protected def polyParamNameString(name: TypeName): String =
+ override protected def TypeParamRefNameString(name: TypeName): String =
name.unexpandedName.toString
override protected def treatAsTypeParam(sym: Symbol): Boolean = sym is TypeParam
diff --git a/compiler/src/dotty/tools/dotc/reporting/diagnostic/messages.scala b/compiler/src/dotty/tools/dotc/reporting/diagnostic/messages.scala
index b0f5f8ab1..87837fd82 100644
--- a/compiler/src/dotty/tools/dotc/reporting/diagnostic/messages.scala
+++ b/compiler/src/dotty/tools/dotc/reporting/diagnostic/messages.scala
@@ -617,7 +617,7 @@ object messages {
|"""
}
- case class WrongNumberOfTypeArgs(fntpe: Type, expectedArgs: List[TypeParamInfo], actual: List[untpd.Tree])(implicit ctx: Context)
+ case class WrongNumberOfTypeArgs(fntpe: Type, expectedArgs: List[ParamInfo], actual: List[untpd.Tree])(implicit ctx: Context)
extends Message(WrongNumberOfTypeArgsID) {
val kind = "Syntax"
@@ -625,7 +625,7 @@ object messages {
private val actualCount = actual.length
private val msgPrefix = if (actualCount > expectedCount) "Too many" else "Not enough"
- //TODO add def simpleParamName to TypeParamInfo
+ //TODO add def simpleParamName to ParamInfo
private val expectedArgString = fntpe
.widen.typeParams
.map(_.paramName.unexpandedName.show)
diff --git a/compiler/src/dotty/tools/dotc/sbt/ExtractAPI.scala b/compiler/src/dotty/tools/dotc/sbt/ExtractAPI.scala
index 082a80b58..8d704f9a2 100644
--- a/compiler/src/dotty/tools/dotc/sbt/ExtractAPI.scala
+++ b/compiler/src/dotty/tools/dotc/sbt/ExtractAPI.scala
@@ -286,7 +286,7 @@ private class ExtractAPICollector(implicit val ctx: Context) extends ThunkHolder
def apiDef(sym: TermSymbol): api.Def = {
def paramLists(t: Type, start: Int = 0): List[api.ParameterList] = t match {
- case pt: PolyType =>
+ case pt: TypeLambda =>
assert(start == 0)
paramLists(pt.resultType)
case mt @ MethodTpe(pnames, ptypes, restpe) =>
@@ -311,8 +311,8 @@ private class ExtractAPICollector(implicit val ctx: Context) extends ThunkHolder
}
val tparams = sym.info match {
- case pt: PolyType =>
- (pt.paramNames, pt.paramBounds).zipped.map((pname, pbounds) =>
+ case pt: TypeLambda =>
+ (pt.paramNames, pt.paramInfos).zipped.map((pname, pbounds) =>
apiTypeParameter(pname.toString, 0, pbounds.lo, pbounds.hi))
case _ =>
Nil
@@ -385,9 +385,9 @@ 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 PolyType(tparams, res) =>
- val apiTparams = tparams.map(apiTypeParameter)
- val apiRes = apiType(res)
+ case tl: TypeLambda =>
+ val apiTparams = tl.typeParams.map(apiTypeParameter)
+ val apiRes = apiType(tl.resType)
new api.Polymorphic(apiRes, apiTparams.toArray)
case rt: RefinedType =>
val name = rt.refinedName.toString
@@ -460,7 +460,7 @@ private class ExtractAPICollector(implicit val ctx: Context) extends ThunkHolder
new api.Annotated(apiType(tpe), Array(apiAnnotation(annot)))
case tp: ThisType =>
apiThis(tp.cls)
- case tp: ParamType =>
+ case tp: ParamRef =>
// TODO: Distinguishing parameters based on their names alone is not enough,
// the binder is also needed (at least for type lambdas).
new api.ParameterRef(tp.paramName.toString)
@@ -497,9 +497,9 @@ private class ExtractAPICollector(implicit val ctx: Context) extends ThunkHolder
new api.Singleton(new api.Path(pathComponents.toArray.reverse ++ Array(Constants.thisPath)))
}
- def apiTypeParameter(tparam: TypeParamInfo): api.TypeParameter =
+ def apiTypeParameter(tparam: ParamInfo): api.TypeParameter =
apiTypeParameter(tparam.paramName.toString, tparam.paramVariance,
- tparam.paramBounds.lo, tparam.paramBounds.hi)
+ tparam.paramInfo.bounds.lo, tparam.paramInfo.bounds.hi)
def apiTypeParameter(name: String, variance: Int, lo: Type, hi: Type): api.TypeParameter =
new api.TypeParameter(name, Array(), Array(), apiVariance(variance),
diff --git a/compiler/src/dotty/tools/dotc/sbt/ExtractDependencies.scala b/compiler/src/dotty/tools/dotc/sbt/ExtractDependencies.scala
index fefa63f6f..0a061c841 100644
--- a/compiler/src/dotty/tools/dotc/sbt/ExtractDependencies.scala
+++ b/compiler/src/dotty/tools/dotc/sbt/ExtractDependencies.scala
@@ -256,9 +256,7 @@ private class ExtractDependenciesCollector(implicit val ctx: Context) extends tp
traverse(tp.underlying)
case tp: ConstantType =>
traverse(tp.underlying)
- case tp: MethodParam =>
- traverse(tp.underlying)
- case tp: PolyParam =>
+ case tp: ParamRef =>
traverse(tp.underlying)
case _ =>
traverseChildren(tp)
diff --git a/compiler/src/dotty/tools/dotc/transform/CollectEntryPoints.scala b/compiler/src/dotty/tools/dotc/transform/CollectEntryPoints.scala
index 9f1e42e31..e82be4378 100644
--- a/compiler/src/dotty/tools/dotc/transform/CollectEntryPoints.scala
+++ b/compiler/src/dotty/tools/dotc/transform/CollectEntryPoints.scala
@@ -88,7 +88,7 @@ class CollectEntryPoints extends MiniPhaseTransform {
case t: PolyType =>
fail("main methods cannot be generic.")
case t: MethodType =>
- if (t.resultType :: t.paramTypes exists (_.typeSymbol.isAbstractType))
+ if (t.resultType :: t.paramInfos exists (_.typeSymbol.isAbstractType))
fail("main methods cannot refer to type parameters or abstract types.", m.symbol.pos)
else
javaPlatform.isJavaMainMethod(m.symbol) || fail("main method must have exact signature (Array[String])Unit", m.symbol.pos)
diff --git a/compiler/src/dotty/tools/dotc/transform/ElimByName.scala b/compiler/src/dotty/tools/dotc/transform/ElimByName.scala
index 59da78590..839552799 100644
--- a/compiler/src/dotty/tools/dotc/transform/ElimByName.scala
+++ b/compiler/src/dotty/tools/dotc/transform/ElimByName.scala
@@ -93,7 +93,7 @@ class ElimByName extends MiniPhaseTransform with InfoTransformer { thisTransform
}
val mt @ MethodType(_) = tree.fun.tpe.widen
- val args1 = tree.args.zipWithConserve(mt.paramTypes)(transformArg)
+ val args1 = tree.args.zipWithConserve(mt.paramInfos)(transformArg)
cpy.Apply(tree)(tree.fun, args1)
}
diff --git a/compiler/src/dotty/tools/dotc/transform/ElimErasedValueType.scala b/compiler/src/dotty/tools/dotc/transform/ElimErasedValueType.scala
index 24c8cdc8d..48be02fa1 100644
--- a/compiler/src/dotty/tools/dotc/transform/ElimErasedValueType.scala
+++ b/compiler/src/dotty/tools/dotc/transform/ElimErasedValueType.scala
@@ -44,9 +44,9 @@ class ElimErasedValueType extends MiniPhaseTransform with InfoTransformer {
case ErasedValueType(_, underlying) =>
elimEVT(underlying)
case tp: MethodType =>
- val paramTypes = tp.paramTypes.mapConserve(elimEVT)
+ val paramTypes = tp.paramInfos.mapConserve(elimEVT)
val retType = elimEVT(tp.resultType)
- tp.derivedMethodType(tp.paramNames, paramTypes, retType)
+ tp.derivedLambdaType(tp.paramNames, paramTypes, retType)
case _ =>
tp
}
diff --git a/compiler/src/dotty/tools/dotc/transform/ElimRepeated.scala b/compiler/src/dotty/tools/dotc/transform/ElimRepeated.scala
index ae3259509..683c8ac38 100644
--- a/compiler/src/dotty/tools/dotc/transform/ElimRepeated.scala
+++ b/compiler/src/dotty/tools/dotc/transform/ElimRepeated.scala
@@ -55,9 +55,9 @@ class ElimRepeated extends MiniPhaseTransform with InfoTransformer with Annotati
val last = paramTypes.last.underlyingIfRepeated(tp.isJava)
paramTypes.init :+ last
} else paramTypes
- tp.derivedMethodType(paramNames, paramTypes1, resultType1)
+ tp.derivedLambdaType(paramNames, paramTypes1, resultType1)
case tp: PolyType =>
- tp.derivedPolyType(tp.paramNames, tp.paramBounds, elimRepeated(tp.resultType))
+ tp.derivedLambdaType(tp.paramNames, tp.paramInfos, elimRepeated(tp.resultType))
case tp =>
tp
}
@@ -139,10 +139,10 @@ 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.derivedPolyType(tp.paramNames, tp.paramBounds, toJavaVarArgs(tp.resultType))
+ tp.derivedLambdaType(tp.paramNames, tp.paramInfos, toJavaVarArgs(tp.resultType))
case tp: MethodType =>
- val inits :+ last = tp.paramTypes
+ val inits :+ last = tp.paramInfos
val last1 = last.underlyingIfRepeated(isJava = true)
- tp.derivedMethodType(tp.paramNames, inits :+ last1, tp.resultType)
+ tp.derivedLambdaType(tp.paramNames, inits :+ last1, tp.resultType)
}
}
diff --git a/compiler/src/dotty/tools/dotc/transform/Erasure.scala b/compiler/src/dotty/tools/dotc/transform/Erasure.scala
index f9c7a8e1e..d64120085 100644
--- a/compiler/src/dotty/tools/dotc/transform/Erasure.scala
+++ b/compiler/src/dotty/tools/dotc/transform/Erasure.scala
@@ -461,12 +461,12 @@ object Erasure extends TypeTestsCasts{
case mt: MethodType =>
val outers = outer.args(fun.asInstanceOf[tpd.Tree]) // can't use fun1 here because its type is already erased
var args0 = outers ::: args ++ protoArgs(pt)
- if (args0.length > MaxImplementedFunctionArity && mt.paramTypes.length == 1) {
+ if (args0.length > MaxImplementedFunctionArity && mt.paramInfos.length == 1) {
val bunchedArgs = untpd.JavaSeqLiteral(args0, TypeTree(defn.ObjectType))
.withType(defn.ArrayOf(defn.ObjectType))
args0 = bunchedArgs :: Nil
}
- val args1 = args0.zipWithConserve(mt.paramTypes)(typedExpr)
+ val args1 = args0.zipWithConserve(mt.paramInfos)(typedExpr)
untpd.cpy.Apply(tree)(fun1, args1) withType mt.resultType
case _ =>
throw new MatchError(i"tree $tree has unexpected type of function ${fun1.tpe.widen}, was ${fun.typeOpt.widen}")
@@ -547,8 +547,8 @@ object Erasure extends TypeTestsCasts{
case SAMType(sam) =>
val implType = meth.tpe.widen
- val List(implParamTypes) = implType.paramTypess
- val List(samParamTypes) = sam.info.paramTypess
+ val List(implParamTypes) = implType.paramInfoss
+ val List(samParamTypes) = sam.info.paramInfoss
val implResultType = implType.resultType
val samResultType = sam.info.resultType
@@ -698,8 +698,8 @@ object Erasure extends TypeTestsCasts{
val rhs = paramss.foldLeft(sel)((fun, vparams) =>
fun.tpe.widen match {
case mt: MethodType =>
- Apply(fun, (vparams, mt.paramTypes).zipped.map(adapt(_, _, untpd.EmptyTree)))
- case a =>
+ Apply(fun, (vparams, mt.paramInfos).zipped.map(adapt(_, _, untpd.EmptyTree)))
+ case a =>
error(s"can not resolve apply type $a")
})
adapt(rhs, resultType)
diff --git a/compiler/src/dotty/tools/dotc/transform/ExplicitOuter.scala b/compiler/src/dotty/tools/dotc/transform/ExplicitOuter.scala
index f17808e62..a6e643992 100644
--- a/compiler/src/dotty/tools/dotc/transform/ExplicitOuter.scala
+++ b/compiler/src/dotty/tools/dotc/transform/ExplicitOuter.scala
@@ -331,7 +331,7 @@ object ExplicitOuter {
def addParam(cls: ClassSymbol, tp: Type): Type =
if (hasOuterParam(cls)) {
val mt @ MethodTpe(pnames, ptypes, restpe) = tp
- mt.derivedMethodType(
+ mt.derivedLambdaType(
nme.OUTER :: pnames, cls.owner.enclosingClass.typeRef :: ptypes, restpe)
} else tp
diff --git a/compiler/src/dotty/tools/dotc/transform/FullParameterization.scala b/compiler/src/dotty/tools/dotc/transform/FullParameterization.scala
index 0cb453b4c..d76a41946 100644
--- a/compiler/src/dotty/tools/dotc/transform/FullParameterization.scala
+++ b/compiler/src/dotty/tools/dotc/transform/FullParameterization.scala
@@ -107,13 +107,13 @@ trait FullParameterization {
val firstArgType = if (liftThisType) thisParamType & clazz.thisType else thisParamType
MethodType(nme.SELF :: Nil)(
mt => firstArgType :: Nil,
- mt => mapClassParams(origResult).substThisUnlessStatic(clazz, MethodParam(mt, 0)))
+ mt => mapClassParams(origResult).substThisUnlessStatic(clazz, mt.newParamRef(0)))
}
/** Replace class type parameters by the added type parameters of the polytype `pt` */
def mapClassParams(tp: Type, pt: PolyType): Type = {
val classParamsRange = (mtparamCount until mtparamCount + ctparams.length).toList
- tp.substDealias(ctparams, classParamsRange map (PolyParam(pt, _)))
+ tp.substDealias(ctparams, classParamsRange map (TypeParamRef(pt, _)))
}
/** The bounds for the added type parameters of the polytype `pt` */
@@ -122,14 +122,14 @@ trait FullParameterization {
info match {
case info: PolyType =>
- PolyType(info.paramNames ++ ctnames, info.variances ++ ctvariances)(
+ PolyType(info.paramNames ++ ctnames)(
pt =>
- (info.paramBounds.map(mapClassParams(_, pt).bounds) ++
+ (info.paramInfos.map(mapClassParams(_, pt).bounds) ++
mappedClassBounds(pt)).mapConserve(_.subst(info, pt).bounds),
pt => resultType(mapClassParams(_, pt)).subst(info, pt))
case _ =>
if (ctparams.isEmpty) resultType(identity)
- else PolyType(ctnames, ctvariances)(mappedClassBounds, pt => resultType(mapClassParams(_, pt)))
+ else PolyType(ctnames)(mappedClassBounds, pt => resultType(mapClassParams(_, pt)))
}
}
@@ -233,7 +233,7 @@ trait FullParameterization {
fun.appliedToArgss(originalDef.vparamss.nestedMap(vparam => ref(vparam.symbol)))
else {
// this type could have changed on forwarding. Need to insert a cast.
- val args = (originalDef.vparamss, fun.tpe.paramTypess).zipped.map((vparams, paramTypes) =>
+ val args = (originalDef.vparamss, fun.tpe.paramInfoss).zipped.map((vparams, paramTypes) =>
(vparams, paramTypes).zipped.map((vparam, paramType) => {
assert(vparam.tpe <:< paramType.widen) // type should still conform to widened type
ref(vparam.symbol).ensureConforms(paramType)
@@ -256,7 +256,7 @@ object FullParameterization {
case MethodTpe(nme.SELF :: Nil, _, restpe) =>
restpe.ensureMethodic.signature
case info @ MethodTpe(nme.SELF :: otherNames, thisType :: otherTypes, restpe) =>
- info.derivedMethodType(otherNames, otherTypes, restpe).signature
+ info.derivedLambdaType(otherNames, otherTypes, restpe).signature
case _ =>
Signature.NotAMethod
}
diff --git a/compiler/src/dotty/tools/dotc/transform/FunctionalInterfaces.scala b/compiler/src/dotty/tools/dotc/transform/FunctionalInterfaces.scala
index 5fd89314a..bde902152 100644
--- a/compiler/src/dotty/tools/dotc/transform/FunctionalInterfaces.scala
+++ b/compiler/src/dotty/tools/dotc/transform/FunctionalInterfaces.scala
@@ -31,8 +31,8 @@ class FunctionalInterfaces extends MiniPhaseTransform {
val maxArgsCount = 2
def shouldSpecialize(m: MethodType)(implicit ctx: Context) =
- (m.paramTypes.size <= maxArgsCount) &&
- m.paramTypes.forall(x => allowedArgumentTypes.contains(x.typeSymbol)) &&
+ (m.paramInfos.size <= maxArgsCount) &&
+ m.paramInfos.forall(x => allowedArgumentTypes.contains(x.typeSymbol)) &&
allowedReturnTypes.contains(m.resultType.typeSymbol)
val functionName = "JFunction".toTermName
@@ -67,7 +67,7 @@ class FunctionalInterfaces extends MiniPhaseTransform {
val names = ctx.atPhase(ctx.erasurePhase) {
implicit ctx => functionSymbol.typeParams.map(_.name)
}
- val interfaceName = (functionName ++ m.paramTypes.length.toString).specializedFor(m.paramTypes ::: m.resultType :: Nil, names, Nil, Nil)
+ val interfaceName = (functionName ++ m.paramInfos.length.toString).specializedFor(m.paramInfos ::: m.resultType :: Nil, names, Nil, Nil)
// symbols loaded from classpath aren't defined in periods earlier than when they where loaded
val interface = ctx.withPhase(ctx.typerPhase).getClassIfDefined(functionPackage ++ interfaceName)
diff --git a/compiler/src/dotty/tools/dotc/transform/MixinOps.scala b/compiler/src/dotty/tools/dotc/transform/MixinOps.scala
index 9f7ceeaed..d91522c25 100644
--- a/compiler/src/dotty/tools/dotc/transform/MixinOps.scala
+++ b/compiler/src/dotty/tools/dotc/transform/MixinOps.scala
@@ -72,7 +72,7 @@ class MixinOps(cls: ClassSymbol, thisTransform: DenotTransformer)(implicit ctx:
def hasPrimitiveMissMatch(tp1: Type, tp2: Type): Boolean = (tp1, tp2) match {
case (tp1: MethodicType, tp2: MethodicType) =>
hasPrimitiveMissMatch(tp1.resultType, tp2.resultType) ||
- tp1.paramTypess.flatten.zip(tp1.paramTypess.flatten).exists(args => hasPrimitiveMissMatch(args._1, args._2))
+ tp1.paramInfoss.flatten.zip(tp1.paramInfoss.flatten).exists(args => hasPrimitiveMissMatch(args._1, args._2))
case _ =>
def isPrimitiveOrValueClass(sym: Symbol): Boolean = sym.isPrimitiveValueClass || sym.isValueClass
isPrimitiveOrValueClass(tp1.typeSymbol) ^ isPrimitiveOrValueClass(tp2.typeSymbol)
diff --git a/compiler/src/dotty/tools/dotc/transform/PatternMatcher.scala b/compiler/src/dotty/tools/dotc/transform/PatternMatcher.scala
index 197d18374..dbc7666f7 100644
--- a/compiler/src/dotty/tools/dotc/transform/PatternMatcher.scala
+++ b/compiler/src/dotty/tools/dotc/transform/PatternMatcher.scala
@@ -1766,7 +1766,7 @@ class PatternMatcher extends MiniPhaseTransform with DenotTransformer {
def applyMethodTypes(method: Type): Extractor = {
val whole = method.finalResultType
- method.paramTypess.head match {
+ method.paramInfoss.head match {
case init :+ last if last.isRepeatedParam => newExtractor(whole, init, repeatedFromVarargs(last))
case tps => newExtractor(whole, tps, NoRepeated)
}
diff --git a/compiler/src/dotty/tools/dotc/transform/ShortcutImplicits.scala b/compiler/src/dotty/tools/dotc/transform/ShortcutImplicits.scala
index b5469610f..1a530b95c 100644
--- a/compiler/src/dotty/tools/dotc/transform/ShortcutImplicits.scala
+++ b/compiler/src/dotty/tools/dotc/transform/ShortcutImplicits.scala
@@ -82,8 +82,8 @@ class ShortcutImplicits extends MiniPhase with IdentityDenotTransformer { thisTr
* @return The type of the `apply` member of `implicit Ts => R`.
*/
private def directInfo(info: Type)(implicit ctx: Context): Type = info match {
- case info: PolyType => info.derivedPolyType(resType = directInfo(info.resultType))
- case info: MethodType => info.derivedMethodType(resType = directInfo(info.resultType))
+ case info: PolyType => info.derivedLambdaType(resType = directInfo(info.resultType))
+ case info: MethodType => info.derivedLambdaType(resType = directInfo(info.resultType))
case info: ExprType => directInfo(info.resultType)
case info => info.member(nme.apply).info
}
diff --git a/compiler/src/dotty/tools/dotc/transform/SuperAccessors.scala b/compiler/src/dotty/tools/dotc/transform/SuperAccessors.scala
index 3c11827fc..728c1696b 100644
--- a/compiler/src/dotty/tools/dotc/transform/SuperAccessors.scala
+++ b/compiler/src/dotty/tools/dotc/transform/SuperAccessors.scala
@@ -178,9 +178,9 @@ class SuperAccessors(thisTransformer: DenotTransformer) {
val accType = {
def accTypeOf(tpe: Type): Type = tpe match {
case tpe: PolyType =>
- tpe.derivedPolyType(tpe.paramNames, tpe.paramBounds, accTypeOf(tpe.resultType))
+ tpe.derivedLambdaType(tpe.paramNames, tpe.paramInfos, accTypeOf(tpe.resultType))
case _ =>
- MethodType(receiverType :: Nil)(mt => tpe.substThis(sym.owner.asClass, MethodParam(mt, 0)))
+ MethodType(receiverType :: Nil)(mt => tpe.substThis(sym.owner.asClass, mt.newParamRef(0)))
}
accTypeOf(sym.info)
}
@@ -230,9 +230,9 @@ class SuperAccessors(thisTransformer: DenotTransformer) {
else clazz.classInfo.selfType
def accTypeOf(tpe: Type): Type = tpe match {
case tpe: PolyType =>
- tpe.derivedPolyType(tpe.paramNames, tpe.paramBounds, accTypeOf(tpe.resultType))
+ tpe.derivedLambdaType(tpe.paramNames, tpe.paramInfos, accTypeOf(tpe.resultType))
case _ =>
- MethodType(receiverType :: Nil)(mt => tpe.substThis(sym.owner.asClass, MethodParam(mt, 0)))
+ MethodType(receiverType :: Nil)(mt => tpe.substThis(sym.owner.asClass, mt.newParamRef(0)))
}
val accType = accTypeOf(sym.info)
val protectedAccessor = clazz.info.decl(accName).suchThat(_.signature == accType.signature).symbol orElse {
diff --git a/compiler/src/dotty/tools/dotc/transform/TreeChecker.scala b/compiler/src/dotty/tools/dotc/transform/TreeChecker.scala
index dd4d95257..ebb5b605b 100644
--- a/compiler/src/dotty/tools/dotc/transform/TreeChecker.scala
+++ b/compiler/src/dotty/tools/dotc/transform/TreeChecker.scala
@@ -287,7 +287,7 @@ class TreeChecker extends Phase with SymTransformer {
res
}
- /** Check that PolyParams and MethodParams refer to an enclosing type */
+ /** Check that TypeParamRefs and MethodParams refer to an enclosing type */
def checkNoOrphans(tp: Type)(implicit ctx: Context) = new TypeMap() {
val definedBinders = mutable.Set[Type]()
def apply(tp: Type): Type = {
@@ -296,7 +296,7 @@ class TreeChecker extends Phase with SymTransformer {
definedBinders += tp
mapOver(tp)
definedBinders -= tp
- case tp: ParamType =>
+ case tp: ParamRef =>
assert(definedBinders.contains(tp.binder), s"orphan param: $tp")
case tp: TypeVar =>
apply(tp.underlying)
diff --git a/compiler/src/dotty/tools/dotc/transform/VCInlineMethods.scala b/compiler/src/dotty/tools/dotc/transform/VCInlineMethods.scala
index ddd414417..ab24e1720 100644
--- a/compiler/src/dotty/tools/dotc/transform/VCInlineMethods.scala
+++ b/compiler/src/dotty/tools/dotc/transform/VCInlineMethods.scala
@@ -86,7 +86,7 @@ class VCInlineMethods extends MiniPhaseTransform with IdentityDenotTransformer {
* by a call to the corresponding extension method, otherwise return it as is.
*/
private def rewireIfNeeded(tree: Tree)(implicit ctx: Context) = tree.tpe.widen match {
- case tp: MethodOrPoly =>
+ case tp: LambdaType =>
tree // The rewiring will be handled by a fully-applied parent node
case _ =>
if (isMethodWithExtension(tree.symbol))
diff --git a/compiler/src/dotty/tools/dotc/typer/Applications.scala b/compiler/src/dotty/tools/dotc/typer/Applications.scala
index 310121f31..4e43e429b 100644
--- a/compiler/src/dotty/tools/dotc/typer/Applications.scala
+++ b/compiler/src/dotty/tools/dotc/typer/Applications.scala
@@ -34,7 +34,7 @@ object Applications {
def extractorMember(tp: Type, name: Name)(implicit ctx: Context) = {
def isPossibleExtractorType(tp: Type) = tp match {
- case _: MethodType | _: PolyType => false
+ case _: MethodOrPoly => false
case _ => true
}
tp.member(name).suchThat(d => isPossibleExtractorType(d.info))
@@ -195,7 +195,7 @@ trait Applications extends Compatibility { self: Typer with Dynamic =>
}
/** The function's type after widening and instantiating polytypes
- * with polyparams in constraint set
+ * with TypeParamRefs in constraint set
*/
val methType = funType.widen match {
case funType: MethodType => funType
@@ -232,7 +232,7 @@ trait Applications extends Compatibility { self: Typer with Dynamic =>
else
fail(err.typeMismatchMsg(methType.resultType, resultType))
// match all arguments with corresponding formal parameters
- matchArgs(orderedArgs, methType.paramTypes, 0)
+ matchArgs(orderedArgs, methType.paramInfos, 0)
case _ =>
if (methType.isError) ok = false
else fail(s"$methString does not take parameters")
@@ -395,7 +395,7 @@ trait Applications extends Compatibility { self: Typer with Dynamic =>
def addTyped(arg: Arg, formal: Type): Type => Type = {
addArg(typedArg(arg, formal), formal)
if (methodType.isParamDependent)
- _.substParam(MethodParam(methodType, n), typeOfArg(arg))
+ _.substParam(methodType.newParamRef(n), typeOfArg(arg))
else
identity
}
@@ -763,7 +763,7 @@ trait Applications extends Compatibility { self: Typer with Dynamic =>
val typedFn = typedExpr(tree.fun, PolyProto(typedArgs.tpes, pt))
typedFn.tpe.widen match {
case pt: PolyType =>
- if (typedArgs.length <= pt.paramBounds.length && !isNamed)
+ if (typedArgs.length <= pt.paramInfos.length && !isNamed)
if (typedFn.symbol == defn.Predef_classOf && typedArgs.nonEmpty) {
val arg = typedArgs.head
checkClassType(arg.tpe, arg.pos, traitReq = false, stablePrefixReq = false)
@@ -883,8 +883,8 @@ trait Applications extends Compatibility { self: Typer with Dynamic =>
}
unapplyFn.tpe.widen match {
- case mt: MethodType if mt.paramTypes.length == 1 =>
- val unapplyArgType = mt.paramTypes.head
+ case mt: MethodType if mt.paramInfos.length == 1 =>
+ val unapplyArgType = mt.paramInfos.head
unapp.println(i"unapp arg tpe = $unapplyArgType, pt = $selType")
val ownType =
if (selType <:< unapplyArgType) {
@@ -1056,17 +1056,17 @@ trait Applications extends Compatibility { self: Typer with Dynamic =>
case _ => if (tp.isRepeatedParam) tp.argTypesHi.head else tp
}
val formals1 =
- if (tp1.isVarArgsMethod && tp2.isVarArgsMethod) tp1.paramTypes map repeatedToSingle
- else tp1.paramTypes
+ if (tp1.isVarArgsMethod && tp2.isVarArgsMethod) tp1.paramInfos map repeatedToSingle
+ else tp1.paramInfos
isApplicable(alt2, formals1, WildcardType) ||
- tp1.paramTypes.isEmpty && tp2.isInstanceOf[MethodOrPoly]
+ tp1.paramInfos.isEmpty && tp2.isInstanceOf[LambdaType]
case tp1: PolyType => // (2)
val tparams = ctx.newTypeParams(alt1.symbol, tp1.paramNames, EmptyFlags, tp1.instantiateBounds)
isAsSpecific(alt1, tp1.instantiate(tparams map (_.typeRef)), alt2, tp2)
case _ => // (3)
tp2 match {
case tp2: MethodType => true // (3a)
- case tp2: PolyType if tp2.isPolymorphicMethodType => true // (3a)
+ case tp2: PolyType if tp2.resultType.isInstanceOf[MethodType] => true // (3a)
case tp2: PolyType => // (3b)
val nestedCtx = ctx.fresh.setExploreTyperState
@@ -1125,7 +1125,7 @@ trait Applications extends Compatibility { self: Typer with Dynamic =>
case mt: ImplicitMethodType =>
resultTypeApprox(mt)
case pt: PolyType =>
- pt.derivedPolyType(pt.paramNames, pt.paramBounds, stripImplicit(pt.resultType))
+ pt.derivedLambdaType(pt.paramNames, pt.paramInfos, stripImplicit(pt.resultType))
case _ =>
tp
}
@@ -1284,10 +1284,9 @@ trait Applications extends Compatibility { self: Typer with Dynamic =>
case x => x
}
- def sizeFits(alt: TermRef, tp: Type): Boolean = tp match {
- case tp: PolyType => sizeFits(alt, tp.resultType)
+ def sizeFits(alt: TermRef, tp: Type): Boolean = tp.stripPoly match {
case tp: MethodType =>
- val ptypes = tp.paramTypes
+ val ptypes = tp.paramInfos
val numParams = ptypes.length
def isVarArgs = ptypes.nonEmpty && ptypes.last.isRepeatedParam
def hasDefault = alt.symbol.hasDefaultParams
@@ -1412,12 +1411,7 @@ trait Applications extends Compatibility { self: Typer with Dynamic =>
recur(altFormals.map(_.tail), args1)
case _ =>
}
- def paramTypes(alt: Type): List[Type] = alt match {
- case mt: MethodType => mt.paramTypes
- case mt: PolyType => paramTypes(mt.resultType)
- case _ => Nil
- }
- recur(alts.map(alt => paramTypes(alt.widen)), pt.args)
+ recur(alts.map(_.widen.firstParamTypes), pt.args)
}
private def harmonizeWith[T <: AnyRef](ts: List[T])(tpe: T => Type, adapt: (T, Type) => T)(implicit ctx: Context): List[T] = {
diff --git a/compiler/src/dotty/tools/dotc/typer/Checking.scala b/compiler/src/dotty/tools/dotc/typer/Checking.scala
index 148ccd6e3..5d1c44efc 100644
--- a/compiler/src/dotty/tools/dotc/typer/Checking.scala
+++ b/compiler/src/dotty/tools/dotc/typer/Checking.scala
@@ -50,12 +50,12 @@ object Checking {
arg.pos.focus)
}
- /** Check that type arguments `args` conform to corresponding bounds in `poly`
+ /** Check that type arguments `args` conform to corresponding bounds in `tl`
* 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 =
- checkBounds(args, poly.paramBounds, _.substParams(poly, _))
+ def checkBounds(args: List[tpd.Tree], tl: TypeLambda)(implicit ctx: Context): Unit =
+ checkBounds(args, tl.paramInfos, _.substParams(tl, _))
/** Check applied type trees for well-formedness. This means
* - all arguments are within their corresponding bounds
@@ -69,20 +69,20 @@ object Checking {
// If `args` is a list of named arguments, return corresponding type parameters,
// otherwise return type parameters unchanged
val tparams = tycon.tpe.typeParams
- def argNamed(tparam: TypeParamInfo) = args.find {
+ def argNamed(tparam: ParamInfo) = args.find {
case NamedArg(name, _) => name == tparam.paramName
case _ => false
}.getOrElse(TypeTree(tparam.paramRef))
val orderedArgs = if (hasNamedArg(args)) tparams.map(argNamed) else args
- val bounds = tparams.map(_.paramBoundsAsSeenFrom(tycon.tpe))
+ val bounds = tparams.map(_.paramInfoAsSeenFrom(tycon.tpe).bounds)
def instantiate(bound: Type, args: List[Type]) =
- bound.LambdaAbstract(tparams).appliedTo(args)
+ HKTypeLambda.fromParams(tparams, bound).appliedTo(args)
checkBounds(orderedArgs, bounds, instantiate)
def checkWildcardHKApply(tp: Type, pos: Position): Unit = tp match {
case tp @ HKApply(tycon, args) if args.exists(_.isInstanceOf[TypeBounds]) =>
tycon match {
- case tycon: PolyType =>
+ case tycon: TypeLambda =>
ctx.errorOrMigrationWarning(
ex"unreducible application of higher-kinded type $tycon to wildcard arguments",
pos)
diff --git a/compiler/src/dotty/tools/dotc/typer/Dynamic.scala b/compiler/src/dotty/tools/dotc/typer/Dynamic.scala
index 000cfd026..25fca546e 100644
--- a/compiler/src/dotty/tools/dotc/typer/Dynamic.scala
+++ b/compiler/src/dotty/tools/dotc/typer/Dynamic.scala
@@ -150,7 +150,7 @@ trait Dynamic { self: Typer with Applications =>
|Structural types only support methods taking up to ${Definitions.MaxStructuralMethodArity} arguments""")
else {
def issueError(msgFn: String => String): Unit = ctx.error(msgFn(""), tree.pos)
- val ctags = tpe.paramTypes.map(pt =>
+ val ctags = tpe.paramInfos.map(pt =>
inferImplicitArg(defn.ClassTagType.appliedTo(pt :: Nil), issueError, tree.pos.endPos))
structuralCall(nme.selectDynamicMethod, ctags).asInstance(tpe.toFunctionType())
}
diff --git a/compiler/src/dotty/tools/dotc/typer/ErrorReporting.scala b/compiler/src/dotty/tools/dotc/typer/ErrorReporting.scala
index a1690955f..6c72c16e0 100644
--- a/compiler/src/dotty/tools/dotc/typer/ErrorReporting.scala
+++ b/compiler/src/dotty/tools/dotc/typer/ErrorReporting.scala
@@ -46,7 +46,7 @@ object ErrorReporting {
errorMsg(ex.toMessage, ctx)
}
- def wrongNumberOfTypeArgs(fntpe: Type, expectedArgs: List[TypeParamInfo], actual: List[untpd.Tree], pos: Position)(implicit ctx: Context) =
+ def wrongNumberOfTypeArgs(fntpe: Type, expectedArgs: List[ParamInfo], actual: List[untpd.Tree], pos: Position)(implicit ctx: Context) =
errorType(WrongNumberOfTypeArgs(fntpe, expectedArgs, actual)(ctx), pos)
class Errors(implicit ctx: Context) {
@@ -74,7 +74,7 @@ object ErrorReporting {
def anonymousTypeMemberStr(tpe: Type) = {
val kind = tpe match {
case _: TypeBounds => "type with bounds"
- case _: PolyType | _: MethodType => "method"
+ case _: MethodOrPoly => "method"
case _ => "value of type"
}
em"$kind $tpe"
@@ -105,9 +105,9 @@ object ErrorReporting {
def whyNoMatchStr(found: Type, expected: Type) = {
def dropJavaMethod(tp: Type): Type = tp match {
case tp: PolyType =>
- tp.derivedPolyType(resType = dropJavaMethod(tp.resultType))
+ tp.derivedLambdaType(resType = dropJavaMethod(tp.resultType))
case tp: JavaMethodType =>
- MethodType(tp.paramNames, tp.paramTypes, dropJavaMethod(tp.resultType))
+ MethodType(tp.paramNames, tp.paramInfos, dropJavaMethod(tp.resultType))
case tp => tp
}
val found1 = dropJavaMethod(found)
@@ -121,12 +121,12 @@ object ErrorReporting {
}
def typeMismatchMsg(found: Type, expected: Type, postScript: String = "") = {
- // replace constrained polyparams and their typevars by their bounds where possible
+ // replace constrained TypeParamRefs and their typevars by their bounds where possible
object reported extends TypeMap {
def setVariance(v: Int) = variance = v
val constraint = ctx.typerState.constraint
def apply(tp: Type): Type = tp match {
- case tp: PolyParam =>
+ case tp: TypeParamRef =>
constraint.entry(tp) match {
case bounds: TypeBounds =>
if (variance < 0) apply(constraint.fullUpperBound(tp))
diff --git a/compiler/src/dotty/tools/dotc/typer/EtaExpansion.scala b/compiler/src/dotty/tools/dotc/typer/EtaExpansion.scala
index 57c1808c9..5aee0fd54 100644
--- a/compiler/src/dotty/tools/dotc/typer/EtaExpansion.scala
+++ b/compiler/src/dotty/tools/dotc/typer/EtaExpansion.scala
@@ -60,7 +60,7 @@ object EtaExpansion {
def liftArgs(defs: mutable.ListBuffer[Tree], methRef: Type, args: List[Tree])(implicit ctx: Context) =
methRef.widen match {
case mt: MethodType =>
- (args, mt.paramNames, mt.paramTypes).zipped map { (arg, name, tp) =>
+ (args, mt.paramNames, mt.paramInfos).zipped map { (arg, name, tp) =>
if (tp.isInstanceOf[ExprType]) arg
else liftArg(defs, arg, if (name contains '$') "" else name.toString + "$")
}
@@ -135,12 +135,12 @@ object EtaExpansion {
val defs = new mutable.ListBuffer[tpd.Tree]
val lifted: Tree = TypedSplice(liftApp(defs, tree))
val paramTypes: List[Tree] =
- if (mt.paramTypes.length == xarity) mt.paramTypes map (_ => TypeTree())
- else mt.paramTypes map TypeTree
+ if (mt.paramInfos.length == xarity) mt.paramInfos map (_ => TypeTree())
+ else mt.paramInfos map TypeTree
val params = (mt.paramNames, paramTypes).zipped.map((name, tpe) =>
ValDef(name, tpe, EmptyTree).withFlags(Synthetic | Param).withPos(tree.pos))
var ids: List[Tree] = mt.paramNames map (name => Ident(name).withPos(tree.pos))
- if (mt.paramTypes.nonEmpty && mt.paramTypes.last.isRepeatedParam)
+ if (mt.paramInfos.nonEmpty && mt.paramInfos.last.isRepeatedParam)
ids = ids.init :+ repeated(ids.last)
var body: Tree = Apply(lifted, ids)
mt.resultType match {
diff --git a/compiler/src/dotty/tools/dotc/typer/Implicits.scala b/compiler/src/dotty/tools/dotc/typer/Implicits.scala
index 681045cc4..6c0be51df 100644
--- a/compiler/src/dotty/tools/dotc/typer/Implicits.scala
+++ b/compiler/src/dotty/tools/dotc/typer/Implicits.scala
@@ -66,16 +66,16 @@ object Implicits {
def discardForView(tpw: Type, argType: Type): Boolean = tpw match {
case mt: MethodType =>
mt.isImplicit ||
- mt.paramTypes.length != 1 ||
- !(argType relaxed_<:< mt.paramTypes.head)(ctx.fresh.setExploreTyperState)
+ mt.paramInfos.length != 1 ||
+ !(argType relaxed_<:< mt.paramInfos.head)(ctx.fresh.setExploreTyperState)
case poly: PolyType =>
// We do not need to call ProtoTypes#constrained on `poly` because
// `refMatches` is always called with mode TypevarsMissContext enabled.
poly.resultType match {
case mt: MethodType =>
mt.isImplicit ||
- mt.paramTypes.length != 1 ||
- !(argType relaxed_<:< wildApprox(mt.paramTypes.head, null, Set.empty)(ctx.fresh.setExploreTyperState))
+ mt.paramInfos.length != 1 ||
+ !(argType relaxed_<:< wildApprox(mt.paramInfos.head, null, Set.empty)(ctx.fresh.setExploreTyperState))
case rtp =>
discardForView(wildApprox(rtp, null, Set.empty), argType)
}
@@ -107,9 +107,8 @@ object Implicits {
!(isFunctionInS2 || isImplicitConverter || isConforms)
}
- def discardForValueType(tpw: Type): Boolean = tpw match {
- case mt: MethodType => !mt.isImplicit
- case mt: PolyType => discardForValueType(tpw.resultType)
+ def discardForValueType(tpw: Type): Boolean = tpw.stripPoly match {
+ case tpw: MethodType => !tpw.isImplicit
case _ => false
}
@@ -387,7 +386,7 @@ trait ImplicitRunInfo { self: RunInfo =>
case _ => arg
}
(apply(tp.tycon) /: tp.args)((tc, arg) => AndType.make(tc, applyArg(arg)))
- case tp: PolyType =>
+ case tp: TypeLambda =>
apply(tp.resType)
case _ =>
mapOver(tp)
diff --git a/compiler/src/dotty/tools/dotc/typer/Inferencing.scala b/compiler/src/dotty/tools/dotc/typer/Inferencing.scala
index 86649d78e..632dbff76 100644
--- a/compiler/src/dotty/tools/dotc/typer/Inferencing.scala
+++ b/compiler/src/dotty/tools/dotc/typer/Inferencing.scala
@@ -119,11 +119,11 @@ object Inferencing {
}
}
- /** If `tree` has a PolyType, infer its type parameters by comparing with expected type `pt` */
+ /** If `tree` has a type lambda type, infer its type parameters by comparing with expected type `pt` */
def inferTypeParams(tree: Tree, pt: Type)(implicit ctx: Context): Tree = tree.tpe match {
- case poly: PolyType =>
- val (poly1, tvars) = constrained(poly, tree)
- val tree1 = tree.withType(poly1).appliedToTypeTrees(tvars)
+ case tl: TypeLambda =>
+ val (tl1, tvars) = constrained(tl, tree)
+ val tree1 = tree.withType(tl1).appliedToTypeTrees(tvars)
tree1.tpe <:< pt
fullyDefinedType(tree1.tpe, "template parent", tree.pos)
tree1
@@ -157,7 +157,7 @@ object Inferencing {
case Apply(fn, _) =>
fn.tpe.widen match {
case mtp: MethodType =>
- val (occ, nocc) = toTest.partition(tvar => mtp.paramTypes.exists(tvar.occursIn))
+ val (occ, nocc) = toTest.partition(tvar => mtp.paramInfos.exists(tvar.occursIn))
occurring(fn, nocc, occ ::: acc)
case _ =>
occurring(fn, toTest, acc)
@@ -176,9 +176,9 @@ object Inferencing {
* -1 (minimize) if constraint is uniformly from below,
* 0 if unconstrained, or constraint is from below and above.
*/
- private def instDirection(param: PolyParam)(implicit ctx: Context): Int = {
+ private def instDirection(param: TypeParamRef)(implicit ctx: Context): Int = {
val constrained = ctx.typerState.constraint.fullBounds(param)
- val original = param.binder.paramBounds(param.paramNum)
+ val original = param.binder.paramInfos(param.paramNum)
val cmp = ctx.typeComparer
val approxBelow =
if (!cmp.isSubTypeWhenFrozen(constrained.lo, original.lo)) 1 else 0
diff --git a/compiler/src/dotty/tools/dotc/typer/Inliner.scala b/compiler/src/dotty/tools/dotc/typer/Inliner.scala
index 6e90367c8..f6d65fbb9 100644
--- a/compiler/src/dotty/tools/dotc/typer/Inliner.scala
+++ b/compiler/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.derivedPolyType(tp.paramNames, tp.paramBounds, addQualType(tp.resultType))
+ case tp: PolyType => tp.derivedLambdaType(tp.paramNames, tp.paramInfos, addQualType(tp.resultType))
case tp: ExprType => addQualType(tp.resultType)
case tp => MethodType(qualType :: Nil, tp)
}
@@ -120,7 +120,8 @@ object Inliner {
// Abstract accessed type over local refs
def abstractQualType(mtpe: Type): Type =
if (localRefs.isEmpty) mtpe
- else mtpe.LambdaAbstract(localRefs.map(_.symbol)).asInstanceOf[PolyType].flatten
+ else PolyType.fromParams(localRefs.map(_.symbol.asType), mtpe)
+ .asInstanceOf[PolyType].flatten
val accessorType = abstractQualType(addQualType(dealiasMap(accessedType)))
val accessor = accessorSymbol(tree, accessorType).asTerm
@@ -327,7 +328,7 @@ class Inliner(call: tpd.Tree, rhs: tpd.Tree)(implicit ctx: Context) {
}
computeParamBindings(tp.resultType, Nil, argss)
case tp: MethodType =>
- (tp.paramNames, tp.paramTypes, argss.head).zipped.foreach { (name, paramtp, arg) =>
+ (tp.paramNames, tp.paramInfos, argss.head).zipped.foreach { (name, paramtp, arg) =>
def isByName = paramtp.dealias.isInstanceOf[ExprType]
paramBinding(name) = arg.tpe.stripAnnots.stripTypeVar match {
case argtpe: SingletonType if isIdempotentExpr(arg) => argtpe
@@ -358,7 +359,7 @@ class Inliner(call: tpd.Tree, rhs: tpd.Tree)(implicit ctx: Context) {
* 2. If given type refers to a parameter, make `paramProxy` refer to the entry stored
* in `paramNames` under the parameter's name. This roundabout way to bind parameter
* references to proxies is done because we not known a priori what the parameter
- * references of a method are (we only know the method's type, but that contains PolyParams
+ * references of a method are (we only know the method's type, but that contains TypeParamRefs
* and MethodParams, not TypeRefs or TermRefs.
*/
private def registerType(tpe: Type): Unit = tpe match {
diff --git a/compiler/src/dotty/tools/dotc/typer/Namer.scala b/compiler/src/dotty/tools/dotc/typer/Namer.scala
index ed580c631..ce2030c01 100644
--- a/compiler/src/dotty/tools/dotc/typer/Namer.scala
+++ b/compiler/src/dotty/tools/dotc/typer/Namer.scala
@@ -113,9 +113,9 @@ trait NamerContextOps { this: Context =>
if (isJava)
for (param <- params)
if (param.info.isDirectRef(defn.ObjectClass)) param.info = defn.AnyType
- make.fromSymbols(params, resultType)
+ make.fromSymbols(params.asInstanceOf[List[TermSymbol]], resultType)
}
- if (typeParams.nonEmpty) monotpe.LambdaAbstract(typeParams)
+ if (typeParams.nonEmpty) PolyType.fromParams(typeParams.asInstanceOf[List[TypeSymbol]], monotpe)
else if (valueParamss.isEmpty) ExprType(monotpe)
else monotpe
}
@@ -298,7 +298,7 @@ class Namer { typer: Typer =>
val inSuperCall1 = if (tree.mods is ParamOrAccessor) EmptyFlags else inSuperCall
// suppress inSuperCall for constructor parameters
val higherKinded = tree match {
- case TypeDef(_, PolyTypeTree(_, _)) if isDeferred => HigherKinded
+ case TypeDef(_, LambdaTypeTree(_, _)) if isDeferred => HigherKinded
case _ => EmptyFlags
}
@@ -795,7 +795,7 @@ class Namer { typer: Typer =>
myTypeParams = {
implicit val ctx = nestedCtx
val tparams = original.rhs match {
- case PolyTypeTree(tparams, _) => tparams
+ case LambdaTypeTree(tparams, _) => tparams
case _ => Nil
}
completeParams(tparams)
@@ -1032,7 +1032,7 @@ class Namer { typer: Typer =>
}
val defaultAlts = meth.altsWith(_.hasDefaultParams)
if (defaultAlts.length == 1)
- paramProto(defaultAlts.head.info.widen.paramTypess, idx)
+ paramProto(defaultAlts.head.info.widen.paramInfoss, idx)
else
WildcardType
}
@@ -1151,9 +1151,7 @@ class Namer { typer: Typer =>
}
def typeDefSig(tdef: TypeDef, sym: Symbol, tparamSyms: List[TypeSymbol])(implicit ctx: Context): Type = {
- def abstracted(tp: Type): Type =
- if (tparamSyms.nonEmpty) tp.LambdaAbstract(tparamSyms) else tp
-
+ def abstracted(tp: Type): Type = HKTypeLambda.fromParams(tparamSyms, tp)
val dummyInfo = abstracted(TypeBounds.empty)
sym.info = dummyInfo
// Temporarily set info of defined type T to ` >: Nothing <: Any.
@@ -1169,7 +1167,7 @@ class Namer { typer: Typer =>
val isDerived = tdef.rhs.isInstanceOf[untpd.DerivedTypeTree]
val rhs = tdef.rhs match {
- case PolyTypeTree(_, body) => body
+ case LambdaTypeTree(_, body) => body
case rhs => rhs
}
val rhsBodyType = typedAheadType(rhs).tpe
diff --git a/compiler/src/dotty/tools/dotc/typer/ProtoTypes.scala b/compiler/src/dotty/tools/dotc/typer/ProtoTypes.scala
index f96b8ae1d..ab342dc17 100644
--- a/compiler/src/dotty/tools/dotc/typer/ProtoTypes.scala
+++ b/compiler/src/dotty/tools/dotc/typer/ProtoTypes.scala
@@ -192,7 +192,7 @@ object ProtoTypes {
/** Forget the types of any arguments that have been typed producing a constraint in a
* typer state that is not yet committed into the one of the current context `ctx`.
- * This is necessary to avoid "orphan" PolyParams that are referred to from
+ * This is necessary to avoid "orphan" TypeParamRefs that are referred to from
* type variables in the typed arguments, but that are not registered in the
* current constraint. A test case is pos/t1756.scala.
* @return True if all arguments have types (in particular, no types were forgotten).
@@ -369,53 +369,53 @@ object ProtoTypes {
/** A prototype for type constructors that are followed by a type application */
@sharable object AnyTypeConstructorProto extends UncachedGroundType with MatchAlways
- /** Add all parameters in given polytype `pt` to the constraint's domain.
+ /** Add all parameters of given type lambda `tl` to the constraint's domain.
* If the constraint contains already some of these parameters in its domain,
- * make a copy of the polytype and add the copy's type parameters instead.
- * Return either the original polytype, or the copy, if one was made.
+ * make a copy of the type lambda and add the copy's type parameters instead.
+ * Return either the original type lambda, or the copy, if one was made.
* Also, if `owningTree` is non-empty, add a type variable for each parameter.
- * @return The added polytype, and the list of created type variables.
+ * @return The added type lambda, and the list of created type variables.
*/
- def constrained(pt: PolyType, owningTree: untpd.Tree)(implicit ctx: Context): (PolyType, List[TypeTree]) = {
+ def constrained(tl: TypeLambda, owningTree: untpd.Tree)(implicit ctx: Context): (TypeLambda, List[TypeTree]) = {
val state = ctx.typerState
assert(!(ctx.typerState.isCommittable && owningTree.isEmpty),
s"inconsistent: no typevars were added to committable constraint ${state.constraint}")
- def newTypeVars(pt: PolyType): List[TypeTree] =
- for (n <- (0 until pt.paramNames.length).toList)
+ def newTypeVars(tl: TypeLambda): List[TypeTree] =
+ for (n <- (0 until tl.paramNames.length).toList)
yield {
val tt = new TypeTree().withPos(owningTree.pos)
- tt.withType(new TypeVar(PolyParam(pt, n), state, tt, ctx.owner))
+ tt.withType(new TypeVar(TypeParamRef(tl, n), state, tt, ctx.owner))
}
val added =
- if (state.constraint contains pt) pt.newLikeThis(pt.paramNames, pt.paramBounds, pt.resultType)
- else pt
+ if (state.constraint contains tl) tl.newLikeThis(tl.paramNames, tl.paramInfos, tl.resultType)
+ else tl
val tvars = if (owningTree.isEmpty) Nil else newTypeVars(added)
ctx.typeComparer.addToConstraint(added, tvars.tpes.asInstanceOf[List[TypeVar]])
(added, tvars)
}
- /** Same as `constrained(pt, EmptyTree)`, but returns just the created polytype */
- def constrained(pt: PolyType)(implicit ctx: Context): PolyType = constrained(pt, EmptyTree)._1
+ /** Same as `constrained(tl, EmptyTree)`, but returns just the created type lambda */
+ def constrained(tl: TypeLambda)(implicit ctx: Context): TypeLambda = constrained(tl, EmptyTree)._1
- /** Create a new polyparam that represents a dependent method parameter singleton */
- def newDepPolyParam(tp: Type)(implicit ctx: Context): PolyParam = {
- val poly = PolyType(ctx.freshName(nme.DEP_PARAM_PREFIX).toTypeName :: Nil, 0 :: Nil)(
+ /** Create a new TypeParamRef that represents a dependent method parameter singleton */
+ def newDepTypeParamRef(tp: Type)(implicit ctx: Context): TypeParamRef = {
+ val poly = PolyType(ctx.freshName(nme.DEP_PARAM_PREFIX).toTypeName :: Nil)(
pt => TypeBounds.upper(AndType(tp, defn.SingletonType)) :: Nil,
pt => defn.AnyType)
ctx.typeComparer.addToConstraint(poly, Nil)
- PolyParam(poly, 0)
+ TypeParamRef(poly, 0)
}
/** The result type of `mt`, where all references to parameters of `mt` are
- * replaced by either wildcards (if typevarsMissContext) or polyparams.
+ * replaced by either wildcards (if typevarsMissContext) or TypeParamRefs.
*/
def resultTypeApprox(mt: MethodType)(implicit ctx: Context): Type =
if (mt.isDependent) {
def replacement(tp: Type) =
- if (ctx.mode.is(Mode.TypevarsMissContext)) WildcardType else newDepPolyParam(tp)
- mt.resultType.substParams(mt, mt.paramTypes.map(replacement))
+ if (ctx.mode.is(Mode.TypevarsMissContext)) WildcardType else newDepTypeParamRef(tp)
+ mt.resultType.substParams(mt, mt.paramInfos.map(replacement))
}
else mt.resultType
@@ -444,10 +444,10 @@ object ProtoTypes {
val rt = normalize(mt.resultType, pt)
pt match {
case pt: IgnoredProto => mt
- case pt: ApplyingProto => mt.derivedMethodType(mt.paramNames, mt.paramTypes, rt)
+ case pt: ApplyingProto => mt.derivedLambdaType(mt.paramNames, mt.paramInfos, rt)
case _ =>
- val ft = defn.FunctionOf(mt.paramTypes, rt)
- if (mt.paramTypes.nonEmpty || ft <:< pt) ft else rt
+ val ft = defn.FunctionOf(mt.paramInfos, rt)
+ if (mt.paramInfos.nonEmpty || ft <:< pt) ft else rt
}
}
case et: ExprType => et.resultType
@@ -458,7 +458,7 @@ object ProtoTypes {
/** Approximate occurrences of parameter types and uninstantiated typevars
* by wildcard types.
*/
- final def wildApprox(tp: Type, theMap: WildApproxMap, seen: Set[PolyParam])(implicit ctx: Context): Type = tp match {
+ final def wildApprox(tp: Type, theMap: WildApproxMap, seen: Set[TypeParamRef])(implicit ctx: Context): Type = tp match {
case tp: NamedType => // default case, inlined for speed
if (tp.symbol.isStatic) tp
else tp.derivedSelect(wildApprox(tp.prefix, theMap, seen))
@@ -469,13 +469,13 @@ object ProtoTypes {
wildApprox(tp.refinedInfo, theMap, seen))
case tp: TypeAlias => // default case, inlined for speed
tp.derivedTypeAlias(wildApprox(tp.alias, theMap, seen))
- case tp @ PolyParam(poly, pnum) =>
+ case tp @ TypeParamRef(poly, pnum) =>
def wildApproxBounds(bounds: TypeBounds) =
if (bounds.lo.isInstanceOf[NamedType] && bounds.hi.isInstanceOf[NamedType])
WildcardType(wildApprox(bounds, theMap, seen).bounds)
else if (seen.contains(tp)) WildcardType
else WildcardType(wildApprox(bounds, theMap, seen + tp).bounds)
- def unconstrainedApprox = wildApproxBounds(poly.paramBounds(pnum))
+ def unconstrainedApprox = wildApproxBounds(poly.paramInfos(pnum))
def approxPoly =
if (ctx.mode.is(Mode.TypevarsMissContext)) unconstrainedApprox
else
@@ -485,8 +485,8 @@ object ProtoTypes {
case inst => wildApprox(inst, theMap, seen)
}
approxPoly
- case MethodParam(mt, pnum) =>
- WildcardType(TypeBounds.upper(wildApprox(mt.paramTypes(pnum), theMap, seen)))
+ case TermParamRef(mt, pnum) =>
+ WildcardType(TypeBounds.upper(wildApprox(mt.paramInfos(pnum), theMap, seen)))
case tp: TypeVar =>
wildApprox(tp.underlying, theMap, seen)
case tp @ HKApply(tycon, args) =>
@@ -532,7 +532,7 @@ object ProtoTypes {
@sharable object AssignProto extends UncachedGroundType with MatchAlways
- private[ProtoTypes] class WildApproxMap(val seen: Set[PolyParam])(implicit ctx: Context) extends TypeMap {
+ private[ProtoTypes] class WildApproxMap(val seen: Set[TypeParamRef])(implicit ctx: Context) extends TypeMap {
def apply(tp: Type) = wildApprox(tp, this, seen)
}
diff --git a/compiler/src/dotty/tools/dotc/typer/ReTyper.scala b/compiler/src/dotty/tools/dotc/typer/ReTyper.scala
index 6080c6644..73e676b57 100644
--- a/compiler/src/dotty/tools/dotc/typer/ReTyper.scala
+++ b/compiler/src/dotty/tools/dotc/typer/ReTyper.scala
@@ -86,7 +86,7 @@ class ReTyper extends Typer {
override def handleUnexpectedFunType(tree: untpd.Apply, fun: Tree)(implicit ctx: Context): Tree = fun.tpe match {
case mt: MethodType =>
- val args: List[Tree] = tree.args.zipWithConserve(mt.paramTypes)(typedExpr(_, _)).asInstanceOf[List[Tree]]
+ val args: List[Tree] = tree.args.zipWithConserve(mt.paramInfos)(typedExpr(_, _)).asInstanceOf[List[Tree]]
assignType(untpd.cpy.Apply(tree)(fun, args), fun, args)
case _ =>
super.handleUnexpectedFunType(tree, fun)
diff --git a/compiler/src/dotty/tools/dotc/typer/TypeAssigner.scala b/compiler/src/dotty/tools/dotc/typer/TypeAssigner.scala
index 6d0fc08f9..2aa7036b4 100644
--- a/compiler/src/dotty/tools/dotc/typer/TypeAssigner.scala
+++ b/compiler/src/dotty/tools/dotc/typer/TypeAssigner.scala
@@ -106,7 +106,7 @@ trait TypeAssigner {
val base = apply(tycon)
var args = tp.baseArgInfos(base.typeSymbol)
if (base.typeParams.length != args.length)
- args = base.typeParams.map(_.paramBounds)
+ args = base.typeParams.map(_.paramInfo)
apply(base.appliedTo(args))
case tp @ RefinedType(parent, name, rinfo) if variance > 0 =>
val parent1 = apply(tp.parent)
@@ -318,9 +318,9 @@ trait TypeAssigner {
def assignType(tree: untpd.Apply, fn: Tree, args: List[Tree])(implicit ctx: Context) = {
val ownType = fn.tpe.widen match {
case fntpe: MethodType =>
- if (sameLength(fntpe.paramTypes, args) || ctx.phase.prev.relaxedTyping) fntpe.instantiate(args.tpes)
+ if (sameLength(fntpe.paramInfos, args) || ctx.phase.prev.relaxedTyping) fntpe.instantiate(args.tpes)
else
- errorType(i"wrong number of arguments for $fntpe: ${fn.tpe}, expected: ${fntpe.paramTypes.length}, found: ${args.length}", tree.pos)
+ errorType(i"wrong number of arguments for $fntpe: ${fn.tpe}, expected: ${fntpe.paramInfos.length}, found: ${args.length}", tree.pos)
case t =>
errorType(i"${err.exprStr(fn)} does not take parameters", tree.pos)
}
@@ -329,7 +329,7 @@ trait TypeAssigner {
def assignType(tree: untpd.TypeApply, fn: Tree, args: List[Tree])(implicit ctx: Context) = {
val ownType = fn.tpe.widen match {
- case pt: PolyType =>
+ case pt: TypeLambda =>
val paramNames = pt.paramNames
if (hasNamedArg(args)) {
// Type arguments which are specified by name (immutable after this first loop)
@@ -348,7 +348,7 @@ trait TypeAssigner {
val newIndex = gapBuf.length
gapBuf += idx
// Re-index unassigned type arguments that remain after transformation
- PolyParam(pt, newIndex)
+ TypeParamRef(pt, newIndex)
}
// Type parameters after naming assignment, conserving paramNames order
@@ -358,7 +358,7 @@ trait TypeAssigner {
val transform = new TypeMap {
def apply(t: Type) = t match {
- case PolyParam(`pt`, idx) => normArgs(idx)
+ case TypeParamRef(`pt`, idx) => normArgs(idx)
case _ => mapOver(t)
}
}
@@ -366,9 +366,9 @@ trait TypeAssigner {
if (gapBuf.isEmpty) resultType1
else {
val gaps = gapBuf.toList
- pt.derivedPolyType(
+ pt.derivedLambdaType(
gaps.map(paramNames),
- gaps.map(idx => transform(pt.paramBounds(idx)).bounds),
+ gaps.map(idx => transform(pt.paramInfos(idx)).bounds),
resultType1)
}
}
@@ -459,8 +459,8 @@ trait TypeAssigner {
tree.withType(ownType)
}
- def assignType(tree: untpd.PolyTypeTree, tparamDefs: List[TypeDef], body: Tree)(implicit ctx: Context) =
- tree.withType(body.tpe.LambdaAbstract(tparamDefs.map(_.symbol)))
+ def assignType(tree: untpd.LambdaTypeTree, tparamDefs: List[TypeDef], body: Tree)(implicit ctx: Context) =
+ tree.withType(HKTypeLambda.fromParams(tparamDefs.map(_.symbol.asType), body.tpe))
def assignType(tree: untpd.ByNameTypeTree, result: Tree)(implicit ctx: Context) =
tree.withType(ExprType(result.tpe))
diff --git a/compiler/src/dotty/tools/dotc/typer/Typer.scala b/compiler/src/dotty/tools/dotc/typer/Typer.scala
index d4a9744e4..2760ceba9 100644
--- a/compiler/src/dotty/tools/dotc/typer/Typer.scala
+++ b/compiler/src/dotty/tools/dotc/typer/Typer.scala
@@ -741,14 +741,14 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
calleeType.widen match {
case mtpe: MethodType =>
val pos = params indexWhere (_.name == param.name)
- if (pos < mtpe.paramTypes.length) {
- val ptype = mtpe.paramTypes(pos)
+ if (pos < mtpe.paramInfos.length) {
+ val ptype = mtpe.paramInfos(pos)
if (isFullyDefined(ptype, ForceDegree.noBottom)) return ptype
}
case _ =>
}
val ofFun =
- if (nme.syntheticParamNames(args.length + 1) contains param.name)
+ if (MethodType.syntheticParamNames(args.length + 1) contains param.name)
i" of expanded function $tree"
else
""
@@ -1074,10 +1074,10 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
wrongNumberOfTypeArgs(tpt1.tpe, tparams, args, tree.pos)
args = args.take(tparams.length)
}
- def typedArg(arg: untpd.Tree, tparam: TypeParamInfo) = {
+ def typedArg(arg: untpd.Tree, tparam: ParamInfo) = {
val (desugaredArg, argPt) =
if (ctx.mode is Mode.Pattern)
- (if (isVarPattern(arg)) desugar.patternVar(arg) else arg, tparam.paramBounds)
+ (if (isVarPattern(arg)) desugar.patternVar(arg) else arg, tparam.paramInfo)
else
(arg, WildcardType)
if (tpt1.symbol.isClass)
@@ -1096,12 +1096,12 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
}
}
- def typedPolyTypeTree(tree: untpd.PolyTypeTree)(implicit ctx: Context): Tree = track("typedPolyTypeTree") {
- val PolyTypeTree(tparams, body) = tree
+ def typedLambdaTypeTree(tree: untpd.LambdaTypeTree)(implicit ctx: Context): Tree = track("typedLambdaTypeTree") {
+ val LambdaTypeTree(tparams, body) = tree
indexAndAnnotate(tparams)
val tparams1 = tparams.mapconserve(typed(_).asInstanceOf[TypeDef])
val body1 = typedType(tree.body)
- assignType(cpy.PolyTypeTree(tree)(tparams1, body1), tparams1, body1)
+ assignType(cpy.LambdaTypeTree(tree)(tparams1, body1), tparams1, body1)
}
def typedByNameTypeTree(tree: untpd.ByNameTypeTree)(implicit ctx: Context): ByNameTypeTree = track("typedByNameTypeTree") {
@@ -1262,10 +1262,10 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
val TypeDef(name, rhs) = tdef
completeAnnotations(tdef, sym)
val rhs1 = tdef.rhs match {
- case rhs @ PolyTypeTree(tparams, body) =>
+ case rhs @ LambdaTypeTree(tparams, body) =>
val tparams1 = tparams.map(typed(_)).asInstanceOf[List[TypeDef]]
val body1 = typedType(body)
- assignType(cpy.PolyTypeTree(rhs)(tparams1, body1), tparams1, body1)
+ assignType(cpy.LambdaTypeTree(rhs)(tparams1, body1), tparams1, body1)
case rhs =>
typedType(rhs)
}
@@ -1285,9 +1285,7 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
* @param psym Its type symbol
* @param cinfo The info of its constructor
*/
- def maybeCall(ref: Tree, psym: Symbol, cinfo: Type): Tree = cinfo match {
- case cinfo: PolyType =>
- maybeCall(ref, psym, cinfo.resultType)
+ def maybeCall(ref: Tree, psym: Symbol, cinfo: Type): Tree = cinfo.stripPoly match {
case cinfo @ MethodType(Nil) if cinfo.resultType.isInstanceOf[ImplicitMethodType] =>
val icall = New(ref).select(nme.CONSTRUCTOR).appliedToNone
typedExpr(untpd.TypedSplice(icall))(superCtx)
@@ -1555,7 +1553,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.PolyTypeTree => typedPolyTypeTree(tree)(localContext(tree, NoSymbol).setNewScope)
+ case tree: untpd.LambdaTypeTree => typedLambdaTypeTree(tree)(localContext(tree, NoSymbol).setNewScope)
case tree: untpd.ByNameTypeTree => typedByNameTypeTree(tree)
case tree: untpd.TypeBoundsTree => typedTypeBoundsTree(tree)
case tree: untpd.Alternative => typedAlternative(tree, pt)
@@ -1741,7 +1739,7 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
def adapt(tree: Tree, pt: Type, original: untpd.Tree = untpd.EmptyTree)(implicit ctx: Context): Tree = /*>|>*/ track("adapt") /*<|<*/ {
/*>|>*/ ctx.traceIndented(i"adapting $tree of type ${tree.tpe} to $pt", typr, show = true) /*<|<*/ {
if (tree.isDef) interpolateUndetVars(tree, tree.symbol)
- else if (!tree.tpe.widen.isInstanceOf[MethodOrPoly]) interpolateUndetVars(tree, NoSymbol)
+ else if (!tree.tpe.widen.isInstanceOf[LambdaType]) interpolateUndetVars(tree, NoSymbol)
tree.overwriteType(tree.tpe.simplified)
adaptInterpolated(tree, pt, original)
}
@@ -1809,12 +1807,12 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
errorTree(tree,
em"""none of the ${err.overloadedAltsStr(altDenots)}
|match $expectedStr""")
- def hasEmptyParams(denot: SingleDenotation) = denot.info.paramTypess == ListOfNil
+ def hasEmptyParams(denot: SingleDenotation) = denot.info.paramInfoss == ListOfNil
pt match {
case pt: FunProto =>
tryInsertApplyOrImplicit(tree, pt)(noMatches)
case _ =>
- if (altDenots exists (_.info.paramTypess == ListOfNil))
+ if (altDenots exists (_.info.paramInfoss == ListOfNil))
typed(untpd.Apply(untpd.TypedSplice(tree), Nil), pt)
else
noMatches
@@ -1841,7 +1839,7 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
}
def adaptToArgs(wtp: Type, pt: FunProto): Tree = wtp match {
- case _: MethodType | _: PolyType =>
+ case _: MethodOrPoly =>
if (pt.args.lengthCompare(1) > 0 && isUnary(wtp) && ctx.canAutoTuple)
adaptInterpolated(tree, pt.tupled, original)
else
@@ -1871,7 +1869,7 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
case TypeBounds(lo, hi)
if (lo eq hi) || (hi <:< lo)(ctx.fresh.setExploreTyperState) =>
inst(lo)
- case tp: PolyParam =>
+ case tp: TypeParamRef =>
constraint.typeVarOfParam(tp).orElse(tp)
case _ => tp
}
@@ -1886,7 +1884,7 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
adaptInterpolated(tree.withType(wtp.resultType), pt, original)
case wtp: ImplicitMethodType if constrainResult(wtp, followAlias(pt)) =>
val tvarsToInstantiate = tvarsInParams(tree)
- wtp.paramTypes.foreach(instantiateSelected(_, tvarsToInstantiate))
+ wtp.paramInfos.foreach(instantiateSelected(_, tvarsToInstantiate))
val constr = ctx.typerState.constraint
def addImplicitArgs(implicit ctx: Context) = {
val errors = new mutable.ListBuffer[() => String]
@@ -1898,7 +1896,7 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
for (err <- errors) ctx.error(err(), tree.pos.endPos)
tree.withType(wtp.resultType)
}
- val args = (wtp.paramNames, wtp.paramTypes).zipped map { (pname, formal) =>
+ val args = (wtp.paramNames, wtp.paramInfos).zipped map { (pname, formal) =>
def implicitArgError(msg: String => String) =
errors += (() => msg(em"parameter $pname of $methodStr"))
if (errors.nonEmpty) EmptyTree
@@ -1941,11 +1939,11 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
// prioritize method parameter types as parameter types of the eta-expanded closure
0
else defn.functionArity(pt)
- else if (pt eq AnyFunctionProto) wtp.paramTypes.length
+ else if (pt eq AnyFunctionProto) wtp.paramInfos.length
else -1
if (arity >= 0 && !tree.symbol.isConstructor)
typed(etaExpand(tree, wtp, arity), pt)
- else if (wtp.paramTypes.isEmpty)
+ else if (wtp.paramInfos.isEmpty)
adaptInterpolated(tpd.Apply(tree, Nil), pt, EmptyTree)
else if (wtp.isImplicit)
err.typeMismatch(tree, pt)
diff --git a/compiler/src/dotty/tools/dotc/typer/VarianceChecker.scala b/compiler/src/dotty/tools/dotc/typer/VarianceChecker.scala
index d5dd5a024..f88098519 100644
--- a/compiler/src/dotty/tools/dotc/typer/VarianceChecker.scala
+++ b/compiler/src/dotty/tools/dotc/typer/VarianceChecker.scala
@@ -88,10 +88,8 @@ class VarianceChecker()(implicit ctx: Context) {
if (sym.variance != 0 && base.isContainedIn(sym.owner)) checkVarianceOfSymbol(sym)
else if (sym.isAliasType) this(status, sym.info.bounds.hi)
else foldOver(status, tp)
- case tp: MethodType =>
- this(status, tp.resultType) // params will be checked in their TypeDef nodes.
- case tp: PolyType =>
- this(status, tp.resultType) // params will be checked in their ValDef nodes.
+ case tp: MethodOrPoly =>
+ this(status, tp.resultType) // params will be checked in their TypeDef or ValDef nodes.
case AnnotatedType(_, annot) if annot.symbol == defn.UncheckedVarianceAnnot =>
status
//case tp: ClassInfo =>
diff --git a/compiler/src/dotty/tools/dotc/typer/Variances.scala b/compiler/src/dotty/tools/dotc/typer/Variances.scala
index 5a1745930..aeeef0275 100644
--- a/compiler/src/dotty/tools/dotc/typer/Variances.scala
+++ b/compiler/src/dotty/tools/dotc/typer/Variances.scala
@@ -79,12 +79,12 @@ object Variances {
varianceInType(parent)(tparam) & varianceInType(rinfo)(tparam)
case tp: RecType =>
varianceInType(tp.parent)(tparam)
- case tp: MethodType =>
- flip(varianceInTypes(tp.paramTypes)(tparam)) & varianceInType(tp.resultType)(tparam)
+ case tp: MethodOrPoly =>
+ flip(varianceInTypes(tp.paramInfos)(tparam)) & varianceInType(tp.resultType)(tparam)
case ExprType(restpe) =>
varianceInType(restpe)(tparam)
case tp @ HKApply(tycon, args) =>
- def varianceInArgs(v: Variance, args: List[Type], tparams: List[TypeParamInfo]): Variance =
+ def varianceInArgs(v: Variance, args: List[Type], tparams: List[ParamInfo]): Variance =
args match {
case arg :: args1 =>
varianceInArgs(
@@ -94,8 +94,6 @@ object Variances {
v
}
varianceInArgs(varianceInType(tycon)(tparam), args, tycon.typeParams)
- case tp: PolyType =>
- flip(varianceInTypes(tp.paramBounds)(tparam)) & varianceInType(tp.resultType)(tparam)
case AnnotatedType(tp, annot) =>
varianceInType(tp)(tparam) & varianceInAnnot(annot)(tparam)
case tp: AndOrType =>
diff --git a/doc-tool/src/dotty/tools/dottydoc/core/DocASTPhase.scala b/doc-tool/src/dotty/tools/dottydoc/core/DocASTPhase.scala
index cfb66fa56..ad8981ea2 100644
--- a/doc-tool/src/dotty/tools/dottydoc/core/DocASTPhase.scala
+++ b/doc-tool/src/dotty/tools/dottydoc/core/DocASTPhase.scala
@@ -94,10 +94,7 @@ class DocASTPhase extends Phase {
NonEntity
else {
val tparams = t.rhs.tpe match {
- case tp: PolyType => tp.paramRefs.zip(tp.variances).map { case (tp, variance) =>
- val varianceSym = if (variance == 1) "+" else if (variance == -1) "-" else ""
- varianceSym + tp.paramName.show
- }
+ case tp: PolyType => tp.paramNames.map(_.show)
case _ => Nil
}
TypeAliasImpl(sym, annotations(sym), flags(t), t.name.show.split("\\$\\$").last, path(sym), alias(t.rhs.tpe), tparams)
diff --git a/doc-tool/src/dotty/tools/dottydoc/model/factories.scala b/doc-tool/src/dotty/tools/dottydoc/model/factories.scala
index 3e766a990..03f11335e 100644
--- a/doc-tool/src/dotty/tools/dottydoc/model/factories.scala
+++ b/doc-tool/src/dotty/tools/dottydoc/model/factories.scala
@@ -79,7 +79,7 @@ object factories {
case TypeBounds(lo, hi) =>
BoundsReference(expandTpe(lo), expandTpe(hi))
- case t: PolyParam =>
+ case t: TypeParamRef =>
typeRef(t.paramName.show, params = params)
case ExprType(tpe) =>
@@ -106,7 +106,7 @@ object factories {
case ci: ClassInfo =>
typeRef(ci.cls.name.show, query = ci.typeSymbol.showFullName)
- case tl: PolyType =>
+ case tl: TypeLambda =>
expandTpe(tl.resType)
case OrType(left, right) =>
@@ -127,7 +127,7 @@ object factories {
def typeParams(sym: Symbol)(implicit ctx: Context): List[String] =
sym.info match {
- case pt: PolyType => // TODO: not sure if this case is needed anymore
+ case pt: TypeLambda => // TODO: not sure if this case is needed anymore
pt.paramNames.map(_.show.split("\\$").last)
case ClassInfo(_, _, _, decls, _) =>
decls.iterator
@@ -156,11 +156,11 @@ object factories {
constructors(sym).head
def paramLists(tpe: Type)(implicit ctx: Context): List[ParamList] = tpe match {
- case pt: PolyType =>
+ case pt: TypeLambda =>
paramLists(pt.resultType)
case mt: MethodType =>
- ParamListImpl(mt.paramNames.zip(mt.paramTypes).map { case (name, tpe) =>
+ ParamListImpl(mt.paramNames.zip(mt.paramInfos).map { case (name, tpe) =>
NamedReference(
name.decode.toString,
returnType(tpe),
@@ -169,13 +169,13 @@ object factories {
)
}, mt.isImplicit) :: paramLists(mt.resultType)
- case mp: MethodParam =>
+ case mp: TermParamRef =>
paramLists(mp.underlying)
case annot: AnnotatedType =>
paramLists(annot.tpe)
- case (_: PolyParam | _: RefinedType | _: TypeRef | _: ThisType |
+ case (_: TypeParamRef | _: RefinedType | _: TypeRef | _: ThisType |
_: ExprType | _: OrType | _: AndType | _: HKApply |
_: TermRef | _: ConstantType) =>
Nil // return types should not be in the paramlist