Skip to content

Commit 241e02d

Browse files
committed
Fix subtle rendering issues with CC in scaladoc
The information that we are within a capture context was not propperly passed to recursive calls of `inner`, which caused some types to be rendered incorrectly. This was due to a bad interplay with implicit parameters and default arguments.
1 parent 005993a commit 241e02d

File tree

1 file changed

+15
-13
lines changed

1 file changed

+15
-13
lines changed

scaladoc/src/dotty/tools/scaladoc/tasty/TypesSupport.scala

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -135,9 +135,9 @@ trait TypesSupport:
135135
case t @ AppliedType(base, args) if t.isFunctionType =>
136136
functionType(base, args)(using inCC = Some(refs))
137137
case t : Refinement if t.isFunctionType =>
138-
inner(base)(using inCC = Some(refs))
138+
inner(base)(using indent = indent, skipTypeSuffix = skipTypeSuffix, inCC = Some(refs))
139139
case t if t.isCapSet => emitCaptureSet(refs, omitCap = false)
140-
case _ => inner(base) ++ emitCapturing(refs)
140+
case t => inner(base) ++ emitCapturing(refs)
141141
case AnnotatedType(tpe, _) =>
142142
inner(tpe)
143143
case tl @ TypeLambda(params, paramBounds, AppliedType(tpe, args))
@@ -159,6 +159,8 @@ trait TypesSupport:
159159
inner(Refinement(at, "apply", mt))
160160

161161
case r: Refinement => { //(parent, name, info)
162+
val inCC0 = inCC
163+
given Option[List[TypeRepr]] = None // do not propagate capture set beyond this point
162164
def getRefinementInformation(t: TypeRepr): List[TypeRepr] = t match {
163165
case r: Refinement => getRefinementInformation(r.parent) :+ r
164166
case t => List(t)
@@ -214,16 +216,16 @@ trait TypesSupport:
214216
val arrPrefix = if isCtx then "?" else ""
215217
val arrow =
216218
if ccEnabled then
217-
inCC match
219+
inCC0 match
218220
case None | Some(Nil) => keyword(arrPrefix + "->").l
219221
case Some(List(c)) if c.isCaptureRoot => keyword(arrPrefix + "=>").l
220222
case Some(refs) => keyword(arrPrefix + "->") :: emitCaptureSet(refs)
221223
else keyword(arrPrefix + "=>").l
222-
val resType = inner(m.resType)(using inCC = None)
224+
val resType = inner(m.resType)
223225
paramList ++ (plain(" ") :: arrow) ++ (plain(" ") :: resType)
224226
else
225227
val sym = defn.FunctionClass(m.paramTypes.length, isCtx)
226-
inner(sym.typeRef.appliedTo(m.paramTypes :+ m.resType))(using inCC = None)
228+
inner(sym.typeRef.appliedTo(m.paramTypes :+ m.resType))
227229
case other => noSupported("Dependent function type without MethodType refinement")
228230
}
229231

@@ -280,7 +282,7 @@ trait TypesSupport:
280282
tpe(tp.typeSymbol)
281283
case _: TermRef | _: ParamRef =>
282284
val suffix = if tp.typeSymbol == Symbol.noSymbol then tpe(typeName).l else tpe(tp.typeSymbol)
283-
inner(qual)(using skipTypeSuffix = true) ++ plain(".").l ++ suffix
285+
inner(qual)(using skipTypeSuffix = true, inCC = inCC) ++ plain(".").l ++ suffix
284286
case ThisType(tr) =>
285287
findSupertype(elideThis, tr.typeSymbol) match
286288
case Some((sym, AppliedType(tr2, args))) =>
@@ -294,7 +296,7 @@ trait TypesSupport:
294296
case _ => tpe(tp.typeSymbol)
295297
case Some(_) => tpe(tp.typeSymbol)
296298
case None =>
297-
val sig = inParens(inner(qual)(using skipTypeSuffix = true), shouldWrapInParens(qual, tp, true))
299+
val sig = inParens(inner(qual)(using skipTypeSuffix = true, inCC = inCC), shouldWrapInParens(qual, tp, true))
298300
sig ++ plain(".").l ++ tpe(tp.typeSymbol)
299301
case _ =>
300302
val sig = inParens(inner(qual), shouldWrapInParens(qual, tp, true))
@@ -304,7 +306,7 @@ trait TypesSupport:
304306
case tr @ TermRef(qual, typeName) =>
305307
val prefix = qual match
306308
case t if skipPrefix(t, elideThis) => Nil
307-
case tp => inner(tp)(using skipTypeSuffix = true) ++ plain(".").l
309+
case tp => inner(tp)(using skipTypeSuffix = true, inCC = inCC) ++ plain(".").l
308310
val suffix = if skipTypeSuffix then Nil else List(plain("."), keyword("type"))
309311
val typeSig = tr.termSymbol.tree match
310312
case vd: ValDef if tr.termSymbol.flags.is(Flags.Module) =>
@@ -323,9 +325,9 @@ trait TypesSupport:
323325
val spaces = " " * (indent)
324326
val casesTexts = cases.flatMap {
325327
case MatchCase(from, to) =>
326-
keyword(caseSpaces + "case ").l ++ inner(from) ++ keyword(" => ").l ++ inner(to)(using indent = indent + 2) ++ plain("\n").l
328+
keyword(caseSpaces + "case ").l ++ inner(from) ++ keyword(" => ").l ++ inner(to)(using indent = indent + 2, inCC = inCC) ++ plain("\n").l
327329
case TypeLambda(_, _, MatchCase(from, to)) =>
328-
keyword(caseSpaces + "case ").l ++ inner(from) ++ keyword(" => ").l ++ inner(to)(using indent = indent + 2) ++ plain("\n").l
330+
keyword(caseSpaces + "case ").l ++ inner(from) ++ keyword(" => ").l ++ inner(to)(using indent = indent + 2, inCC = inCC) ++ plain("\n").l
329331
}
330332
inner(sc) ++ keyword(" match ").l ++ plain("{\n").l ++ casesTexts ++ plain(spaces + "}").l
331333

@@ -359,7 +361,7 @@ trait TypesSupport:
359361
): SSignature =
360362
import reflect._
361363
val arrow = plain(" ") :: (emitFunctionArrow(using qctx)(funTy, inCC) ++ plain(" ").l)
362-
given Option[List[TypeRepr]] = None // FIXME: this is ugly
364+
given Option[List[TypeRepr]] = None // do not propagate capture set beyond this point
363365
args match
364366
case Nil => Nil
365367
case List(rtpe) => plain("()").l ++ arrow ++ inner(rtpe)
@@ -389,14 +391,14 @@ trait TypesSupport:
389391
private def typeBoundsTreeOfHigherKindedType(using Quotes)(low: reflect.TypeRepr, high: reflect.TypeRepr)(using elideThis: reflect.ClassDef, inCC: Option[List[reflect.TypeRepr]]) =
390392
import reflect._
391393
def regularTypeBounds(low: TypeRepr, high: TypeRepr) =
392-
if low == high then keyword(" = ").l ++ inner(low)(using elideThis)
394+
if low == high then keyword(" = ").l ++ inner(low)(using elideThis, inCC = inCC)
393395
else typeBound(low, low = true)(using elideThis) ++ typeBound(high, low = false)(using elideThis)
394396
high.match
395397
case TypeLambda(params, paramBounds, resType) =>
396398
if resType.typeSymbol == defn.AnyClass then
397399
plain("[").l ++ commas(params.zip(paramBounds).map { (name, typ) =>
398400
val normalizedName = if name.matches("_\\$\\d*") then "_" else name
399-
tpe(normalizedName)(using inCC).l ++ inner(typ)(using elideThis)
401+
tpe(normalizedName)(using inCC).l ++ inner(typ)(using elideThis, inCC = inCC)
400402
}) ++ plain("]").l
401403
else
402404
regularTypeBounds(low, high)

0 commit comments

Comments
 (0)