Skip to content

Commit 94fd10c

Browse files
bracevacnatsukagami
authored andcommitted
Fix rendering of capture variables in paramlists
1 parent 07e9bda commit 94fd10c

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
@@ -3,7 +3,7 @@ package dotty.tools.scaladoc.tasty
33
import dotty.tools.scaladoc._
44
import dotty.tools.scaladoc.{Signature => DSignature}
55

6-
import dotty.tools.scaladoc.cc.CaptureDefs
6+
import dotty.tools.scaladoc.cc.*
77

88
import scala.quoted._
99

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

469+
val isCaptureVar = ccEnabled && argument.derivesFromCapSet
470+
469471
val name = symbol.normalizedName
470472
val normalizedName = if name.matches("_\\$\\d*") then "_" else name
471473
val boundsSignature = argument.rhs.asSignature(classDef, symbol.owner)
@@ -481,7 +483,8 @@ trait ClassLikeSupport:
481483
variancePrefix,
482484
normalizedName,
483485
symbol.dri,
484-
signature
486+
signature,
487+
isCaptureVar,
485488
)
486489

487490
def parseTypeDef(typeDef: TypeDef, classDef: ClassDef): Member =
@@ -491,15 +494,13 @@ trait ClassLikeSupport:
491494
case LambdaTypeTree(params, body) => isTreeAbstract(body)
492495
case _ => false
493496
}
497+
498+
val isCaptureVar = ccEnabled && typeDef.derivesFromCapSet
499+
494500
val (generics, tpeTree) = typeDef.rhs match
495501
case LambdaTypeTree(params, body) => (params.map(mkTypeArgument(_, classDef)), body)
496502
case tpe => (Nil, tpe)
497503

498-
val isCaptureVar = ccEnabled && typeDef.rhs.match
499-
case t: TypeTree => t.tpe.derivesFrom(CaptureDefs.Caps_CapSet)
500-
case t: TypeBoundsTree => t.tpe.derivesFrom(CaptureDefs.Caps_CapSet)
501-
case _ => false
502-
503504
val defaultKind = Kind.Type(!isTreeAbstract(typeDef.rhs), symbol.isOpaque, generics, isCaptureVar).asInstanceOf[Kind.Type]
504505
val kind = if symbol.flags.is(Flags.Enum) then Kind.EnumCase(defaultKind)
505506
else defaultKind

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

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,8 @@ trait TypesSupport:
156156
case tl @ TypeLambda(params, paramBounds, resType) =>
157157
plain("[").l ++ commas(params.zip(paramBounds).map { (name, typ) =>
158158
val normalizedName = if name.matches("_\\$\\d*") then "_" else name
159-
tpe(normalizedName).l ++ inner(typ, skipThisTypePrefix)
159+
val suffix = if ccEnabled && typ.derivesFrom(CaptureDefs.Caps_CapSet) then List(Keyword("^")) else Nil
160+
tpe(normalizedName).l ++ suffix ++ inner(typ, skipThisTypePrefix)
160161
}) ++ plain("]").l
161162
++ keyword(" =>> ").l
162163
++ inner(resType, skipThisTypePrefix)
@@ -174,8 +175,11 @@ trait TypesSupport:
174175
}
175176

176177
def getParamBounds(t: PolyType): SSignature = commas(
177-
t.paramNames.zip(t.paramBounds.map(inner(_, skipThisTypePrefix)))
178-
.map(b => tpe(b(0)).l ++ b(1))
178+
t.paramNames.zip(t.paramBounds.map(inner(_, skipThisTypePrefix))).zipWithIndex
179+
.map { case ((name, bound), idx) =>
180+
val suffix = if ccEnabled && t.param(idx).derivesFrom(CaptureDefs.Caps_CapSet) then List(Keyword("^")) else Nil
181+
tpe(name).l ++ suffix ++ bound
182+
}
179183
)
180184

181185
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)