Capture checking in pattern matches

After test case reduction, this is the smallest I can make this:

//> using scala 3.nightly
//> using option -language:experimental.captureChecking

import caps.*

trait Rand extends SharedCapability

def foo[A](as: List[Rand ?=> A]): Rand ?=> A =
  as match
    case head :: tail => head
    case _            => ???

Something is tripping the compiler up - I think the pattern match, but this is purely intuition backed with nothing else. I’m getting the following compile error:

[error] ./rep.sc:10:10
[error] Found:    ::[(rep$_.this.Rand) ?=> A]
[error] Required: ::[(rep$_.this.Rand^'s1) ?->'s2 A^'s3]
[error] 
[error] Note that (rep$_.this.Rand) ?=> A does not conform to (rep$_.this.Rand^'s1) ?->'s2 A^'s3 because (rep$_.this.Rand^'s1) ?->'s2 A^'s3 is boxed but (rep$_.this.Rand) ?=> A is not.
[error] 
[error] The error occurred for a synthesized tree:  x1.$asInstanceOf[::[(rep$_.this.Rand) ?=> A]^{x1}]
[error] 
[error] where:    ?=> refers to a fresh root capability created in value x2 of type argument ::[(rep$_.this.Rand) ?=> A]^{x1}
[error]     case head :: tail => head
[error]          ^

I have to admit this is a little unclear to me - it might be a case of a perfectly clear error message to someone who actually understands capture checking but not to mere mortals, but. Just as an experiment, I tried the same code but replacing all ?=> with ?→ to see if it had to do with impure computations, and I get the following error:

[error] ./rep.sc:10:30
[error] Found:    (contextual$1 : rep$_.this.Rand)
[error] Required: rep$_.this.Rand^{}
[error] 
[error] Note that capability contextual$1 cannot be included in capture set {} of value head.
[error] 
[error] The error occurred for a synthesized tree:  contextual$1
[error]     case head :: tail => head

This feels even more confusing: why does the compiler conclude that I need a Rand with an empty capture set?

This and also the SAM issue could well be problems with capture set inference. Can you please file issues for these? Thanks!

Done here!

1 Like