Skip to content

Commit a14c79e

Browse files
Only allow erased parameters in erased definitions (#19686)
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.
2 parents bfc8a0d + f4ff6e3 commit a14c79e

File tree

9 files changed

+54
-72
lines changed

9 files changed

+54
-72
lines changed

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

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

555555
private def checkErasedDef(tree: ValOrDefDef)(using Context): Unit =
556+
def checkOnlyErasedParams(): Unit = tree match
557+
case tree: DefDef =>
558+
for params <- tree.paramss; param <- params if !param.symbol.isType && !param.symbol.is(Erased) do
559+
report.error("erased definition can only have erased parameters", param.srcPos)
560+
case _ =>
561+
556562
if tree.symbol.is(Erased, butNot = Macro) then
563+
checkOnlyErasedParams()
557564
val tpe = tree.rhs.tpe
558565
if tpe.derivesFrom(defn.NothingClass) then
559566
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

tests/pos/i7741.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ class A1 {
44
@native private def a: Unit
55
}
66
trait A2 {
7-
erased def i(a: Int): Int
7+
erased def i(erased a: Int): Int
88
}
99
trait A3 {
1010
erased val a: Int

0 commit comments

Comments
 (0)