Skip to content

Commit 98971a6

Browse files
committed
Enforce implementation restrictions
- no nested rewrites - calls to rewrite unapplys only in rewrite code
1 parent 3bfea78 commit 98971a6

File tree

6 files changed

+64
-40
lines changed

6 files changed

+64
-40
lines changed

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -935,6 +935,9 @@ trait Applications extends Compatibility { self: Typer with Dynamic =>
935935
else trySelectUnapply(qual1)(_ => notAnExtractor(sel))
936936
}
937937

938+
if (unapplyFn.symbol.isRewriteMethod)
939+
checkInRewriteContext("implementation restriction: call to rewrite unapply", tree.pos)
940+
938941
/** Add a `Bind` node for each `bound` symbol in a type application `unapp` */
939942
def addBinders(unapp: Tree, bound: List[Symbol]) = unapp match {
940943
case TypeApply(fn, args) =>

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -254,6 +254,8 @@ object PrepareInlineable {
254254
}
255255

256256
def checkRewriteMethod(inlined: Symbol, body: Tree)(implicit ctx: Context) = {
257+
if (ctx.outer.inRewriteMethod)
258+
ctx.error(ex"implementation restriction: nested rewrite methods are not supported", inlined.pos)
257259
if (inlined.name == nme.unapply && tupleArgs(body).isEmpty)
258260
ctx.warning(
259261
em"rewrite unapply method can be rewritten only if its tight hand side is a tuple (e1, ..., eN)",

tests/neg/nested-rewrites.scala

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
object Test {
2+
3+
rewrite def f1(x: Int) = {
4+
rewrite def g(x: Int) = x // error: implementation restriction: nested rewrite methods are not supported
5+
g(x)
6+
}
7+
8+
rewrite def f2(x: Int) = {
9+
object o {
10+
rewrite def g(x: Int) = x // error: implementation restriction: nested rewrite methods are not supported
11+
}
12+
o.g(x)
13+
}
14+
}
15+
object Test0 {
16+
17+
def f(x: Int) = {
18+
rewrite def g(x: Int) = rewrite x match {
19+
case 0 => 0
20+
}
21+
g(0)
22+
transparent val Y = 0
23+
g(Y)
24+
25+
rewrite def h(x: Int) = rewrite x match {
26+
case Y => 0
27+
}
28+
h(0)
29+
}
30+
31+
f(0)
32+
33+
}
34+
35+
object Test1 {
36+
37+
erased rewrite def f(x: Int) = {
38+
erased rewrite def g(x: Int) = rewrite x match { // error: implementation restriction: nested rewrite methods are not supported
39+
case 0 => 0
40+
}
41+
g(0)
42+
transparent val Y = 0
43+
g(Y)
44+
45+
rewrite def h(x: Int) = rewrite x match { // error: implementation restriction: nested rewrite methods are not supported
46+
case Y => 0
47+
}
48+
h(0)
49+
}
50+
51+
f(0)
52+
53+
}

tests/neg/tuple-patterns2.scala

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
object Test {
2+
(1, 2) match {
3+
case x *: xs => // error: call to rewrite unapply
4+
}
5+
}

tests/pos/transparent-nested.scala

Lines changed: 0 additions & 39 deletions
This file was deleted.

tests/run/i4803d/App_2.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ object Test {
1010
println(power2(x3))
1111
}
1212

13-
rewrite def power2(x: Double) = {
13+
def power2(x: Double) = {
1414
rewrite def power(x: Double, transparent n: Long) = ~PowerMacro.powerCode('(x), n)
1515
power(x, 2)
1616
}

0 commit comments

Comments
 (0)