File tree 4 files changed +39
-0
lines changed
compiler/src/dotty/tools/dotc
4 files changed +39
-0
lines changed Original file line number Diff line number Diff line change @@ -131,6 +131,7 @@ public enum ErrorMessageID {
131
131
MatchCaseOnlyNullWarningID ,
132
132
ImportRenamedTwiceID ,
133
133
TypeTestAlwaysSucceedsID ,
134
+ LocalDefMayNotBeFinalID ,
134
135
;
135
136
136
137
public int errorNumber () {
Original file line number Diff line number Diff line change @@ -1560,6 +1560,15 @@ object messages {
1560
1560
" A trait can never be final since it is abstract and must be extended to be useful."
1561
1561
}
1562
1562
1563
+ case class LocalDefMayNotBeFinal (sym : Symbol )(
1564
+ implicit ctx : Context )
1565
+ extends Message (LocalDefMayNotBeFinalID ) {
1566
+ val msg = hl """ $sym may not be ${" final" }. """
1567
+ val kind = " Syntax"
1568
+ val explanation =
1569
+ hl " Only ${" def" }s that appear as fields may be marked as ${" final" }, but $sym is a local definition. "
1570
+ }
1571
+
1563
1572
case class NativeMembersMayNotHaveImplementation (sym : Symbol )(
1564
1573
implicit ctx : Context )
1565
1574
extends Message (NativeMembersMayNotHaveImplementationID ) {
Original file line number Diff line number Diff line change @@ -369,6 +369,8 @@ object Checking {
369
369
if (! ok && ! sym.is(Synthetic ))
370
370
fail(i " modifier ` $flag` is not allowed for this definition " )
371
371
372
+ def isClassLike (sym : Symbol ) = sym.isClass || sym.is(Module ) || sym.isAnonymousClass
373
+
372
374
if (sym.is(Transparent ) &&
373
375
( sym.is(ParamAccessor ) && sym.owner.isClass
374
376
|| sym.is(TermParam ) && ! sym.owner.isTransparentMethod
@@ -387,6 +389,9 @@ object Checking {
387
389
fail(AbstractOverrideOnlyInTraits (sym))
388
390
if (sym.is(Trait ) && sym.is(Final ))
389
391
fail(TraitsMayNotBeFinal (sym))
392
+ if (sym.is(Method ) && sym.is(Final ) && ! isClassLike(sym.owner)) {
393
+ fail(LocalDefMayNotBeFinal (sym))
394
+ }
390
395
// Skip ModuleVal since the annotation will also be on the ModuleClass
391
396
if (sym.hasAnnotation(defn.TailrecAnnot ) && ! sym.is(Method | ModuleVal ))
392
397
fail(TailrecNotApplicable (sym))
Original file line number Diff line number Diff line change
1
+ class Test {
2
+ def foo = {
3
+ final def bar = 1 // error: local def may not be final
4
+ final val v = 42 // ok: this is a constant expression
5
+ }
6
+
7
+ {
8
+ final def foo (x : Int ) = x // error: local def may not be final
9
+ }
10
+
11
+ final def foo2 (x : Int ) = x // ok: final allowed in class field
12
+
13
+ object Foo {
14
+ final def foo (x : Int ) = x // ok, but redundant
15
+ }
16
+
17
+ abstract class Bar {
18
+ def foo : Int
19
+ }
20
+
21
+ val x = new Bar {
22
+ override final def foo = 42 // ok: def is a field
23
+ }
24
+ }
You can’t perform that action at this time.
0 commit comments