Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Introduce warning supression for problematic pattern-matches #91

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions core/src/main/scala/libretto/CoreLib.scala
Original file line number Diff line number Diff line change
Expand Up @@ -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] =
Expand Down Expand Up @@ -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],
Expand All @@ -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],
Expand Down Expand Up @@ -3322,6 +3325,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 {
Expand All @@ -3346,6 +3350,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 =>
Expand Down Expand Up @@ -3681,6 +3686,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 =
Expand Down Expand Up @@ -3746,6 +3752,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) =>
Expand Down
2 changes: 2 additions & 0 deletions core/src/main/scala/libretto/InvertLib.scala
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package libretto

import libretto.lambda.util.SourcePos
import scala.annotation.nowarn

object InvertLib {
def apply(
Expand Down Expand Up @@ -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],
Expand Down
2 changes: 2 additions & 0 deletions core/src/main/scala/libretto/scaletto/ScalettoLib.scala
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down Expand Up @@ -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 =>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand All @@ -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 {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -192,6 +193,7 @@ object Wire {
}

import Wire.Outlet
import scala.annotation.nowarn

enum Result {
case Zero
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
4 changes: 4 additions & 0 deletions lambda/src/main/scala/libretto/lambda/Bin.scala
Original file line number Diff line number Diff line change
Expand Up @@ -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]`, ...
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand All @@ -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
Expand Down
2 changes: 2 additions & 0 deletions lambda/src/main/scala/libretto/lambda/Lambdas.scala
Original file line number Diff line number Diff line change
Expand Up @@ -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]
Expand Down Expand Up @@ -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,
Expand Down
13 changes: 13 additions & 0 deletions lambda/src/main/scala/libretto/lambda/LambdasImpl.scala
Original file line number Diff line number Diff line change
Expand Up @@ -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[-⚬, |*|],
Expand Down Expand Up @@ -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])]] =
Expand Down Expand Up @@ -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]]] =
Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -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],
Expand Down Expand Up @@ -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],
Expand Down Expand Up @@ -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],
Expand Down Expand Up @@ -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 {
Expand All @@ -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 {
Expand All @@ -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 {
Expand All @@ -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] =>
Expand Down
3 changes: 3 additions & 0 deletions lambda/src/main/scala/libretto/lambda/Projection.scala
Original file line number Diff line number Diff line change
Expand Up @@ -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]]
Expand Down Expand Up @@ -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,
Expand Down
Loading