Closed
Description
Compiler version
The main
branch
Minimized code
import language.experimental.captureChecking
def runOps[C^](ops: List[() ->{C^} Unit]): Unit =
ops.foreach: op =>
op()
def boom(f: () => Unit): () -> Unit =
() => runOps(f :: Nil)
Output
It type-checks.
Expectation
It should not type-check. Accepting the boom
function is clearly unsound: given any impure operations that could perform arbitrary effects, boom
could hide its captures and pretend that this operation is pure.
The capture checker rejects the morally equivalent variant that uses only reach capabilities:
def runOpsAlt(ops: List[() => Unit]): Unit =
ops.foreach: op =>
op()
The compiler complains:
-- Error: issues/drop-caparg.scala:4:15 --------------------------------------------------------------------------------------------------------------------------------------------------------------------------
4 | ops.foreach: op =>
| ^
| Local reach capability ops* leaks into capture scope of method runOpsAlt
5 | op()
We should do something similar with capture polymorphism.
/cc @odersky