Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 22 additions & 2 deletions compiler/src/dotty/tools/dotc/core/TypeOps.scala
Original file line number Diff line number Diff line change
Expand Up @@ -706,9 +706,29 @@ object TypeOps:
def loop(args: List[Tree], boundss: List[TypeBounds]): Unit = args match
case arg :: args1 => boundss match
case bounds :: boundss1 =>

// Drop caps.Pure from a bound (1) at the top-level, (2) in an `&`, (3) under a type lambda.
def dropPure(tp: Type): Option[Type] = tp match
case tp @ AndType(tp1, tp2) =>
for tp1o <- dropPure(tp1); tp2o <- dropPure(tp2) yield
tp.derivedAndType(tp1o, tp2o)
case tp: HKTypeLambda =>
for rt <- dropPure(tp.resType) yield
tp.derivedLambdaType(resType = rt)
case _ =>
if tp.typeSymbol == defn.PureClass then None
else Some(tp)

val relevantBounds =
if Feature.ccEnabled then bounds
else
// Drop caps.Pure from bound, it should be checked only when capture checking is enabled
dropPure(bounds.hi).match
case Some(hi1) => bounds.derivedTypeBounds(bounds.lo, hi1)
case None => TypeBounds(bounds.lo, defn.AnyKindType)
arg.tpe match
case TypeBounds(lo, hi) => checkOverlapsBounds(lo, hi, arg, bounds)
case tp => checkOverlapsBounds(tp, tp, arg, bounds)
case TypeBounds(lo, hi) => checkOverlapsBounds(lo, hi, arg, relevantBounds)
case tp => checkOverlapsBounds(tp, tp, arg, relevantBounds)
loop(args1, boundss1)
case _ =>
case _ =>
Expand Down
10 changes: 10 additions & 0 deletions tests/neg-custom-args/captures/puretest.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import caps.Pure
def foo[C <: Pure]() = ()
def bar[T, C <: Iterable[T] & Pure]() = ()
def baz[CC[_] <: Pure]() = ()
def bam[CC[A] <: Pure & Iterable[A]]() = ()
def test =
foo[Int]() // error
bar[Int, List[Int]]() // error
baz[Seq]() // error
bam[Seq]() // error
10 changes: 10 additions & 0 deletions tests/pos/puretest.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import caps.Pure
def foo[C <: Pure]() = ()
def bar[T, C <: Iterable[T] & Pure]() = ()
def baz[CC[_] <: Pure]() = ()
def bam[CC[A] <: Pure & Iterable[A]]() = ()
def test =
foo[Int]()
bar[Int, List[Int]]()
baz[Seq]()
bam[Seq]()
Loading