Skip to content
This repository
Browse code

[backport] SI-7439 Avoid NPE in `isMonomorphicType` with stub symbols.

`originalInfo` can return null for stub symbols; deal with that
as we used to before a regression in 016bc3d.

After this change, we can once again delete A_1.class and still compile
code instantiating B_1. (A_1 is only referred to in a method signature
of B_1 which is not called from our code.)

	scala> new B_1
	warning: Class A_1 not found - continuing with a stub.
	res0: B_1 = B_1@5284b8f

In practice, this situation arises when someone uses a third
party class that was compiled against other libraries not avaialable
on the current compilation classpath.

(cherry picked from commit a954321)
  • Loading branch information...
commit 8d74fa024262c1bd2dc7ed64788b95f888396c05 1 parent 7e996c1
Jason Zaugg retronym authored
4 src/reflect/scala/reflect/internal/Symbols.scala
@@ -709,7 +709,9 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
709 709 final def isMonomorphicType =
710 710 isType && {
711 711 val info = originalInfo
712   - info.isComplete && !info.isHigherKinded
  712 + ( (info eq null)
  713 + || (info.isComplete && !info.isHigherKinded)
  714 + )
713 715 }
714 716
715 717 def isStrictFP = hasAnnotation(ScalaStrictFPAttr) || (enclClass hasAnnotation ScalaStrictFPAttr)
1  test/files/run/t7439.check
... ... @@ -0,0 +1 @@
  1 +pos: NoPosition Class A_1 not found - continuing with a stub. WARNING
3  test/files/run/t7439/A_1.java
... ... @@ -0,0 +1,3 @@
  1 +public class A_1 {
  2 +
  3 +}
3  test/files/run/t7439/B_1.java
... ... @@ -0,0 +1,3 @@
  1 +public class B_1 {
  2 + public void b(A_1[] a) {}
  3 +}
31 test/files/run/t7439/Test_2.scala
... ... @@ -0,0 +1,31 @@
  1 +import scala.tools.partest._
  2 +import java.io.File
  3 +
  4 +object Test extends StoreReporterDirectTest {
  5 + def code = ???
  6 +
  7 + def compileCode(code: String) = {
  8 + val classpath = List(sys.props("partest.lib"), testOutput.path) mkString sys.props("path.separator")
  9 + compileString(newCompiler("-cp", classpath, "-d", testOutput.path))(code)
  10 + }
  11 +
  12 + def C = """
  13 + class C {
  14 + new B_1
  15 + }
  16 + """
  17 +
  18 + def show(): Unit = {
  19 + //compileCode(C)
  20 + assert(filteredInfos.isEmpty, filteredInfos)
  21 +
  22 + // blow away the entire package
  23 + val a1Class = new File(testOutput.path, "A_1.class")
  24 + assert(a1Class.exists)
  25 + assert(a1Class.delete())
  26 +
  27 + // bad symbolic reference error expected (but no stack trace!)
  28 + compileCode(C)
  29 + println(storeReporter.infos.mkString("\n")) // Included a NullPointerException before.
  30 + }
  31 +}

0 comments on commit 8d74fa0

Please sign in to comment.
Something went wrong with that request. Please try again.