@@ -27,40 +27,46 @@ object QuotePatterns:
27
27
28
28
/** Check for restricted patterns */
29
29
def checkPattern (quotePattern : QuotePattern )(using Context ): Unit =
30
- val typevars = new tpd.TreeAccumulator [Set [Symbol ]] {
31
- override def apply (typevars : Set [Symbol ], tree : tpd.Tree )(using Context ): Set [Symbol ] = tree match {
32
- case _ : SplicePattern => typevars
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
- typevars
37
- case tree : NamedDefTree =>
38
- if tree.name.is(NameKinds .WildcardParamName ) then
39
- report.warning(
40
- " Use of `_` for lambda in quoted pattern. Use explicit lambda instead or use `$_` to match any term." ,
41
- tree.srcPos)
42
- if tree.name.isTermName && ! tree.nameSpan.isSynthetic && tree.name != nme.ANON_FUN && tree.name.startsWith(" $" ) then
43
- report.error(" Names cannot start with $ quote pattern" , tree.namePos)
44
- val typevars1 = tree match
30
+ def validatePatternAndCollectTypeVars (): Set [Symbol ] = new tpd.TreeAccumulator [Set [Symbol ]] {
31
+ override def apply (typevars : Set [Symbol ], tree : tpd.Tree )(using Context ): Set [Symbol ] =
32
+ // Collect type variables
33
+ val typevars1 = tree match
45
34
case tree @ DefDef (_, paramss, _, _) =>
46
35
typevars union paramss.flatMap{ params => params match
47
36
case TypeDefs (tdefs) => tdefs.map(_.symbol)
48
37
case _ => List .empty
49
- }.toSet
38
+ }.toSet union typevars
50
39
case _ => typevars
51
- foldOver(typevars1, tree)
52
- case _ : Match =>
53
- report.error(" Implementation restriction: cannot match `match` expressions" , tree.srcPos)
54
- typevars
55
- case _ : Try =>
56
- report.error(" Implementation restriction: cannot match `try` expressions" , tree.srcPos)
57
- typevars
58
- case _ : Return =>
59
- report.error(" Implementation restriction: cannot match `return` statements" , tree.srcPos)
60
- typevars
61
- case _ => foldOver(typevars, tree)
62
- }
63
- }.apply(Set .empty, quotePattern.body)
40
+
41
+ // Validate pattern
42
+ tree match
43
+ case _ : SplicePattern => typevars1
44
+ case tdef : TypeDef if tdef.symbol.isClass =>
45
+ val kind = if tdef.symbol.is(Module ) then " objects" else " classes"
46
+ report.error(em " Implementation restriction: cannot match $kind" , tree.srcPos)
47
+ typevars1
48
+ case tree : NamedDefTree =>
49
+ if tree.name.is(NameKinds .WildcardParamName ) then
50
+ report.warning(
51
+ " Use of `_` for lambda in quoted pattern. Use explicit lambda instead or use `$_` to match any term." ,
52
+ tree.srcPos)
53
+ if tree.name.isTermName && ! tree.nameSpan.isSynthetic && tree.name != nme.ANON_FUN && tree.name.startsWith(" $" ) then
54
+ report.error(" Names cannot start with $ quote pattern" , tree.namePos)
55
+ foldOver(typevars1, tree)
56
+ case _ : Match =>
57
+ report.error(" Implementation restriction: cannot match `match` expressions" , tree.srcPos)
58
+ typevars1
59
+ case _ : Try =>
60
+ report.error(" Implementation restriction: cannot match `try` expressions" , tree.srcPos)
61
+ typevars1
62
+ case _ : Return =>
63
+ report.error(" Implementation restriction: cannot match `return` statements" , tree.srcPos)
64
+ typevars1
65
+ case _ =>
66
+ foldOver(typevars1, tree)
67
+ }.apply(Set .empty, quotePattern.body)
68
+
69
+ val boundTypeVars = validatePatternAndCollectTypeVars()
64
70
65
71
/*
66
72
* This part checks well-formedness of arguments to hoas patterns.
@@ -87,15 +93,15 @@ object QuotePatterns:
87
93
val capturedTypeVarsSet = capturedTypeVars.map(_.symbol).toSet
88
94
new TypeAccumulator [Set [Type ]] {
89
95
def apply (x : Set [Type ], tp : Type ): Set [Type ] =
90
- if typevars .contains(tp.typeSymbol) && ! capturedTypeVarsSet.contains(tp.typeSymbol) then
96
+ if boundTypeVars .contains(tp.typeSymbol) && ! capturedTypeVarsSet.contains(tp.typeSymbol) then
91
97
foldOver(x + tp, tp)
92
98
else
93
99
foldOver(x, tp)
94
100
}.apply(Set .empty, arg.tpe)
95
101
96
102
for (typearg <- tree.typeargs) // case (1)
97
103
do
98
- if ! typevars .contains(typearg.symbol) then
104
+ if ! boundTypeVars .contains(typearg.symbol) then
99
105
report.error(" Type arguments of a hoas pattern needs to be defined inside the quoted pattern" , typearg.srcPos)
100
106
for (arg <- tree.args) // case (2)
101
107
do
0 commit comments