@@ -185,34 +185,6 @@ object CheckCaptures:
185185 if ccConfig.useSealed then check.traverse(tp)
186186 end disallowRootCapabilitiesIn
187187
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-
216188 /** If we are not under the sealed policy, and a tree is an application that unboxes
217189 * its result or is a try, check that the tree's type does not have covariant universal
218190 * capabilities.
@@ -409,14 +381,14 @@ class CheckCaptures extends Recheck, SymTransformer:
409381 if lastEnv != null && env.nestedClosure.exists && env.nestedClosure == lastEnv.owner then
410382 () // access is from a nested closure, so it's OK
411383 else c.pathRoot match
412- case ref : NamedType if ! ref.symbol.hasAnnotation(defn. UseAnnot ) =>
384+ case ref : NamedType if ! ref.symbol.isUseParam =>
413385 val what = if ref.isType then " Capture set parameter" else " Local reach capability"
414386 report.error(
415387 em """ $what $c leaks into capture scope of ${env.ownerString}.
416388 |To allow this, the ${ref.symbol} should be declared with a @use annotation """ , pos)
417389 case _ =>
418390
419- def recur (cs : CaptureSet , env : Env , lastEnv : Env | Null )( using Context ) : Unit =
391+ def recur (cs : CaptureSet , env : Env , lastEnv : Env | Null ): Unit =
420392 if env.isOpen && ! env.owner.isStaticOwner && ! cs.isAlwaysEmpty then
421393 // Only captured references that are visible from the environment
422394 // should be included.
@@ -480,6 +452,40 @@ class CheckCaptures extends Recheck, SymTransformer:
480452 case _ =>
481453 if sym.exists && curEnv.isOpen then markFree(capturedVars(sym), pos)
482454
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+
483489 override def recheckIdent (tree : Ident , pt : Type )(using Context ): Type =
484490 val sym = tree.symbol
485491 if sym.is(Method ) then
@@ -558,8 +564,8 @@ class CheckCaptures extends Recheck, SymTransformer:
558564 */
559565 override def prepareFunction (funtpe : MethodType , meth : Symbol )(using Context ): MethodType =
560566 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
563569 case Some (ann) => AnnotatedType (formal, ann)
564570 case _ => formal
565571 funtpe.derivedLambdaType(paramInfos = paramInfosWithUses)
@@ -725,7 +731,7 @@ class CheckCaptures extends Recheck, SymTransformer:
725731 val meth = tree.fun match
726732 case fun @ Select (qual, nme.apply) => qual.symbol.orElse(fun.symbol)
727733 case fun => fun.symbol
728- disallowCapInTypeArgs(tree.fun, meth, tree.args, thisPhase )
734+ disallowCapInTypeArgs(tree.fun, meth, tree.args)
729735 val res = Existential .toCap(super .recheckTypeApply(tree, pt))
730736 includeCallCaptures(tree.symbol, res, tree.srcPos)
731737 checkContains(tree)
@@ -956,7 +962,7 @@ class CheckCaptures extends Recheck, SymTransformer:
956962 for case tpt : TypeTree <- impl.parents do
957963 tpt.tpe match
958964 case AppliedType (fn, args) =>
959- disallowCapInTypeArgs(tpt, fn.typeSymbol, args.map(TypeTree (_)), thisPhase )
965+ disallowCapInTypeArgs(tpt, fn.typeSymbol, args.map(TypeTree (_)))
960966 case _ =>
961967 inNestedLevelUnless(cls.is(Module )):
962968 super .recheckClassDef(tree, impl, cls)
0 commit comments