Skip to content

Commit 28f04c6

Browse files
Merge pull request #10735 from dotty-staging/add-reflect-MatchCase-type
Add reflect `MatchCase` `TypeRepr`
2 parents 4d0a7d8 + a207caa commit 28f04c6

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): (TypeRepr, TypeRepr) = (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
*
@@ -2688,6 +2689,40 @@ trait Quotes { self: runtime.QuoteUnpickler & runtime.QuoteMatching =>
26882689
end extension
26892690
end TypeLambdaMethods
26902691

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

26932728
/** 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)