@@ -686,9 +686,9 @@ object Trees {
686
686
* phases. After `pickleQuotes` phase, the only quotes that exist are in `inline`
687
687
* methods. These are dropped when we remove the inline method implementations.
688
688
*
689
- * Type quotes `'[body]` from the parser are desugared into quote patterns (using a `Type.of[T]]`)
690
- * when type checking. TASTy files will not contain type quotes. Type quotes are used again
691
- * in the `staging` phase to represent the reification of `Type.of[T]]`.
689
+ * Type quotes `'[body]` from the parser are typed into `QuotePattern`s when type checking.
690
+ * TASTy files will not contain type quotes. Type quotes are used again in the `staging`
691
+ * phase to represent the reification of `Type.of[T]]`.
692
692
*
693
693
* Type tags `tags` are always empty before the `staging` phase. Tags for stage inconsistent
694
694
* types are added in the `staging` phase to level 0 quotes. Tags for types that refer to
@@ -737,13 +737,37 @@ object Trees {
737
737
type ThisTree [+ T <: Untyped ] = Splice [T ]
738
738
}
739
739
740
+ /** A tree representing a quote pattern `'{ type binding1; ...; body }` or `'[ type binding1; ...; body ]`.
741
+ * `QuotePattern`s are created the type checker when typing an `untpd.Quote` in a pattern context.
742
+ *
743
+ * `QuotePattern`s are checked are encoded into `unapply`s in the `staging` phase.
744
+ * We also encode the tree before pickling it TASTy. Therefore we still load quote patterns as `unapply`s
745
+ * as we did before the existence of `QuotePattern`.
746
+ *
747
+ * The `bindings` contain the list of quote pattern type variable definitions (`Bind`s) in the oreder in
748
+ * which they are defined in the source.
749
+ *
750
+ * @param bindings Type variable definitions (`Bind` tree)
751
+ * @param body Quoted pattern (without type variable definitions)
752
+ * @param quotes A reference to the given `Quotes` instance in scope
753
+ */
754
+ case class QuotePattern [+ T <: Untyped ] private [ast] (bindings : List [Tree [T ]], body : Tree [T ], quotes : Tree [T ])(implicit @ constructorOnly src : SourceFile )
755
+ extends PatternTree [T ] {
756
+ type ThisTree [+ T <: Untyped ] = QuotePattern [T ]
757
+
758
+ /** Type of the quoted pattern */
759
+ def bodyType (using Context ): Type =
760
+ val quoteType = typeOpt // `Expr[T]` or `Type[T]`
761
+ quoteType.argInfos.head // T
762
+ }
763
+
740
764
/** A tree representing a pattern splice `${ pattern }`, `$ident` or `$ident(args*)` in a quote pattern.
741
765
*
742
766
* Parser will only create `${ pattern }` and `$ident`, hence they will not have args.
743
767
* While typing, the `$ident(args*)` the args are identified and desugared into a `SplicePattern`
744
768
* containing them.
745
769
*
746
- * SplicePattern are removed after typing the pattern and are not present in TASTy .
770
+ * ` SplicePattern` can only be contained within a `QuotePattern` .
747
771
*
748
772
* @param body The tree that was spliced
749
773
* @param args The arguments of the splice (the HOAS arguments)
@@ -1163,6 +1187,7 @@ object Trees {
1163
1187
type Inlined = Trees .Inlined [T ]
1164
1188
type Quote = Trees .Quote [T ]
1165
1189
type Splice = Trees .Splice [T ]
1190
+ type QuotePattern = Trees .QuotePattern [T ]
1166
1191
type SplicePattern = Trees .SplicePattern [T ]
1167
1192
type TypeTree = Trees .TypeTree [T ]
1168
1193
type InferredTypeTree = Trees .InferredTypeTree [T ]
@@ -1342,6 +1367,10 @@ object Trees {
1342
1367
case tree : Splice if (expr eq tree.expr) => tree
1343
1368
case _ => finalize(tree, untpd.Splice (expr)(sourceFile(tree)))
1344
1369
}
1370
+ def QuotePattern (tree : Tree )(bindings : List [Tree ], body : Tree , quotes : Tree )(using Context ): QuotePattern = tree match {
1371
+ case tree : QuotePattern if (bindings eq tree.bindings) && (body eq tree.body) && (quotes eq tree.quotes) => tree
1372
+ case _ => finalize(tree, untpd.QuotePattern (bindings, body, quotes)(sourceFile(tree)))
1373
+ }
1345
1374
def SplicePattern (tree : Tree )(body : Tree , args : List [Tree ])(using Context ): SplicePattern = tree match {
1346
1375
case tree : SplicePattern if (body eq tree.body) && (args eq tree.args) => tree
1347
1376
case _ => finalize(tree, untpd.SplicePattern (body, args)(sourceFile(tree)))
@@ -1587,6 +1616,8 @@ object Trees {
1587
1616
cpy.Quote (tree)(transform(body)(using quoteContext), transform(tags))
1588
1617
case tree @ Splice (expr) =>
1589
1618
cpy.Splice (tree)(transform(expr)(using spliceContext))
1619
+ case tree @ QuotePattern (bindings, body, quotes) =>
1620
+ cpy.QuotePattern (tree)(transform(bindings), transform(body)(using quoteContext), transform(quotes))
1590
1621
case tree @ SplicePattern (body, args) =>
1591
1622
cpy.SplicePattern (tree)(transform(body)(using spliceContext), transform(args))
1592
1623
case tree @ Hole (isTerm, idx, args, content) =>
@@ -1734,6 +1765,8 @@ object Trees {
1734
1765
this (this (x, body)(using quoteContext), tags)
1735
1766
case Splice (expr) =>
1736
1767
this (x, expr)(using spliceContext)
1768
+ case QuotePattern (bindings, body, quotes) =>
1769
+ this (this (this (x, bindings), body)(using quoteContext), quotes)
1737
1770
case SplicePattern (body, args) =>
1738
1771
this (this (x, body)(using spliceContext), args)
1739
1772
case Hole (_, _, args, content) =>
0 commit comments