Skip to content

Commit 4a7b3d3

Browse files
committed
Fix printing of type lambdas
1 parent df53e4d commit 4a7b3d3

File tree

1 file changed

+26
-9
lines changed

1 file changed

+26
-9
lines changed

src/dotty/tools/dotc/printing/RefinedPrinter.scala

Lines changed: 26 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ class RefinedPrinter(_ctx: Context) extends PlainPrinter(_ctx) {
1919

2020
/** A stack of enclosing DefDef, TypeDef, or ClassDef, or ModuleDefs nodes */
2121
private var enclosingDef: untpd.Tree = untpd.EmptyTree
22-
22+
private var lambdaNestingLevel: Int = 0
2323
private var myCtx: Context = _ctx
2424
override protected[this] implicit def ctx: Context = myCtx
2525

@@ -116,18 +116,35 @@ class RefinedPrinter(_ctx: Context) extends PlainPrinter(_ctx) {
116116
if (defn.isFunctionClass(cls)) return toTextFunction(args)
117117
if (defn.isTupleClass(cls)) return toTextTuple(args)
118118
return (toTextLocal(tycon) ~ "[" ~ Text(args map argText, ", ") ~ "]").close
119-
case TypeLambda(variances, argBoundss, body) =>
120-
val paramNames = variances.indices.toList.map("X" + _)
119+
case tp @ TypeLambda(variances, argBoundss, body) =>
120+
val prefix = ((('X' - 'A') + lambdaNestingLevel) % 26 + 'A').toChar
121+
val paramNames = variances.indices.toList.map(prefix.toString + _)
121122
val instantiate = new TypeMap {
123+
def contains(tp1: Type, tp2: Type): Boolean =
124+
tp1.eq(tp2) || {
125+
tp1.stripTypeVar match {
126+
case RefinedType(parent, _) => contains(parent, tp2)
127+
case _ => false
128+
}
129+
}
122130
def apply(t: Type): Type = t match {
123-
case TypeRef(RefinedThis(rt), name) if name.isHkArgName && rt.eq(tp) =>
124-
TypeRef.withFixedSym(
125-
NoPrefix, paramNames(name.hkArgIndex).toTypeName, defn.AnyClass)
126-
case _ => mapOver(t)
131+
case TypeRef(RefinedThis(rt), name) if name.isHkArgName && contains(tp, rt) =>
132+
// Make up a name that prints as "Xi". Need to be careful we do not
133+
// accidentally unique-hash to something else. That's why we can't
134+
// use prefix = NoPrefix or a WithFixedSym instance.
135+
TypeRef.withSymAndName(
136+
defn.EmptyPackageClass.thisType, defn.AnyClass,
137+
paramNames(name.hkArgIndex).toTypeName)
138+
case _ =>
139+
mapOver(t)
127140
}
128141
}
129-
return typeLambdaText(paramNames, variances, argBoundss,
130-
instantiate(body).argInfo)
142+
val instArgs = argBoundss.map(instantiate).asInstanceOf[List[TypeBounds]]
143+
val instBody = instantiate(body).dropAlias
144+
lambdaNestingLevel += 1
145+
try
146+
return typeLambdaText(paramNames, variances, instArgs, instBody)
147+
finally lambdaNestingLevel -=1
131148
case tp: TypeRef =>
132149
val hideType = tp.symbol is AliasPreferred
133150
if (hideType && !ctx.phase.erasedTypes && !tp.symbol.isCompleting) {

0 commit comments

Comments
 (0)