Skip to content

Commit 42fa9b2

Browse files
committed
Fix #4815: Illegal modifier on local def
During parsing, disallow the use of "final" in local definitions. e.g. def foo = { final def bar = 42 // error: final in local def is disallowed final var x = 42 // error final type X = Int // error }
1 parent 36c2e34 commit 42fa9b2

File tree

4 files changed

+36
-4
lines changed

4 files changed

+36
-4
lines changed

compiler/src/dotty/tools/dotc/parsing/Parsers.scala

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2545,7 +2545,12 @@ object Parsers {
25452545
def localDef(start: Int, implicitMods: Modifiers = EmptyModifiers): Tree = {
25462546
var mods = defAnnotsMods(localModifierTokens)
25472547
for (imod <- implicitMods.mods) mods = addMod(mods, imod)
2548-
defOrDcl(start, mods)
2548+
if (mods.is(Final)) {
2549+
// A final modifier means the local definition is "class-like".
2550+
tmplDef(start, mods)
2551+
} else {
2552+
defOrDcl(start, mods)
2553+
}
25492554
}
25502555

25512556
/** BlockStatSeq ::= { BlockStat semi } [ResultExpr]

language-server/src/dotty/tools/languageserver/Memory.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,11 +37,11 @@ object Memory {
3737
}
3838

3939
def stats(): String = {
40-
final val M = 2 << 20
40+
val M = 2 << 20
4141
val runtime = Runtime.getRuntime
4242
def total = runtime.totalMemory / M
4343
def maximal = runtime.maxMemory / M
4444
def free = runtime.freeMemory / M
4545
s"total used memory: $total MB, free: $free MB, maximal available = $maximal MB"
4646
}
47-
}
47+
}

tests/neg/t4815.scala

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
class Test {
2+
def foo = {
3+
final def bar = 1 // error: local def may not be final
4+
final val v = 42 // error: local val may not be final
5+
final var v2 = 100 // error: local var may not be final
6+
final type T = Int // error: local type def may not be final
7+
}
8+
9+
{
10+
final def foo(x: Int) = x // error: local def may not be final
11+
}
12+
13+
final def foo2(x: Int) = x // ok: final allowed in class field
14+
15+
object Foo {
16+
final def foo(x: Int) = x // ok, but redundant
17+
}
18+
19+
abstract class Bar {
20+
def foo: Int
21+
}
22+
23+
val x = new Bar {
24+
override final def foo = 42 // ok: def is a field
25+
}
26+
}

tests/run/tasty-eval/quoted_2.scala

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,11 @@
22
import Macros._
33

44
object Test {
5+
final val y = 5
6+
57
def main(args: Array[String]): Unit = {
68
println(foo(1)) // "Some(1)"
79
println(foo(1 + 7)) // "Some(8)"
8-
final val y = 5
910
println(foo(y)) // "Some(5)"
1011
println(foo(y + 1))
1112
val x = 4

0 commit comments

Comments
 (0)