Skip to content

Commit 8ce3ea2

Browse files
committed
Fix level checking for this.type in macros
1 parent 74e15ba commit 8ce3ea2

File tree

3 files changed

+68
-3
lines changed

3 files changed

+68
-3
lines changed

compiler/src/dotty/tools/dotc/transform/ReifyQuotes.scala

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -239,7 +239,14 @@ class ReifyQuotes extends MacroTransformWithImplicits {
239239
def levelOK(sym: Symbol)(implicit ctx: Context): Boolean = levelOf.get(sym) match {
240240
case Some(l) =>
241241
l == level ||
242-
level == -1 && sym == defn.TastyTasty_macroContext
242+
level == -1 && (
243+
sym == defn.TastyTasty_macroContext ||
244+
// here we assume that Splicer.canBeSpliced was true before going to level -1,
245+
// this implies that all non-inline arguments are quoted and that the following two cases are checked
246+
// on inline parameters or type parameters.
247+
sym.is(Param) ||
248+
sym.isClass // reference to this in inline methods
249+
)
243250
case None =>
244251
!sym.is(Param) || levelOK(sym.owner)
245252
}
@@ -594,9 +601,10 @@ class ReifyQuotes extends MacroTransformWithImplicits {
594601
"""Malformed macro.
595602
|
596603
|Expected the ~ to be at the top of the RHS:
597-
| inline def foo(x: X, ..., y: Y): Int = ~impl(x, ... '(y))
604+
| inline def foo(inline x: X, ..., y: Y): Int = ~impl(x, ... '(y))
598605
|
599-
|The contents of the splice must call a static method. Arguments must be quoted or inlined.
606+
| * The contents of the splice must call a static method
607+
| * All arguments must be quoted or inline
600608
""".stripMargin, tree.rhs.pos)
601609
EmptyTree
602610
}

tests/neg/quote-this.scala

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
import scala.quoted._
2+
3+
class Foo {
4+
5+
def f: Unit = '{
6+
def bar[T](x: T): T = x
7+
bar[
8+
this.type // error
9+
] {
10+
this // error
11+
}
12+
}
13+
14+
inline def i(): Unit = ~Foo.impl[Any]('{
15+
'(this) // error
16+
})
17+
18+
inline def j(that: Foo): Unit = ~Foo.impl[Any]('{
19+
'(that) // error
20+
})
21+
22+
inline def k(): Unit = ~Foo.impl[Any](this) // error
23+
inline def l(that: Foo): Unit = ~Foo.impl[Any](that) // error
24+
25+
}
26+
27+
object Foo {
28+
def impl[T](x: Any): Expr[Unit] = '()
29+
}

tests/pos/quote-this.scala

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import scala.quoted._
2+
3+
class Foo {
4+
def a: Expr[Int] = '(1)
5+
def b: Expr[Int] = '{
6+
~this.a
7+
}
8+
9+
def d: Expr[Expr[Int]] = '{ '(1) }
10+
def e: Expr[Expr[Int]] = '{
11+
'( ~(~this.d) )
12+
}
13+
14+
def foo[T](x: T): T = x
15+
16+
def f = '{
17+
~foo[this.type](this).a
18+
}
19+
20+
inline def g(): Unit = ~Foo.impl[this.type](1)
21+
inline def h(): Unit = ~Foo.impl[Any]('(this))
22+
inline def i(that: Foo): Unit = ~Foo.impl[that.type](1)
23+
24+
}
25+
26+
object Foo {
27+
def impl[T](x: Any): Expr[Unit] = '()
28+
}

0 commit comments

Comments
 (0)