Skip to content

Commit 005993a

Browse files
committed
Fix rendering of capture variables in paramlists
1 parent 7b50cf8 commit 005993a

File tree

6 files changed

+34
-14
lines changed

6 files changed

+34
-14
lines changed

local/project/dummy/capturevars.scala

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,15 +10,18 @@ trait Test:
1010
type Ordinary2 >: Int <: String
1111
type T[-C^ >: {a,b}]
1212
type U[+C^]
13+
type Foo = [C^ >: {a,b} <: {a,b,cap}] =>> AnyRef^{C}
1314
type C^
1415
type D^ >: {C} <: {a,b}
1516
type E^ <: C
1617
type F^ <: {D,E}
1718
type G^ = C
19+
type H^ = {C}
1820
def foo[C^ >: {a,b}](x: T[C]): Unit
1921
def bar(x: T[{a,b}]): Unit
2022
def baz(x: T[{a,b,caps.cap}]): Unit
2123
def foo2[C^](x: U[C]): Unit
2224
def bar2(x: U[{a,b,cap}]): Unit
2325
def baz2(x: U[{caps.cap}]): Unit
24-
def test[E^, F^ >: {caps.cap} <: {}](x: T[{E,a,b}], y: U[F]): Unit
26+
def test[E^, F^ >: {caps.cap} <: {}, G <: [C^ >: {a,b} <: {a,b}] =>> AnyRef^{C}](x: T[{E,a,b}], y: U[F]): Unit
27+
val poly: [C^ >: {a,b}] => (f: () ->{C} Unit) -> Int ->{C} Unit

scaladoc/src/dotty/tools/scaladoc/api.scala

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,8 @@ case class TypeParameter(
121121
variance: "" | "+" | "-",
122122
name: String,
123123
dri: DRI,
124-
signature: Signature
124+
signature: Signature,
125+
isCaptureVar: Boolean = false // under capture checking
125126
)
126127

127128
case class Link(name: String, dri: DRI)

scaladoc/src/dotty/tools/scaladoc/cc/CaptureOps.scala

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,15 @@ extension (using qctx: Quotes)(tpe: qctx.reflect.TypeRepr) // FIXME clean up and
107107
case _ => false
108108
end extension
109109

110+
extension (using qctx: Quotes)(typedef: qctx.reflect.TypeDef)
111+
def derivesFromCapSet: Boolean =
112+
import qctx.reflect.*
113+
typedef.rhs.match
114+
case t: TypeTree => t.tpe.derivesFrom(CaptureDefs.Caps_CapSet)
115+
case t: TypeBoundsTree => t.tpe.derivesFrom(CaptureDefs.Caps_CapSet)
116+
case _ => false
117+
end extension
118+
110119
/** Matches `import scala.language.experimental.captureChecking` */
111120
object CCImport:
112121
def unapply(using qctx: Quotes)(tree: qctx.reflect.Tree): Boolean =

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

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import dotty.tools.scaladoc._
55
import dotty.tools.scaladoc.{Signature => DSignature}
66
import dotty.tools.scaladoc.Inkuire
77

8-
import dotty.tools.scaladoc.cc.CaptureDefs
8+
import dotty.tools.scaladoc.cc.*
99

1010
import scala.quoted._
1111

@@ -466,6 +466,8 @@ trait ClassLikeSupport:
466466
else if argument.symbol.flags.is(Flags.Contravariant) then "-"
467467
else ""
468468

469+
val isCaptureVar = ccEnabled && argument.derivesFromCapSet
470+
469471
val name = argument.symbol.normalizedName
470472
val normalizedName = if name.matches("_\\$\\d*") then "_" else name
471473
val boundsSignature = memberInfo.get(name).fold(argument.rhs.asSignature(classDef))(_.asSignature(classDef))
@@ -479,7 +481,8 @@ trait ClassLikeSupport:
479481
variancePrefix,
480482
normalizedName,
481483
argument.symbol.dri,
482-
signature
484+
signature,
485+
isCaptureVar,
483486
)
484487

485488
def parseTypeDef(typeDef: TypeDef, classDef: ClassDef): Member =
@@ -488,15 +491,13 @@ trait ClassLikeSupport:
488491
case LambdaTypeTree(params, body) => isTreeAbstract(body)
489492
case _ => false
490493
}
494+
495+
val isCaptureVar = ccEnabled && typeDef.derivesFromCapSet
496+
491497
val (generics, tpeTree) = typeDef.rhs match
492498
case LambdaTypeTree(params, body) => (params.map(mkTypeArgument(_, classDef)), body)
493499
case tpe => (Nil, tpe)
494500

495-
val isCaptureVar = ccEnabled && typeDef.rhs.match
496-
case t: TypeTree => t.tpe.derivesFrom(CaptureDefs.Caps_CapSet)
497-
case t: TypeBoundsTree => t.tpe.derivesFrom(CaptureDefs.Caps_CapSet)
498-
case _ => false
499-
500501
val defaultKind = Kind.Type(!isTreeAbstract(typeDef.rhs), typeDef.symbol.isOpaque, generics, isCaptureVar).asInstanceOf[Kind.Type]
501502
val kind = if typeDef.symbol.flags.is(Flags.Enum) then Kind.EnumCase(defaultKind)
502503
else defaultKind

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

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,8 @@ trait TypesSupport:
146146
case tl @ TypeLambda(params, paramBounds, resType) =>
147147
plain("[").l ++ commas(params.zip(paramBounds).map { (name, typ) =>
148148
val normalizedName = if name.matches("_\\$\\d*") then "_" else name
149-
tpe(normalizedName).l ++ inner(typ)
149+
val suffix = if ccEnabled && typ.derivesFrom(CaptureDefs.Caps_CapSet) then List(Keyword("^")) else Nil
150+
tpe(normalizedName).l ++ suffix ++ inner(typ)
150151
}) ++ plain("]").l
151152
++ keyword(" =>> ").l
152153
++ inner(resType)
@@ -164,8 +165,11 @@ trait TypesSupport:
164165
}
165166

166167
def getParamBounds(t: PolyType): SSignature = commas(
167-
t.paramNames.zip(t.paramBounds.map(inner(_)))
168-
.map(b => tpe(b(0)).l ++ b(1))
168+
t.paramNames.zip(t.paramBounds.map(inner(_))).zipWithIndex
169+
.map { case ((name, bound), idx) =>
170+
val suffix = if ccEnabled && t.param(idx).derivesFrom(CaptureDefs.Caps_CapSet) then List(Keyword("^")) else Nil
171+
tpe(name).l ++ suffix ++ bound
172+
}
169173
)
170174

171175
def getParamList(m: MethodType): SSignature =

scaladoc/src/dotty/tools/scaladoc/translators/ScalaSignatureUtils.scala

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,9 @@ case class SignatureBuilder(content: Signature = Nil) extends ScalaSignatureUtil
66
def name(str: String, dri: DRI, isCaptureVar: Boolean = false/*under CC*/): SignatureBuilder =
77
val suffix = if isCaptureVar then List(Keyword("^")) else Nil
88
copy(content = content ++ (Name(str, dri) :: suffix))
9-
def tpe(text: String, dri: Option[DRI]): SignatureBuilder = copy(content = content :+ Type(text, dri))
9+
def tpe(text: String, dri: Option[DRI], isCaptureVar: Boolean = false/*under CC*/): SignatureBuilder =
10+
val suffix = if isCaptureVar then List(Keyword("^")) else Nil
11+
copy(content = content ++ (Type(text, dri) :: suffix))
1012
def keyword(str: String): SignatureBuilder = copy(content = content :+ Keyword(str))
1113
def tpe(text: String, dri: DRI): SignatureBuilder = copy(content = content :+ Type(text, Some(dri)))
1214
def signature(s: Signature): SignatureBuilder = copy(content = content ++ s)
@@ -92,7 +94,7 @@ case class SignatureBuilder(content: Signature = Nil) extends ScalaSignatureUtil
9294
}
9395

9496
def typeParamList(on: TypeParameterList) = list(on.toList, List(Plain("[")), List(Plain("]"))){ (bdr, e) =>
95-
bdr.annotationsInline(e).keyword(e.variance).tpe(e.name, Some(e.dri)).signature(e.signature)
97+
bdr.annotationsInline(e).keyword(e.variance).tpe(e.name, Some(e.dri), e.isCaptureVar).signature(e.signature)
9698
}
9799

98100
def functionTermParameters(paramss: Seq[TermParameterList]) =

0 commit comments

Comments
 (0)