This page is no longer maintained — Please continue to the home page at www.scala-lang.org

How to detect errors in compiler-generated code?

2 replies
odersky
Joined: 2008-07-29,
User offline. Last seen 45 weeks 6 days ago.

Hi Hubert,

I am trying to get value classes working, and stumbled on a problem
this morning. I
was trying to create an array of two Meters, where Meter is a value class.

class Meter(...) extends AnyVal ...
val x: Meter
val arr = Array(x, x + x)

It crashed in superaccessors because a generated manifest contained an
error value (stacktrace appended). The problem was clearly that
superaccessors should not have been run because typer produced an
error. But that error was never reported. I had some fun debugging
this, because when I instrumented setError, and looked at the
stacktrace, I got nonsensical error messages that were due to other
previous errors that were also swallowed without trace.

The error occurred in compiler-generated code, so strictly speaking
this is an internal problem for scalac. However, needless to say, it's
a debugging nightmare.

I think two things should happen:

1. Errors in compiler-generated code should also be guaranteed to be
reported, so that they do not cause crashes later in the
transformation pipeline.

2. There should be a way to see errors as they are generated. To that
purpose, I added a line
to Contexts#issue:

def issue(err: AbsTypeError) {
if (settings.debug.value) println("issuing error: "+err)
if (reportErrors) unitError(err.errPos, addDiagString(err.errMsg))
else if (bufferErrors) { buffer += err }
else throw new TypeError(err.errPos, err.errMsg)
}

I am not 100% sure we want to tie this to Ydebug (seems reasonable, though).

Can you review that patch and dig deeper on (1)? Thanks!

To reproduce:

Check out my brach topic/inline from github. You might have to do a
pull-binaries before building. Then, compile class

test/files/run/Meter.scala.

You should see the crash in superaccessors. Compile again with
-Ydebug. That should show you what went wrong and then abort with
stacktrace in setError. As you can see, setError is called from within
a silent... in Implits#manifestFactoryCall.

Cheers

adriaanm
Joined: 2010-02-08,
User offline. Last seen 31 weeks 4 days ago.
Re: How to detect errors in compiler-generated code?
looks like an untyped subtree in an otherwise typed tree to me --a

On Mon, Feb 13, 2012 at 11:54 AM, martin odersky <martin.odersky@epfl.ch> wrote:
Hi Hubert,

I am trying to get value classes working, and stumbled on a problem
this morning. I
was trying to create an array of two Meters, where Meter is a value class.

 class Meter(...) extends AnyVal ...
 val x: Meter
 val arr = Array(x, x + x)

It crashed in superaccessors because a generated manifest contained an
error value (stacktrace appended). The problem was clearly that
superaccessors should not have been run because typer produced an
error. But that error was never reported. I had some fun debugging
this, because when I instrumented setError, and looked at the
stacktrace, I got nonsensical error messages that were due to other
previous errors that were also swallowed without trace.

The error occurred in compiler-generated code, so strictly speaking
this is an internal problem for scalac. However, needless to say, it's
a debugging nightmare.

I think two things should happen:

 1. Errors in compiler-generated code should also be guaranteed to be
reported, so that they do not cause crashes later in the
transformation pipeline.

 2. There should be a way to see errors as they are generated. To that
purpose, I added a line
to Contexts#issue:

  def issue(err: AbsTypeError) {
     if (settings.debug.value) println("issuing error: "+err)
     if (reportErrors) unitError(err.errPos, addDiagString(err.errMsg))
     else if (bufferErrors) { buffer += err }
     else throw new TypeError(err.errPos, err.errMsg)
   }

I am not 100% sure we want to tie this to Ydebug (seems reasonable, though).

Can you review that patch and dig deeper on (1)? Thanks!

To reproduce:

Check out my brach topic/inline from github. You might have to do a
pull-binaries before building. Then, compile class

 test/files/run/Meter.scala.

You should see the crash in superaccessors. Compile again with
-Ydebug. That should show you what went wrong and then abort with
stacktrace in setError. As you can see, setError is called from within
a silent... in Implits#manifestFactoryCall.

Cheers

odersky
Joined: 2008-07-29,
User offline. Last seen 45 weeks 6 days ago.
Re: How to detect errors in compiler-generated code?

On Mon, Feb 13, 2012 at 12:01 PM, Adriaan Moors wrote:
> looks like an untyped subtree in an otherwise typed tree to me --a
>
Maybe that's the end result is untyped as a result of the typer
bailing out. The stacktrace with -Ydebug shows that it certainly does
attempt to type-check the offending tree.

Cheers

Copyright © 2012 École Polytechnique Fédérale de Lausanne (EPFL), Lausanne, Switzerland