Skip to content

Commit 03085e0

Browse files
authored
Merge pull request #14732 from dotty-staging/fix-14536
Handle this prefix in objects (in quote patterns)
2 parents 90b3eda + 0e77c82 commit 03085e0

File tree

5 files changed

+64
-0
lines changed

5 files changed

+64
-0
lines changed

compiler/src/scala/quoted/runtime/impl/QuoteMatcher.scala

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -247,6 +247,8 @@ object QuoteMatcher {
247247
case ref: Ident =>
248248
ref.tpe match
249249
case TermRef(qual: TermRef, _) => tpd.ref(qual) =?= qual2
250+
case TermRef(qual: ThisType, _) if qual.classSymbol.is(Module, butNot = Package) =>
251+
tpd.ref(qual.classSymbol.companionModule) =?= qual2
250252
case _ => matched
251253
/* Match reference */
252254
case _: Ident if symbolMatch(scrutinee, pattern) => matched

tests/pos-macros/i14536/Macro_1.scala

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import quoted.*
2+
3+
inline def isFoo(inline x: Any): Boolean = ${ isFooImpl('x) }
4+
5+
def isFooImpl(x: Expr[Any])(using Quotes): Expr[Boolean] =
6+
x match
7+
case '{ ($p: Parent).foo } => '{ true }
8+
case _ => '{ false }
9+
10+
trait Parent:
11+
def foo = 0

tests/pos-macros/i14536/Test_2.scala

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
object Child extends Parent:
2+
def bar = isFoo(foo)
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
import quoted.*
2+
import scala.compiletime.testing.{typeChecks, typeCheckErrors}
3+
import scala.compiletime.testing.{Error, ErrorKind}
4+
5+
transparent inline def assertCompiles(inline code: String): Unit =
6+
${ assertCompilesImpl('code, '{typeCheckErrors(code)}) }
7+
8+
given FromExpr[ErrorKind] with {
9+
def unapply(expr: Expr[ErrorKind])(using Quotes) = expr match {
10+
case '{ ErrorKind.Parser } => Some(ErrorKind.Parser)
11+
case '{ ErrorKind.Typer } => Some(ErrorKind.Typer)
12+
case _ => None
13+
}
14+
}
15+
16+
given FromExpr[Error] with {
17+
def unapply(expr: Expr[Error])(using Quotes) = expr match {
18+
case '{ Error(${Expr(msg)}, ${Expr(line)}, ${Expr(col)}, ${Expr(kind)}) } => Some(Error(msg, line, col, kind))
19+
case _ => None
20+
}
21+
}
22+
23+
private def assertCompilesImpl(self: Expr[_], typeChecked: Expr[List[Error]])(using Quotes): Expr[Unit] = {
24+
import quotes.reflect._
25+
26+
def checkCompile(code: String): Expr[Unit] = {
27+
// For some reason `typeChecked.valueOrError` is failing here, so instead we grab
28+
// the varargs argument to List.apply and use that to extract the list of errors
29+
val errors = typeChecked.asTerm.underlyingArgument match {
30+
case Apply(TypeApply(Select(Ident("List"), "apply"), _), List(seq)) =>
31+
seq.asExprOf[Seq[Error]].valueOrError.toList
32+
}
33+
34+
'{}
35+
}
36+
37+
self.asTerm.underlyingArgument match {
38+
39+
case Literal(StringConstant(code)) =>
40+
checkCompile(code.toString)
41+
42+
case Apply(Select(_, "stripMargin"), List(Literal(StringConstant(code)))) =>
43+
checkCompile(code.toString.stripMargin)
44+
45+
case _ =>
46+
report.throwError("The 'assertCompiles' function only works with String literals.")
47+
}
48+
}

tests/pos-macros/i14536b/Test_2.scala

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
def test = assertCompiles("val a: String = 2")

0 commit comments

Comments
 (0)