@@ -26,31 +26,51 @@ object QuotePatterns:
26
26
import tpd ._
27
27
28
28
/** Check for restricted patterns */
29
- def checkPattern (quotePattern : QuotePattern )(using Context ): Unit = new tpd.TreeTraverser {
30
- def traverse (tree : Tree )(using Context ): Unit = tree match {
31
- case _ : SplicePattern =>
32
- case tdef : TypeDef if tdef.symbol.isClass =>
33
- val kind = if tdef.symbol.is(Module ) then " objects" else " classes"
34
- report.error(em " Implementation restriction: cannot match $kind" , tree.srcPos)
35
- case tree : NamedDefTree =>
36
- if tree.name.is(NameKinds .WildcardParamName ) then
37
- report.warning(
38
- " Use of `_` for lambda in quoted pattern. Use explicit lambda instead or use `$_` to match any term." ,
39
- tree.srcPos)
40
- if tree.name.isTermName && ! tree.nameSpan.isSynthetic && tree.name != nme.ANON_FUN && tree.name.startsWith(" $" ) then
41
- report.error(" Names cannot start with $ quote pattern" , tree.namePos)
42
- traverseChildren(tree)
43
- case _ : Match =>
44
- report.error(" Implementation restriction: cannot match `match` expressions" , tree.srcPos)
45
- case _ : Try =>
46
- report.error(" Implementation restriction: cannot match `try` expressions" , tree.srcPos)
47
- case _ : Return =>
48
- report.error(" Implementation restriction: cannot match `return` statements" , tree.srcPos)
49
- case _ =>
50
- traverseChildren(tree)
51
- }
29
+ def checkPattern (quotePattern : QuotePattern )(using Context ): Unit =
30
+ new tpd.TreeTraverser {
31
+ def traverse (tree : Tree )(using Context ): Unit = tree match {
32
+ case _ : SplicePattern =>
33
+ case tdef : TypeDef if tdef.symbol.isClass =>
34
+ val kind = if tdef.symbol.is(Module ) then " objects" else " classes"
35
+ report.error(em " Implementation restriction: cannot match $kind" , tree.srcPos)
36
+ case tree : NamedDefTree =>
37
+ if tree.name.is(NameKinds .WildcardParamName ) then
38
+ report.warning(
39
+ " Use of `_` for lambda in quoted pattern. Use explicit lambda instead or use `$_` to match any term." ,
40
+ tree.srcPos)
41
+ if tree.name.isTermName && ! tree.nameSpan.isSynthetic && tree.name != nme.ANON_FUN && tree.name.startsWith(" $" ) then
42
+ report.error(" Names cannot start with $ quote pattern" , tree.namePos)
43
+ traverseChildren(tree)
44
+ case _ : Match =>
45
+ report.error(" Implementation restriction: cannot match `match` expressions" , tree.srcPos)
46
+ case _ : Try =>
47
+ report.error(" Implementation restriction: cannot match `try` expressions" , tree.srcPos)
48
+ case _ : Return =>
49
+ report.error(" Implementation restriction: cannot match `return` statements" , tree.srcPos)
50
+ case _ =>
51
+ traverseChildren(tree)
52
+ }
52
53
53
- }.traverse(quotePattern.body)
54
+ }.traverse(quotePattern.body)
55
+
56
+ new tpd.TreeAccumulator [List [Symbol ]] {
57
+ override def apply (typevars : List [Symbol ], tree : tpd.Tree )(using Context ): List [Symbol ] = tree match {
58
+ case tree : SplicePattern =>
59
+ for (typearg <- tree.typeargs)
60
+ do
61
+ if ! typevars.contains(typearg.symbol) then
62
+ report.error(" Type parameters to a hoas pattern needs to be introduced in the quoted pattern" , typearg.srcPos)
63
+ typevars
64
+ case tree @ DefDef (_, paramss, _, _) =>
65
+ val newTypevars = paramss flatMap { params => params match
66
+ case TypeDefs (tdefs) => tdefs map (_.symbol)
67
+ case _ => List .empty
68
+ }
69
+ foldOver(typevars ++: newTypevars, tree.rhs)
70
+ typevars
71
+ case _ => foldOver(typevars, tree)
72
+ }
73
+ }.apply(List .empty, quotePattern.body)
54
74
55
75
/** Encode the quote pattern into an `unapply` that the pattern matcher can handle.
56
76
*
0 commit comments