aboutsummaryrefslogtreecommitdiff
path: root/src/dotty/tools/dotc/printing/RefinedPrinter.scala
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2015-12-05 18:21:56 +0100
committerMartin Odersky <odersky@gmail.com>2015-12-06 16:17:43 +0100
commit56dd29d3d3b0524d03a93965160e651a5d757b92 (patch)
treeb0076e97e3e51aab559f27c12c0e7adbab4203c1 /src/dotty/tools/dotc/printing/RefinedPrinter.scala
parentd186a333c55b738ee35a81cb185da2f3e7ab4742 (diff)
downloaddotty-56dd29d3d3b0524d03a93965160e651a5d757b92.tar.gz
dotty-56dd29d3d3b0524d03a93965160e651a5d757b92.tar.bz2
dotty-56dd29d3d3b0524d03a93965160e651a5d757b92.zip
Fix printing of type lambdas
Diffstat (limited to 'src/dotty/tools/dotc/printing/RefinedPrinter.scala')
-rw-r--r--src/dotty/tools/dotc/printing/RefinedPrinter.scala35
1 files changed, 26 insertions, 9 deletions
diff --git a/src/dotty/tools/dotc/printing/RefinedPrinter.scala b/src/dotty/tools/dotc/printing/RefinedPrinter.scala
index dd485ad60..e015fd4cf 100644
--- a/src/dotty/tools/dotc/printing/RefinedPrinter.scala
+++ b/src/dotty/tools/dotc/printing/RefinedPrinter.scala
@@ -19,7 +19,7 @@ class RefinedPrinter(_ctx: Context) extends PlainPrinter(_ctx) {
/** A stack of enclosing DefDef, TypeDef, or ClassDef, or ModuleDefs nodes */
private var enclosingDef: untpd.Tree = untpd.EmptyTree
-
+ private var lambdaNestingLevel: Int = 0
private var myCtx: Context = _ctx
override protected[this] implicit def ctx: Context = myCtx
@@ -116,18 +116,35 @@ class RefinedPrinter(_ctx: Context) extends PlainPrinter(_ctx) {
if (defn.isFunctionClass(cls)) return toTextFunction(args)
if (defn.isTupleClass(cls)) return toTextTuple(args)
return (toTextLocal(tycon) ~ "[" ~ Text(args map argText, ", ") ~ "]").close
- case TypeLambda(variances, argBoundss, body) =>
- val paramNames = variances.indices.toList.map("X" + _)
+ case tp @ TypeLambda(variances, argBoundss, body) =>
+ val prefix = ((('X' - 'A') + lambdaNestingLevel) % 26 + 'A').toChar
+ val paramNames = variances.indices.toList.map(prefix.toString + _)
val instantiate = new TypeMap {
+ def contains(tp1: Type, tp2: Type): Boolean =
+ tp1.eq(tp2) || {
+ tp1.stripTypeVar match {
+ case RefinedType(parent, _) => contains(parent, tp2)
+ case _ => false
+ }
+ }
def apply(t: Type): Type = t match {
- case TypeRef(RefinedThis(rt), name) if name.isHkArgName && rt.eq(tp) =>
- TypeRef.withFixedSym(
- NoPrefix, paramNames(name.hkArgIndex).toTypeName, defn.AnyClass)
- case _ => mapOver(t)
+ case TypeRef(RefinedThis(rt), name) if name.isHkArgName && contains(tp, rt) =>
+ // Make up a name that prints as "Xi". Need to be careful we do not
+ // accidentally unique-hash to something else. That's why we can't
+ // use prefix = NoPrefix or a WithFixedSym instance.
+ TypeRef.withSymAndName(
+ defn.EmptyPackageClass.thisType, defn.AnyClass,
+ paramNames(name.hkArgIndex).toTypeName)
+ case _ =>
+ mapOver(t)
}
}
- return typeLambdaText(paramNames, variances, argBoundss,
- instantiate(body).argInfo)
+ val instArgs = argBoundss.map(instantiate).asInstanceOf[List[TypeBounds]]
+ val instBody = instantiate(body).dropAlias
+ lambdaNestingLevel += 1
+ try
+ return typeLambdaText(paramNames, variances, instArgs, instBody)
+ finally lambdaNestingLevel -=1
case tp: TypeRef =>
val hideType = tp.symbol is AliasPreferred
if (hideType && !ctx.phase.erasedTypes && !tp.symbol.isCompleting) {