Skip to content

Change representation of retains annotation? #22842

Open
@odersky

Description

@odersky

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.
  • ?

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions