-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Fix #4815: Illegal modifier on local def #4850
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
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should be fixed in the parser. The parser currently rejects:
class Test {
def foo = {
private def bar = 1
}
}
I would check why final
is not rejected as well
@@ -0,0 +1,24 @@ | |||
class Test { | |||
def foo = { | |||
final def bar = 1 // error: local def may not be final |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
scalac
rejects this. I think we should reject it as well
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure I understand. We do reject this. This is what this PR does.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry, it was meant for the line below (i.e. final val v = 42
)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, I see. There's at least one test that uses this feature (constant value expression):
- https://github.com/lampepfl/dotty/blob/946ba3f2d938b54e316749aef1c2ff117ecdb325/tests/run/tasty-eval/quoted_2.scala#L8
- Additionally, it seem to be explicitly allowed by the spec: https://scala-lang.org/files/archive/spec/2.12/04-basic-declarations-and-definitions.html#value-declarations-and-definitions
A constant value definition is of the form
final val x = e
where e is a constant expression. The final modifier must be present and no type annotation may be given. References to the constant value x are themselves treated as constant expressions; in the generated code they are replaced by the definition's right-hand side e.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This part of the spec only specifies what a constant value is, not where it is allowed. Looking at the syntax part of the spec, it doesn't seems to be allowed
BlockStat ::= Import
| {Annotation} [‘implicit’ | ‘lazy’] Def
| {Annotation} {LocalModifier} TmplDef
| Expr1
Def ::= PatVarDef
| ‘def’ FunDef
| ‘type’ {nl} TypeDef
| TmplDef
PatVarDef ::= ‘val’ PatDef
| ‘var’ VarDef
Thanks for taking a look. Here's why I ended up adding the check in the typer. There are four places I considered doing the check on:
This seemed rather ugly because the first thing
Does that make sense? Is there a reason the check should be shoehorned into the Parser? |
Thanks for the link. I think I see how to make the Dotty version of |
Moved the change to the parser a la scalac. PTAL. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM. Thanks @abeln 🎉
You can change the final val in dotty.tools.languageserver.Memory
to a normal val
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 }
Done. PTAL. |
During typechecking, disallow the use of
final
in localdefs
.e.g.