@@ -185,34 +185,6 @@ object CheckCaptures:
185
185
if ccConfig.useSealed then check.traverse(tp)
186
186
end disallowRootCapabilitiesIn
187
187
188
- /** Under the sealed policy, disallow the root capability in type arguments.
189
- * Type arguments come either from a TypeApply node or from an AppliedType
190
- * which represents a trait parent in a template.
191
- * @param fn the type application, of type TypeApply or TypeTree
192
- * @param sym the constructor symbol (could be a method or a val or a class)
193
- * @param args the type arguments
194
- */
195
- private def disallowCapInTypeArgs (fn : Tree , sym : Symbol , args : List [Tree ], thisPhase : Phase )(using Context ): Unit =
196
- def isExempt = sym.isTypeTestOrCast || sym == defn.Compiletime_erasedValue
197
- if ccConfig.useSealed && ! isExempt then
198
- val paramNames = atPhase(thisPhase.prev):
199
- fn.tpe.widenDealias match
200
- case tl : TypeLambda => tl.paramNames
201
- case ref : AppliedType if ref.typeSymbol.isClass => ref.typeSymbol.typeParams.map(_.name)
202
- case t =>
203
- println(i " parent type: $t" )
204
- args.map(_ => EmptyTypeName )
205
- for case (arg : TypeTree , pname) <- args.lazyZip(paramNames) do
206
- def where = if sym.exists then i " in an argument of $sym" else " "
207
- val (addendum, pos) =
208
- if arg.isInferred
209
- then (" \n This is often caused by a local capability$where\n leaking as part of its result." , fn.srcPos)
210
- else if arg.span.exists then (" " , arg.srcPos)
211
- else (" " , fn.srcPos)
212
- disallowRootCapabilitiesIn(arg.knownType, NoSymbol ,
213
- i " Type variable $pname of $sym" , " be instantiated to" , addendum, pos)
214
- end disallowCapInTypeArgs
215
-
216
188
/** If we are not under the sealed policy, and a tree is an application that unboxes
217
189
* its result or is a try, check that the tree's type does not have covariant universal
218
190
* capabilities.
@@ -409,14 +381,14 @@ class CheckCaptures extends Recheck, SymTransformer:
409
381
if lastEnv != null && env.nestedClosure.exists && env.nestedClosure == lastEnv.owner then
410
382
() // access is from a nested closure, so it's OK
411
383
else c.pathRoot match
412
- case ref : NamedType if ! ref.symbol.hasAnnotation(defn. UseAnnot ) =>
384
+ case ref : NamedType if ! ref.symbol.isUseParam =>
413
385
val what = if ref.isType then " Capture set parameter" else " Local reach capability"
414
386
report.error(
415
387
em """ $what $c leaks into capture scope of ${env.ownerString}.
416
388
|To allow this, the ${ref.symbol} should be declared with a @use annotation """ , pos)
417
389
case _ =>
418
390
419
- def recur (cs : CaptureSet , env : Env , lastEnv : Env | Null )( using Context ) : Unit =
391
+ def recur (cs : CaptureSet , env : Env , lastEnv : Env | Null ): Unit =
420
392
if env.isOpen && ! env.owner.isStaticOwner && ! cs.isAlwaysEmpty then
421
393
// Only captured references that are visible from the environment
422
394
// should be included.
@@ -480,6 +452,40 @@ class CheckCaptures extends Recheck, SymTransformer:
480
452
case _ =>
481
453
if sym.exists && curEnv.isOpen then markFree(capturedVars(sym), pos)
482
454
455
+ /** Under the sealed policy, disallow the root capability in type arguments.
456
+ * Type arguments come either from a TypeApply node or from an AppliedType
457
+ * which represents a trait parent in a template. Also, if a corresponding
458
+ * formal type parameter is declared or implied @use, charge the deep capture
459
+ * set of the argument to the environent.
460
+ * @param fn the type application, of type TypeApply or TypeTree
461
+ * @param sym the constructor symbol (could be a method or a val or a class)
462
+ * @param args the type arguments
463
+ */
464
+ def disallowCapInTypeArgs (fn : Tree , sym : Symbol , args : List [Tree ])(using Context ): Unit =
465
+ def isExempt = sym.isTypeTestOrCast || sym == defn.Compiletime_erasedValue
466
+ if ccConfig.useSealed && ! isExempt then
467
+ val paramNames = atPhase(thisPhase.prev):
468
+ fn.tpe.widenDealias match
469
+ case tl : TypeLambda => tl.paramNames
470
+ case ref : AppliedType if ref.typeSymbol.isClass => ref.typeSymbol.typeParams.map(_.name)
471
+ case t =>
472
+ println(i " parent type: $t" )
473
+ args.map(_ => EmptyTypeName )
474
+
475
+ for case (arg : TypeTree , pname) <- args.lazyZip(paramNames) do
476
+ def where = if sym.exists then i " in an argument of $sym" else " "
477
+ val (addendum, pos) =
478
+ if arg.isInferred
479
+ then (" \n This is often caused by a local capability$where\n leaking as part of its result." , fn.srcPos)
480
+ else if arg.span.exists then (" " , arg.srcPos)
481
+ else (" " , fn.srcPos)
482
+ disallowRootCapabilitiesIn(arg.knownType, NoSymbol ,
483
+ i " Type variable $pname of $sym" , " be instantiated to" , addendum, pos)
484
+
485
+ val param = fn.symbol.paramNamed(pname)
486
+ if param.isUseParam then markFree(arg.knownType.deepCaptureSet, pos)
487
+ end disallowCapInTypeArgs
488
+
483
489
override def recheckIdent (tree : Ident , pt : Type )(using Context ): Type =
484
490
val sym = tree.symbol
485
491
if sym.is(Method ) then
@@ -558,8 +564,8 @@ class CheckCaptures extends Recheck, SymTransformer:
558
564
*/
559
565
override def prepareFunction (funtpe : MethodType , meth : Symbol )(using Context ): MethodType =
560
566
val paramInfosWithUses = funtpe.paramInfos.zipWithConserve(funtpe.paramNames): (formal, pname) =>
561
- val paramOpt = meth.rawParamss.nestedFind(_.name == pname)
562
- paramOpt.flatMap(_. getAnnotation(defn.UseAnnot ) ) match
567
+ val param = meth.paramNamed( pname)
568
+ param. getAnnotation(defn.UseAnnot ) match
563
569
case Some (ann) => AnnotatedType (formal, ann)
564
570
case _ => formal
565
571
funtpe.derivedLambdaType(paramInfos = paramInfosWithUses)
@@ -725,7 +731,7 @@ class CheckCaptures extends Recheck, SymTransformer:
725
731
val meth = tree.fun match
726
732
case fun @ Select (qual, nme.apply) => qual.symbol.orElse(fun.symbol)
727
733
case fun => fun.symbol
728
- disallowCapInTypeArgs(tree.fun, meth, tree.args, thisPhase )
734
+ disallowCapInTypeArgs(tree.fun, meth, tree.args)
729
735
val res = Existential .toCap(super .recheckTypeApply(tree, pt))
730
736
includeCallCaptures(tree.symbol, res, tree.srcPos)
731
737
checkContains(tree)
@@ -956,7 +962,7 @@ class CheckCaptures extends Recheck, SymTransformer:
956
962
for case tpt : TypeTree <- impl.parents do
957
963
tpt.tpe match
958
964
case AppliedType (fn, args) =>
959
- disallowCapInTypeArgs(tpt, fn.typeSymbol, args.map(TypeTree (_)), thisPhase )
965
+ disallowCapInTypeArgs(tpt, fn.typeSymbol, args.map(TypeTree (_)))
960
966
case _ =>
961
967
inNestedLevelUnless(cls.is(Module )):
962
968
super .recheckClassDef(tree, impl, cls)
0 commit comments