From 99f6d8c0e4e5cdf0f5b91a5d6a39977639abc57e Mon Sep 17 00:00:00 2001 From: Mateusz Kowalewski <7350866+MateuszKowalewski@users.noreply.github.com> Date: Sun, 2 Jul 2023 17:55:44 +0200 Subject: [PATCH] Introduce warning supression for problematic pattern-matches This is a temporary workaround. The long term goal is to get rid of these nasty annotations again. This will need support form the Scala team though. --- core/src/main/scala/libretto/CoreLib.scala | 7 +++ core/src/main/scala/libretto/InvertLib.scala | 2 + .../scala/libretto/scaletto/ScalettoLib.scala | 2 + .../impl/futurebased/FutureExecutor.scala | 2 + .../unaryArithmetic/package.scala | 2 + .../SunflowerProcessingFacility.scala | 2 + .../src/main/scala/libretto/lambda/Bin.scala | 4 ++ .../main/scala/libretto/lambda/Lambdas.scala | 2 + .../scala/libretto/lambda/LambdasImpl.scala | 13 ++++++ .../scala/libretto/lambda/Projection.scala | 3 ++ .../main/scala/libretto/lambda/Shuffle.scala | 45 +++++++++++++++++-- .../main/scala/libretto/lambda/Shuffled.scala | 9 ++++ .../src/test/scala/libretto/lambda/Fun.scala | 2 + .../scala/libretto/stream/CoreStreams.scala | 4 ++ .../stream/scaletto/ScalettoStreams.scala | 3 ++ .../scaletto/ScalettoTestExecutor.scala | 2 + 16 files changed, 101 insertions(+), 3 deletions(-) diff --git a/core/src/main/scala/libretto/CoreLib.scala b/core/src/main/scala/libretto/CoreLib.scala index 9ea08b4c..147dc9b3 100644 --- a/core/src/main/scala/libretto/CoreLib.scala +++ b/core/src/main/scala/libretto/CoreLib.scala @@ -5,6 +5,7 @@ import libretto.lambda.util.SourcePos import libretto.util.unapply.* import libretto.util.{Equal, ∀} import scala.annotation.tailrec +import scala.annotation.nowarn object CoreLib { def apply(dsl: CoreDSL): CoreLib[dsl.type] = @@ -1199,6 +1200,7 @@ class CoreLib[DSL <: CoreDSL](val dsl: DSL) { lib => def selectAgainstR[A](using A: SignalingJunction.Negative[A]): (A |&| A) -⚬ (A |*| Need) = |&|.swap > selectAgainstL > swap + @nowarn("msg=match may not be exhaustive") def racePreferred[A, B](using A: Signaling.Positive[A], B: Signaling.Positive[B], @@ -1215,6 +1217,7 @@ class CoreLib[DSL <: CoreDSL](val dsl: DSL) { lib => } } + @nowarn("msg=match may not be exhaustive") def raceHandicap[A, B, C](f: (Ping |*| B) -⚬ C)(using A: Signaling.Positive[A], C: Signaling.Positive[C], @@ -3533,6 +3536,7 @@ class CoreLib[DSL <: CoreDSL](val dsl: DSL) { lib => /** Merges the two lists as they unfold, i.e. as soon as the next element becomes available in one of the lists, * it also becomes available as the next element of the result list. */ + @nowarn("msg=match may not be exhaustive") def merge[T]: (LList[T] |*| LList[T]) -⚬ LList[T] = rec { self => λ { case as |*| bs => race(as |*| bs) switch { @@ -3557,6 +3561,7 @@ class CoreLib[DSL <: CoreDSL](val dsl: DSL) { lib => * their timely appearence in the input list is sufficient for them to come before * the inserted element. */ + @nowarn("msg=match may not be exhaustive") def insertBySignal[T](using Signaling.Positive[T]): (T |*| LList[T]) -⚬ LList[T] = rec { self => λ { case a |*| as => @@ -3892,6 +3897,7 @@ class CoreLib[DSL <: CoreDSL](val dsl: DSL) { lib => def mapSequentially[A, B](f: A -⚬ B)(using Signaling.Positive[B]): Endless[A] -⚬ Endless[B] = mapSequence(f > notifyPosFst) + @nowarn("msg=match may not be exhaustive") def foldLeftSequentially[B, A](f: (B |*| A) -⚬ B)(using Signaling.Positive[B] ): (B |*| Endless[A]) -⚬ B = @@ -3957,6 +3963,7 @@ class CoreLib[DSL <: CoreDSL](val dsl: DSL) { lib => def go: ((A |*| Endless[A]) |*| Endless[A]) -⚬ Endless[A] = rec { self => λ { case (a |*| as) |*| bs => val po |*| pi = constant(lInvertPongPing) + @nowarn("msg=match may not be exhaustive") val res: $[One |&| (A |*| Endless[A])] = race[Ping, A](pi |*| a) switch { case Left(?(_) |*| a) => diff --git a/core/src/main/scala/libretto/InvertLib.scala b/core/src/main/scala/libretto/InvertLib.scala index eb5cec73..b09182c4 100644 --- a/core/src/main/scala/libretto/InvertLib.scala +++ b/core/src/main/scala/libretto/InvertLib.scala @@ -1,6 +1,7 @@ package libretto import libretto.lambda.util.SourcePos +import scala.annotation.nowarn object InvertLib { def apply( @@ -54,6 +55,7 @@ class InvertLib[ ): $[(A |*| B) |+| (A |*| B)] = coreLib.race[A, B](a |*| b) + @nowarn("msg=match may not be exhaustive") def race[B](using SourcePos, LambdaContext)(b: ??[B])(using Signaling.Positive[A], Signaling.Negative[B], diff --git a/core/src/main/scala/libretto/scaletto/ScalettoLib.scala b/core/src/main/scala/libretto/scaletto/ScalettoLib.scala index 6a2d7243..7b686b6a 100644 --- a/core/src/main/scala/libretto/scaletto/ScalettoLib.scala +++ b/core/src/main/scala/libretto/scaletto/ScalettoLib.scala @@ -8,6 +8,7 @@ import scala.annotation.targetName import scala.concurrent.duration.* import scala.reflect.TypeTest import scala.util.Random +import scala.annotation.nowarn object ScalettoLib { def apply( @@ -117,6 +118,7 @@ class ScalettoLib[ def delayValRandomMs[A](minMs: Int, maxMs: Int): Val[A] -⚬ Val[A] = delayVal(delayRandomMs(minMs, maxMs)) + @nowarn("msg=match may not be exhaustive") def latestValue[A]: (Val[A] |*| LList[Val[A]]) -⚬ (Endless[Val[A]] |*| Done) = rec { self => λ { case +(a) |*| as => producing { case outAs |*| outDone => diff --git a/core/src/main/scala/libretto/scaletto/impl/futurebased/FutureExecutor.scala b/core/src/main/scala/libretto/scaletto/impl/futurebased/FutureExecutor.scala index 48570f0d..1cc77248 100644 --- a/core/src/main/scala/libretto/scaletto/impl/futurebased/FutureExecutor.scala +++ b/core/src/main/scala/libretto/scaletto/impl/futurebased/FutureExecutor.scala @@ -8,6 +8,7 @@ import libretto.scaletto.ScalettoExecutor import libretto.scaletto.impl.FreeScaletto import libretto.util.Async import scala.concurrent.ExecutionContext +import scala.annotation.nowarn object FutureExecutor { def apply( @@ -29,6 +30,7 @@ object FutureExecutor { override def scheduler(s: Scheduler): ExecutionParam[Unit] = ExecutionParams.Free.wrap(SchedulerParam(s)) + @nowarn("msg=type test") def extract[A](pa: ExecutionParam[A]): (Option[Scheduler], A) = { import ExecutionParams.Free.{One, Zip, Ext} pa match { diff --git a/examples/src/main/scala/libretto/examples/interactionNets/unaryArithmetic/package.scala b/examples/src/main/scala/libretto/examples/interactionNets/unaryArithmetic/package.scala index 0e436d9c..980474ce 100644 --- a/examples/src/main/scala/libretto/examples/interactionNets/unaryArithmetic/package.scala +++ b/examples/src/main/scala/libretto/examples/interactionNets/unaryArithmetic/package.scala @@ -27,6 +27,7 @@ object Wire { def dup : (Wire |*| Wire) -⚬ Proper = injectL ∘ injectR def eraser: One -⚬ Proper = injectR + @nowarn("msg=match may not be exhaustive") def switchWith[A, R]( caseZero: A -⚬ R, caseSucc: (A |*| Wire) -⚬ R, @@ -192,6 +193,7 @@ object Wire { } import Wire.Outlet +import scala.annotation.nowarn enum Result { case Zero diff --git a/examples/src/main/scala/libretto/examples/sunflowers/SunflowerProcessingFacility.scala b/examples/src/main/scala/libretto/examples/sunflowers/SunflowerProcessingFacility.scala index 0055649e..d63d3956 100644 --- a/examples/src/main/scala/libretto/examples/sunflowers/SunflowerProcessingFacility.scala +++ b/examples/src/main/scala/libretto/examples/sunflowers/SunflowerProcessingFacility.scala @@ -3,8 +3,10 @@ package libretto.examples.sunflowers import libretto.scaletto.StarterKit.* import libretto.stream.scaletto.DefaultStreams.ValSource import libretto.stream.scaletto.DefaultStreams.ValSource.{Polled, fromChoice, notifyAction, poll} +import scala.annotation.nowarn object SunflowerProcessingFacility { + @nowarn("msg=match may not be exhaustive") def blueprint: ValSource[Sunflower] -⚬ (ValSource[SeedsPack] |*| ValSource[OilBottle]) = rec { self => λ { sunflowers => // give names to the outputs diff --git a/lambda/src/main/scala/libretto/lambda/Bin.scala b/lambda/src/main/scala/libretto/lambda/Bin.scala index 4aa4c113..2194a58b 100644 --- a/lambda/src/main/scala/libretto/lambda/Bin.scala +++ b/lambda/src/main/scala/libretto/lambda/Bin.scala @@ -2,6 +2,7 @@ package libretto.lambda import libretto.lambda.util.{BiInjective, Exists, Injective, Masked, TypeEq, UniqueTypeArg} import libretto.lambda.util.TypeEq.Refl +import scala.annotation.nowarn /** * Binary tree with leafs holding values of types `F[X]`, `F[Y]`, ... @@ -92,6 +93,7 @@ sealed trait Bin[<*>[_, _], T[_], F[_], A] { ) extends Partitioned[G, H, ~⚬] } + @nowarn("msg=type test") def deduplicateLeafs[->[_, _]]( dup: [x] => F[x] => T[x] -> (T[x] <*> T[x]), )(using @@ -294,6 +296,7 @@ object Bin { case class Branch[<*>[_, _], T[_], F[_], A, B](l: Bin[<*>, T, F, A], r: Bin[<*>, T, F, B]) extends Bin[<*>, T, F, A <*> B] case class Leaf[<*>[_, _], T[_], F[_], A](value: F[A]) extends Bin[<*>, T, F, T[A]] + @nowarn("msg=match may not be exhaustive") def branchesOf[<*>[_, _], T[_], F[_], A, B](tree: Bin[<*>, T, F, A <*> B])(using leafIsNotBranch: [x, y, z] => (T[x] =:= (y <*> z)) => Nothing, )(using @@ -311,6 +314,7 @@ object Bin { } ) + @nowarn("msg=match may not be exhaustive") def valueOf[<*>[_, _], T[_], F[_], A](tree: Bin[<*>, T, F, T[A]])(using leafIsNotBranch: [x, y, z] => (T[x] =:= (y <*> z)) => Nothing, )(using diff --git a/lambda/src/main/scala/libretto/lambda/Lambdas.scala b/lambda/src/main/scala/libretto/lambda/Lambdas.scala index 936d9a39..1fc1eebc 100644 --- a/lambda/src/main/scala/libretto/lambda/Lambdas.scala +++ b/lambda/src/main/scala/libretto/lambda/Lambdas.scala @@ -4,6 +4,7 @@ import libretto.lambda.Lambdas.Error import libretto.lambda.Lambdas.Error.LinearityViolation import libretto.lambda.util.{Applicative, BiInjective, Exists, UniqueTypeArg} import scala.annotation.targetName +import scala.annotation.nowarn trait Lambdas[-⚬[_, _], |*|[_, _], V] { final type Tupled[F[_], A] = libretto.lambda.Tupled[|*|, F, A] @@ -130,6 +131,7 @@ trait Lambdas[-⚬[_, _], |*|[_, _], V] { Context, ): AbsRes[A, B] + @nowarn("msg=match may not be exhaustive") protected def switchImpl[<+>[_, _], A, B]( cases: Sink[VFun, <+>, A, B], sum: [X, Y] => (X -⚬ B, Y -⚬ B) => (X <+> Y) -⚬ B, diff --git a/lambda/src/main/scala/libretto/lambda/LambdasImpl.scala b/lambda/src/main/scala/libretto/lambda/LambdasImpl.scala index ac4a9ff0..a8d8aab1 100644 --- a/lambda/src/main/scala/libretto/lambda/LambdasImpl.scala +++ b/lambda/src/main/scala/libretto/lambda/LambdasImpl.scala @@ -6,6 +6,7 @@ import libretto.lambda.Lambdas.Error.LinearityViolation import libretto.lambda.util.{Applicative, BiInjective, Exists, Injective, Masked, TypeEq, UniqueTypeArg} import libretto.lambda.util.TypeEq.Refl import scala.annotation.{tailrec, targetName} +import scala.annotation.nowarn class LambdasImpl[-⚬[_, _], |*|[_, _], V](using ssc: SymmetricSemigroupalCategory[-⚬, |*|], @@ -631,6 +632,7 @@ class LambdasImpl[-⚬[_, _], |*|[_, _], V](using override def cap2_gcd_this[T, Y](that: CaptureSnd[T, Y])(using ev: (Var[A1] |*| Var[A2]) =:= Var[T]): Option[Tail[Var[T], Var[T |*| Y] |*| Var[A1 |*| A2]]] = varIsNotPair(ev.flip) + @nowarn("msg=match may not be exhaustive") override def asZip[P1, P2](using ev: (Var[A1] |*| Var[A2]) =:= (P1 |*| P2), ): Exists[[V1] =>> Exists[[V2] =>> (Zip[V1, V2], P1 =:= Var[V1], P2 =:= Var[V2], Var[A1 |*| A2] =:= Var[V1 |*| V2])]] = @@ -702,6 +704,7 @@ class LambdasImpl[-⚬[_, _], |*|[_, _], V](using case (None, Some(_)) => bug(s"Variable ${that.resultVar} appeared as a result of two different projections") + @nowarn("msg=match may not be exhaustive") override def unzip_gcd_this[T1, T2](that: Unzip[T1, T2])(using ev: Var[A1 |*| A2] =:= Var[T1 |*| T2], ): Option[Tail[Var[T1 |*| T2], (Var[T1] |*| Var[T2]) |*| Var[A1]]] = @@ -855,6 +858,7 @@ class LambdasImpl[-⚬[_, _], |*|[_, _], V](using override def unzip_gcd_this[T1, T2](that: Unzip[T1, T2])(using ev: Var[A] =:= Var[T1 |*| T2]): Option[Tail[Var[T1 |*| T2], (Var[T1] |*| Var[T2]) |*| Var[X |*| A]]] = UnhandledCase.raise(s"${this.getClass.getSimpleName}.unzip_gcd_this") + @nowarn("msg=match may not be exhaustive") override def cap1_gcd_this[T, Y](that: CaptureFst[T, Y])(using ev: Var[A] =:= Var[T]): Option[Tail[Var[T], Var[Y |*| T] |*| Var[X |*| A]]] = ev match { case Injective[Var](TypeEq(Refl())) => (that.resultVar testEqual this.resultVar) map { @@ -889,6 +893,7 @@ class LambdasImpl[-⚬[_, _], |*|[_, _], V](using override def cap1_gcd_this[T, Y](that: CaptureFst[T, Y])(using Var[A] =:= Var[T]): Option[Tail[Var[T], Var[Y |*| T] |*| Var[A |*| X]]] = None + @nowarn("msg=match may not be exhaustive") override def cap2_gcd_this[T, Y](that: CaptureSnd[T, Y])(using ev: Var[A] =:= Var[T]): Option[Tail[Var[T], Var[T |*| Y] |*| Var[A |*| X]]] = ev match { case Injective[Var](TypeEq(Refl())) => (that.resultVar testEqual this.resultVar) map { @@ -935,6 +940,8 @@ class LambdasImpl[-⚬[_, _], |*|[_, _], V](using } } + @nowarn("msg=match may not be exhaustive") + @nowarn("msg=type test") def gcd[C[_], D[_], X, Y, Z]( f: Op.Affine[C[Var[X]], Y], g: Op.Affine[D[Var[X]], Z], @@ -964,6 +971,7 @@ class LambdasImpl[-⚬[_, _], |*|[_, _], V](using } } + @nowarn("msg=match may not be exhaustive") private def gcdZips[A1, A2, B1, B2]( z1: Zip[A1, A2], z2: Zip[B1, B2], @@ -1070,6 +1078,7 @@ class LambdasImpl[-⚬[_, _], |*|[_, _], V](using case Op.Prj2(_, _) => None } + @nowarn("msg=match may not be exhaustive") def pullBumpDupVar[A, F[_], V, C[_], B, D[_], Y]( pre: Tail[A, F[Var[V]]], post: Tail[F[C[Var[V]]], B], @@ -1211,6 +1220,7 @@ class LambdasImpl[-⚬[_, _], |*|[_, _], V](using } object Unvar { case class SingleVar[V]() extends Unvar[Var[V], V] { + @nowarn("msg=match may not be exhaustive") override def uniqueOutType[C](that: Unvar[Var[V], C]): V =:= C = that.maskInput.visit([VV] => (that: Unvar[VV, C], ev: VV =:= Var[V]) => { that match { @@ -1225,6 +1235,7 @@ class LambdasImpl[-⚬[_, _], |*|[_, _], V](using } case class Par[A1, A2, X1, X2](u1: Unvar[A1, X1], u2: Unvar[A2, X2]) extends Unvar[A1 |*| A2, X1 |*| X2] { + @nowarn("msg=match may not be exhaustive") override def uniqueOutType[C](that: Unvar[A1 |*| A2, C]): (X1 |*| X2) =:= C = that.maskInput.visit([A] => (that: Unvar[A, C], ev: A =:= (A1 |*| A2)) => { that match { @@ -1248,6 +1259,7 @@ class LambdasImpl[-⚬[_, _], |*|[_, _], V](using override def pair[A1, A2, X1, X2](f1: Unvar[A1, X1], f2: Unvar[A2, X2]): Unvar[A1 |*| A2, X1 |*| X2] = Unvar.Par(f1, f2) + @nowarn("msg=match may not be exhaustive") override def unpair[A1, A2, X](f: Unvar[A1 |*| A2, X]): Unpaired[A1, A2, X] = f.maskInput.visit[Unpaired[A1, A2, X]]([A] => (u: Unvar[A, X], ev: A =:= (A1 |*| A2)) => { u match { @@ -1266,6 +1278,7 @@ class LambdasImpl[-⚬[_, _], |*|[_, _], V](using [V, A, B] => (ev: Var[V] =:= (A |*| B)) => throw new AssertionError("Var[A] =:= (A |*| B)") extension[F[_], V, U](ev: F[Var[V]] =:= (Var[U] |*| Var[U])) { + @nowarn("msg=match may not be exhaustive") def deriveEquality(f: Focus[|*|, F]): V =:= U = f match { case f: Focus.Fst[pair, f1, q] => diff --git a/lambda/src/main/scala/libretto/lambda/Projection.scala b/lambda/src/main/scala/libretto/lambda/Projection.scala index 8d9ac71d..fe6babc2 100644 --- a/lambda/src/main/scala/libretto/lambda/Projection.scala +++ b/lambda/src/main/scala/libretto/lambda/Projection.scala @@ -2,6 +2,7 @@ package libretto.lambda import libretto.lambda.util.{BiInjective, Exists, TypeEq} import libretto.lambda.util.TypeEq.Refl +import scala.annotation.nowarn sealed trait Projection[|*|[_, _], P, Q] { def at[F[_]](f: Focus[|*|, F]): Projection[|*|, F[P], F[Q]] @@ -73,6 +74,8 @@ object Projection { switchFromPair[P1, P2, R](caseDiscardFst, caseDiscardSnd, casePar) } + @nowarn("msg=match may not be exhaustive") + @nowarn("msg=type test") def switchFromPair[P1, P2, R](using ev: P =:= (P1 |*| P2))( caseDiscardFst: (p2: Projection[|*|, P2, Q]) => R, caseDiscardSnd: (p1: Projection[|*|, P1, Q]) => R, diff --git a/lambda/src/main/scala/libretto/lambda/Shuffle.scala b/lambda/src/main/scala/libretto/lambda/Shuffle.scala index 998c04d4..9724f398 100644 --- a/lambda/src/main/scala/libretto/lambda/Shuffle.scala +++ b/lambda/src/main/scala/libretto/lambda/Shuffle.scala @@ -5,6 +5,7 @@ import libretto.lambda.util.{BiInjective, Exists, TypeEq} import libretto.lambda.util.BiInjective.* import libretto.lambda.util.TypeEq.Refl import libretto.lambda.Projection.Proper +import scala.annotation.nowarn class Shuffle[|*|[_, _]](using inj: BiInjective[|*|]) { sealed trait ~⚬[A, B] { @@ -180,7 +181,7 @@ class Shuffle[|*|[_, _]](using inj: BiInjective[|*|]) { } override def chaseFw[F[_], T](i: Focus[|*|, F])(using ev: (A1 |*| A2) =:= F[T]): ChaseFwRes[F, T, B1 |*| B2] = { - val res0: ChaseFwRes[F, T, X1 |*| X2] = + @nowarn("msg=match may not be exhaustive") val res0: ChaseFwRes[F, T, X1 |*| X2] = i match case Focus.Id() => ChaseFwRes.Split(summon[T =:= F[T]] andThen ev.flip) @@ -356,6 +357,7 @@ class Shuffle[|*|[_, _]](using inj: BiInjective[|*|]) { override def after[F0[_]](f: [x] => Unit => F0[x] ~⚬ F[x]): ChaseFwRes[F0, X, B] = Transported[F0, X, G, B]([t] => (_: Unit) => f[t](()) > s[t](()), g, ev) + @nowarn("msg=match may not be exhaustive") override def thenSnd[B1, B2, C](f: B2 ~⚬ C)(using ev1: B =:= (B1 |*| B2)): ChaseFwRes[F, X, B1 |*| C] = g match { case Focus.Id() => @@ -428,6 +430,7 @@ class Shuffle[|*|[_, _]](using inj: BiInjective[|*|]) { [t] => (_: Unit) => par(fst, s[t](())), ) + @nowarn("msg=match may not be exhaustive") override def afterAssocLR[A1, A2, A3](using ev1: (A2 |*| A3) =:= A): ChaseBwRes[(A1 |*| A2) |*| A3, [x] =>> A1 |*| G[x], X] = f match { case Focus.Id() => @@ -450,6 +453,7 @@ class Shuffle[|*|[_, _]](using inj: BiInjective[|*|]) { } } + @nowarn("msg=match may not be exhaustive") override def afterAssocRL[A1, A2, A3](using ev1: (A1 |*| A2) =:= A): ChaseBwRes[A1 |*| (A2 |*| A3), [x] =>> G[x] |*| A3, X] = f match { case Focus.Id() => @@ -472,6 +476,7 @@ class Shuffle[|*|[_, _]](using inj: BiInjective[|*|]) { } } + @nowarn("msg=match may not be exhaustive") override def afterXI[A1, A2, A3](using ev1: (A1 |*| A3) =:= A): ChaseBwRes[A1 |*| (A2 |*| A3), [x] =>> A2 |*| G[x], X] = f match { case Focus.Id() => @@ -494,6 +499,7 @@ class Shuffle[|*|[_, _]](using inj: BiInjective[|*|]) { } } + @nowarn("msg=match may not be exhaustive") override def afterIX[A1, A2, A3](using ev1: (A1 |*| A3) =:= A): ChaseBwRes[(A1 |*| A2) |*| A3, [x] =>> G[x] |*| A2, X] = f match { case Focus.Id() => @@ -516,6 +522,7 @@ class Shuffle[|*|[_, _]](using inj: BiInjective[|*|]) { } } + @nowarn("msg=match may not be exhaustive") override def afterIXI1[A1, A2, A3, A4](using ev1: (A1 |*| A3) =:= A): ChaseBwRes[(A1 |*| A2) |*| (A3 |*| A4), [x] =>> G[x] |*| (A2 |*| A4), X] = f match { case Focus.Id() => @@ -672,6 +679,7 @@ class Shuffle[|*|[_, _]](using inj: BiInjective[|*|]) { }}}} } + @nowarn("msg=match may not be exhaustive") def chaseFw[F[_], T](i: Focus[|*|, F])(using ev: (X1 |*| X2) =:= F[T]): ChaseFwRes[F, T, Y1 |*| Y2] = i match { case Focus.Id() => @@ -706,6 +714,7 @@ class Shuffle[|*|[_, _]](using inj: BiInjective[|*|]) { } } + @nowarn("msg=match may not be exhaustive") def chaseBw[G[_], T](i: Focus[|*|, G])(using ev: (Y1 |*| Y2) =:= G[T]): ChaseBwRes[X1 |*| X2, G, T] = i match { case Focus.Id() => @@ -762,6 +771,7 @@ class Shuffle[|*|[_, _]](using inj: BiInjective[|*|]) { def chaseBwFst[G[_], T](i: Focus[|*|, G])(using B1 =:= G[T]): ChaseBwRes[A1 |*| A2, [t] =>> G[t] |*| B2, T] def chaseBwSnd[G[_], T](i: Focus[|*|, G])(using B2 =:= G[T]): ChaseBwRes[A1 |*| A2, [t] =>> B1 |*| G[t], T] + @nowarn("msg=match may not be exhaustive") final def translate[<*>[_, _], F[_, _], S]( fa: F[A1 |*| A2, S], )( @@ -1051,6 +1061,7 @@ class Shuffle[|*|[_, _]](using inj: BiInjective[|*|]) { } } + @nowarn("msg=match may not be exhaustive") final override def chaseFw[F[_], T](i: Focus[|*|, F])(using ev: F[T] =:= (A1 |*| A2)): ChaseFwRes[F, T, B1 |*| B2] = i match { case Focus.Id() => @@ -1065,6 +1076,7 @@ class Shuffle[|*|[_, _]](using inj: BiInjective[|*|]) { chaseFwSnd[f2, T](snd.i) } + @nowarn("msg=match may not be exhaustive") final override def chaseBw[G[_], T](i: Focus[|*|, G])(using ev: (B1 |*| B2) =:= G[T]): ChaseBwRes[A1 |*| A2, G, T] = i match { case Focus.Id() => @@ -1311,6 +1323,8 @@ class Shuffle[|*|[_, _]](using inj: BiInjective[|*|]) { F.zip(a1, g(F.zip(a2, a3))) } + @nowarn("msg=match may not be exhaustive") + @nowarn("msg=type test") override def translateLR[<*>[_,_], F[_,_], S12, S3]( fa12: F[A1 |*| A2, S12], fa3 : F[A3, S3], @@ -1325,6 +1339,7 @@ class Shuffle[|*|[_, _]](using inj: BiInjective[|*|]) { }} } + @nowarn("msg=match may not be exhaustive") override def translateRL[<*>[_, _], F[_, _], T1, T2]( fa1: F[A1, T1], fb23: F[B2 |*| B3, T2], @@ -1340,6 +1355,7 @@ class Shuffle[|*|[_, _]](using inj: BiInjective[|*|]) { Exists(Exists((m.pair(fa1, fa2), fa3, tgt.Transfer.AssocLR(h)))) } + @nowarn("msg=match may not be exhaustive") override def chaseFwFst[F[_], T](i: Focus[|*|, F])(using ev: F[T] =:= (A1 |*| A2), ): ChaseFwRes[[t] =>> F[t] |*| A3, T, A1 |*| (B2 |*| B3)] = @@ -1400,6 +1416,7 @@ class Shuffle[|*|[_, _]](using inj: BiInjective[|*|]) { Xfer(assocLR[A11, A12, A2] > snd(f1), f2, AssocLR(g)) } + @nowarn("msg=match may not be exhaustive") override def thenAssocRL[B21, B22, C1, C2]( that: AssocRL[A1, B21, B22, C1, C2], )(using @@ -1423,6 +1440,7 @@ class Shuffle[|*|[_, _]](using inj: BiInjective[|*|]) { case Decomposition(f1, f2, h) => Xfer(fst(Id0(ev)) > ix > fst(f1), f2, IX(h)) } + @nowarn("msg=match may not be exhaustive") override def thenXI[B21, B22, C2, C3]( that: XI[A1, B21, B22, C2, C3], )(using @@ -1573,6 +1591,8 @@ class Shuffle[|*|[_, _]](using inj: BiInjective[|*|]) { F.zip(g(F.zip(a1, a2)), a3) } + @nowarn("msg=match may not be exhaustive") + @nowarn("msg=type test") override def translateLR[<*>[_, _], F[_, _], S1, S23]( fa1: F[A1, S1], fa23: F[A2 |*| A3, S23], @@ -1586,6 +1606,7 @@ class Shuffle[|*|[_, _]](using inj: BiInjective[|*|]) { Exists(Exists((tgt.Transfer.AssocRL[S1, v.X1, v.X2, e1.T, e2.T](g1), m.pair(fb1, fb2), fa3))) }} + @nowarn("msg=match may not be exhaustive") override def translateRL[<*>[_, _], F[_, _], T1, T2]( fb12: F[B1 |*| B2, T1], fa3: F[A3, T2], @@ -1607,6 +1628,7 @@ class Shuffle[|*|[_, _]](using inj: BiInjective[|*|]) { .after([t] => (_: Unit) => assocRL[F[t], A2, A3]) } + @nowarn("msg=match may not be exhaustive") override def chaseFwSnd[F[_], T](i: Focus[|*|, F])(using ev: F[T] =:= (A2 |*| A3)): ChaseFwRes[[t] =>> A1 |*| F[t], T, (B1 |*| B2) |*| A3] = i match { case Focus.Id() => @@ -1649,6 +1671,7 @@ class Shuffle[|*|[_, _]](using inj: BiInjective[|*|]) { case Decomposition(f1, f2, h) => Xfer(f1, fst(f2) > swap, XI(h)) } + @nowarn("msg=match may not be exhaustive") override def thenAssocLR[D1, D2, C2, C3]( that: AssocLR[D1, D2, A3, C2, C3], )(using @@ -1837,6 +1860,8 @@ class Shuffle[|*|[_, _]](using inj: BiInjective[|*|]) { F.zip(g(F.zip(a1, a3)), a2) } + @nowarn("msg=match may not be exhaustive") + @nowarn("msg=type test") override def translateLR[<*>[_, _], F[_, _], S12, S3]( fa12: F[A1 |*| A2, S12], fa3: F[A3, S3], @@ -1851,6 +1876,7 @@ class Shuffle[|*|[_, _]](using inj: BiInjective[|*|]) { case e1 @ Exists.Some(e2 @ Exists.Some((g1, fb1, fb2))) => Exists(Exists((tgt.Transfer.IX[v.X1, v.X2, S3, e1.T, e2.T](g1), m.pair(fb1, fb2), fa2))) + @nowarn("msg=match may not be exhaustive") override def translateRL[<*>[_, _], F[_, _], T1, T2]( fb12: F[B1 |*| B2, T1], fa2: F[A2, T2], @@ -1865,6 +1891,7 @@ class Shuffle[|*|[_, _]](using inj: BiInjective[|*|]) { case Exists.Some(Exists.Some((fa1, fa3, g1))) => Exists(Exists((m.pair(fa1, fa2), fa3, tgt.Transfer.IX(g1)))) + @nowarn("msg=match may not be exhaustive") override def chaseFwFst[F[_], T](i: Focus[|*|, F])(using ev: F[T] =:= (A1 |*| A2)): ChaseFwRes[[t] =>> F[t] |*| A3, T, (B1 |*| B2) |*| A2] = ev match { case TypeEq(Refl()) => i match @@ -2107,6 +2134,8 @@ class Shuffle[|*|[_, _]](using inj: BiInjective[|*|]) { F.zip(a2, g(F.zip(a1, a3))) } + @nowarn("msg=match may not be exhaustive") + @nowarn("msg=type test") override def translateLR[<*>[_, _], F[_, _], S1, S23]( fa1: F[A1, S1], fa23: F[A2 |*| A3, S23], @@ -2121,6 +2150,7 @@ class Shuffle[|*|[_, _]](using inj: BiInjective[|*|]) { case e1 @ Exists.Some(e2 @ Exists.Some((g1, fb2, fb3))) => Exists(Exists((tgt.Transfer.XI[S1, v.X1, v.X2, e1.T, e2.T](g1), fa2, m.pair(fb2, fb3)))) + @nowarn("msg=match may not be exhaustive") override def translateRL[<*>[_, _], F[_, _], T1, T2]( fb1: F[A2, T1], fb23: F[B2 |*| B3, T2], @@ -2145,12 +2175,13 @@ class Shuffle[|*|[_, _]](using inj: BiInjective[|*|]) { ).thenSnd[A2, A1 |*| A3, B2 |*| B3](g.asShuffle) } + @nowarn("msg=match may not be exhaustive") override def chaseFwSnd[F[_], T](i: Focus[|*|, F])(using ev: F[T] =:= (A2 |*| A3)): ChaseFwRes[[t] =>> A1 |*| F[t], T, A2 |*| (B2 |*| B3)] = i match { case Focus.Id() => ChaseFwRes.Split(ev) case i: Focus.Fst[pair, f1, z] => - (summon[(f1[T] |*| z) =:= F[T]] andThen ev) match { case BiInjective[|*|](TypeEq(Refl()), TypeEq(Refl())) => + (summon[(f1[T] |*| z) =:= F[T]] andThen ev) match { case BiInjective[|*|](TypeEq(Refl()), TypeEq(Refl())) => type G[t] = A1 |*| (f1[t] |*| A3) type H[t] = f1[t] |*| (B2 |*| B3) ChaseFwRes.Transported[G, T, H, A2 |*| (B2 |*| B3)]( @@ -2160,7 +2191,7 @@ class Shuffle[|*|[_, _]](using inj: BiInjective[|*|]) { ) } case i: Focus.Snd[pair, f2, z] => - (summon[(z |*| f2[T]) =:= F[T]] andThen ev) match { case BiInjective[|*|](TypeEq(Refl()), TypeEq(Refl())) => + (summon[(z |*| f2[T]) =:= F[T]] andThen ev) match { case BiInjective[|*|](TypeEq(Refl()), TypeEq(Refl())) => g.chaseFw[[x] =>> A1 |*| f2[x], T](i.i.inSnd[A1]) .inSnd[A2] .after([x] => (_: Unit) => xi[A1, A2, f2[x]]) @@ -2198,6 +2229,7 @@ class Shuffle[|*|[_, _]](using inj: BiInjective[|*|]) { Xfer(f1, assocLR[A21, A22, A3] > snd(f2), XI(g)) } + @nowarn("msg=match may not be exhaustive") override def thenAssocRL[B2_, B3_, C1, C2]( that: AssocRL[A2, B2_, B3_, C1, C2], )(using @@ -2225,6 +2257,7 @@ class Shuffle[|*|[_, _]](using inj: BiInjective[|*|]) { Xfer(f1, ix[A21, A22, A3] > fst(f2), AssocRL(h)) } + @nowarn("msg=match may not be exhaustive") override def thenXI[B2_, B3_, C2, C3]( that: XI[A2, B2_, B3_, C2, C3], )(using @@ -2239,6 +2272,7 @@ class Shuffle[|*|[_, _]](using inj: BiInjective[|*|]) { t.xi_this_xi(that) } + @nowarn("msg=match may not be exhaustive") override def thenIXI[B11, B12, B21, B22, C1, C2, C3, C4]( that: IXI[B11, B12, B21, B22, C1, C2, C3, C4] )(using @@ -2393,6 +2427,7 @@ class Shuffle[|*|[_, _]](using inj: BiInjective[|*|]) { F.zip(g1(F.zip(a1, a3)), g2(F.zip(a2, a4))) } + @nowarn("msg=match may not be exhaustive") override def translateLR[<*>[_, _], F[_, _], S1, S2]( fa12: F[A1 |*| A2, S1], fa34: F[A3 |*| A4, S2], @@ -2412,6 +2447,7 @@ class Shuffle[|*|[_, _]](using inj: BiInjective[|*|]) { ))) }}}} + @nowarn("msg=match may not be exhaustive") override def translateRL[<*>[_, _], F[_, _], T1, T2]( fb12: F[B1 |*| B2, T1], fb34: F[B3 |*| B4, T2], @@ -2430,6 +2466,7 @@ class Shuffle[|*|[_, _]](using inj: BiInjective[|*|]) { case Exists.Some(Exists.Some((fa2, fa4, h2))) => Exists(Exists((m.pair(fa1, fa2), m.pair(fa3, fa4), tgt.Transfer.IXI(h1, h2)))) + @nowarn("msg=match may not be exhaustive") override def chaseFwFst[F[_], T](i: Focus[|*|, F])(using ev: F[T] =:= (A1 |*| A2), ): ChaseFwRes[[t] =>> F[t] |*| (A3 |*| A4), T, B1 |*| B2 |*| (B3 |*| B4)] = @@ -2450,6 +2487,7 @@ class Shuffle[|*|[_, _]](using inj: BiInjective[|*|]) { .after([t] => (_: Unit) => ixi[A1, f2[t], A3, A4]) } + @nowarn("msg=match may not be exhaustive") override def chaseFwSnd[F[_], T](i: Focus[|*|, F])(using ev: F[T] =:= (A3 |*| A4), ): ChaseFwRes[[t] =>> A1 |*| A2 |*| F[t], T, B1 |*| B2 |*| (B3 |*| B4)] = @@ -2517,6 +2555,7 @@ class Shuffle[|*|[_, _]](using inj: BiInjective[|*|]) { t.ixi_sndThis_assocRL(g1, that) } + @nowarn("msg=match may not be exhaustive") override def thenIX[B1_, B2_, C1, C2]( that: IX[B1_, B2_, B3 |*| B4, C1, C2], )(using diff --git a/lambda/src/main/scala/libretto/lambda/Shuffled.scala b/lambda/src/main/scala/libretto/lambda/Shuffled.scala index 1ab328bf..ef41c517 100644 --- a/lambda/src/main/scala/libretto/lambda/Shuffled.scala +++ b/lambda/src/main/scala/libretto/lambda/Shuffled.scala @@ -4,6 +4,7 @@ import libretto.lambda.{Projection => P} import libretto.lambda.util.{Applicative, BiInjective, Exists, TypeEq} import libretto.lambda.util.TypeEq.Refl import libretto.lambda.Projection.Proper +import scala.annotation.nowarn object Shuffled { type With[->[_, _], |*|[_, _], S <: Shuffle[|*|]] = @@ -443,6 +444,7 @@ sealed abstract class Shuffled[->[_, _], |*|[_, _]](using BiInjective[|*|]) { def chaseFwFst[F[_], X](i: Focus[|*|, F])(using ev: A1 =:= F[X]): ChaseFwRes.Blocked[[x] =>> F[x] |*| A2, X, B] def chaseFwSnd[F[_], X](i: Focus[|*|, F])(using ev: A2 =:= F[X]): ChaseFwRes.Blocked[[x] =>> A1 |*| F[x], X, B] + @nowarn("msg=match may not be exhaustive") final override def chaseFw[F[_], X](i: Focus[|*|, F])(using ev: (A1 |*| A2) =:= F[X]): ChaseFwRes.Blocked[F, X, B] = ev match { case TypeEq(Refl()) => i match { @@ -464,6 +466,7 @@ sealed abstract class Shuffled[->[_, _], |*|[_, _]](using BiInjective[|*|]) { def chaseBwFst[G[_], X](i: Focus[|*|, G])(using B1 =:= G[X]): ChaseBwRes.Blocked[A, [x] =>> G[x] |*| B2, X] def chaseBwSnd[G[_], X](i: Focus[|*|, G])(using B2 =:= G[X]): ChaseBwRes.Blocked[A, [x] =>> B1 |*| G[x], X] + @nowarn("msg=match may not be exhaustive") final override def chaseBw[G[_], X](i: Focus[|*|, G])(using ev: (B1 |*| B2) =:= G[X]): ChaseBwRes.Blocked[A, G, X] = i match case Focus.Id() => @@ -775,6 +778,7 @@ sealed abstract class Shuffled[->[_, _], |*|[_, _]](using BiInjective[|*|]) { (tgt.Plated.SemiCons(semiHead1, s, t, tail1), b) } + @nowarn("msg=match may not be exhaustive") override def translate[->>[_, _], <*>[_, _], F[_, _], S]( fa: F[A1 |*| A2, S], om: ObjectMap[|*|, <*>, F], @@ -874,6 +878,7 @@ sealed abstract class Shuffled[->[_, _], |*|[_, _]](using BiInjective[|*|]) { (tgt.Plated.SemiSnoc(init1, t.rebase(tgt), s, sl1), F.zip(b1, b2)) } + @nowarn("msg=match may not be exhaustive") override def translate[->>[_, _], <*>[_, _], F[_, _], S]( fa: F[A, S], om: ObjectMap[|*|, <*>, F], @@ -1003,6 +1008,8 @@ sealed abstract class Shuffled[->[_, _], |*|[_, _]](using BiInjective[|*|]) { ) } + @nowarn("msg=match may not be exhaustive") + @nowarn("msg=type test") override def translate[->>[_, _], <*>[_, _], F[_, _], S]( fa: F[A1 |*| A2, S], om: ObjectMap[|*|, <*>, F], @@ -1054,6 +1061,7 @@ sealed abstract class Shuffled[->[_, _], |*|[_, _]](using BiInjective[|*|]) { def project[C](p: Projection[|*|, B1 |*| B2, C]): ProjectRes[A1 |*| A2, C] = ProjectRes(asShuffle.project(p)) + @nowarn("msg=match may not be exhaustive") def translate[->>[_, _], <*>[_, _], F[_, _], S1, S2]( fa1: F[A1, S1], fa2: F[A2, S2], @@ -1320,6 +1328,7 @@ sealed abstract class Shuffled[->[_, _], |*|[_, _]](using BiInjective[|*|]) { override def andThen[C](that: Shuffled[B, C]): ChaseFwRes[F, X, C] = that.chaseFw[G, X](g)(using ev.flip).after(s) + @nowarn("msg=match may not be exhaustive") override def thenSnd[B1, B2, C2](using ev1: B =:= (B1 |*| B2))(that: Shuffled[B2, C2]): ChaseFwRes[F, X, B1 |*| C2] = g match { case g: Focus.Fst[pair, g1, b2] => diff --git a/lambda/src/test/scala/libretto/lambda/Fun.scala b/lambda/src/test/scala/libretto/lambda/Fun.scala index 1f7e251f..daea7592 100644 --- a/lambda/src/test/scala/libretto/lambda/Fun.scala +++ b/lambda/src/test/scala/libretto/lambda/Fun.scala @@ -3,6 +3,7 @@ package libretto.lambda import libretto.lambda.Lambdas.Error.LinearityViolation.{OverUnder, Overused, Underused} import libretto.lambda.util.{BiInjective, SourcePos, TypeEq} import libretto.lambda.util.TypeEq.Refl +import scala.annotation.nowarn sealed trait Fun[A, B] { @@ -222,6 +223,7 @@ object Fun { case Pair[A, B](_1: Values[A], _2: Values[B]) extends Values[A ** B] } + @nowarn("msg=match may not be exhaustive") private def evaluate[A, B](f: Fun[A, B])(a: Values[A]): Values[B] = { import Values.{Pair, SingleVal} diff --git a/stream/src/main/scala/libretto/stream/CoreStreams.scala b/stream/src/main/scala/libretto/stream/CoreStreams.scala index 0187af41..a4ffa57e 100644 --- a/stream/src/main/scala/libretto/stream/CoreStreams.scala +++ b/stream/src/main/scala/libretto/stream/CoreStreams.scala @@ -2,6 +2,7 @@ package libretto.stream import libretto.{CoreDSL, CoreLib} import libretto.lambda.util.Exists +import scala.annotation.nowarn object CoreStreams { def apply( @@ -568,6 +569,7 @@ class CoreStreams[DSL <: CoreDSL, Lib <: CoreLib[DSL]]( val sndClosed: Source[A |+| B] -⚬ (Polled[A] |*| Done) = close[A |+| B].introFst(done > Polled.empty[A]) + @nowarn("msg=match may not be exhaustive") val bothPolled: Source[A |+| B] -⚬ (Polled[A] |*| Polled[B]) = λ { src => poll(src) switch { @@ -635,6 +637,7 @@ class CoreStreams[DSL <: CoreDSL, Lib <: CoreLib[DSL]]( from(onClose, onPoll) } + @nowarn("msg=match may not be exhaustive") def go1: (Ping |*| (Polled[A] |*| Source[A])) -⚬ Source[A] = λ { case downstreamActing |*| (as |*| bs) => (as :>> notifyEither) match { @@ -767,6 +770,7 @@ class CoreStreams[DSL <: CoreDSL, Lib <: CoreLib[DSL]]( * If the input source runs out of elements before the input list does, * the remaining elements of the input list are returned. */ + @nowarn("msg=match may not be exhaustive") def takeForeach[X, A]: (LList[X] |*| Source[A]) -⚬ (LList[X |*| A] |*| LList[X] |*| Done) = rec { takeForeach => λ { case (xs |*| as) => diff --git a/stream/src/main/scala/libretto/stream/scaletto/ScalettoStreams.scala b/stream/src/main/scala/libretto/stream/scaletto/ScalettoStreams.scala index 69261f7f..fca577b2 100644 --- a/stream/src/main/scala/libretto/stream/scaletto/ScalettoStreams.scala +++ b/stream/src/main/scala/libretto/stream/scaletto/ScalettoStreams.scala @@ -6,6 +6,7 @@ import libretto.scaletto.{Scaletto, ScalettoLib} import libretto.stream.InvertStreams import scala.annotation.{tailrec, targetName} import scala.concurrent.duration.FiniteDuration +import scala.annotation.nowarn object ScalettoStreams { type Of[ @@ -381,6 +382,7 @@ abstract class ScalettoStreams { def prefetch[A](n: Int): ValSource[A] -⚬ ValSource[A] = Source.prefetch[Val[A]](n)(neglect, Exists(inversionDuality[LList[Done]])) + @nowarn("msg=match may not be exhaustive") def dropUntilFirstDemand[A]: ValSource[A] -⚬ ValSource[A] = rec { self => poll > λ { as => producing { out => @@ -576,6 +578,7 @@ abstract class ScalettoStreams { def delayBy[A]: (Done |*| Polled[A]) -⚬ Polled[A] = Source.Polled.delayBy + @nowarn("msg=match may not be exhaustive") def dup[A]( dupSource: ValSource[A] -⚬ (ValSource[A] |*| ValSource[A]), ): Polled[A] -⚬ (Polled[A] |*| Polled[A]) = diff --git a/testing/src/main/scala/libretto/testing/scaletto/ScalettoTestExecutor.scala b/testing/src/main/scala/libretto/testing/scaletto/ScalettoTestExecutor.scala index f17ac32c..79a30b12 100644 --- a/testing/src/main/scala/libretto/testing/scaletto/ScalettoTestExecutor.scala +++ b/testing/src/main/scala/libretto/testing/scaletto/ScalettoTestExecutor.scala @@ -7,6 +7,7 @@ import libretto.scaletto.{Scaletto, ScalettoBridge, ScalettoExecutor, StarterKit import libretto.testing.{ManualClock, ManualClockParams, TestExecutor, TestResult} import libretto.util.Async import scala.concurrent.duration.FiniteDuration +import scala.annotation.nowarn object ScalettoTestExecutor { import ExecutionParam.Instantiation @@ -85,6 +86,7 @@ object ScalettoTestExecutor { ExecutionParams.Free.wrap(ManualClockParam) } + @nowarn("msg=type test") def instantiate[A, P[_]](p: ExecutionParam[A])(using ep: ExecutionParams.WithScheduler[P], ): Instantiation[A, P] = {