Skip to content

Commit 725ce12

Browse files
committed
Support rendering of .rd capabilities
1 parent 14833f5 commit 725ce12

File tree

3 files changed

+26
-8
lines changed

3 files changed

+26
-8
lines changed

local/project/dummy/sep-pairs.scala

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,3 +21,7 @@ def copyPair(@consume @use p: Pair[Ref^, Ref^]): Pair[Ref^, Ref^] =
2121
val y: Ref^{p.snd*} = p.snd
2222
Pair(x, y)
2323

24+
trait TestRd:
25+
def copyPair(@use p: Pair[Ref^, Ref^]): Pair[Ref^{p.fst*}, Ref^{p.snd*}]
26+
def rdPair(@consume p: Pair[Ref^, Ref^]): Int ->{p.fst*.rd} Int
27+
val rdPairV: (p: Pair[Ref^, Ref^]) => Int ->{p.fst*, p.snd*.rd} Int

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

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,9 @@ extension (using qctx: Quotes)(ann: qctx.reflect.Symbol)
6666

6767
def isReachCapabilityAnnot: Boolean =
6868
ann == CaptureDefs.ReachCapabilityAnnot
69+
70+
def isReadOnlyCapabilityAnnot: Boolean =
71+
ann == CaptureDefs.ReadOnlyCapabilityAnnot
6972
end extension
7073

7174
extension (using qctx: Quotes)(tpe: qctx.reflect.TypeRepr) // FIXME clean up and have versions on Symbol for those
@@ -113,6 +116,15 @@ object ReachCapability:
113116
case _ => None
114117
end ReachCapability
115118

119+
object ReadOnlyCapability:
120+
def unapply(using qctx: Quotes)(ty: qctx.reflect.TypeRepr): Option[qctx.reflect.TypeRepr] =
121+
import qctx.reflect._
122+
ty match
123+
case AnnotatedType(base, Apply(Select(New(annot), _), Nil)) if annot.symbol.isReadOnlyCapabilityAnnot =>
124+
Some(base)
125+
case _ => None
126+
end ReadOnlyCapability
127+
116128
/** Decompose capture sets in the union-type-encoding into the sequence of atomic `TypeRepr`s.
117129
* Returns `None` if the type is not a capture set.
118130
*/
@@ -122,11 +134,12 @@ def decomposeCaptureRefs(using qctx: Quotes)(typ0: qctx.reflect.TypeRepr): Optio
122134
def include(t: TypeRepr): Boolean = { buffer += t; true }
123135
def traverse(typ: TypeRepr): Boolean =
124136
typ match
125-
case OrType(t1, t2) => traverse(t1) && traverse(t2)
126-
case t @ ThisType(_) => include(t)
127-
case t @ TermRef(_, _) => include(t)
128-
case t @ ParamRef(_, _) => include(t)
129-
case t @ ReachCapability(_) => include(t)
137+
case OrType(t1, t2) => traverse(t1) && traverse(t2)
138+
case t @ ThisType(_) => include(t)
139+
case t @ TermRef(_, _) => include(t)
140+
case t @ ParamRef(_, _) => include(t)
141+
case t @ ReachCapability(_) => include(t)
142+
case t @ ReadOnlyCapability(_) => include(t)
130143
case t if t.typeSymbol == defn.NothingClass => true
131144
// TODO: are atoms only ever the above? Then we could refine the return type
132145
case _ => report.warning(s"Unexpected type tree $typ while trying to extract capture references from $typ0"); false // TODO remove warning eventually

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

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -460,9 +460,10 @@ trait TypesSupport:
460460
private def renderCapability(using Quotes)(ref: reflect.TypeRepr)(using elideThis: reflect.ClassDef): SSignature =
461461
import reflect._
462462
ref match
463-
case ReachCapability(c) => renderCapability(c) :+ Keyword("*")
464-
case ThisType(_) => List(Keyword("this"))
465-
case t => inner(t)(using skipTypeSuffix = true, inCC = Some(Nil))
463+
case ReachCapability(c) => renderCapability(c) :+ Keyword("*")
464+
case ReadOnlyCapability(c) => renderCapability(c) :+ Keyword(".rd")
465+
case ThisType(_) => List(Keyword("this"))
466+
case t => inner(t)(using skipTypeSuffix = true, inCC = Some(Nil))
466467

467468
private def renderCaptureSet(using Quotes)(refs: List[reflect.TypeRepr])(using elideThis: reflect.ClassDef): SSignature =
468469
import dotty.tools.scaladoc.tasty.NameNormalizer._

0 commit comments

Comments
 (0)