@@ -182,34 +182,6 @@ object CheckCaptures:
182182 if ccConfig.useSealed then check.traverse(tp)
183183 end disallowRootCapabilitiesIn
184184
185- /** Under the sealed policy, disallow the root capability in type arguments.
186- * Type arguments come either from a TypeApply node or from an AppliedType
187- * which represents a trait parent in a template.
188- * @param fn the type application, of type TypeApply or TypeTree
189- * @param sym the constructor symbol (could be a method or a val or a class)
190- * @param args the type arguments
191- */
192- private def disallowCapInTypeArgs (fn : Tree , sym : Symbol , args : List [Tree ], thisPhase : Phase )(using Context ): Unit =
193- def isExempt = sym.isTypeTestOrCast || sym == defn.Compiletime_erasedValue
194- if ccConfig.useSealed && ! isExempt then
195- val paramNames = atPhase(thisPhase.prev):
196- fn.tpe.widenDealias match
197- case tl : TypeLambda => tl.paramNames
198- case ref : AppliedType if ref.typeSymbol.isClass => ref.typeSymbol.typeParams.map(_.name)
199- case t =>
200- println(i " parent type: $t" )
201- args.map(_ => EmptyTypeName )
202- for case (arg : TypeTree , pname) <- args.lazyZip(paramNames) do
203- def where = if sym.exists then i " in an argument of $sym" else " "
204- val (addendum, pos) =
205- if arg.isInferred
206- then (" \n This is often caused by a local capability$where\n leaking as part of its result." , fn.srcPos)
207- else if arg.span.exists then (" " , arg.srcPos)
208- else (" " , fn.srcPos)
209- disallowRootCapabilitiesIn(arg.knownType, NoSymbol ,
210- i " Type variable $pname of $sym" , " be instantiated to" , addendum, pos)
211- end disallowCapInTypeArgs
212-
213185 /** If we are not under the sealed policy, and a tree is an application that unboxes
214186 * its result or is a try, check that the tree's type does not have covariant universal
215187 * capabilities.
@@ -404,14 +376,14 @@ class CheckCaptures extends Recheck, SymTransformer:
404376 if lastEnv != null && env.nestedClosure.exists && env.nestedClosure == lastEnv.owner then
405377 () // access is from a nested closure, so it's OK
406378 else c.pathRoot match
407- case ref : NamedType if ! ref.symbol.hasAnnotation(defn. UseAnnot ) =>
379+ case ref : NamedType if ! ref.symbol.isUseParam =>
408380 val what = if ref.isType then " Capture set parameter" else " Local reach capability"
409381 report.error(
410382 em """ $what $c leaks into capture scope of ${env.ownerString}.
411383 |To allow this, the ${ref.symbol} should be declared with a @use annotation """ , pos)
412384 case _ =>
413385
414- def recur (cs : CaptureSet , env : Env , lastEnv : Env | Null )( using Context ) : Unit =
386+ def recur (cs : CaptureSet , env : Env , lastEnv : Env | Null ): Unit =
415387 if env.isOpen && ! env.owner.isStaticOwner && ! cs.isAlwaysEmpty then
416388 // Only captured references that are visible from the environment
417389 // should be included.
@@ -475,6 +447,40 @@ class CheckCaptures extends Recheck, SymTransformer:
475447 case _ =>
476448 if sym.exists && curEnv.isOpen then markFree(capturedVars(sym), pos)
477449
450+ /** Under the sealed policy, disallow the root capability in type arguments.
451+ * Type arguments come either from a TypeApply node or from an AppliedType
452+ * which represents a trait parent in a template. Also, if a corresponding
453+ * formal type parameter is declared or implied @use, charge the deep capture
454+ * set of the argument to the environent.
455+ * @param fn the type application, of type TypeApply or TypeTree
456+ * @param sym the constructor symbol (could be a method or a val or a class)
457+ * @param args the type arguments
458+ */
459+ def disallowCapInTypeArgs (fn : Tree , sym : Symbol , args : List [Tree ])(using Context ): Unit =
460+ def isExempt = sym.isTypeTestOrCast || sym == defn.Compiletime_erasedValue
461+ if ccConfig.useSealed && ! isExempt then
462+ val paramNames = atPhase(thisPhase.prev):
463+ fn.tpe.widenDealias match
464+ case tl : TypeLambda => tl.paramNames
465+ case ref : AppliedType if ref.typeSymbol.isClass => ref.typeSymbol.typeParams.map(_.name)
466+ case t =>
467+ println(i " parent type: $t" )
468+ args.map(_ => EmptyTypeName )
469+
470+ for case (arg : TypeTree , pname) <- args.lazyZip(paramNames) do
471+ def where = if sym.exists then i " in an argument of $sym" else " "
472+ val (addendum, pos) =
473+ if arg.isInferred
474+ then (" \n This is often caused by a local capability$where\n leaking as part of its result." , fn.srcPos)
475+ else if arg.span.exists then (" " , arg.srcPos)
476+ else (" " , fn.srcPos)
477+ disallowRootCapabilitiesIn(arg.knownType, NoSymbol ,
478+ i " Type variable $pname of $sym" , " be instantiated to" , addendum, pos)
479+
480+ val param = fn.symbol.paramNamed(pname)
481+ if param.isUseParam then markFree(arg.knownType.deepCaptureSet, pos)
482+ end disallowCapInTypeArgs
483+
478484 override def recheckIdent (tree : Ident , pt : Type )(using Context ): Type =
479485 val sym = tree.symbol
480486 if sym.is(Method ) then
@@ -553,8 +559,8 @@ class CheckCaptures extends Recheck, SymTransformer:
553559 */
554560 override def prepareFunction (funtpe : MethodType , meth : Symbol )(using Context ): MethodType =
555561 val paramInfosWithUses = funtpe.paramInfos.zipWithConserve(funtpe.paramNames): (formal, pname) =>
556- val paramOpt = meth.rawParamss.nestedFind(_.name == pname)
557- paramOpt.flatMap(_. getAnnotation(defn.UseAnnot ) ) match
562+ val param = meth.paramNamed( pname)
563+ param. getAnnotation(defn.UseAnnot ) match
558564 case Some (ann) => AnnotatedType (formal, ann)
559565 case _ => formal
560566 funtpe.derivedLambdaType(paramInfos = paramInfosWithUses)
@@ -720,7 +726,7 @@ class CheckCaptures extends Recheck, SymTransformer:
720726 val meth = tree.fun match
721727 case fun @ Select (qual, nme.apply) => qual.symbol.orElse(fun.symbol)
722728 case fun => fun.symbol
723- disallowCapInTypeArgs(tree.fun, meth, tree.args, thisPhase )
729+ disallowCapInTypeArgs(tree.fun, meth, tree.args)
724730 val res = Existential .toCap(super .recheckTypeApply(tree, pt))
725731 includeCallCaptures(tree.symbol, res, tree.srcPos)
726732 checkContains(tree)
@@ -951,7 +957,7 @@ class CheckCaptures extends Recheck, SymTransformer:
951957 for case tpt : TypeTree <- impl.parents do
952958 tpt.tpe match
953959 case AppliedType (fn, args) =>
954- disallowCapInTypeArgs(tpt, fn.typeSymbol, args.map(TypeTree (_)), thisPhase )
960+ disallowCapInTypeArgs(tpt, fn.typeSymbol, args.map(TypeTree (_)))
955961 case _ =>
956962 inNestedLevelUnless(cls.is(Module )):
957963 super .recheckClassDef(tree, impl, cls)
0 commit comments