Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Only allow erased parameters in erased definitions #19686

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions compiler/src/dotty/tools/dotc/transform/PostTyper.scala
Original file line number Diff line number Diff line change
Expand Up @@ -553,7 +553,14 @@ class PostTyper extends MacroTransform with InfoTransformer { thisPhase =>
report.error("classes that extend MacroAnnotation must not be inner/local classes", sym.srcPos)

private def checkErasedDef(tree: ValOrDefDef)(using Context): Unit =
def checkOnlyErasedParams(): Unit = tree match
case tree: DefDef =>
for params <- tree.paramss; param <- params if !param.symbol.isType && !param.symbol.is(Erased) do
report.error("erased definition can only have erased parameters", param.srcPos)
case _ =>

if tree.symbol.is(Erased, butNot = Macro) then
checkOnlyErasedParams()
val tpe = tree.rhs.tpe
if tpe.derivesFrom(defn.NothingClass) then
report.error("`erased` definition cannot be implemented with en expression of type Nothing", tree.srcPos)
Expand Down
2 changes: 1 addition & 1 deletion tests/coverage/run/erased/test.scala
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import scala.language.experimental.erasedDefinitions

erased def parameterless: String = "y"

erased def e(x: String): String = "x"
erased def e(erased x: String): String = "x"
def foo(erased a: String)(b: String): String =
println(s"foo(a)($b)")
b
Expand Down
42 changes: 21 additions & 21 deletions tests/coverage/run/erased/test.scoverage.check
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@ test$package
Object
<empty>.test$package
foo
181
203
188
210
7
println
Apply
Expand All @@ -42,8 +42,8 @@ test$package
Object
<empty>.test$package
foo
189
202
196
209
7
s
Apply
Expand All @@ -59,8 +59,8 @@ test$package
Object
<empty>.test$package
foo
132
139
146
6
foo
DefDef
Expand All @@ -76,8 +76,8 @@ test$package
Object
<empty>.test$package
identity
245
269
252
276
11
println
Apply
Expand All @@ -93,8 +93,8 @@ test$package
Object
<empty>.test$package
identity
253
268
260
275
11
s
Apply
Expand All @@ -110,8 +110,8 @@ test$package
Object
<empty>.test$package
identity
209
221
216
228
10
identity
DefDef
Expand All @@ -127,8 +127,8 @@ test$package
Object
<empty>.test$package
Test
300
323
307
330
16
foo
Apply
Expand All @@ -144,8 +144,8 @@ test$package
Object
<empty>.test$package
Test
326
342
333
349
17
foo
Apply
Expand All @@ -161,8 +161,8 @@ test$package
Object
<empty>.test$package
Test
345
374
352
381
18
foo
Apply
Expand All @@ -178,8 +178,8 @@ test$package
Object
<empty>.test$package
Test
357
373
364
380
18
identity
Apply
Expand All @@ -195,8 +195,8 @@ test$package
Object
<empty>.test$package
Test
275
289
282
296
15
Test
DefDef
Expand Down
17 changes: 3 additions & 14 deletions tests/neg/erased-1.scala
Original file line number Diff line number Diff line change
Expand Up @@ -12,25 +12,14 @@ object Test {
})
foo1(a) // OK
foo2( // error
a // error
)
foo3( // error
a
a // Ok
)
a // error
}
erased def foo2(a: Int): Int = {
foo0(a) // OK
foo1(a) // OK
foo2(a) // OK
foo3(a) // OK
a // OK
}
erased def foo3(erased a: Int): Int = {
erased def foo2(erased a: Int): Int = {
foo0(a) // OK
foo1(a) // OK
foo2(a) // OK
foo3(a) // OK
a // OK
}
}
}
21 changes: 4 additions & 17 deletions tests/neg/erased-2.scala
Original file line number Diff line number Diff line change
Expand Up @@ -8,39 +8,26 @@ object Test {
)
foo1(u) // OK
foo2( // error
u // error
)
foo3( // error
u
u // Ok
)
u // error
u // error
}
erased def foo2(a: Int): Int = {
foo0(u) // OK
foo1(u) // OK
foo2(u) // OK
foo3(u) // OK
u // warn
u // OK
}
erased def foo3(erased a: Int): Int = {
erased def foo2(erased a: Int): Int = {
foo0(u) // OK
foo1(u) // OK
foo2(u) // OK
foo3(u) // OK
u // warn
u // OK
}

erased val foo4: Int = {
erased val foo3: Int = {
foo0(u) // OK
foo1(u) // OK
foo2(u) // OK
foo3(u) // OK
u // warn
u // OK
}

erased def u: Int = 42
}
}
21 changes: 4 additions & 17 deletions tests/neg/erased-3.scala
Original file line number Diff line number Diff line change
Expand Up @@ -8,40 +8,27 @@ object Test {
)
foo1(u()) // OK
foo2( // error
u() // error
)
foo3( // error
u()
u() // Ok
)
u() // error
u() // error
}
erased def foo2(a: Int): Int = {
foo0(u()) // OK
foo1(u()) // OK
foo2(u()) // OK
foo3(u()) // OK
u() // warn
u() // OK
}
erased def foo3(erased a: Int): Int = {
erased def foo2(erased a: Int): Int = {
foo0(u()) // OK
foo1(u()) // OK
foo2(u()) // OK
foo3(u()) // OK
u() // warn
u() // OK
}

erased val foo4: Int = {
erased val foo3: Int = {
foo0(u()) // OK
foo1(u()) // OK
foo2(u()) // OK
foo3(u()) // OK
println()
u() // warn
u() // OK
}

erased def u(): Int = 42
}
}
2 changes: 1 addition & 1 deletion tests/neg/erased-args-lifted.scala
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

object Test {
def foo(a: Int)(b: Int, c: Int) = 42
erased def bar(i: Int): Int = {
erased def bar(erased i: Int): Int = {
println(1)
42
}
Expand Down
12 changes: 12 additions & 0 deletions tests/neg/erased-params.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import scala.language.experimental.erasedDefinitions

erased def test1(x: Int): Int = x // error
erased def test2(erased x: Int): Int = x
erased def test3(erased x: Int, erased y: Int): Int = x
erased def test4(erased x: Int, y: Int): Int = x // error
erased def test5(x: Int, erased y: Int): Int = y // error
erased def test6(x: Int, y: Int): Int = y // error // error
erased def test7(erased x: Int)(erased y: Int): Int = x
erased def test8(erased x: Int)(y: Int): Int = x // error
erased def test9(x: Int)(erased y: Int): Int = y // error
erased def test10(x: Int)(y: Int): Int = y // error // error
2 changes: 1 addition & 1 deletion tests/pos/i7741.scala
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ class A1 {
@native private def a: Unit
}
trait A2 {
erased def i(a: Int): Int
erased def i(erased a: Int): Int
}
trait A3 {
erased val a: Int
Expand Down
Loading