Capabilities

dotty.tools.dotc.cc.Capabilities
object Capabilities

Capabilities are members of capture sets. They partially overlap with types as shown in the trait hierarchy below.

Capability --+-- RootCapabilty -----+-- GlobalCap | +-- FreshCap | +-- ResultCap | +-- CoreCapability ----+-- ObjectCapability --+-- TermRef | | +-- ThisType | | +-- TermParamRef | | | +-- SetCapability -----+-- TypeRef | +-- TypeParamRef | +-- DerivedCapability -+-- ReadOnly +-- Reach +-- Maybe

All CoreCapabilities are Types, or, more specifically instances of TypeProxy.

Attributes

Graph
Supertypes
class Object
trait Matchable
class Any
Self type

Members list

Type members

Classlikes

class CapToFresh(origin: Origin)(using x$2: Context) extends BiTypeMap, FollowAliasesMap

Map each occurrence of cap to a different Fresh instance Exception: CapSet^ stays as it is.

Map each occurrence of cap to a different Fresh instance Exception: CapSet^ stays as it is.

Attributes

Supertypes
trait BiTypeMap
class TypeMap
trait Type => Type
class Object
trait Matchable
class Any
Show all
Self type
trait Capability extends Showable

A trait for references in CaptureSets. These can be NamedTypes, ThisTypes or ParamRefs, as well as three kinds of AnnotatedTypes representing readOnly, reach, and maybe capabilities. If there are several annotations they come with an order: * first, .rd next, ? last.

A trait for references in CaptureSets. These can be NamedTypes, ThisTypes or ParamRefs, as well as three kinds of AnnotatedTypes representing readOnly, reach, and maybe capabilities. If there are several annotations they come with an order: * first, .rd next, ? last.

Attributes

Supertypes
trait Showable
class Object
trait Matchable
class Any
Known subtypes
class TermParamRef
class TermRef
class ThisType
class TypeParamRef
class TypeRef
class ParamRef
class Maybe
class Reach
class ReadOnly
class FreshCap
object GlobalCap
class ResultCap
Show all

The base trait of all capabilties represented as types

The base trait of all capabilties represented as types

Attributes

Supertypes
trait Capability
class TypeProxy
class Type
trait Showable
trait Hashable
class Object
trait Matchable
class Any
Show all
Known subtypes
class TermParamRef
class TermRef
class ThisType
class TypeParamRef
class TypeRef
class ParamRef
Show all

Attributes

Supertypes
trait Capability
trait Showable
class Object
trait Matchable
class Any
Known subtypes
class Maybe
class Reach
class ReadOnly
case class FreshCap extends RootCapability

The class of "fresh" roots. These do subsume other capabilties in scope. They track with hidden sets which other capabilities were subsumed. Hidden sets are inspected by separation checking.

The class of "fresh" roots. These do subsume other capabilties in scope. They track with hidden sets which other capabilities were subsumed. Hidden sets are inspected by separation checking.

Value parameters

origin

an indication where and why the FreshCap was created, used for diagnostics

owner

the owner of the context in which the FreshCap was created

Attributes

Companion
object
Supertypes
trait Serializable
trait Product
trait Equals
trait Capability
trait Showable
class Object
trait Matchable
class Any
Show all
object FreshCap

Attributes

Companion
class
Supertypes
class Object
trait Matchable
class Any
Self type
FreshCap.type
object GlobalCap extends RootCapability

The global root capability referenced as caps.cap cap does not subsume other capabilities, except in arguments of withCapAsRoot calls.

The global root capability referenced as caps.cap cap does not subsume other capabilities, except in arguments of withCapAsRoot calls.

Attributes

Supertypes
trait Capability
trait Showable
class Object
trait Matchable
class Any
Show all
Self type
GlobalCap.type
case class Maybe(underlying: Capability) extends DerivedCapability

If x is a capability, its maybe capability x?. x? stands for a capability x that might or might not be part of a capture set. We have {} <: {x?} <: {x}. Maybe capabilities cannot be propagated between sets. If a <: b and a acquires x? then x is propagated to b as a conservative approximation.

If x is a capability, its maybe capability x?. x? stands for a capability x that might or might not be part of a capture set. We have {} <: {x?} <: {x}. Maybe capabilities cannot be propagated between sets. If a <: b and a acquires x? then x is propagated to b as a conservative approximation.

Maybe capabilities should only arise for capture sets that appear in invariant position in their surrounding type. They are similar to TypeBounds types, but restricted to capture sets. For instance,

Array[C^{x?}]

should be morally equivalent to

Array[_ >: C^{} <: C^{x}]

but it has fewer issues with type inference.

Attributes

Supertypes
trait Serializable
trait Product
trait Equals
trait Capability
trait Showable
class Object
trait Matchable
class Any
Show all

Attributes

Supertypes
trait Capability
class TypeProxy
class Type
trait Showable
trait Hashable
class Object
trait Matchable
class Any
Show all
Known subtypes
class TermParamRef
class TermRef
class ThisType
enum Origin

The place of - and cause for - creating a fresh capability. Used for error diagnostics

The place of - and cause for - creating a fresh capability. Used for error diagnostics

Attributes

Supertypes
trait Enum
trait Serializable
trait Product
trait Equals
class Object
trait Matchable
class Any
Show all
case class Reach(underlying: ObjectCapability) extends DerivedCapability

If x is a capability, its reach capability x*. x* stands for all capabilities reachable through x. We have {x} <: {x*} <: dcs(x)} where the deep capture set dcs(x) of x is the union of all capture sets that appear in covariant position in the type of x. If x and y are different variables then {x*} and {y*} are unrelated.

If x is a capability, its reach capability x*. x* stands for all capabilities reachable through x. We have {x} <: {x*} <: dcs(x)} where the deep capture set dcs(x) of x is the union of all capture sets that appear in covariant position in the type of x. If x and y are different variables then {x*} and {y*} are unrelated.

Reach capabilities cannot wrap read-only capabilities or maybe capabilities. We have (x.rd).reach = x*.rd (x.rd)? = (x*)?

Attributes

Supertypes
trait Serializable
trait Product
trait Equals
trait Capability
trait Showable
class Object
trait Matchable
class Any
Show all
case class ReadOnly(underlying: ObjectCapability | RootCapability | Reach) extends DerivedCapability

The readonly capability x.rd. We have {x.rd} <: {x}.

The readonly capability x.rd. We have {x.rd} <: {x}.

Read-only capabilities cannot wrap maybe capabilities but they can wrap reach capabilities. We have (x?).readOnly = (x.rd)?

Attributes

Supertypes
trait Serializable
trait Product
trait Equals
trait Capability
trait Showable
class Object
trait Matchable
class Any
Show all
case class ResultCap(binder: MethodicType) extends RootCapability

A root capability associated with a function type. These are conceptually existentially quantified over the function's result type.

A root capability associated with a function type. These are conceptually existentially quantified over the function's result type.

Value parameters

binder

The function type with which the capability is associated. It is a MethodicType since we also have ResultCaps that are associated with the ExprTypes of parameterless functions. Currently we never create results over PolyTypes. TODO change this? Setup: In the setup phase, cap instances in the result of a dependent function type or method type such as (x: T): C^{cap} are converted to ResultCap(binder) instances, where binder refers to the method type. Most other cap instances are mapped to Fresh instances instead. For example the cap in the result of T => C^{cap} is mapped to a Fresh instance. If one needs to use a dependent function type yet one still want to map cap to a fresh instance instead an existential root, one can achieve that by the use of a type alias. For instance, the following type creates an existential for ^: (x: A) => (C^{x}, D^) By contrast, this variant creates a fresh instance instead: type F[X] = (x: A) => (C^{x}, X) F[D^] The trick is that the argument D^ is mapped to D^{fresh} before the F alias is expanded.

Attributes

Supertypes
trait Serializable
trait Product
trait Equals
trait Capability
trait Showable
class Object
trait Matchable
class Any
Show all
trait RootCapability extends Capability

The base trait of all root capabilities

The base trait of all root capabilities

Attributes

Supertypes
trait Capability
trait Showable
class Object
trait Matchable
class Any
Known subtypes
class FreshCap
object GlobalCap
class ResultCap

Attributes

Supertypes
trait Capability
class TypeProxy
class Type
trait Showable
trait Hashable
class Object
trait Matchable
class Any
Show all
Known subtypes
class TypeParamRef
class TypeRef

Types

opaque type Validity

Value members

Concrete methods

def capToFresh(tp: Type, origin: Origin)(using Context): Type

Maps cap to fresh. CapToFresh is a BiTypeMap since we don't want to freeze a set when it is mapped. On the other hand, we do not want Fresh values to flow back to cap since that would fail disallowRootCapability tests elsewhere. We therefore use withoutMappedFutureElems to prevent the map being installed for future use.

Maps cap to fresh. CapToFresh is a BiTypeMap since we don't want to freeze a set when it is mapped. On the other hand, we do not want Fresh values to flow back to cap since that would fail disallowRootCapability tests elsewhere. We therefore use withoutMappedFutureElems to prevent the map being installed for future use.

Attributes

def currentId(using Context): Validity
def freshToCap(tp: Type)(using Context): Type

Maps fresh to cap

Maps fresh to cap

Attributes

def resultToFresh(tp: Type, origin: Origin)(using Context): Type

Map top-level free existential variables one-to-one to Fresh instances

Map top-level free existential variables one-to-one to Fresh instances

Attributes

def toResult(tp: Type, mt: MethodicType, fail: Message => Unit)(using Context): Type

Replace all occurrences of cap (or fresh) in parts of this type by an existentially bound variable bound by mt. Stop at function or method types since these have been mapped before.

Replace all occurrences of cap (or fresh) in parts of this type by an existentially bound variable bound by mt. Stop at function or method types since these have been mapped before.

Attributes

def toResultInResults(sym: Symbol, fail: Message => Unit, keepAliases: Boolean)(tp: Type)(using Context): Type

Map global roots in function results to result roots. Also, map roots in the types of parameterless def methods.

Map global roots in function results to result roots. Also, map roots in the types of parameterless def methods.

Attributes

def validId(runId: Int, iterId: Int): Validity

Concrete fields