dotty.tools.dotc.cc
Members list
Type members
Classlikes
Attributes
- Supertypes
- Known subtypes
-
object MaybeCapabilityobject ReachCapability
An extractor for caps.capsOf[X]
, which is used to express a generic capture set as a tree in a @retains annotation.
An extractor for caps.capsOf[X]
, which is used to express a generic capture set as a tree in a @retains annotation.
Attributes
- Supertypes
- Self type
-
CapsOfApply.type
An annotation representing a capture set and whether it is boxed. It simulates a normal @retains annotation except that it is more efficient, supports variables as capture sets, and adds a boxed
flag. These annotations are created during capture checking. Before that there are only regular @retains and @retainsByName annotations.
An annotation representing a capture set and whether it is boxed. It simulates a normal @retains annotation except that it is more efficient, supports variables as capture sets, and adds a boxed
flag. These annotations are created during capture checking. Before that there are only regular @retains and @retainsByName annotations.
Value parameters
- boxed
-
whether the type carrying the annotation is boxed
- cls
-
the underlying class (either annotation.retains or annotation.retainsByName)
- refs
-
the capture set
Attributes
- Supertypes
-
trait Serializabletrait Producttrait Equalsclass Annotationtrait Showableclass Objecttrait Matchableclass AnyShow all
A trait for references in CaptureSets. These can be NamedTypes, ThisTypes or ParamRefs, as well as two kinds of AnnotatedTypes representing reach and maybe capabilities.
A trait for references in CaptureSets. These can be NamedTypes, ThisTypes or ParamRefs, as well as two kinds of AnnotatedTypes representing reach and maybe capabilities.
Attributes
- Supertypes
- Known subtypes
-
trait SingletonCaptureRefclass TermParamRefclass TermRefclass CachedTermRefclass ThisTypeclass CachedThisTypeclass AnnotatedTypeclass CachedAnnotatedTypeclass TypeParamRefclass TypeRefclass CachedTypeRefShow all
A class for capture sets. Capture sets can be constants or variables. Capture sets support inclusion constraints <:< where <:< is subcapturing.
A class for capture sets. Capture sets can be constants or variables. Capture sets support inclusion constraints <:< where <:< is subcapturing.
They also allow
- mapping with functions from elements to capture sets
- filtering with predicates on elements
- intersecting wo capture sets
That is, constraints can be of the forms
cs1 <:< cs2 cs1 = ∪ {f(x) | x ∈ cs2} where f is a function from capture references to capture sets. cs1 = ∪ {x | x ∈ cs2, p(x)} where p is a predicate on capture references cs1 = cs2 ∩ cs2
We call the resulting constraint system "monadic set constraints". To support capture propagation across maps, mappings are supported only if the mapped function is either a bijection or if it is idempotent on capture references (c.f. doc comment on map
below).
Attributes
- Companion
- object
- Supertypes
- Known subtypes
-
class Constclass EmptyWithProvenanceobject Fluidclass Varclass DerivedVarclass BiMappedclass Filteredclass Diffclass Mappedclass RefiningVarShow all
Attributes
- Companion
- class
- Supertypes
- Self type
-
CaptureSet.type
A (possibly boxed) capturing type. This is internally represented as an annotated type with a @retains or @retainsByName annotation, but the extractor will succeed only at phase CheckCaptures. That way, we can ignore caturing information until phase CheckCaptures since it is wrapped in a plain annotation.
A (possibly boxed) capturing type. This is internally represented as an annotated type with a @retains or @retainsByName annotation, but the extractor will succeed only at phase CheckCaptures. That way, we can ignore caturing information until phase CheckCaptures since it is wrapped in a plain annotation.
The same trick does not work for the boxing information. Boxing is context dependent, so we have to add that information in the Setup step preceding CheckCaptures. Boxes are added for all type arguments of methods. For type arguments of applied types a different strategy is used where we box arguments of applied types that are not functions when accessing the argument.
An alternative strategy would add boxes also to arguments of applied types during setup. But this would have to be done for all possibly accessibly types from the compiled units as well as their dependencies. It's difficult to do this in a DenotationTransformer without accidentally forcing symbol infos. That's why this alternative was not implemented. If we would go back on this it would make sense to also treat captuyring types different from annotations and to generate them all during Setup and in DenotationTransformers.
Attributes
- Supertypes
- Self type
-
CapturingType.type
The capture checker
Attributes
- Companion
- object
- Supertypes
-
class Rechecktrait SymTransformertrait DenotTransformerclass Phaseclass Objecttrait Matchableclass AnyShow all
- Self type
Drop retains annotations in the type.
Drop retains annotations in the type.
Attributes
- Supertypes
Offers utility method to be used for type maps that follow aliases
Offers utility method to be used for type maps that follow aliases
Attributes
- Supertypes
An extractor for a contains argument
An extractor for a contains parameter
Handling existentials in CC:
Handling existentials in CC:
- We generally use existentials only in function and method result types
- All occurrences of an EX-bound variable appear co-variantly in the bound type
In Setup:
-
Convert occurrences of
cap
in function results to existentials. Precise rules below. -
Conversions are done in two places:
- As part of mapping from local types of parameters and results to infos of methods. The local types just use
cap
, whereas the result type in the info uses EX-bound variables. - When converting functions or methods appearing in explicitly declared types. Here again, we only replace cap's in fucntion results.
- As part of mapping from local types of parameters and results to infos of methods. The local types just use
-
Conversion is done with a BiTypeMap in
Existential.mapCap
.
In reckeckApply and recheckTypeApply:
- If an EX is toplevel in the result type, replace its bound variable occurrences with
cap
.
Level checking and avoidance:
-
Environments, capture refs, and capture set variables carry levels
- levels start at 0
- The level of a block or template statement sequence is one higher than the level of its environment
- The level of a TermRef is the level of the environment where its symbol is defined.
- The level of a ThisType is the level of the statements of the class to which it beloongs.
- The level of a TermParamRef is currently -1 (i.e. TermParamRefs are not yet checked using this system)
- The level of a capture set variable is the level of the environment where it is created.
-
Variables also carry info whether they accept
cap
or not. Variables introduced under a box don't, the others do. -
Capture set variables do not accept elements of level higher than the variable's level
-
We use avoidance to heal such cases: If the level-incorrect ref appears
- covariantly: widen to underlying capture set, reject if that is cap and the variable does not allow it
- contravariantly: narrow to {}
- invarianty: reject with error
In cv-computation (markFree):
- Reach capabilities x* of a parameter x cannot appear in the capture set of the owning method. They have to be widened to dcs(x), or, where this is not possible, it's an error.
In box adaptation:
- Check that existential variables are not boxed or unboxed.
Subtype rules
-
new alphabet: existentially bound variables
a
. -
they can be stored in environments Gamma.
-
they are alpha-renable, usual hygiene conditions apply
Gamma |- EX a.T <: U if Gamma, a |- T <: U
Gamma |- T <: EX a.U if exists capture set C consisting of capture refs and ex-bound variables bound in Gamma such that Gamma |- T <: [a := C]U
Representation:
EX a.T[a] is represented as a dependent function type
(a: Exists) => T[a]]
where Exists is defined in caps like this:
sealed trait Exists extends Capability
The defn.RefinedFunctionOf extractor will exclude existential types from its results, so only normal refined functions match.
Let boundvar(ex)
be the TermParamRef defined by the existential type ex
.
Subtype checking algorithm, general scheme:
Maintain two structures in TypeComparer:
openExistentials: List[TermParamRef]
assocExistentials: Map[TermParamRef, List[TermParamRef]]
openExistentials
corresponds to the list of existential variables stored in the environment. assocExistentials
maps existential variables bound by existentials appearing on the right to the value of openExistentials
at the time when the existential on the right was dropped.
Subtype checking algorithm, steps to add for tp1 <:< tp2:
If tp1 is an existential EX a.tp1a:
val saved = openExistentials
openExistentials = boundvar(tp1) :: openExistentials
try tp1a <:< tp2
finally openExistentials = saved
If tp2 is an existential EX a.tp2a:
val saved = assocExistentials
assocExistentials = assocExistentials + (boundvar(tp2) -> openExistentials)
try tp1 <:< tp2a
finally assocExistentials = saved
If tp2 is an existentially bound variable: assocExistentials(tp2).isDefined && (assocExistentials(tp2).contains(tp1) || tp1 is not existentially bound)
Subtype checking algorithm, comparing two capture sets CS1 <:< CS2:
We need to map the (possibly to-be-added) existentials in CS1 to existentials in CS2 so that we can compare them. We use assocExistentals
for that: To map an EX-variable V1 in CS1, pick the last (i.e. outermost, leading to the smallest type) EX-variable in assocExistentials
that has V1 in its possible instances. To go the other way (and therby produce a BiTypeMap), map an EX-variable V2 in CS2 to the first (i.e. innermost) EX-variable it can be instantiated to. If either direction is not defined, we choose a special "bad-existetal" value that represents and out-of-scope existential. This leads to failure of the comparison.
Existential source syntax:
Existential types are ususally not written in source, since we still allow the ^
syntax that can express most of them more concesely (see below for translation rules). But we should also allow to write existential types explicity, even if it ends up mainly for debugging. To express them, we use the encoding with Exists
, so a typical expression of an existential would be
(x: Exists) => A ->{x} B
Existential types can only at the top level of the result type of a function or method.
Restrictions on Existential Types: (to be implemented if we want to keep the source syntax for users).
- An existential capture ref must be the only member of its set. This is
intended to model the idea that existential variables effectibely range
over capture sets, not capture references. But so far our calculus
and implementation does not yet acoommodate first-class capture sets.
- Existential capture refs must appear co-variantly in their bound type
So the following would all be illegal:
EX x.C^{x, io} // error: multiple members
EX x.() => EX y.C^{x, y} // error: multiple members
EX x.C^{x} ->{x} D // error: contra-variant occurrence
EX x.Set[C^{x}] // error: invariant occurrence
Expansion of ^:
We expand all occurrences of cap
in the result types of functions or methods to existentially quantified types. Nested scopes are expanded before outer ones.
The expansion algorithm is then defined as follows:
1. In a result type, replace every occurrence of ^ with a fresh existentially
bound variable and quantify over all variables such introduced.
2. After this step, type aliases are expanded. If aliases have aliases in arguments,
the outer alias is expanded before the aliases in the arguments. Each time an alias
is expanded that reveals a `^`, apply step (1).
3. The algorithm ends when no more alieases remain to be expanded.
Examples:
- `A => B` is an alias type that expands to `(A -> B)^`, therefore
`() -> A => B` expands to `() -> EX c. A ->{c} B`.
- `() => Iterator[A => B]` expands to `() => EX c. Iterator[A ->{c} B]`
- `A -> B^` expands to `A -> EX c.B^{c}`.
- If we define `type Fun[T] = A -> T`, then `() -> Fun[B^]` expands to `() -> EX c.Fun[B^{c}]`, which
dealiases to `() -> EX c.A -> B^{c}`.
- If we define
type F = A -> Fun[B^]
then the type alias expands to
type F = A -> EX c.A -> B^{c}
Attributes
- Supertypes
- Self type
-
Existential.type
A typemap that follows aliases and keeps their transformed results if there is a change.
A typemap that follows aliases and keeps their transformed results if there is a change.
Attributes
- Supertypes
An extractor for all kinds of function types as well as method and poly types. It includes aliases of function types such as =>
. TODO: Can we do without?
An extractor for all kinds of function types as well as method and poly types. It includes aliases of function types such as =>
. TODO: Can we do without?
Attributes
- Returns
-
1st half: The argument types or empty if this is a type function 2nd half: The result type
- Supertypes
- Self type
-
FunctionOrMethod.type
An exception thrown if a @retains argument is not syntactically a CaptureRef
An exception thrown if a @retains argument is not syntactically a CaptureRef
Attributes
- Supertypes
An extractor for ref @maybeCapability
, which is used to express the maybe capability ref?
as a type.
An extractor for ref @maybeCapability
, which is used to express the maybe capability ref?
as a type.
Attributes
- Supertypes
- Self type
-
MaybeCapability.type
An extractor for ref @annotation.internal.reachCapability
, which is used to express the reach capability ref*
as a type.
An extractor for ref @annotation.internal.reachCapability
, which is used to express the reach capability ref*
as a type.
Attributes
- Supertypes
- Self type
-
ReachCapability.type
An extractor for caps.reachCapability(ref)
, which is used to express a reach capability as a tree in a @retains annotation.
An extractor for caps.reachCapability(ref)
, which is used to express a reach capability as a tree in a @retains annotation.
Attributes
- Supertypes
- Self type
-
ReachCapabilityApply.type
A builder and extractor for annotated types with @retains or @retainsByName annotations.
A builder and extractor for annotated types with @retains or @retainsByName annotations.
Attributes
- Supertypes
- Self type
-
RetainingType.type
Phase that sets up everthing for capture checking.
Phase that sets up everthing for capture checking.
A tree traverser that prepares a compilation unit to be capture checked. It does the following:
- For every inferred type, drop any retains annotations, add capture sets to all its parts, add refinements to class types and function types. (c.f. mapInferred)
- For explicit capturing types, expand throws aliases to the underlying (pure) function, and add some implied capture sets to curried functions (c.f. expandThrowsAlias, expandAbbreviations).
- Add capture sets to self types of classes and objects, unless the self type was written explicitly.
- Box the types of mutable variables and type arguments to methods (type arguments of types are boxed on access).
- Link the external types of val and def symbols with the inferred types based on their parameter symbols.
Attributes
- Companion
- object
- Supertypes
-
trait SetupAPItrait SymTransformerclass PreRechecktrait DenotTransformerclass Phaseclass Objecttrait Matchableclass AnyShow all
- Self type
Attributes
- Supertypes
-
trait CaptureReftrait SingletonTypetrait ValueTypetrait ValueTypeOrPrototrait TermTypeclass TypeProxyclass Typetrait Showabletrait Hashableclass Objecttrait Matchableclass AnyShow all
- Known subtypes
Classification and transformation methods for function methods and synthetic case class methods that need to be treated specially. In particular, compute capturing types for some of these methods which have inferred (result-)types that need to be established under separate compilation.
Classification and transformation methods for function methods and synthetic case class methods that need to be treated specially. In particular, compute capturing types for some of these methods which have inferred (result-)types that need to be established under separate compilation.
Attributes
- Supertypes
- Self type
-
Synthetics.type
Value members
Concrete methods
The currently valid CCState
The currently valid CCState
Attributes
A dependent function type with given arguments and result type TODO Move somewhere else where we treat all function type related ops together.
A dependent function type with given arguments and result type TODO Move somewhere else where we treat all function type related ops together.
Attributes
Are we at checkCaptures phase?
Are we at checkCaptures phase?
Attributes
Are we at checkCaptures or Setup phase?
Are we at checkCaptures or Setup phase?
Attributes
Extensions
Extensions
Does this symbol allow results carrying the universal capability? Currently this is true only for function type applies (since their results are unboxed) and erasedValue
since this function is magic in that is allows to conjure global capabilies from nothing (aside: can we find a more controlled way to achieve this?). But it could be generalized to other functions that so that they can take capability classes as arguments.
Does this symbol allow results carrying the universal capability? Currently this is true only for function type applies (since their results are unboxed) and erasedValue
since this function is magic in that is allows to conjure global capabilies from nothing (aside: can we find a more controlled way to achieve this?). But it could be generalized to other functions that so that they can take capability classes as arguments.
Attributes
A class is pure if:
A class is pure if:
- one its base types has an explicitly declared self type with an empty capture set
- or it is a value class
- or it is an exception
- or it is one of Nothing, Null, or String
Attributes
It's a parameter accessor that is not annotated @constructorOnly or @uncheckedCaptures
It's a parameter accessor that is not annotated @constructorOnly or @uncheckedCaptures
Attributes
This symbol is one of retains
or retainsCap
This symbol is one of retains
or retainsCap
Attributes
This symbol is one of retains
, retainsCap
, orretainsByName
This symbol is one of retains
, retainsCap
, orretainsByName
Attributes
sym
is annotated @use or it is a type parameter with a matching
sym
is annotated @use or it is a type parameter with a matching
Attributes
When applying sym
, would the result type be unboxed? This is the case if the result type contains a top-level reference to an enclosing class or method type parameter and the method does not allow root capture. If the type parameter is instantiated to a boxed type, that type would have to be unboxed in the method's result.
When applying sym
, would the result type be unboxed? This is the case if the result type contains a top-level reference to an enclosing class or method type parameter and the method does not allow root capture. If the type parameter is instantiated to a boxed type, that type would have to be unboxed in the method's result.
Attributes
If this is a unboxed capturing type with nonempty capture set, its boxed version. Or, if type is a TypeBounds of capturing types, the version where the bounds are boxed. The identity for all other types.
If this is a unboxed capturing type with nonempty capture set, its boxed version. Or, if type is a TypeBounds of capturing types, the version where the bounds are boxed. The identity for all other types.
Attributes
The capture set consisting of all top-level captures of tp
that appear under a box. Unlike for boxed
this also considers parents of capture types, unions and intersections, and type proxies other than abstract types.
The capture set consisting of all top-level captures of tp
that appear under a box. Unlike for boxed
this also considers parents of capture types, unions and intersections, and type proxies other than abstract types.
Attributes
The capture set of a type. This is:
The capture set of a type. This is:
- For trackable capture references: The singleton capture set consisting of just the reference, provided the underlying capture set of their info is not empty.
- For other capture references: The capture set of their info
- For all other types: The result of CaptureSet.ofType
Attributes
A type capturing ref
A type capturing ref
Attributes
A type capturing the capture set cs
. If this type is already a capturing type the two capture sets are combined.
A type capturing the capture set cs
. If this type is already a capturing type the two capture sets are combined.
Attributes
The deep capture set of a type. This is by default the union of all covariant capture sets embedded in the widened type, as computed by CaptureSet.ofTypeDeeply
. If that set is nonempty, and the type is a singleton capability x
or a reach capability x*
, the deep capture set can be narrowed to{x*}
.
The deep capture set of a type. This is by default the union of all covariant capture sets embedded in the widened type, as computed by CaptureSet.ofTypeDeeply
. If that set is nonempty, and the type is a singleton capability x
or a reach capability x*
, the deep capture set can be narrowed to{x*}
.
Attributes
Attributes
Tests whether the type derives from caps.Capability
, which means references of this type are maximal capabilities.
Tests whether the type derives from caps.Capability
, which means references of this type are maximal capabilities.
Attributes
Drop @retains annotations everywhere
Drop @retains annotations everywhere
Attributes
If this type is a capturing type, the version with boxed statues as given by boxed
. If it is a TermRef of a capturing type, and the box status flips, widen to a capturing type that captures the TermRef.
If this type is a capturing type, the version with boxed statues as given by boxed
. If it is a TermRef of a capturing type, and the box status flips, widen to a capturing type that captures the TermRef.
Attributes
Is type known to be always pure by its class structure? In that case, adding a capture set to it would not make sense.
Is type known to be always pure by its class structure? In that case, adding a capture set to it would not make sense.
Attributes
Is the box status of tp
and tp2
compatible? I.ee they are box boxed, or both unboxed, or one of them has an empty capture set.
Is the box status of tp
and tp2
compatible? I.ee they are box boxed, or both unboxed, or one of them has an empty capture set.
Attributes
Is the boxedCaptureSet of this type nonempty?
Is the boxedCaptureSet of this type nonempty?
Attributes
Is this type a CaptureRef that can be tracked? This is true for
Is this type a CaptureRef that can be tracked? This is true for
- all ThisTypes and all TermParamRef,
- stable TermRefs with NoPrefix or ThisTypes as prefixes,
- the root capability
caps.cap
- abstract or parameter TypeRefs that derive from caps.CapSet
- annotated types that represent reach or maybe capabilities
Attributes
If x
is a capture ref, its maybe capability x?
, represented internally as x @maybeCapability
. 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 capture ref, its maybe capability x?
, represented internally as x @maybeCapability
. 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 TypeBunds 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
If this part starts with C.this
, the class C
. Otherwise, if it starts with a reference r
, r
's owner. Otherwise NoSymbol.
If this part starts with C.this
, the class C
. Otherwise, if it starts with a reference r
, r
's owner. Otherwise NoSymbol.
Attributes
The first element of this path type
The first element of this path type
Attributes
If x
is a capture ref, its reach capability x*
, represented internally as x @reachCapability
. 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 capture ref, its reach capability x*
, represented internally as x @reachCapability
. 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.
Attributes
Map capturing type to their parents. Capturing types accessible via dealising are also stripped.
Map capturing type to their parents. Capturing types accessible via dealising are also stripped.
Attributes
If this is a unboxed capturing type with nonempty capture set, its boxed version. Or, if type is a TypeBounds of capturing types, the version where the bounds are boxed. The identity for all other types.
If this is a unboxed capturing type with nonempty capture set, its boxed version. Or, if type is a TypeBounds of capturing types, the version where the bounds are boxed. The identity for all other types.
Attributes
If ref
is a trackable capture ref, and tp
has only covariant occurrences of a universal capture set, replace all these occurrences by {ref*}
. This implements the new aspect of the (Var) rule, which can now be stated as follows:
If ref
is a trackable capture ref, and tp
has only covariant occurrences of a universal capture set, replace all these occurrences by {ref*}
. This implements the new aspect of the (Var) rule, which can now be stated as follows:
x: T in E
E |- x: T'
where T' is T with (1) the toplevel capture set replaced by {x}
and (2) all covariant occurrences of cap replaced by x*
, provided there are no occurrences in T
at other variances. (1) is standard, whereas (2) is new.
For (2), multiple-flipped covariant occurrences of cap won't be replaced. In other words,
- For xs: List[File^] ==> List[File^{xs*}], the cap is replaced;
- while f: [R] -> (op: File^ => R) -> R remains unchanged.
Without this restriction, the signature of functions like withFile:
(path: String) -> [R] -> (op: File^ => R) -> R
could be refined to
(path: String) -> [R] -> (op: File^{withFile*} => R) -> R
which is clearly unsound.
Why is this sound? Covariant occurrences of cap must represent capabilities that are reachable from x
, so they are included in the meaning of {x*}
. At the same time, encapsulation is still maintained since no covariant occurrences of cap are allowed in instance types of type variables.
Attributes
The arguments of a @retains, @retainsCap or @retainsByName annotation
The arguments of a @retains, @retainsCap or @retainsByName annotation
Attributes
Map tree with CaptureRef type to its type, map CapSet^{refs} to the refs
references, throw IllegalCaptureRef otherwise
Map tree with CaptureRef type to its type, map CapSet^{refs} to the refs
references, throw IllegalCaptureRef otherwise
Attributes
Convert a @retains or @retainsByName annotation tree to the capture set it represents. For efficience, the result is cached as an Attachment on the tree.
Convert a @retains or @retainsByName annotation tree to the capture set it represents. For efficience, the result is cached as an Attachment on the tree.