Reputation: 419
At http://www.artima.com/pins1ed/builtin-control-structures.html#7.7, I see the following code
val a = 1;
{
val a = 2
println(a)
}
println(a)
where it says that the semicolon is required here, but why?
From the rule at http://www.artima.com/pins1ed/classes-and-objects.html#4.2 , I think the semicolon should be auto added since
val a = 1
can be a legal statement.{
, which I think can start a legal statement. (Since there's no compile error if I add the semicolon and separate the first two lines into two statements.)val a = 1
is not in parentheses or brackets.Upvotes: 3
Views: 159
Reputation: 67280
Because it would be a legal call to apply
:
implicit class RichInt(i: Int) {
def apply(thunk: => Unit) = 33
}
val a = 1
{
val a = 2
println(a)
}
println(a) // 33 !
1 { ... }
is short for 1.apply {...}
. Now apply
is not defined for an Int
by default, but as the implicit enrichment shows, it is perfectly possible.
Edit: The semicolon inference conditions are described in '§1.2 Newline Characters' of the Scala Language Specification. The inferred semicolon is called 'special token "nl
"' in that text.
In general, three rules are given (summarised ex-negativo in this blog entry), and in your example they are all satisfied. The reason that the semicolon is still not inferred is given further down in the text.
The Scala grammar ... contains productions where optional
nl
tokens, but not semicolons, are accepted. This has the effect that a newline in one of these positions does not [!] terminate an expression or statement.
The relevant case of such an extra rule is the following:
A single new line token is accepted
– in front of an opening brace “{”, if that brace is a legal continuation of the current statement or expression ...
Example 1.2.2 shows the case of anonymous an subclass which I had referred to in the comment.
Upvotes: 5