@@ -833,6 +833,19 @@ class SepCheck(checker: CheckCaptures.CheckerAPI) extends tpd.TreeTraverser:
833833 case t =>
834834 foldOver(c, t)
835835
836+ def checkNoTParamBounds (refsToCheck : Refs , descr : => String , pos : SrcPos ): Unit =
837+ for ref <- refsToCheck do
838+ ref match
839+ case ref : FreshCap =>
840+ ref.origin match
841+ case Origin .InDecl (sym) if sym.isAbstractOrParamType =>
842+ report.error(
843+ em """ Separation failure: $descr $ref, which appears in the bound of $sym.
844+ |This is not allowed. The $sym has to be returned explicitly in the result type. """ ,
845+ pos)
846+ case _ =>
847+ case _ =>
848+
836849 /** If `tpe` appears as a (result-) type of a definition, treat its
837850 * hidden set minus its explicitly declared footprint as consumed.
838851 * If `tpe` appears as an argument to a consume parameter, treat
@@ -847,8 +860,11 @@ class SepCheck(checker: CheckCaptures.CheckerAPI) extends tpd.TreeTraverser:
847860 // "see through them" when we look at hidden sets.
848861 then
849862 val refs = tpe.deepCaptureSet.elems
850- val toCheck = refs.transHiddenSet.directFootprint.nonPeaks.deduct(refs.directFootprint.nonPeaks)
851- checkConsumedRefs(toCheck, tpe, role, i " ${role.description} $tpe hides " , pos)
863+ val refsStar = refs.transHiddenSet
864+ val toCheck = refsStar.directFootprint.nonPeaks.deduct(refs.directFootprint.nonPeaks)
865+ def descr = i " ${role.description} $tpe hides "
866+ checkConsumedRefs(toCheck, tpe, role, descr, pos)
867+ checkNoTParamBounds(refsStar, descr, pos)
852868 case TypeRole .Argument (arg, _) =>
853869 if tpe.hasAnnotation(defn.ConsumeAnnot ) then
854870 val capts = spanCaptures(arg).directFootprint.nonPeaks
0 commit comments