Skip to content

Commit ac8971e

Browse files
committed
Move all disallowRootCapabilitiesIn calls to checkCaptures
That way, we avoid having to call the function potentially before capture types are formed.
1 parent 54aea78 commit ac8971e

File tree

2 files changed

+22
-17
lines changed

2 files changed

+22
-17
lines changed

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

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,7 @@ object CheckCaptures:
144144
* or if it refers to an unsealed type parameter that could possibly be instantiated with
145145
* cap in a way that's visible at the type.
146146
*/
147-
def disallowRootCapabilitiesIn(tp: Type, carrier: Symbol, what: String, have: String, addendum: String, pos: SrcPos)(using Context) =
147+
private def disallowRootCapabilitiesIn(tp: Type, carrier: Symbol, what: String, have: String, addendum: String, pos: SrcPos)(using Context) =
148148
val check = new TypeTraverser:
149149
extension (tparam: Symbol) def isParametricIn(carrier: Symbol): Boolean =
150150
val encl = carrier.owner.enclosingMethodOrClass
@@ -172,9 +172,9 @@ object CheckCaptures:
172172
traverse(hi)
173173
case _ =>
174174
traverseChildren(t)
175-
case AnnotatedType(tp, ann) if ann.symbol == defn.UncheckedCapturesAnnot =>
175+
case AnnotatedType(_, ann) if ann.symbol == defn.UncheckedCapturesAnnot =>
176176
()
177-
case _ =>
177+
case t =>
178178
if variance >= 0 then
179179
t.captureSet.disallowRootCapability: () =>
180180
def part = if t eq tp then "" else i"the part $t of "
@@ -534,6 +534,20 @@ class CheckCaptures extends Recheck, SymTransformer:
534534
else ownType
535535
end instantiate
536536

537+
override def recheckTypeApply(tree: TypeApply, pt: Type)(using Context): Type =
538+
if allowUniversalInBoxed then
539+
val TypeApply(fn, args) = tree
540+
val polyType = atPhase(thisPhase.prev):
541+
fn.tpe.widen.asInstanceOf[TypeLambda]
542+
for case (arg: TypeTree, pinfo, pname) <- args.lazyZip(polyType.paramInfos).lazyZip((polyType.paramNames)) do
543+
if pinfo.bounds.hi.hasAnnotation(defn.Caps_SealedAnnot) then
544+
def where = if fn.symbol.exists then i" in an argument of ${fn.symbol}" else ""
545+
disallowRootCapabilitiesIn(arg.knownType, fn.symbol,
546+
i"Sealed type variable $pname", "be instantiated to",
547+
i"This is often caused by a local capability$where\nleaking as part of its result.",
548+
tree.srcPos)
549+
super.recheckTypeApply(tree, pt)
550+
537551
override def recheckClosure(tree: Closure, pt: Type, forceDependent: Boolean)(using Context): Type =
538552
val cs = capturedVars(tree.meth.symbol)
539553
capt.println(i"typing closure $tree with cvs $cs")
@@ -574,7 +588,11 @@ class CheckCaptures extends Recheck, SymTransformer:
574588
override def recheckValDef(tree: ValDef, sym: Symbol)(using Context): Type =
575589
try
576590
if sym.is(Module) then sym.info // Modules are checked by checking the module class
577-
else checkInferredResult(super.recheckValDef(tree, sym), tree)
591+
else
592+
if sym.is(Mutable) && !sym.hasAnnotation(defn.UncheckedCapturesAnnot) then
593+
disallowRootCapabilitiesIn(tree.tpt.knownType, sym,
594+
i"mutable $sym", "have type", "", sym.srcPos)
595+
checkInferredResult(super.recheckValDef(tree, sym), tree)
578596
finally
579597
if !sym.is(Param) then
580598
// Parameters with inferred types belong to anonymous methods. We need to wait

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

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -433,9 +433,6 @@ class Setup extends PreRecheck, SymTransformer, SetupAPI:
433433
val defCtx = if sym.isOneOf(TermParamOrAccessor) then ctx else ctx.withOwner(sym)
434434
inContext(defCtx):
435435
transformResultType(tpt, sym)
436-
if sym.is(Mutable) && !sym.hasAnnotation(defn.UncheckedCapturesAnnot) then
437-
CheckCaptures.disallowRootCapabilitiesIn(tpt.knownType, sym,
438-
i"mutable $sym", "have type", "", sym.srcPos)
439436
ccSetup.println(i"mapped $tree = ${tpt.knownType}")
440437
traverse(tree.rhs)
441438

@@ -444,16 +441,6 @@ class Setup extends PreRecheck, SymTransformer, SetupAPI:
444441
for case arg: TypeTree <- args do
445442
transformTT(arg, boxed = true, exact = false) // type arguments in type applications are boxed
446443

447-
if allowUniversalInBoxed then
448-
val polyType = fn.tpe.widen.asInstanceOf[TypeLambda]
449-
for case (arg: TypeTree, pinfo, pname) <- args.lazyZip(polyType.paramInfos).lazyZip((polyType.paramNames)) do
450-
if pinfo.bounds.hi.hasAnnotation(defn.Caps_SealedAnnot) then
451-
def where = if fn.symbol.exists then i" in an argument of ${fn.symbol}" else ""
452-
CheckCaptures.disallowRootCapabilitiesIn(arg.knownType, fn.symbol,
453-
i"Sealed type variable $pname", "be instantiated to",
454-
i"This is often caused by a local capability$where\nleaking as part of its result.",
455-
tree.srcPos)
456-
457444
case tree: TypeDef if tree.symbol.isClass =>
458445
inContext(ctx.withOwner(tree.symbol)):
459446
traverseChildren(tree)

0 commit comments

Comments
 (0)