Skip to content

Commit 39eba3a

Browse files
committed
Only allow erased parameters in erased definitions
So far, we do not have any use case for them. We could enable them in a later version. The current implementation does not handle correctly the non-erased arguments to erased definitions. These should always be evaluated, but in some cases we can dorp them by mistake.
1 parent 8776677 commit 39eba3a

File tree

8 files changed

+53
-71
lines changed

8 files changed

+53
-71
lines changed

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

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -536,7 +536,14 @@ class PostTyper extends MacroTransform with InfoTransformer { thisPhase =>
536536
report.error("classes that extend MacroAnnotation must not be inner/local classes", sym.srcPos)
537537

538538
private def checkErasedDef(tree: ValOrDefDef)(using Context): Unit =
539+
def checkOnlyErasedParams(): Unit = tree match
540+
case tree: DefDef =>
541+
for params <- tree.paramss; param <- params if !param.symbol.isType && !param.symbol.is(Erased) do
542+
report.error("erased definition can only have erased parameters", param.srcPos)
543+
case _ =>
544+
539545
if tree.symbol.is(Erased, butNot = Macro) then
546+
checkOnlyErasedParams()
540547
val tpe = tree.rhs.tpe
541548
if tpe.derivesFrom(defn.NothingClass) then
542549
report.error("`erased` definition cannot be implemented with en expression of type Nothing", tree.srcPos)

tests/coverage/run/erased/test.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import scala.language.experimental.erasedDefinitions
22

33
erased def parameterless: String = "y"
44

5-
erased def e(x: String): String = "x"
5+
erased def e(erased x: String): String = "x"
66
def foo(erased a: String)(b: String): String =
77
println(s"foo(a)($b)")
88
b

tests/coverage/run/erased/test.scoverage.check

Lines changed: 21 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,8 @@ test$package
2525
Object
2626
<empty>.test$package
2727
foo
28-
181
29-
203
28+
188
29+
210
3030
7
3131
println
3232
Apply
@@ -42,8 +42,8 @@ test$package
4242
Object
4343
<empty>.test$package
4444
foo
45-
189
46-
202
45+
196
46+
209
4747
7
4848
s
4949
Apply
@@ -59,8 +59,8 @@ test$package
5959
Object
6060
<empty>.test$package
6161
foo
62-
132
6362
139
63+
146
6464
6
6565
foo
6666
DefDef
@@ -76,8 +76,8 @@ test$package
7676
Object
7777
<empty>.test$package
7878
identity
79-
245
80-
269
79+
252
80+
276
8181
11
8282
println
8383
Apply
@@ -93,8 +93,8 @@ test$package
9393
Object
9494
<empty>.test$package
9595
identity
96-
253
97-
268
96+
260
97+
275
9898
11
9999
s
100100
Apply
@@ -110,8 +110,8 @@ test$package
110110
Object
111111
<empty>.test$package
112112
identity
113-
209
114-
221
113+
216
114+
228
115115
10
116116
identity
117117
DefDef
@@ -127,8 +127,8 @@ test$package
127127
Object
128128
<empty>.test$package
129129
Test
130-
300
131-
323
130+
307
131+
330
132132
16
133133
foo
134134
Apply
@@ -144,8 +144,8 @@ test$package
144144
Object
145145
<empty>.test$package
146146
Test
147-
326
148-
342
147+
333
148+
349
149149
17
150150
foo
151151
Apply
@@ -161,8 +161,8 @@ test$package
161161
Object
162162
<empty>.test$package
163163
Test
164-
345
165-
374
164+
352
165+
381
166166
18
167167
foo
168168
Apply
@@ -178,8 +178,8 @@ test$package
178178
Object
179179
<empty>.test$package
180180
Test
181-
357
182-
373
181+
364
182+
380
183183
18
184184
identity
185185
Apply
@@ -195,8 +195,8 @@ test$package
195195
Object
196196
<empty>.test$package
197197
Test
198-
275
199-
289
198+
282
199+
296
200200
15
201201
Test
202202
DefDef

tests/neg/erased-1.scala

Lines changed: 3 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -12,25 +12,14 @@ object Test {
1212
})
1313
foo1(a) // OK
1414
foo2( // error
15-
a // error
16-
)
17-
foo3( // error
18-
a
15+
a // Ok
1916
)
2017
a // error
2118
}
22-
erased def foo2(a: Int): Int = {
23-
foo0(a) // OK
24-
foo1(a) // OK
25-
foo2(a) // OK
26-
foo3(a) // OK
27-
a // OK
28-
}
29-
erased def foo3(erased a: Int): Int = {
19+
erased def foo2(erased a: Int): Int = {
3020
foo0(a) // OK
3121
foo1(a) // OK
3222
foo2(a) // OK
33-
foo3(a) // OK
3423
a // OK
3524
}
36-
}
25+
}

tests/neg/erased-2.scala

Lines changed: 4 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -8,39 +8,26 @@ object Test {
88
)
99
foo1(u) // OK
1010
foo2( // error
11-
u // error
12-
)
13-
foo3( // error
14-
u
11+
u // Ok
1512
)
1613
u // error
1714
u // error
1815
}
19-
erased def foo2(a: Int): Int = {
20-
foo0(u) // OK
21-
foo1(u) // OK
22-
foo2(u) // OK
23-
foo3(u) // OK
24-
u // warn
25-
u // OK
26-
}
27-
erased def foo3(erased a: Int): Int = {
16+
erased def foo2(erased a: Int): Int = {
2817
foo0(u) // OK
2918
foo1(u) // OK
3019
foo2(u) // OK
31-
foo3(u) // OK
3220
u // warn
3321
u // OK
3422
}
3523

36-
erased val foo4: Int = {
24+
erased val foo3: Int = {
3725
foo0(u) // OK
3826
foo1(u) // OK
3927
foo2(u) // OK
40-
foo3(u) // OK
4128
u // warn
4229
u // OK
4330
}
4431

4532
erased def u: Int = 42
46-
}
33+
}

tests/neg/erased-3.scala

Lines changed: 4 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -8,40 +8,27 @@ object Test {
88
)
99
foo1(u()) // OK
1010
foo2( // error
11-
u() // error
12-
)
13-
foo3( // error
14-
u()
11+
u() // Ok
1512
)
1613
u() // error
1714
u() // error
1815
}
19-
erased def foo2(a: Int): Int = {
20-
foo0(u()) // OK
21-
foo1(u()) // OK
22-
foo2(u()) // OK
23-
foo3(u()) // OK
24-
u() // warn
25-
u() // OK
26-
}
27-
erased def foo3(erased a: Int): Int = {
16+
erased def foo2(erased a: Int): Int = {
2817
foo0(u()) // OK
2918
foo1(u()) // OK
3019
foo2(u()) // OK
31-
foo3(u()) // OK
3220
u() // warn
3321
u() // OK
3422
}
3523

36-
erased val foo4: Int = {
24+
erased val foo3: Int = {
3725
foo0(u()) // OK
3826
foo1(u()) // OK
3927
foo2(u()) // OK
40-
foo3(u()) // OK
4128
println()
4229
u() // warn
4330
u() // OK
4431
}
4532

4633
erased def u(): Int = 42
47-
}
34+
}

tests/neg/erased-args-lifted.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
object Test {
44
def foo(a: Int)(b: Int, c: Int) = 42
5-
erased def bar(i: Int): Int = {
5+
erased def bar(erased i: Int): Int = {
66
println(1)
77
42
88
}

tests/neg/erased-params.scala

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import scala.language.experimental.erasedDefinitions
2+
3+
erased def test1(x: Int): Int = x // error
4+
erased def test2(erased x: Int): Int = x
5+
erased def test3(erased x: Int, erased y: Int): Int = x
6+
erased def test4(erased x: Int, y: Int): Int = x // error
7+
erased def test5(x: Int, erased y: Int): Int = y // error
8+
erased def test6(x: Int, y: Int): Int = y // error // error
9+
erased def test7(erased x: Int)(erased y: Int): Int = x
10+
erased def test8(erased x: Int)(y: Int): Int = x // error
11+
erased def test9(x: Int)(erased y: Int): Int = y // error
12+
erased def test10(x: Int)(y: Int): Int = y // error // error

0 commit comments

Comments
 (0)