Missing error report in parentheses

Since I studied Scala, they often remind me of g ++ errors when reading cryptic output from scalac . However, today I came across the fact that I doubt that this will happen even in the g++ universe.

A friend sent me a very simple piece of code with a fairly common error:

 case class Var(name: String) extends ArithExpr { override def eval(env: Env) = env.lookup(name) match { case Some(d) => d case None => throw new IllegalArgumentException("Env " + env + " does not contain a binding for " + name) } override def exprString = name // } // <-- MISSING THIS BRACE 

Here is the full source file. Since the case class Var declaration does not have a closing bracket, you might think that the compiler would tell you that the opening bracket for this declaration (on line 11) does not have its closing brace. However, scalac reports that it "accepts" the missing closing shape in the middle of the previous case class declaration (line 7). (Full error output is included at the bottom of the published code.)

Most scalac error messages make sense if you understand the internals of the language, but here I am completely losing. How does the missing closing bracket in a later class declaration extend to the already successfully parsed class definition previously in the file?

How do you explain this to a novice beginner Scala? The remaining closing bracket is exactly the kind of error that a newcomer to Scala can usually bring, but the error message here seems to cause the user to be confused for now, which would probably be more useful to report something like error: you seem to be missing a '}' somewhere instead.

Note. I know that the usual answer to questions such as “just use the IDE and incremental compilation will immediately mark it” or “syntax highlighting should make this error obvious” - but my question asks a question about scalac , so please keep in mind that I know these are valid points, but I just want to understand what is happening with the compiler here.

Update:

Let me try a different approach to explaining my confusion. The error is due to the missing closing bracket, so this is clearly a problem with nesting the brackets. Converting the text (code) into a fragment that I sent to a series of pairs of lines of line +, we get the following:

 1{ 4} 6{ 9} 11{ 12{ 15} 19{ 22} 24{ 26} 28{ 33} 

We obviously have a missing closing piece. I could understand scalac , suggesting that the missing curly brace could go in any of these places (each of them is represented by x):

 1{ 4} 6{ 9} 11{ x 12{ x 15} x <-- HERE OR HERE OR HERE 19{ x 22} x <-- OR HERE OR HERE 24{ x 26} x <-- OR HERE OR HERE 28{ x 33} x <-- OR HERE OR HERE 

However, this is what the scalac result scalac :

  +----- I THINK YOU ARE MISSING A | CLOSING BRACE RIGHT HERE! 1{ V 4} 6{ x 9} 11{ 12{ 15} 19{ 22} 24{ 26} 28{ 33} 

This part of the input is already well nested! How could one add another closing piece?

Edit: It seems to me that I should repeat my main question again: how would you explain this error message (and how to find the root of the error in the source) to a Scala newbie?

+6
source share
2 answers

Following the suggestion of Jörg W Mittag in my commentary on my question, I re-opened the old ticket in the Scala tracker: Confusing Unmatched bracket closing errors . I added the code from this question as a new, short, reproducible example of this class of confused error messages.

+1
source

Consider the following example (I deliberately removed the indent):

 case class Foo( i: Int ) { case class Bar( d: Double ) { def get = d } 

It does not compile, but there are several possible correct codes:

 case class Foo( i: Int ) { } case class Bar( d: Double ) { def get = d } //OR case class Foo( i: Int ) { case class Bar( d: Double ) { def get = d } } //OR even (still won't compile but the structure is correct so the compiler will proceed with //another error) case class Foo( i: Int ) { case class Bar( d: Double ) { } def get = d } 

So, how should the compiler guess which version is correct? In this case, he chooses the first place, which may make sense:

 hello.scala:3: error: Missing closing brace `}' assumed here def get = d 

Which corresponds to the third option.

+4
source

Source: https://habr.com/ru/post/923355/


All Articles