@@ -403,30 +403,46 @@ class CheckCaptures extends Recheck:
403
403
show(unit.tpdTree) // this dows not print tree, but makes its variables visible for dependency printing
404
404
}
405
405
406
+ def checkNotGlobal (tree : Tree , tp : Type , allArgs : Tree * )(using Context ): Unit =
407
+ for ref <- tp.captureSet.elems do
408
+ val isGlobal = ref match
409
+ case ref : TermRef =>
410
+ ref.isRootCapability || ref.prefix != NoPrefix && ref.symbol.hasAnnotation(defn.AbilityAnnot )
411
+ case _ => false
412
+ if isGlobal then
413
+ val what = if ref.isRootCapability then " universal" else " global"
414
+ val notAllowed = i " is not allowed to capture the $what capability $ref"
415
+ def msg =
416
+ if allArgs.isEmpty then
417
+ i " type of mutable variable ${knownType(tree)}$notAllowed"
418
+ else tree match
419
+ case tree : InferredTypeTree =>
420
+ i """ inferred type argument ${knownType(tree)}$notAllowed
421
+ |
422
+ |The inferred arguments are: [ ${allArgs.map(knownType)}%, %] """
423
+ case _ => s " type argument $notAllowed"
424
+ report.error(msg, tree.srcPos)
425
+
406
426
def checkNotGlobal (tree : Tree , allArgs : Tree * )(using Context ): Unit =
407
427
if disallowGlobal then
408
428
tree match
409
429
case LambdaTypeTree (_, restpt) =>
410
430
checkNotGlobal(restpt, allArgs* )
411
431
case _ =>
412
- for ref <- knownType(tree).captureSet.elems do
413
- val isGlobal = ref match
414
- case ref : TermRef =>
415
- ref.isRootCapability || ref.prefix != NoPrefix && ref.symbol.hasAnnotation(defn.AbilityAnnot )
416
- case _ => false
417
- val what = if ref.isRootCapability then " universal" else " global"
418
- if isGlobal then
419
- val notAllowed = i " is not allowed to capture the $what capability $ref"
420
- def msg =
421
- if allArgs.isEmpty then
422
- i " type of mutable variable ${knownType(tree)}$notAllowed"
423
- else tree match
424
- case tree : InferredTypeTree =>
425
- i """ inferred type argument ${knownType(tree)}$notAllowed
426
- |
427
- |The inferred arguments are: [ ${allArgs.map(knownType)}%, %] """
428
- case _ => s " type argument $notAllowed"
429
- report.error(msg, tree.srcPos)
432
+ checkNotGlobal(tree, knownType(tree), allArgs* )
433
+
434
+ def checkNotGlobalDeep (tree : Tree )(using Context ): Unit =
435
+ val checker = new TypeTraverser :
436
+ def traverse (tp : Type ): Unit = tp match
437
+ case tp : TypeRef =>
438
+ tp.info match
439
+ case TypeBounds (_, hi) => traverse(hi)
440
+ case _ =>
441
+ case tp : TermRef =>
442
+ case _ =>
443
+ checkNotGlobal(tree, tp)
444
+ traverseChildren(tp)
445
+ checker.traverse(knownType(tree))
430
446
431
447
object PostRefinerCheck extends TreeTraverser :
432
448
def traverse (tree : Tree )(using Context ) =
@@ -467,7 +483,7 @@ class CheckCaptures extends Recheck:
467
483
case _ =>
468
484
inferred.foreachPart(checkPure, StopAt .Static )
469
485
case t : ValDef if t.symbol.is(Mutable ) =>
470
- checkNotGlobal (t.tpt)
486
+ checkNotGlobalDeep (t.tpt)
471
487
case _ =>
472
488
traverseChildren(tree)
473
489
0 commit comments