@@ -171,8 +171,7 @@ object CheckCaptures:
171171 def part = if t eq tp then " " else i " the part $t of "
172172 report.error(
173173 em """ $what cannot $have $tp since
174- | ${part}that type captures the root capability `cap`.
175- | $addendum""" ,
174+ | ${part}that type captures the root capability `cap`. $addendum""" ,
176175 pos)
177176 traverse(parent)
178177 case t =>
@@ -681,23 +680,34 @@ class CheckCaptures extends Recheck, SymTransformer:
681680 else ownType
682681 end instantiate
683682
683+ def disallowCapInTypeArgs (fn : Tree , sym : Symbol , args : List [Tree ])(using Context ): Unit =
684+ def isExempt = sym.isTypeTestOrCast || sym == defn.Compiletime_erasedValue
685+ if ccConfig.useSealed && ! isExempt then
686+ val paramNames = atPhase(thisPhase.prev):
687+ fn.tpe.widenDealias match
688+ case tl : TypeLambda => tl.paramNames
689+ case ref : AppliedType if ref.typeSymbol.isClass => ref.typeSymbol.typeParams.map(_.name)
690+ case t =>
691+ println(i " parent type: $t" )
692+ args.map(_ => EmptyTypeName )
693+ for case (arg : TypeTree , pname) <- args.lazyZip(paramNames) do
694+ def where = if sym.exists then i " in an argument of $sym" else " "
695+ val (addendum, pos) =
696+ if arg.isInferred
697+ then (" \n This is often caused by a local capability$where\n leaking as part of its result." , fn.srcPos)
698+ else if arg.span.exists then (" " , arg.srcPos)
699+ else (" " , fn.srcPos)
700+ disallowRootCapabilitiesIn(arg.knownType, NoSymbol ,
701+ i " Type variable $pname of $sym" , " be instantiated to" , addendum, pos)
702+ end disallowCapInTypeArgs
703+
684704 override def recheckTypeApply (tree : TypeApply , pt : Type )(using Context ): Type =
685- val meth = tree.symbol
686- if ccConfig.useSealed then
687- val TypeApply (fn, args) = tree
688- val polyType = atPhase(thisPhase.prev):
689- fn.tpe.widen.asInstanceOf [TypeLambda ]
690- def isExempt (sym : Symbol ) =
691- sym.isTypeTestOrCast || sym == defn.Compiletime_erasedValue
692- for case (arg : TypeTree , formal, pname) <- args.lazyZip(polyType.paramRefs).lazyZip((polyType.paramNames)) do
693- if ! isExempt(meth) then
694- def where = if meth.exists then i " in an argument of $meth" else " "
695- disallowRootCapabilitiesIn(arg.knownType, NoSymbol ,
696- i " Sealed type variable $pname" , " be instantiated to" ,
697- i " This is often caused by a local capability $where\n leaking as part of its result. " ,
698- tree.srcPos)
705+ val meth = tree.fun match
706+ case fun @ Select (qual, nme.apply) => qual.symbol.orElse(fun.symbol)
707+ case fun => fun.symbol
708+ disallowCapInTypeArgs(tree.fun, meth, tree.args)
699709 val res = Existential .toCap(super .recheckTypeApply(tree, pt))
700- includeCallCaptures(meth , res, tree.srcPos)
710+ includeCallCaptures(tree.symbol , res, tree.srcPos)
701711 checkContains(tree)
702712 res
703713 end recheckTypeApply
@@ -801,7 +811,7 @@ class CheckCaptures extends Recheck, SymTransformer:
801811 case _ => " "
802812 s " an anonymous function $location"
803813 else encl.show
804- (NoSymbol , i " \n Note that $sym does not count as local since it is captured by $enclStr" )
814+ (NoSymbol , i " \n\ n Note that $sym does not count as local since it is captured by $enclStr" )
805815 case _ =>
806816 (sym, " " )
807817 disallowRootCapabilitiesIn(
@@ -922,6 +932,11 @@ class CheckCaptures extends Recheck, SymTransformer:
922932 checkSubset(thisSet,
923933 CaptureSet .empty.withDescription(i " of pure base class $pureBase" ),
924934 selfType.srcPos, cs1description = " captured by this self type" )
935+ for case tpt : TypeTree <- impl.parents do
936+ tpt.tpe match
937+ case AppliedType (fn, args) =>
938+ disallowCapInTypeArgs(tpt, fn.typeSymbol, args.map(TypeTree (_)))
939+ case _ =>
925940 inNestedLevelUnless(cls.is(Module )):
926941 super .recheckClassDef(tree, impl, cls)
927942 finally
@@ -945,8 +960,8 @@ class CheckCaptures extends Recheck, SymTransformer:
945960 val tp = super .recheckTry(tree, pt)
946961 if ccConfig.useSealed && Feature .enabled(Feature .saferExceptions) then
947962 disallowRootCapabilitiesIn(tp, ctx.owner,
948- " result of `try`" , " have type" ,
949- " This is often caused by a locally generated exception capability leaking as part of its result." ,
963+ " The result of `try`" , " have type" ,
964+ " \n This is often caused by a locally generated exception capability leaking as part of its result." ,
950965 tree.srcPos)
951966 tp
952967
@@ -1587,8 +1602,7 @@ class CheckCaptures extends Recheck, SymTransformer:
15871602 && ! arg.typeSymbol.name.is(WildcardParamName )
15881603 then
15891604 CheckCaptures .disallowRootCapabilitiesIn(arg, NoSymbol ,
1590- " Array" , " have element type" ,
1591- " Since arrays are mutable, they have to be treated like variables,\n so their element type must be sealed." ,
1605+ " Array" , " have element type" , " " ,
15921606 pos)
15931607 traverseChildren(t)
15941608 case defn.RefinedFunctionOf (rinfo : MethodType ) =>
0 commit comments