Navigation Menu

Skip to content
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

Cannot compile java.lang.{Throwable,CloneNotSupportedException,InterruptedException} anymore #8367

Closed
scabug opened this issue Mar 6, 2014 · 15 comments

Comments

@scabug
Copy link

scabug commented Mar 6, 2014

Scala 2.11.0-RC1 exhibits absurd errors while compiling classes named java.lang.Throwable, java.lang.CloneNotSupportedException and java.lang.InterruptedException (yes, these 3, all others work fine). It used to be compilable in 2.10 and until 2.11.0-M8.

The following source "minimizes" the problem, but with enough meat to show that other classes of exceptions do work. Keeping only either of the three broken classes still produces the error.

Compiling the following with Scala 2.11.0-RC1 (just Scala, no need to have the Scala.js plugin to break it):

package java.lang

class Throwable(s: String, private var e: Throwable) extends Object with java.io.Serializable {
  def this() = this(null, null)
  def this(s: String) = this(s, null)
  def this(e: Throwable) = this(null, e)

  private[this] var stackTrace: Array[StackTraceElement] = _

  fillInStackTrace()

  def initCause(cause: Throwable): Throwable = {
    e = cause
    this
  }

  def getMessage(): String = s
  def getCause(): Throwable = e
  def getLocalizedMessage(): String = getMessage()

  def fillInStackTrace(): Throwable = this

  def getStackTrace(): Array[StackTraceElement] = ???

  def setStackTrace(stackTrace: Array[StackTraceElement]): Unit = ???

  def printStackTrace(): Unit = ???
  def printStackTrace(out: java.io.PrintStream): Unit = ???
  def printStackTrace(s: java.io.PrintWriter): Unit = ???

  override def toString() = {
    val className = getClass.getName
    val message = getMessage()
    if (message eq null) className
    else className + ": " + message
  }
}


/* java.lang.*Exception.java */

class Exception(s: String, e: Throwable) extends Throwable(s, e) {
  def this(e: Throwable) = this(null, e)
  def this(s: String) = this(s, null)
  def this() = this(null, null)
}

class RuntimeException(s: String, e: Throwable) extends Exception(s, e) {
  def this(e: Throwable) = this(null, e)
  def this(s: String) = this(s, null)
  def this() = this(null, null)
}

class ArithmeticException(s: String) extends RuntimeException(s) {
  def this() = this(null)
}

class ClassCastException(s: String) extends RuntimeException(s) {
  def this() = this(null)
}

class CloneNotSupportedException(s: String) extends Exception(s) {
  def this() = this(null)
}

class InterruptedException(s: String) extends Exception(s) {
  def this() = this(null)
}

class NullPointerException(s: String) extends RuntimeException(s) {
  def this() = this(null)
}

produces the following 3 absurd errors:

[error] /home/doeraene/temp/bug/Throwables.scala:3: self constructor arguments cannot reference unconstructed `this`
[error] class Throwable(s: String, private var e: Throwable) extends Object with java.io.Serializable {
[error]                                                              ^
[error] /home/doeraene/temp/bug/Throwables.scala:62: self constructor arguments cannot reference unconstructed `this`
[error] class CloneNotSupportedException(s: String) extends Exception(s) {
[error]                                                     ^
[error] /home/doeraene/temp/bug/Throwables.scala:66: self constructor arguments cannot reference unconstructed `this`
[error] class InterruptedException(s: String) extends Exception(s) {
[error]                                               ^
[error] three errors found

It worked fine with 2.11.0-M8.

If you want to reproduce in the context of Scala.js, you can clone the branch scala-2.11.0-RC1 in my fork:
https://github.com/sjrd/scala-js/tree/scala-2.11.0-RC1
and in sbt:

> ++2.11.0-RC1
> scalajs-javalib/compile

I want to stress that this is a blocker for Scala.js. I just can't build Scala.js for RC1.

@scabug
Copy link
Author

scabug commented Mar 6, 2014

Imported From: https://issues.scala-lang.org/browse/SI-8367?orig=1
Reporter: @sjrd
Affected Versions: 2.11.0-RC1
See #8389
Attachments:

@scabug
Copy link
Author

scabug commented Mar 6, 2014

@adriaanm said:
Regressed in commit 51b16e421ddd4e6c7e90ba945addf39ffcb4fa41
Author: Eugene Burmako xeno.by@gmail.com
Date: Tue Jan 28 11:29:28 2014 +0300

SI-8192 adds ClassSymbol.isPrimaryConstructor

BTW, finding this commit is easy with git bisect and our own tooling (https://github.com/retronym/libscala, https://github.com/adriaanm/binfu/blob/master/scalac-head):

 ~/ $ RUNNER=scalac scala-hash v2.11.0-M8 /Users/adriaan/Desktop/Bugs/t8367.scala 
 ~/ $ RUNNER=scalac scala-hash v2.11.0-RC1 /Users/adriaan/Desktop/Bugs/t8367.scala 
/Users/adriaan/Desktop/Bugs/t8367.scala:3: error: self constructor arguments cannot reference unconstructed `this`
class Throwable(s: String, private var e: Throwable) extends Object with java.io.Serializable {
                                                             ^
/Users/adriaan/Desktop/Bugs/t8367.scala:62: error: self constructor arguments cannot reference unconstructed `this`
class CloneNotSupportedException(s: String) extends Exception(s) {
                                                    ^
/Users/adriaan/Desktop/Bugs/t8367.scala:66: error: self constructor arguments cannot reference unconstructed `this`
class InterruptedException(s: String) extends Exception(s) {
                                              ^
three errors found

[ master $%> ] scala/ $ g bisect start
[ master $%|BISECTING> ] scala/ $ g bisect good v2.11.0-M8
[ master $%|BISECTING> ] scala/ $ g bisect bad v2.11.0-RC1
[ (ed4ae1d359...) $%|BISECTING ] scala/ $ g bisect run scalac-head /Users/adriaan/Desktop/Bugs/t8367.scala 
[...]
51b16e421ddd4e6c7e90ba945addf39ffcb4fa41 is the first bad commit
commit 51b16e421ddd4e6c7e90ba945addf39ffcb4fa41
Author: Eugene Burmako <xeno.by@gmail.com>
Date:   Tue Jan 28 11:29:28 2014 +0300

    SI-8192 adds ClassSymbol.isPrimaryConstructor
    

@scabug
Copy link
Author

scabug commented Mar 6, 2014

@adriaanm said:
(Part of the monster PR scala/scala#3452)

@scabug
Copy link
Author

scabug commented Mar 6, 2014

@adriaanm said:
Some seriously weird shit going on here.

package java.lang

// SI-8367 shows something is wrong with primaryConstructor and it was made worse with the fix for SI-8192
// perhaps primaryConstructor should not return NoSymbol when isJavaDefined
// or, perhaps isJavaDefined should be refined (the package definition above is pretty sneaky) 
// also, why does this only happen for a (scala-defined!) class with this special name?
// (there are a couple of others: CloneNotSupportedException,InterruptedException)
class Throwable

// class CloneNotSupportedException 
// class InterruptedException

yields

RUNNER=scalac scala-hash v2.11.0-RC1 /Users/adriaan/Desktop/Bugs/t8367.scala -Xprint:typer
/Users/adriaan/Desktop/Bugs/t8367.scala:10: error: self constructor arguments cannot reference unconstructed `this`
// class InterruptedException
                             ^
[[syntax trees at end of                     typer]] // t8367.scala
package java.lang {
  class Throwable extends scala.AnyRef {
    def <init>(): Throwable = {
      Throwable.super.<init>();
      ()
    }
  }
}

one error found

wait, what? my comment has a type error!?

@scabug
Copy link
Author

scabug commented Mar 6, 2014

@xeno-by said:
Thanks for figuring out the culprit. I'll take a look tomorrow evening.

@scabug
Copy link
Author

scabug commented Mar 6, 2014

@adriaanm said:
Thanks -- I'm taking a quick look now as well, because my previous comment indicates some really weird stuff is going on....

@scabug
Copy link
Author

scabug commented Mar 6, 2014

@adriaanm said:
In any case, I don't think we should change the semantics of primaryConstructor for isJavaDefined symbols at this point.

@scabug
Copy link
Author

scabug commented Mar 7, 2014

@scabug
Copy link
Author

scabug commented Mar 7, 2014

@gkossakowski said:

BTW, finding this commit is easy with git bisect and our own tooling (https://github.com/retronym/libscala, https://github.com/adriaanm/binfu/blob/master/scalac-head):

libscala has scala-bisector which nicely encapsulates the whole bisection logic.

@scabug
Copy link
Author

scabug commented Mar 7, 2014

@xeno-by said:
scala/scala#3607

@scabug
Copy link
Author

scabug commented Mar 10, 2014

@retronym said:
@adriaanm Regrarding the oddly positioned error message, looks like its a bug in the parser:

% cat sandbox/Throwable.scala
package java.lang

// SI-8367 shows something is wrong with primaryConstructor and it was made worse with the fix for SI-8192
// perhaps primaryConstructor should not return NoSymbol when isJavaDefined
// or, perhaps isJavaDefined should be refined (the package definition above is pretty sneaky)
// also, why does this only happen for a (scala-defined!) class with this special name?
// (there are a couple of others: CloneNotSupportedException,InterruptedException)
class Throwable

// class CloneNotSupportedException
// class InterruptedException

% scalac-hash master -Xprint-pos -Xprint:parser  sandbox/Throwable.scala
[[syntax trees at end of                    parser]] // Throwable.scala
[13]package [13]java.lang {
  [476]class Throwable extends [485][554]scala.AnyRef {
    [554]def <init>() = [554]{
      [NoPosition][NoPosition][NoPosition]super.<init>();
      [554]()
    }
  }
}

Regarding "why does this only happen for a (scala-defined!) class with this special name?", I believe this is because the compiler forces loading of those symbols from the Java class-files during typechecking, e.g. with:

// TreeInfo.scala
private def isSimpleThrowable(tp: Type): Boolean = tp match {
    case TypeRef(pre, sym, args) =>
      (pre == NoPrefix || pre.widen.typeSymbol.isStatic) &&
      (sym isNonBottomSubClass ThrowableClass) &&  /* bq */ !sym.isTrait
    case _ =>
      false
  }

@scabug
Copy link
Author

scabug commented Mar 10, 2014

@retronym said:
Here's a stab at fixing the parser bug: scala/scala#3612

@scabug
Copy link
Author

scabug commented Mar 10, 2014

@retronym said:
Stab retracted, and the parser bug is now tracked as #8389

@scabug scabug closed this as completed Mar 10, 2014
@scabug
Copy link
Author

scabug commented Mar 19, 2014

@sjrd said:
Thanks for fixing this issue so quickly! As Adriaan already noticed, we've been able to build Scala.js for 2.11.0-RC3 today without any issue:
scala-js/scala-js@cd9cab4
:-)

@scabug
Copy link
Author

scabug commented Mar 19, 2014

@adriaanm said:
Good to hear! Thanks for the report and tracking our releases so quickly!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants