CaptureChecker

dotty.tools.dotc.cc.CheckCaptures.CaptureChecker
class CaptureChecker(ictx: Context) extends Rechecker, CheckerAPI

Attributes

Graph
Supertypes
trait CheckerAPI
class Rechecker
class Object
trait Matchable
class Any

Members list

Type members

Types

type BoxErrors = ListBuffer[Message] | Null

Value members

Concrete methods

def adapt(actual: Type, expected: Type, pos: SrcPos, boxErrors: BoxErrors)(using Context): Type

Adapt actual type to expected type. This involves:

Adapt actual type to expected type. This involves:

  • narrow toplevel captures of x's underlying type to {x} according to CC's VAR rule
  • narrow nested captures of x's underlying type to {x*}
  • do box adaptation

Attributes

def adaptBoxed(actual: Type, expected: Type, pos: SrcPos, covariant: Boolean, alwaysConst: Boolean, boxErrors: BoxErrors)(using Context): Type

Adapt actual type to expected type by inserting boxing and unboxing conversions

Adapt actual type to expected type by inserting boxing and unboxing conversions

Value parameters

alwaysConst

always make capture set variables constant after adaptation

Attributes

def assertSub(cs1: CaptureSet, cs2: CaptureSet)(using Context): Unit

Assert subcapturing cs1 <: cs2 (available for debugging, otherwise unused)

Assert subcapturing cs1 <: cs2 (available for debugging, otherwise unused)

Attributes

If sym is a class or method nested inside a term, a capture set variable representing the captured variables of the environment associated with sym.

If sym is a class or method nested inside a term, a capture set variable representing the captured variables of the environment associated with sym.

Attributes

def checkArraysAreSealedIn(tp: Type, pos: SrcPos)(using Context): Unit

Under the unsealed policy: Arrays are like vars, check that their element types do not contains cap (in fact it would work also to check on array creation like we do under sealed).

Under the unsealed policy: Arrays are like vars, check that their element types do not contains cap (in fact it would work also to check on array creation like we do under sealed).

Attributes

override def checkConformsExpr(actual: Type, expected: Type, tree: Tree, addenda: Addenda)(using Context): Type

Massage actual and expected types before checking conformance. Massaging is done by the methods following this one:

Massage actual and expected types before checking conformance. Massaging is done by the methods following this one:

  • align dependent function types and add outer references in the expected type
  • adapt boxing in the actual type If the resulting types are not compatible, try again with an actual type where local capture roots are instantiated to root variables.

Attributes

Definition Classes
def checkContains(tree: TypeApply)(using Context): Unit

Faced with a tree of form caps.contansImpl[CS, r.type], check that R is a tracked capability and assert that {r} <: CS.

Faced with a tree of form caps.contansImpl[CS, r.type], check that R is a tracked capability and assert that {r} <: CS.

Attributes

def checkElem(elem: CaptureRef, cs: CaptureSet, pos: SrcPos, provenance: => String)(using Context): Unit

Check subcapturing {elem} <: cs, report error on failure

Check subcapturing {elem} <: cs, report error on failure

Attributes

def checkInferredResult(tp: Type, tree: ValOrDefDef)(using Context): Type

If val or def definition with inferred (result) type is visible in other compilation units, check that the actual inferred type conforms to the expected type where all inferred capture sets are dropped. This ensures that if files compile separately, they will also compile in a joint compilation.

If val or def definition with inferred (result) type is visible in other compilation units, check that the actual inferred type conforms to the expected type where all inferred capture sets are dropped. This ensures that if files compile separately, they will also compile in a joint compilation.

Attributes

def checkOK(res: CompareResult, prefix: => String, pos: SrcPos, provenance: => String)(using Context): Unit

If res is not CompareResult.OK, report an error

If res is not CompareResult.OK, report an error

Attributes

Check overrides again, taking capture sets into account. TODO: Can we avoid doing overrides checks twice? We need to do them here since only at this phase CaptureTypes are relevant But maybe we can then elide the check during the RefChecks phase under captureChecking?

Check overrides again, taking capture sets into account. TODO: Can we avoid doing overrides checks twice? We need to do them here since only at this phase CaptureTypes are relevant But maybe we can then elide the check during the RefChecks phase under captureChecking?

Attributes

def checkSelfTypes(unit: Tree)(using Context): Unit

Check that self types of subclasses conform to self types of super classes. (See comment below how this is achieved). The check assumes that classes without an explicit self type have the universal capture set {cap} on the self type. If a class without explicit self type is not effectivelySealed it is checked that the inferred self type is universal, in order to assure that joint and separate compilation give the same result.

Check that self types of subclasses conform to self types of super classes. (See comment below how this is achieved). The check assumes that classes without an explicit self type have the universal capture set {cap} on the self type. If a class without explicit self type is not effectivelySealed it is checked that the inferred self type is universal, in order to assure that joint and separate compilation give the same result.

Attributes

def checkSubset(cs1: CaptureSet, cs2: CaptureSet, pos: SrcPos, provenance: => String, cs1description: String)(using Context): Unit

Check subcapturing cs1 <: cs2, report error on failure

Check subcapturing cs1 <: cs2, report error on failure

Attributes

override def checkUnit(unit: CompilationUnit)(using Context): Unit

Attributes

Definition Classes
def completeDef(tree: ValOrDefDef, sym: Symbol)(using Context): Type

Check a ValDef or DefDef as an action performed in a completer. Since these checks can appear out of order, we need to first create the correct environment for checking the definition.

Check a ValDef or DefDef as an action performed in a completer. Since these checks can appear out of order, we need to first create the correct environment for checking the definition.

Attributes

def disallowCapInTypeArgs(fn: Tree, sym: Symbol, args: List[Tree])(using Context): Unit

Under the sealed policy, disallow the root capability in type arguments. Type arguments come either from a TypeApply node or from an AppliedType which represents a trait parent in a template. Also, if a corresponding formal type parameter is declared or implied @use, charge the deep capture set of the argument to the environent.

Under the sealed policy, disallow the root capability in type arguments. Type arguments come either from a TypeApply node or from an AppliedType which represents a trait parent in a template. Also, if a corresponding formal type parameter is declared or implied @use, charge the deep capture set of the argument to the environent.

Value parameters

args

the type arguments

fn

the type application, of type TypeApply or TypeTree

sym

the constructor symbol (could be a method or a val or a class)

Attributes

def includeCallCaptures(sym: Symbol, resType: Type, pos: SrcPos)(using Context): Unit

Include references captured by the called method in the current environment stack

Include references captured by the called method in the current environment stack

Attributes

override def instantiate(mt: MethodType, argTypes: List[Type], sym: Symbol)(using Context): Type

Handle an application of method sym with type mt to arguments of types argTypes. This means

Handle an application of method sym with type mt to arguments of types argTypes. This means

  • Instantiate result type with actual arguments
  • if sym is a constructor, refine its type with refineInstanceType If all argument types are mutually different trackable capture references, use a BiTypeMap, since that is more precise. Otherwise use a normal idempotent map, which might lose information in the case where the result type contains captureset variables that are further constrained afterwards.

Attributes

Definition Classes
def isOfNestedMethod(env: Env | Null)(using Context): Boolean

Does the given environment belong to a method that is (a) nested in a term and (b) not the method of an anonympus function?

Does the given environment belong to a method that is (a) nested in a term and (b) not the method of an anonympus function?

Attributes

def markFree(sym: Symbol, pos: SrcPos)(using Context): Unit

Include sym in the capture sets of all enclosing environments nested in the the environment in which sym is defined.

Include sym in the capture sets of all enclosing environments nested in the the environment in which sym is defined.

Attributes

def markFree(sym: Symbol, ref: TermRef, pos: SrcPos)(using Context): Unit
def markFree(cs: CaptureSet, pos: SrcPos)(using Context): Unit

Make sure the (projected) cs is a subset of the capture sets of all enclosing environments. At each stage, only include references from cs that are outside the environment's owner

Make sure the (projected) cs is a subset of the capture sets of all enclosing environments. At each stage, only include references from cs that are outside the environment's owner

Attributes

def nextEnvToCharge(env: Env, included: Env => Boolean)(using Context): Env

The next environment enclosing env that needs to be charged with free references.

The next environment enclosing env that needs to be charged with free references.

Value parameters

included

Whether an environment is included in the range of environments to charge. Once included is false, no more environments need to be charged.

Attributes

def postCheck(unit: Tree)(using Context): Unit

Perform the following kinds of checks

Perform the following kinds of checks

  • Check that arguments of TypeApplys and AppliedTypes conform to their bounds.
  • Heal ill-formed capture sets of type parameters. See healTypeParam.

Attributes

def postCheckWF(unit: Tree)(using Context): Unit

Perform the following kinds of checks:

Perform the following kinds of checks:

  • Check all explicitly written capturing types for well-formedness using checkWellFormedPost.
  • Check that publicly visible inferred types correspond to the type they have without capture checking.

Attributes

override def prepareFunction(funtpe: MethodType, meth: Symbol)(using Context): MethodType

Hook for massaging a function before it is applied. Copies all @use annotations on method parameter symbols to the corresponding paramInfo types.

Hook for massaging a function before it is applied. Copies all @use annotations on method parameter symbols to the corresponding paramInfo types.

Attributes

Definition Classes
override def recheck(tree: Tree, pt: Type)(using Context): Type

The main recheck method does some box adapation for all nodes:

The main recheck method does some box adapation for all nodes:

  • If expected type pt is boxed and the tree is a lambda or a reference, don't propagate free variables.
  • If the expected type is not boxed but the result type is boxed, simulate an unboxing by adding all references in the boxed capture set of the result type to the current environment.

Attributes

Definition Classes
override def recheckApply(tree: Apply, pt: Type)(using Context): Type

Recheck applications, with special handling of unsafeAssumePure. More work is done in recheckApplication, recheckArg and instantiate below.

Recheck applications, with special handling of unsafeAssumePure. More work is done in recheckApplication, recheckArg and instantiate below.

Attributes

Definition Classes
override def recheckBlock(tree: Block, pt: Type)(using Context): Type

Attributes

Definition Classes
override def recheckClassDef(tree: TypeDef, impl: Template, cls: ClassSymbol)(using Context): Type

Recheck classDef by enforcing the following class-specific capture set relations:

Recheck classDef by enforcing the following class-specific capture set relations:

  1. The capture set of a class includes the capture sets of its parents.
  2. The capture set of the self type of a class includes the capture set of the class.
  3. The capture set of the self type of a class includes the capture set of every class parameter, unless the parameter is marked @constructorOnly or @untrackedCaptures.
  4. If the class extends a pure base class, the capture set of the self type must be empty. Also, check that trait parents represented as applied types don't have cap in their type arguments. Other generic parents are represented as TypeApplys, where the same check is already done in the TypeApply.

Attributes

Definition Classes
override def recheckClosure(tree: Closure, pt: Type, forceDependent: Boolean)(using Context): Type

Recheck Closure node: add the captured vars of the anonymoys function to the result type. See also recheckClosureBlock which rechecks the block containing the anonymous function and the Closure node.

Recheck Closure node: add the captured vars of the anonymoys function to the result type. See also recheckClosureBlock which rechecks the block containing the anonymous function and the Closure node.

Attributes

Definition Classes
override def recheckClosureBlock(mdef: DefDef, expr: Closure, pt: Type)(using Context): Type

Recheck a lambda of the form { def $anonfun(...) = ...; closure($anonfun, ...)}

Recheck a lambda of the form { def $anonfun(...) = ...; closure($anonfun, ...)}

Attributes

Definition Classes
override def recheckDefDef(tree: DefDef, sym: Symbol)(using Context): Type

Recheck method definitions:

Recheck method definitions:

  • check body in a nested environment that tracks uses, in a nested level, and in a nested context that knows abaout Contains parameters so that we can assume they are true.
  • for externally visible definitions: check that their inferred type does not refine what was known before capture checking.
  • Interpolate contravariant capture set variables in result type unless def is anonymous.

Attributes

Definition Classes
override def recheckFinish(tpe: Type, tree: Tree, pt: Type)(using Context): Type

Under the old unsealed policy: check that cap is ot unboxed

Under the old unsealed policy: check that cap is ot unboxed

Attributes

Definition Classes
override def recheckIdent(tree: Ident, pt: Type)(using Context): Type

Attributes

Definition Classes
override def recheckSelection(tree: Select, qualType: Type, name: Name, pt: Type)(using Context): Type

A specialized implementation of the selection rule.

A specialized implementation of the selection rule.

E |- f: T{ m: R^Cr }^{f}

E |- f.m: R^C

The implementation picks as C one of {f} or Cr, depending on the outcome of a mightSubcapture test. It picks {f} if it might subcapture Cr and picks Cr otherwise.

Attributes

Definition Classes
override def recheckTry(tree: Try, pt: Type)(using Context): Type

Under the sealed policy and with saferExceptions, disallow cap in the result type of a try

Under the sealed policy and with saferExceptions, disallow cap in the result type of a try

Attributes

Definition Classes
override def recheckTypeApply(tree: TypeApply, pt: Type)(using Context): Type

Recheck type applications:

Recheck type applications:

  • Map existential captures in result to cap
  • include captures of called methods in environment
  • don't allow cap to appear covariantly in type arguments
  • special handling of contains[A, B] calls

Attributes

Definition Classes
override def recheckTyped(tree: Typed)(using Context): Type

If type is of the form T @requiresCapability(x), mark x as free in the current environment. This is used to require the correct CanThrow capability when encountering a throw.

If type is of the form T @requiresCapability(x), mark x as free in the current environment. This is used to require the correct CanThrow capability when encountering a throw.

Attributes

Definition Classes
override def recheckValDef(tree: ValDef, sym: Symbol)(using Context): Type

Recheck val and var definitions:

Recheck val and var definitions:

  • disallow cap in the type of mutable vars.
  • for externally visible definitions: check that their inferred type does not refine what was known before capture checking.
  • Interpolate contravariant capture set variables in result type.

Attributes

Definition Classes
override def selectionProto(tree: Select, pt: Type)(using Context): Type

The expected type for the qualifier of a selection. If the selection could be part of a capabaility path, we return a PathSelectionProto.

The expected type for the qualifier of a selection. If the selection could be part of a capabaility path, we return a PathSelectionProto.

Attributes

Definition Classes
override def seqLiteralElemProto(tree: SeqLiteral, pt: Type, declared: Type)(using Context): Type

Elements of a SeqLiteral instantiate a Seq or Array parameter, so they should be boxed.

Elements of a SeqLiteral instantiate a Seq or Array parameter, so they should be boxed.

Attributes

Definition Classes
override def skipRecheck(sym: Symbol)(using Context): Boolean

The normal rechecking if sym was already completed before

The normal rechecking if sym was already completed before

Attributes

Definition Classes

Inherited methods

def checkConforms(tpe: Type, pt: Type, tree: Tree)(using Context): Type

Check that widened types of tpe and pt are compatible.

Check that widened types of tpe and pt are compatible.

Attributes

Inherited from:
Rechecker
def isCompatible(actual: Type, expected: Type)(using Context): Boolean

Attributes

Inherited from:
Rechecker

If true, remember the new types of nodes in this compilation unit as an attachment in the unit's tpdTree node. By default, this is enabled when -Xprint:cc is set. Can be overridden.

If true, remember the new types of nodes in this compilation unit as an attachment in the unit's tpdTree node. By default, this is enabled when -Xprint:cc is set. Can be overridden.

Attributes

Inherited from:
Rechecker
def recheckAlternative(tree: Alternative, pt: Type)(using Context): Type

Attributes

Inherited from:
Rechecker
def recheckAnnotated(tree: Annotated)(using Context): Type

Attributes

Inherited from:
Rechecker
def recheckAssign(tree: Assign)(using Context): Type

Attributes

Inherited from:
Rechecker
def recheckBind(tree: Bind, pt: Type)(using Context): Type

Attributes

Inherited from:
Rechecker
def recheckCase(tree: CaseDef, selType: Type, pt: Type)(using Context): Type

Attributes

Inherited from:
Rechecker
def recheckDef(tree: ValOrDefDef, sym: Symbol)(using Context): Type

Attributes

Inherited from:
Rechecker
def recheckIf(tree: If, pt: Type)(using Context): Type

Attributes

Inherited from:
Rechecker
def recheckInlined(tree: Inlined, pt: Type)(using Context): Type

Attributes

Inherited from:
Rechecker
def recheckLabeled(tree: Labeled, pt: Type)(using Context): Type

Attributes

Inherited from:
Rechecker
def recheckMatch(tree: Match, pt: Type)(using Context): Type

Attributes

Inherited from:
Rechecker

Attributes

Inherited from:
Rechecker
def recheckReturn(tree: Return)(using Context): Type

Attributes

Inherited from:
Rechecker
def recheckSelect(tree: Select, pt: Type)(using Context): Type

Attributes

Inherited from:
Rechecker
def recheckSelection(tree: Select, qualType: Type, name: Name, sharpen: Denotation => Denotation)(using Context): Type

Attributes

Inherited from:
Rechecker
def recheckSeqLiteral(tree: SeqLiteral, pt: Type)(using Context): Type

Attributes

Inherited from:
Rechecker
def recheckStart(tree: Tree, pt: Type)(using Context): Type

Recheck tree without adapting it, returning its new type.

Recheck tree without adapting it, returning its new type.

Value parameters

pt

the expected result type

tree

the original tree

Attributes

Inherited from:
Rechecker
def recheckStats(stats: List[Tree])(using Context): Unit

Attributes

Inherited from:
Rechecker
def recheckTypeDef(tree: TypeDef, sym: Symbol)(using Context): Type

Attributes

Inherited from:
Rechecker
def recheckTypeTree(tree: TypeTree)(using Context): Type

Attributes

Inherited from:
Rechecker
def recheckWhileDo(tree: WhileDo)(using Context): Type

Attributes

Inherited from:
Rechecker
def reset()(using Context): Unit

Reset all references in prevSelDenots to the denotations they had before this phase.

Reset all references in prevSelDenots to the denotations they had before this phase.

Attributes

Inherited from:
Rechecker
def widenSkolems(tp: Type)(using Context): Type

Typing and previous transforms sometimes leaves skolem types in prefixes of NamedTypes in expected that do not match the actual Type. -Ycheck does not complain (need to find out why), but a full recheck does. We compensate by de-skolemizing everywhere in expected except when variance is negative.

Typing and previous transforms sometimes leaves skolem types in prefixes of NamedTypes in expected that do not match the actual Type. -Ycheck does not complain (need to find out why), but a full recheck does. We compensate by de-skolemizing everywhere in expected except when variance is negative.

Attributes

Returns

If tp contains SkolemTypes in covariant or invariant positions, the type where these SkolemTypes are mapped to their underlying type. Otherwise, tp itself

Inherited from:
Rechecker

Extensions

Inherited extensions

extension [T <: Tree](tree: T)

Was a new type installed for this tree?

Was a new type installed for this tree?

Attributes

Inherited from:
Rechecker
def nuType(using Context): Type

The new type of the tree, or if none was installed, the original type

The new type of the tree, or if none was installed, the original type

Attributes

Inherited from:
Rechecker
def setNuType(tpe: Type): Unit

Set new type of the tree if none was installed yet and the new type is different from the current type.

Set new type of the tree if none was installed yet and the new type is different from the current type.

Attributes

Inherited from:
Rechecker