Skip to content

Commit c65fe68

Browse files
committed
Add reflect MatchCase TypeRepr
This represents the `MATCHCASEtype` type in `TastyFormat` and hides the `scala.runtime.MatchCase` internal encoding.
1 parent ff3637f commit c65fe68

File tree

5 files changed

+67
-14
lines changed

5 files changed

+67
-14
lines changed

compiler/src/scala/quoted/runtime/impl/QuotesImpl.scala

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1760,7 +1760,7 @@ class QuotesImpl private (using val ctx: Context) extends Quotes, QuoteUnpickler
17601760

17611761
object AppliedTypeTypeTest extends TypeTest[TypeRepr, AppliedType]:
17621762
def unapply(x: TypeRepr): Option[AppliedType & x.type] = x match
1763-
case tpe: (Types.AppliedType & x.type) => Some(tpe)
1763+
case tpe: (Types.AppliedType & x.type) if !tpe.tycon.isRef(dotc.core.Symbols.defn.MatchCaseClass) => Some(tpe)
17641764
case _ => None
17651765
end AppliedTypeTypeTest
17661766

@@ -2051,6 +2051,27 @@ class QuotesImpl private (using val ctx: Context) extends Quotes, QuoteUnpickler
20512051
end extension
20522052
end TypeLambdaMethods
20532053

2054+
type MatchCase = dotc.core.Types.AppliedType
2055+
2056+
given MatchCaseTypeTest: TypeTest[TypeRepr, MatchCase] with
2057+
def unapply(x: TypeRepr): Option[MatchCase & x.type] = x match
2058+
case x: (Types.AppliedType & x.type) if x.tycon.isRef(dotc.core.Symbols.defn.MatchCaseClass) => Some(x)
2059+
case _ => None
2060+
end MatchCaseTypeTest
2061+
2062+
object MatchCase extends MatchCaseModule:
2063+
def apply(pattern: TypeRepr, rhs: TypeRepr): MatchCase =
2064+
Types.AppliedType(dotc.core.Symbols.defn.MatchCaseClass.typeRef, List(pattern, rhs))
2065+
def unapply(x: MatchCase): Some[(TypeRepr, TypeRepr)] = Some((x.pattern, x.rhs))
2066+
end MatchCase
2067+
2068+
given MatchCaseMethods: MatchCaseMethods with
2069+
extension (self: MatchCase)
2070+
def pattern: TypeRepr = self.args(0)
2071+
def rhs: TypeRepr = self.args(1)
2072+
end extension
2073+
end MatchCaseMethods
2074+
20542075
type TypeBounds = dotc.core.Types.TypeBounds
20552076

20562077
object TypeBoundsTypeTest extends TypeTest[TypeRepr, TypeBounds]:

library/src/scala/quoted/Quotes.scala

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,7 @@ trait Quotes { self: runtime.QuoteUnpickler & runtime.QuoteMatching =>
175175
* +- LambdaType -+- MethodOrPoly -+- MethodType
176176
* | | +- PolyType
177177
* | +- TypeLambda
178+
* +- MatchCase
178179
* +- TypeBounds
179180
* +- NoPrefix
180181
*
@@ -2678,6 +2679,40 @@ trait Quotes { self: runtime.QuoteUnpickler & runtime.QuoteMatching =>
26782679
end extension
26792680
end TypeLambdaMethods
26802681

2682+
/** Case of a `MatchType` containing pattern `case P => R`.
2683+
*
2684+
* Note: cases with type bindings are represented nested in a `TypeLambda`.
2685+
*/
2686+
type MatchCase <: TypeRepr
2687+
2688+
/** `TypeTest` that allows testing at runtime in a pattern match if a `TypeRepr` is a `MatchCase` */
2689+
given MatchCaseTypeTest: TypeTest[TypeRepr, MatchCase]
2690+
2691+
/** Module object of `type MatchCase` */
2692+
val MatchCase: MatchCaseModule
2693+
2694+
/** Methods of the module object `val MatchCase` */
2695+
trait MatchCaseModule { this: MatchCase.type =>
2696+
/* Create match type case `case <pattern> => <rhs>` */
2697+
def apply(pattern: TypeRepr, rhs: TypeRepr): MatchCase
2698+
/* Matches a match type case `case <pattern> => <rhs>` */
2699+
def unapply(x: MatchCase): Some[(TypeRepr, TypeRepr)]
2700+
}
2701+
2702+
/** Makes extension methods on `MatchCase` available without any imports */
2703+
given MatchCaseMethods: MatchCaseMethods
2704+
2705+
/** Extension methods of `MatchCase` */
2706+
trait MatchCaseMethods:
2707+
extension (self: MatchCase)
2708+
/** Pattern `P` of `case P => R` in a `MatchType` */
2709+
def pattern: TypeRepr
2710+
/** RHS `R` of `case P => R` in a `MatchType` */
2711+
def rhs: TypeRepr
2712+
end extension
2713+
end MatchCaseMethods
2714+
2715+
26812716
// ----- TypeBounds -----------------------------------------------
26822717

26832718
/** Type bounds */

scala3doc/src/dotty/dokka/tasty/SyntheticSupport.scala

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -96,13 +96,3 @@ trait SyntheticsSupport:
9696
given dotc.core.Contexts.Context = qctx.asInstanceOf[scala.quoted.runtime.impl.QuotesImpl].ctx
9797
val cSym = c.symbol.asInstanceOf[dotc.core.Symbols.Symbol]
9898
cSym.typeRef.appliedTo(cSym.typeParams.map(_.typeRef)).asInstanceOf[TypeRepr]
99-
100-
object MatchTypeCase:
101-
def unapply(tpe: TypeRepr): Option[(TypeRepr, TypeRepr)] =
102-
tpe match
103-
case AppliedType(t, Seq(from, to)) /*if t == MatchCaseType*/ =>
104-
Some((from, to))
105-
case TypeLambda(paramNames, paramTypes, AppliedType(t, Seq(from, to))) /*if t == MatchCaseType*/ =>
106-
Some((from, to))
107-
case _ =>
108-
None

scala3doc/src/dotty/dokka/tasty/TypesSupport.scala

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -240,7 +240,9 @@ trait TypesSupport:
240240

241241
case MatchType(bond, sc, cases) =>
242242
val casesTexts = cases.flatMap {
243-
case MatchTypeCase(from, to) =>
243+
case MatchCase(from, to) =>
244+
texts(" case ") ++ inner(from) ++ texts(" => ") ++ inner(to) ++ texts("\n")
245+
case TypeLambda(_, _, MatchCase(from, to)) =>
244246
texts(" case ") ++ inner(from) ++ texts(" => ") ++ inner(to) ++ texts("\n")
245247
}
246248
inner(sc) ++ texts(" match {\n") ++ casesTexts ++ texts("}")

tests/run-macros/tasty-construct-types/Macro_1.scala

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,9 @@ object Macros {
3636
TypeLambda(
3737
List("t"),
3838
_ => List(TypeBounds(TypeRepr.of[Nothing], TypeRepr.of[Any])),
39-
tl => TypeRepr.of[scala.runtime.MatchCase].appliedTo(List(TypeRepr.of[List].appliedTo(tl.param(0)), tl.param(0)))))
39+
tl => MatchCase(TypeRepr.of[List].appliedTo(tl.param(0)), tl.param(0))),
40+
MatchCase(TypeRepr.of[Int], TypeRepr.of[Int])
41+
)
4042
)
4143

4244
assert(x1T =:= TypeRepr.of[1])
@@ -46,7 +48,10 @@ object Macros {
4648
assert(x5T =:= TypeRepr.of[RefineMe { type T = Int }])
4749
assert(x6T =:= TypeRepr.of[List[Int]])
4850
assert(x7T =:= TypeRepr.of[7 @TestAnnotation])
49-
assert(x8T =:= TypeRepr.of[List[8] match { case List[t] => t }])
51+
assert(x8T =:= TypeRepr.of[List[8] match {
52+
case List[t] => t
53+
case Int => Int
54+
}])
5055

5156
'{
5257
println("Ok")

0 commit comments

Comments
 (0)