From db529d9bff6757c4f2fe139de898fb1dc969a0bd Mon Sep 17 00:00:00 2001 From: odersky Date: Wed, 10 Apr 2024 18:43:06 +0200 Subject: [PATCH] Rewrite reaches tests to fix tasty-cc nightly failures The reaches.scala pos test failed the nightly with tasty cc since one line violated the new condition for reaches capabilities. The problem was not discoveed in normal testing since it used the `List` class, which is capture checked only in the nightly. We now make the relevant bits of `List` explicit in the test itself, so that it is always capture checked. The failing line got moved to neg. --- tests/neg-custom-args/captures/reaches.check | 5 +++++ tests/neg-custom-args/captures/reaches.scala | 18 ++++++++++++++++++ tests/pos-custom-args/captures/reaches.scala | 12 +++++++++++- 3 files changed, 34 insertions(+), 1 deletion(-) diff --git a/tests/neg-custom-args/captures/reaches.check b/tests/neg-custom-args/captures/reaches.check index ee628a212ce7..a1c5a56369e9 100644 --- a/tests/neg-custom-args/captures/reaches.check +++ b/tests/neg-custom-args/captures/reaches.check @@ -41,3 +41,8 @@ | Required: File^{id*} | | longer explanation available when compiling with `-explain` +-- Error: tests/neg-custom-args/captures/reaches.scala:77:5 ------------------------------------------------------------ +77 | ps.map((x, y) => compose1(x, y)) // error: cannot mix cap and * + | ^^^^^^ + | Reach capability cap and universal capability cap cannot both + | appear in the type [B](f: ((box A ->{ps*} A, box A ->{ps*} A)) => B): List[B] of this expression diff --git a/tests/neg-custom-args/captures/reaches.scala b/tests/neg-custom-args/captures/reaches.scala index 8ba7f60d6335..de5e4362cdf2 100644 --- a/tests/neg-custom-args/captures/reaches.scala +++ b/tests/neg-custom-args/captures/reaches.scala @@ -59,3 +59,21 @@ def attack2 = val leaked = usingFile[File^{id*}]: f => val f1: File^{id*} = id(f) // error f1 + +class List[+A]: + def head: A = ??? + def tail: List[A] = ??? + def map[B](f: A => B): List[B] = ??? + def nonEmpty: Boolean = ??? + +extension [A](x: A) def :: (xs: List[A]): List[A] = ??? + +object Nil extends List[Nothing] + +def compose1[A, B, C](f: A => B, g: B => C): A ->{f, g} C = + z => g(f(z)) + +def mapCompose[A](ps: List[(A => A, A => A)]): List[A ->{ps*} A] = + ps.map((x, y) => compose1(x, y)) // error: cannot mix cap and * + + diff --git a/tests/pos-custom-args/captures/reaches.scala b/tests/pos-custom-args/captures/reaches.scala index 0f7df02e13b1..f17c25712c39 100644 --- a/tests/pos-custom-args/captures/reaches.scala +++ b/tests/pos-custom-args/captures/reaches.scala @@ -10,6 +10,16 @@ class Ref[T](init: T): def get: T = x def set(y: T) = { x = y } +class List[+A]: + def head: A = ??? + def tail: List[A] = ??? + def map[B](f: A -> B): List[B] = ??? + def nonEmpty: Boolean = ??? + +extension [A](x: A) def :: (xs: List[A]): List[A] = ??? + +object Nil extends List[Nothing] + def runAll(xs: List[Proc]): Unit = var cur: List[() ->{xs*} Unit] = xs // OK, by revised VAR while cur.nonEmpty do @@ -36,7 +46,7 @@ def compose2[A, B, C](f: A => B, g: B => C): A => C = z => g(f(z)) def mapCompose[A](ps: List[(A => A, A => A)]): List[A ->{ps*} A] = - ps.map((x, y) => compose1(x, y)) + ps.map((x, y) => compose1(x, y)) // Does not work if map takes an impure function, see reaches in neg @annotation.capability class IO