-
Notifications
You must be signed in to change notification settings - Fork 1.1k
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
Check bounds in match type case bodies #17602
Changes from all commits
f1f819b
cb4cab4
fa89ac4
1c75447
f304a07
ecb4207
76c8268
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -488,12 +488,19 @@ class PostTyper extends MacroTransform with InfoTransformer { thisPhase => | |
// case x: (_: Tree[?]) | ||
case m @ MatchTypeTree(bounds, selector, cases) => | ||
// Analog to the case above for match types | ||
def transformIgnoringBoundsCheck(x: CaseDef): CaseDef = | ||
withMode(Mode.Pattern)(super.transform(x)).asInstanceOf[CaseDef] | ||
def transformCase(x: CaseDef): CaseDef = | ||
val gadtCtx = x.pat.removeAttachment(typer.Typer.InferredGadtConstraints) match | ||
case Some(gadt) => ctx.fresh.setGadtState(GadtState(gadt)) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is this enough to ensure that, after There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm not inserting any casts, if that's what you're asking. And I'm hoping we can handle things like: class Foo
class Bar
class Res[X <: Bar]
type MT[X <: Foo | Bar] = X match
case Foo => Unit
case Bar => Res[X] // X vs bounds check <: Bar in part also because I've found adding a type intersection (for types) doesn't fix errors like adding a type casting (for terms) fixes errors... There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. So we can either:
😭 |
||
case None => ctx | ||
inContext(gadtCtx)(cpy.CaseDef(tree)( | ||
withMode(Mode.Pattern)(transform(x.pat)), | ||
transform(x.guard), | ||
transform(x.body), | ||
)) | ||
cpy.MatchTypeTree(tree)( | ||
super.transform(bounds), | ||
super.transform(selector), | ||
cases.mapConserve(transformIgnoringBoundsCheck) | ||
cases.mapConserve(transformCase) | ||
) | ||
case Block(_, Closure(_, _, tpt)) if ExpandSAMs.needsWrapperClass(tpt.tpe) => | ||
superAcc.withInvalidCurrentClass(super.transform(tree)) | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
type FlatMap[Tup <: Tuple, F[_] <: Tuple] <: Tuple = Tup match | ||
case EmptyTuple => EmptyTuple | ||
case h *: t => Tuple.Concat[F[h], FlatMap[t, F]] |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
type Fold0[Tup <: Tuple, Z, F[_, _]] = Tup match | ||
case EmptyTuple => Z | ||
case h *: t => F[h, Fold0[t, Z, F]] | ||
|
||
|
||
type Union0[T <: Tuple] = Fold0[T, Nothing, [x, y] =>> x | y] | ||
|
||
type Union1[Tup <: Tuple] = Tup match | ||
case EmptyTuple => Nothing | ||
case h *: t => h | Union1[t] | ||
|
||
|
||
import Tuple.Map as Map0 | ||
|
||
type Map1[Tup <: Tuple, F[_ <: Union0[Tup]]] <: Tuple = Tup match | ||
case EmptyTuple => EmptyTuple | ||
case h *: t => F[h & Union0[Tup]] *: Map1[t, [x <: Union0[t]] =>> F[x & Union0[Tup]]] | ||
|
||
type Map2[Tup <: Tuple, F[_]] <: Tuple = Tup match | ||
case EmptyTuple => EmptyTuple | ||
case h *: t => F[h] *: Map2[t, F] | ||
|
||
//type Map3[Tup <: Tuple, F[_ <: Union1[Tup]]] <: Tuple = Tup match | ||
// case EmptyTuple => EmptyTuple | ||
// case h *: t => F[h] *: Map3[t, F] | ||
|
||
type Map4 [Tup <: Tuple, F[_ <: Union1[Tup]]] = Map4UB[Tup, F, Union1[Tup]] | ||
type Map4UB[Tup <: Tuple, F[_ <: UB], UB] <: Tuple = Tup match | ||
case EmptyTuple => EmptyTuple | ||
case h *: t => F[h & UB] *: Map4UB[t, F, UB] | ||
|
||
type Map5 [Tup <: Tuple, F[_ <: Union1[Tup]]] = Map5UB[Tup, Union1[Tup], F, Tup] | ||
type Map5UB[Tup <: Tuple, UB, F[_ <: UB], Tup1 <: Tuple] <: Tuple = Tup1 match | ||
case EmptyTuple => EmptyTuple | ||
case h *: t => F[h & UB] *: Map5UB[Tup, UB, F, t] | ||
|
||
trait Dt[T] | ||
case class IBox[A <: Int](v: A) | ||
|
||
class Test[H, T <: Tuple]: | ||
//def t0 = { val x: Dt[H] *: Map0[T, Dt] = ???; val y: Map0[H *: T, Dt] = x } | ||
def t1 = { val x: Dt[H] *: Map1[T, Dt] = ???; val y: Map1[H *: T, Dt] = x } | ||
def t2 = { val x: Dt[H] *: Map2[T, Dt] = ???; val y: Map2[H *: T, Dt] = x } | ||
//def t3 = { val x: Dt[H] *: Map3[T, Dt] = ???; val y: Map3[H *: T, Dt] = x } | ||
//def t4 = { val x: Dt[H] *: Map4[T, Dt] = ???; val y: Map4[H *: T, Dt] = x } | ||
//def t5 = { val x: Dt[H] *: Map5[T, Dt] = ???; val y: Map5[H *: T, Dt] = x } | ||
|
||
def i0 = { val x: Map0[(1, 2), IBox] = (IBox(1), IBox(2)) } | ||
def i1 = { val x: Map1[(1, 2), IBox] = (IBox(1), IBox(2)) } | ||
//def i2 = { val x: Map2[(1, 2), IBox] = (IBox(1), IBox(2)) } | ||
//def i3 = { val x: Map3[(1, 2), IBox] = (IBox(1), IBox(2)) } | ||
def i4 = { val x: Map4[(1, 2), IBox] = (IBox(1), IBox(2)) } | ||
def i5 = { val x: Map5[(1, 2), IBox] = (IBox(1), IBox(2)) } |
This file was deleted.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
import scala.compiletime.ops.string.+ | ||
import scala.compiletime.ops.any | ||
|
||
type Index = Int & Singleton | ||
|
||
sealed trait Indices | ||
|
||
final case class :::[+H <: Index, +T <: Indices](head: H, tail: T) extends Indices: | ||
override def toString = s"$head ::: $tail" | ||
|
||
sealed trait INil extends Indices | ||
case object INil extends INil | ||
|
||
object Indices: | ||
type ToString[X <: Indices] <: String = X match | ||
case INil => "INil" | ||
case head ::: tail => any.ToString[head] + " ::: " + ToString[tail] | ||
|
||
type Contains[Haystack <: Indices, Needle <: Index] <: Boolean = Haystack match | ||
case head ::: tail => head match | ||
case Needle => true | ||
case _ => Contains[tail, Needle] | ||
case INil => false | ||
|
||
type RemoveValue[RemoveFrom <: Indices, Value <: Index] <: Indices = RemoveFrom match | ||
case INil => INil | ||
case head ::: tail => head match | ||
case Value => RemoveValue[tail, Value] | ||
case _ => head ::: RemoveValue[tail, Value] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
AndType
is supposed to be commutative, so if we do this we must also do the mirror: