Skip to content

Commit 3e49481

Browse files
committed
Make sure that QuoteContext are stable
In the internal encoding of the splices we assume that these are stable and use them for some path-dependent types. If they are not stable, some of the internal inferred types become less precise.
1 parent 613a419 commit 3e49481

File tree

10 files changed

+33
-18
lines changed

10 files changed

+33
-18
lines changed

compiler/src/dotty/tools/dotc/typer/QuotesAndSplices.scala

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,12 @@ trait QuotesAndSplices {
4646
case _ =>
4747
}
4848
val qctx = inferImplicitArg(defn.QuoteContextClass.typeRef, tree.span)
49-
if (level == 0 && qctx.tpe.isInstanceOf[SearchFailureType])
49+
50+
if qctx.tpe.isInstanceOf[SearchFailureType] then
5051
ctx.error(missingArgMsg(qctx, defn.QuoteContextClass.typeRef, ""), ctx.source.atSpan(tree.span))
52+
else if !qctx.tpe.isStable then
53+
ctx.error(em"Quotes require stable QuoteContext, but found non stable $qctx", qctx.sourcePos)
54+
5155
val tree1 =
5256
if ctx.mode.is(Mode.Pattern) && level == 0 then
5357
typedQuotePattern(tree, pt, qctx)

tests/neg-macros/quote-this.scala

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,14 @@ class Foo {
1212
}
1313

1414
inline def i(): Unit = ${ Foo.impl[Any]('{
15-
given QuoteContext = ???
15+
val x: QuoteContext = ???
16+
given x.type = x
1617
'this // error
1718
}) }
1819

1920
inline def j(that: Foo): Unit = ${ Foo.impl[Any]('{
20-
given QuoteContext = ???
21+
val x: QuoteContext = ???
22+
given x.type = x
2123
'that // error
2224
}) }
2325

tests/neg/i4044a.scala

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,16 @@ def test(using QuoteContext) = {
44

55
val a = '{1}
66
'{
7-
given QuoteContext = ???
7+
val qctx: QuoteContext = ???
8+
given qctx.type = qctx
89
a // error
910
$a
1011
'{$a} // error
11-
'{ given QuoteContext = ???; '{$a} } // error
12+
'{
13+
val qctx: QuoteContext = ???
14+
given qctx.type = qctx
15+
'{$a} // error
16+
}
1217
}
1318

1419
}

tests/neg/i4044b.scala

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,17 +3,23 @@ import scala.quoted._
33
def test(using QuoteContext) = {
44

55
'{
6-
given QuoteContext = ???
6+
val qctx: QuoteContext = ???
7+
given qctx.type = qctx
78

89
val b = '{3}
910

1011
'{
11-
given QuoteContext = ???
12+
val qctx: QuoteContext = ???
13+
given qctx.type = qctx
1214

1315
b // error
1416
${b}
1517
${ '{b} } // error
16-
'{ given QuoteContext = ???; '{$b} } // error
18+
'{
19+
val qctx: QuoteContext = ???
20+
given qctx.type = qctx
21+
'{$b} // error
22+
}
1723
}
1824

1925
}

tests/neg/i7052b.scala

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
import scala.quoted._
22
class Test {
33
def foo(str: String)(using QuoteContext) = '{
4-
given QuoteContext = ???
4+
val qctx: QuoteContext = ???
5+
given qctx.type = qctx
56
'{
67
@deprecated(str, "") // error
78
def bar = ???

tests/neg/quote-0.scala

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@ def test(using QuoteContext) = {
55
val x: Int = 0
66

77
'{
8-
given QuoteContext = ???
8+
val qctx: QuoteContext = ???
9+
given qctx.type = qctx
910

1011
'{x + 1} // error: wrong staging level
1112

tests/pos/i4380b.scala

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import scala.quoted._
22

3-
object Test {
4-
given QuoteContext = ???
3+
class Test(using qctx: QuoteContext) {
54
def step(k: (String => Expr[Unit])): Expr[Unit] = '{}
65
def meth(): Unit = '{
76
(i: Int) => ${ step(el => '{} ) }

tests/pos/quote-1.scala

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import scala.quoted._
22

3-
object Test {
4-
given QuoteContext = ???
3+
class Test(using QuoteContext) {
54

65
def f[T](x: Expr[T])(implicit t: Type[T]) = '{
76
val y: $t = $x

tests/pos/quote-lift.scala

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import scala.quoted._
22

3-
object Test {
4-
given QuoteContext = ???
3+
class Test(using QuoteContext) {
54

65
'{ ${implicitly[Liftable[Int]].toExpr(1)} }
76

tests/pos/quoted-inline-quote.scala

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import scala.quoted._
2-
class Foo {
2+
class Foo(using QuoteContext) {
33
inline def foo(x: Expr[String])(using QuoteContext) = '{ println(${x}) }
44

5-
given QuoteContext = ???
65
foo('{"abc"})
76
}

0 commit comments

Comments
 (0)