Open
Description
The current definition of the internal @retains
annotation is this one:
/** An annotation that indicates capture of a set of references under -Ycc.
*
* T @retains(x, y, z)
*
* is the internal representation used for the capturing type
*
* T ^ {x, y, z}
*
* The annotation can also be written explicitly if one wants to avoid the
* non-standard capturing type syntax.
*/
@experimental
class retains(xs: (Any@retainsArg)*) extends annotation.StaticAnnotation
I wonder whether it would not be better to define it differently:
class retains[C] extends annotation.StaticAnnotation
Here, C
would be a type representing a capture set. Since we don't have sets in Tasty, we can represent it as a union type. For instance,
T ^ {x, y.rd, z*, X}
would be represented as
T @retains[
x.type
| y.type @readOnlyCapability
| z.type @reachCapability
| X]
In other words, it's exactly the representation we use for capture sets, but as a union type.
Advantages:
- No need to convert to and from an intermediate representation.
- More compact representation since we do not need trees
- Possibility to better hash those annotated types. I noted that in larger projects we create a huge number of
@retains
-annotated types because trees use identity hash codes.
Downsides:
- We lose positions for error reporting. The most common errors would be "x cannot be tracked since its capture set is empty". Or "x is redundant because it is subsumed by y`". In both cases we can only underline the whole annotation, not the specific capability.
- ?