Skip to content

Commit a8074e3

Browse files
bracevacnatsukagami
authored andcommitted
Support rendering of .rd capabilities
1 parent 80e6d50 commit a8074e3

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
@@ -478,9 +478,10 @@ trait TypesSupport:
478478
): SSignature =
479479
import reflect._
480480
ref match
481-
case ReachCapability(c) => renderCapability(c, skipThisTypePrefix) :+ Keyword("*")
482-
case ThisType(_) => List(Keyword("this"))
483-
case t => inner(t, skipThisTypePrefix)(using skipTypeSuffix = true, inCC = Some(Nil))
481+
case ReachCapability(c) => renderCapability(c, skipThisTypePrefix) :+ Keyword("*")
482+
case ReadOnlyCapability(c) => renderCapability(c, skipThisTypePrefix) :+ Keyword(".rd")
483+
case ThisType(_) => List(Keyword("this"))
484+
case t => inner(t, skipThisTypePrefix)(using skipTypeSuffix = true, inCC = Some(Nil))
484485

485486
private def renderCaptureSet(using Quotes)(refs: List[reflect.TypeRepr], skipThisTypePrefix: Boolean)(
486487
using elideThis: reflect.ClassDef, originalOwner: reflect.Symbol

0 commit comments

Comments
 (0)