diff --git a/compiler/src/dotty/tools/dotc/typer/Typer.scala b/compiler/src/dotty/tools/dotc/typer/Typer.scala index 287c6addb5ba..87fbcc43c6ec 100644 --- a/compiler/src/dotty/tools/dotc/typer/Typer.scala +++ b/compiler/src/dotty/tools/dotc/typer/Typer.scala @@ -48,7 +48,7 @@ import staging.StagingLevel import reporting.* import Nullables.* import NullOpsDecorator.* -import cc.{Setup, CheckCaptures, isRetainsLike, derivesFromCapSet} +import cc.{Setup, CheckCaptures, isRetainsLike, derivesFromCapSet, RetainingAnnotation} import config.MigrationVersion import dotty.tools.dotc.core.Mode.Interactive import transform.CheckUnused.withOriginalName @@ -2690,8 +2690,13 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer val tycon = typedType(tree.tycon) def spliced(tree: Tree) = untpd.TypedSplice(tree) val tparam = untpd.Ident(tree.paramName).withSpan(tree.span.withEnd(tree.span.point)) - if Feature.ccEnabled && typed(tparam).tpe.derivesFromCapSet then - report.error(em"Capture variable `${tree.paramName}` cannot have a context bound.", tycon.srcPos) + if Feature.ccEnabled then + if typed(tparam).tpe.derivesFromCapSet then + report.error(em"Capture variable `${tree.paramName}` cannot have a context bound.", tycon.srcPos) + tycon.tpe match + case AnnotatedType(_, _ : RetainingAnnotation) => + report.error(em"Context bound `${tree.tycon}` cannot have a capture set.", tycon.srcPos) + case _ => if tycon.tpe.typeParams.nonEmpty then val tycon0 = tycon.withType(tycon.tpe.etaCollapse) typed(untpd.AppliedTypeTree(spliced(tycon0), tparam :: Nil)) diff --git a/tests/neg-custom-args/captures/in-context-bounds.scala b/tests/neg-custom-args/captures/in-context-bounds.scala new file mode 100644 index 000000000000..d23594ac7cd2 --- /dev/null +++ b/tests/neg-custom-args/captures/in-context-bounds.scala @@ -0,0 +1,11 @@ +package e + +import caps.* + +trait A[T] +trait B[T] extends caps.SharedCapability + +def wantsA1[C^, T: (A^{C})](x: T): A[T] = summon[A[T]] // error +def wantsA2[T: (A^)](x: T): A[T] = summon[A[T]] // error +def wantsA3[T: B](x: T): B[T] = summon[B[T]] // ok +