Capture leak when using varargs?

The error messages do give you a bit of a run-around. They are both correct, but not helpful since the obvious fix to the type mismatch causes the leakage error for the reach capability. I tried in Warn if reach capability in result will likely cause leakage by odersky · Pull Request #24860 · scala/scala3 · GitHub to give you a warning at the point where you try toi add the reach capability to the result. That now produces the following for your example:

-- Warning: tests/neg-custom-args/captures/nicolas2.scala:9:53 ---------------------------------------------------------
9 |def oneOf[A](head: Rand ?=> A, tail: (Rand ?=> A)*): Rand ?->{head, tail*} A =
  |                                                     ^^^^^^^^^^^^^^^^^^^^^^^
  |                             Reach capability tail* in function result refers to parameter tail.
  |                             To avoid errors of the form "Local reach capability tail* leaks into capture scope ..."
  |                             you should replace the reach capability with a new capset variable in method oneOf.
-- Error: tests/neg-custom-args/captures/nicolas2.scala:11:5 -----------------------------------------------------------
11 |  all(nextInt(all.length))  // error
   |  ^^^^^^^^^^^^^^^^^^^^^^^^
   |  Local reach capability tail* leaks into capture scope of method oneOf.
   |  You could try to abstract the capabilities referred to by tail* in a capset variable.

The correct way to fix the example is:

import caps.*

trait Rand extends SharedCapability:
  def range(min: Int, max: Int): Int

def nextInt(max: Int): Rand ?-> Int =
  r ?=> r.range(0, max)

def oneOf[A, B^](head: Rand ?=> A, tail: (Rand ?->{B} A)*): Rand ?->{head, B} A =
  val all: Seq[Rand ?->{head, B} A] = head +: tail // error
  all(nextInt(all.length))