Skip to content

Commit 7bbf5ed

Browse files
committed
Ensure that type params of HOAS patterns are introduced inside the quote
1 parent c653745 commit 7bbf5ed

File tree

4 files changed

+57
-36
lines changed

4 files changed

+57
-36
lines changed

compiler/src/dotty/tools/dotc/quoted/QuotePatterns.scala

Lines changed: 44 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -26,31 +26,51 @@ object QuotePatterns:
2626
import tpd._
2727

2828
/** 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+
}
5253

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)
5474

5575
/** Encode the quote pattern into an `unapply` that the pattern matcher can handle.
5676
*

tests/neg-macros/hoas-pattern-with-type-params-1.scala renamed to tests/neg-macros/hoas-pattern-with-bounded-type-params.scala

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
/*
2+
* Supporting hoas quote pattern with bounded type variable
3+
* is future todo.
4+
*/
15

26
import scala.quoted.*
37

tests/neg-macros/hoas-pattern-with-type-params-2.scala

Lines changed: 0 additions & 12 deletions
This file was deleted.
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import scala.quoted.*
2+
3+
def test(body: Expr[Any])(using Quotes): Expr[String] =
4+
body match
5+
case '{ [A] => (x : A) => $b[A] : A => A } => // error // error
6+
Expr("Hoas pattern should always take value params")
7+
case '{ (a:Int) => $b[Int](a) : String } => // error
8+
Expr("Type params of a hoas pattern should be introduced inside the quote")
9+
case _ => Expr("not matched")

0 commit comments

Comments
 (0)