Skip to content

Commit 27a7ce7

Browse files
committed
Improve naming and comments around "disallow roots"
1 parent 99b24d7 commit 27a7ce7

File tree

2 files changed

+31
-30
lines changed

2 files changed

+31
-30
lines changed

compiler/src/dotty/tools/dotc/cc/CaptureSet.scala

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -468,11 +468,11 @@ sealed abstract class CaptureSet extends Showable:
468468
case elem: FreshCap => elem.ccOwner.isContainedIn(rootLimit)
469469
case _ => false
470470

471-
/** Invoke `handler` if this set has (or later aquires) a root capability.
472-
* Excluded are Fresh instances unless their ccOwner is contained in `upto`.
471+
/** Invoke `handler` if this set has (or later aquires) a bad root capability.
472+
* Fresh instances count as good as long as their ccOwner is outside `upto`.
473473
* If `upto` is NoSymbol, all Fresh instances are admitted.
474474
*/
475-
def disallowRootCapability(upto: Symbol)(handler: () => Context ?=> Unit)(using Context): this.type =
475+
def disallowBadRoots(upto: Symbol)(handler: () => Context ?=> Unit)(using Context): this.type =
476476
if elems.exists(isBadRoot(upto, _)) then handler()
477477
this
478478

@@ -840,10 +840,10 @@ object CaptureSet:
840840
|| isConst
841841
|| varState.canRecord && { includeDep(cs); true }
842842

843-
override def disallowRootCapability(upto: Symbol)(handler: () => Context ?=> Unit)(using Context): this.type =
843+
override def disallowBadRoots(upto: Symbol)(handler: () => Context ?=> Unit)(using Context): this.type =
844844
rootLimit = upto
845845
rootAddedHandler = handler
846-
super.disallowRootCapability(upto)(handler)
846+
super.disallowBadRoots(upto)(handler)
847847

848848
override def ensureWellformed(handler: Capability => (Context) ?=> Unit)(using Context): this.type =
849849
newElemAddedHandler = handler
@@ -945,7 +945,7 @@ object CaptureSet:
945945
* Test case: Without that tweak, logger.scala would not compile.
946946
*/
947947
class RefiningVar(owner: Symbol)(using Context) extends Var(owner):
948-
override def disallowRootCapability(upto: Symbol)(handler: () => Context ?=> Unit)(using Context) = this
948+
override def disallowBadRoots(upto: Symbol)(handler: () => Context ?=> Unit)(using Context) = this
949949

950950
/** A variable that is derived from some other variable via a map or filter. */
951951
abstract class DerivedVar(owner: Symbol, initialElems: Refs)(using @constructorOnly ctx: Context)

compiler/src/dotty/tools/dotc/cc/CheckCaptures.scala

Lines changed: 25 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -120,11 +120,11 @@ object CheckCaptures:
120120
report.error(em"$elem: $tpe is not a legal element of a capture set", ann.srcPos)
121121
ann.retainedSet.retainedElementsRaw.foreach(check)
122122

123-
/** Under the sealed policy, report an error if some part of `tp` contains the
124-
* root capability in its capture set or if it refers to a type parameter that
125-
* could possibly be instantiated with cap in a way that's visible at the type.
123+
/** Disallow bad roots anywhere in type `tp``.
124+
* @param upto controls up to which owner local fresh capabilities should be disallowed.
125+
* See disallowBadRoots for details.
126126
*/
127-
private def disallowRootCapabilitiesIn(tp: Type, upto: Symbol, what: String, have: String, addendum: String, pos: SrcPos)(using Context) =
127+
private def disallowBadRootsIn(tp: Type, upto: Symbol, what: => String, have: => String, addendum: => String, pos: SrcPos)(using Context) =
128128
val check = new TypeTraverser:
129129

130130
private val seen = new EqHashSet[TypeRef]
@@ -151,7 +151,7 @@ object CheckCaptures:
151151
case CapturingType(parent, refs) =>
152152
if variance >= 0 then
153153
val openScopes = openExistentialScopes
154-
refs.disallowRootCapability(upto): () =>
154+
refs.disallowBadRoots(upto): () =>
155155
def part =
156156
if t eq tp then ""
157157
else
@@ -179,7 +179,7 @@ object CheckCaptures:
179179
case t =>
180180
traverseChildren(t)
181181
check.traverse(tp)
182-
end disallowRootCapabilitiesIn
182+
end disallowBadRootsIn
183183

184184
trait CheckerAPI:
185185
/** Complete symbol info of a val or a def */
@@ -534,8 +534,9 @@ class CheckCaptures extends Recheck, SymTransformer:
534534
// Under deferredReaches, don't propagate out of methods inside terms.
535535
// The use set of these methods will be charged when that method is called.
536536

537-
recur(cs, curEnv, null)
538-
useInfos += ((tree, cs, curEnv))
537+
if !cs.isAlwaysEmpty then
538+
recur(cs, curEnv, null)
539+
useInfos += ((tree, cs, curEnv))
539540
end markFree
540541

541542
/** If capability `c` refers to a parameter that is not @use declared, report an error.
@@ -570,16 +571,16 @@ class CheckCaptures extends Recheck, SymTransformer:
570571
case _ =>
571572
tp
572573

573-
/** Under the sealed policy, disallow the root capability in type arguments.
574-
* Type arguments come either from a TypeApply node or from an AppliedType
574+
/** Type arguments come either from a TypeApply node or from an AppliedType
575575
* which represents a trait parent in a template.
576-
* Also, if a corresponding formal type parameter is declared or implied @use,
577-
* charge the deep capture set of the argument to the environent.
576+
* - Disallow global cap and result caps in such arguments.
577+
* - If a corresponding formal type parameter is declared or implied @use,
578+
* charge the deep capture set of the argument to the environent.
578579
* @param fn the type application, of type TypeApply or TypeTree
579580
* @param sym the constructor symbol (could be a method or a val or a class)
580581
* @param args the type arguments
581582
*/
582-
def disallowCapInTypeArgs(fn: Tree, sym: Symbol, args: List[Tree])(using Context): Unit =
583+
def markFreeTypeArgs(fn: Tree, sym: Symbol, args: List[Tree])(using Context): Unit =
583584
def isExempt = sym.isTypeTestOrCast || defn.capsErasedValueMethods.contains(sym)
584585
if !isExempt then
585586
val paramNames = atPhase(thisPhase.prev):
@@ -592,17 +593,17 @@ class CheckCaptures extends Recheck, SymTransformer:
592593

593594
for case (arg: TypeTree, pname) <- args.lazyZip(paramNames) do
594595
def where = if sym.exists then i" in an argument of $sym" else ""
595-
val (addendum, errTree) =
596+
def addendum =
596597
if arg.isInferred
597-
then (i"\nThis is often caused by a local capability$where\nleaking as part of its result.", fn)
598-
else if arg.span.exists then ("", arg)
599-
else ("", fn)
600-
disallowRootCapabilitiesIn(arg.nuType, NoSymbol,
598+
then i"\nThis is often caused by a local capability$where\nleaking as part of its result."
599+
else ""
600+
def errTree = if !arg.isInferred && arg.span.exists then arg else fn
601+
disallowBadRootsIn(arg.nuType, NoSymbol,
601602
i"Type variable $pname of $sym", "be instantiated to", addendum, errTree.srcPos)
602603

603604
val param = fn.symbol.paramNamed(pname)
604605
if param.isUseParam then markFree(arg.nuType.deepCaptureSet, errTree)
605-
end disallowCapInTypeArgs
606+
end markFreeTypeArgs
606607

607608
/** Rechecking idents involves:
608609
* - adding call captures for idents referring to methods
@@ -870,7 +871,7 @@ class CheckCaptures extends Recheck, SymTransformer:
870871
case fun @ Select(qual, nme.apply) => qual.symbol.orElse(fun.symbol)
871872
case fun => fun.symbol
872873
def methDescr = if meth.exists then i"$meth's type " else ""
873-
disallowCapInTypeArgs(tree.fun, meth, tree.args)
874+
markFreeTypeArgs(tree.fun, meth, tree.args)
874875
val funType = super.recheckTypeApply(tree, pt)
875876
val res = resultToFresh(funType, Origin.ResultInstance(funType, meth))
876877
includeCallCaptures(tree.symbol, res, tree)
@@ -986,7 +987,7 @@ class CheckCaptures extends Recheck, SymTransformer:
986987
i"\n\nNote that $sym does not count as local since it is captured by $enclStr"
987988
case _ =>
988989
""
989-
disallowRootCapabilitiesIn(
990+
disallowBadRootsIn(
990991
tree.tpt.nuType, NoSymbol, i"Mutable $sym", "have type", addendum, sym.srcPos)
991992
checkInferredResult(super.recheckValDef(tree, sym), tree)
992993
finally
@@ -1169,7 +1170,7 @@ class CheckCaptures extends Recheck, SymTransformer:
11691170
for case tpt: TypeTree <- impl.parents do
11701171
tpt.tpe match
11711172
case AppliedType(fn, args) =>
1172-
disallowCapInTypeArgs(tpt, fn.typeSymbol, args.map(TypeTree(_)))
1173+
markFreeTypeArgs(tpt, fn.typeSymbol, args.map(TypeTree(_)))
11731174
case _ =>
11741175
ccState.inNestedLevelUnless(cls.is(Module)):
11751176
super.recheckClassDef(tree, impl, cls)
@@ -1202,7 +1203,7 @@ class CheckCaptures extends Recheck, SymTransformer:
12021203
recheck(tree.expr, pt)
12031204
val tp = recheckTryRest(bodyType, tree.cases, tree.finalizer, pt)
12041205
if Feature.enabled(Feature.saferExceptions) then
1205-
disallowRootCapabilitiesIn(tp, ctx.owner,
1206+
disallowBadRootsIn(tp, ctx.owner,
12061207
"The result of `try`", "have type",
12071208
"\nThis is often caused by a locally generated exception capability leaking as part of its result.",
12081209
tree.srcPos)
@@ -1946,7 +1947,7 @@ class CheckCaptures extends Recheck, SymTransformer:
19461947
if !(pos.span.isSynthetic && ctx.reporter.errorsReported)
19471948
&& !arg.typeSymbol.name.is(WildcardParamName)
19481949
then
1949-
CheckCaptures.disallowRootCapabilitiesIn(arg, NoSymbol,
1950+
CheckCaptures.disallowBadRootsIn(arg, NoSymbol,
19501951
"Array", "have element type", "",
19511952
pos)
19521953
traverseChildren(t)

0 commit comments

Comments
 (0)