diff options
author | Martin Odersky <odersky@gmail.com> | 2015-12-05 18:21:56 +0100 |
---|---|---|
committer | Martin Odersky <odersky@gmail.com> | 2015-12-06 16:17:43 +0100 |
commit | 56dd29d3d3b0524d03a93965160e651a5d757b92 (patch) | |
tree | b0076e97e3e51aab559f27c12c0e7adbab4203c1 /src/dotty/tools/dotc/printing/RefinedPrinter.scala | |
parent | d186a333c55b738ee35a81cb185da2f3e7ab4742 (diff) | |
download | dotty-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.scala | 35 |
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) { |