With this option: -language:experimental.captureChecking
the code below:
import scala.collection.mutable.ListBuffer
open class MyItem
open class MyContainer[T <: MyItem]:
private val consumers = ListBuffer.empty[T => Unit]
private def execute(input: T): Unit =
for consumer <- consumers do
consumer(input)
gives this error when evaluating the def:
Found: (consumer: (x$0: T^?) => Unit) ->? Unit
Required: (consumer: box (x$0: T^?) => Unit) → Unit
Note that (x$0: T^?) => Unit cannot be box-converted to box (x$0: T^?) => Unit
since at least one of their capture sets contains the root capability cap
Like for my previous question I don’t have the faintest idea if this is the intended behaviour, and I need to fix my code, or not…
The error message is not great. We still have a lot of work to do on better error diagnostics.
Essentially the problem is that there are restrictions what you can do with arbitrary side effects. T => Unit is the type of functions that can do anything. We can’t allow to have mutable structures such as ListBuffer contain them because then we could leak local capabilities by appending to a global ListBuffer.
You can avoid the problems by using pure functions T -> Unit or functions with a non-universal capture set such as T ->{io} Unit.
The boxing lingo is admittedly obscure. It’s currently like this so that compiler developers can better diagnose where the internal type checking sees an error. In future versions we should hide that better.