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

Separate compilation breaks with reflective call #11773

Open
JanBessai opened this issue Oct 16, 2019 · 2 comments

Comments

@JanBessai
Copy link

@JanBessai JanBessai commented Oct 16, 2019

There seems to be some issue with reflective calls and incremental separate compilation:

Types.scala:

import language.reflectiveCalls

object Types {
  trait Parent {
    type T
  }

  type Aux[TT] = Parent { type T = TT }

  final class Child[TT](val child: Aux[TT]) extends Parent {
    override type T = child.T
  }

  final object Leaf extends Parent {
    override type T = String
  }
}

Works.scala

import Types._

object Works {
  val x: Child[String] = new Child[String](Leaf)    
}

Fails.scala

import Types._

object Fails {
  val x: Aux[String] = new Child[String](Leaf)
}

Now with the distributed version of scala 2.13.1 and scala 2.12.9 from nixos I can do:

$ scalac Types.scala
$ scalac Works.scala 

while

$ scalac Types.scala
$ scalac Fails.scala 

results in

Fails.scala:4: error: type mismatch;
 found   : Types.Child[String]
 required: Types.Aux[String]
    (which expands to)  Types.Parent{type T = String}
  val x: Aux[String] = new Child[String](Leaf)
                       ^
one error found

When I recompile Types.scala it works:

$ scalac Types.scala Fails.scala

A diff on the generated .class files of Types.scala between the two runs shows no difference:

$ mkdir single
$ scalac Types.scala
$ cp *.class single/
$ rm *.class
$ scalac Types.scala Fails.scala
$ mkdir both
$ cp *.class both/
$ diff single both
Only in both: Fails.class
Only in both: Fails$.class

I condensed the example out of a larger project which uses sbt.

I doubt that it is relevant, but here is my java version:

$ java -version
openjdk version "11.0.3-internal" 2019-04-16
OpenJDK Runtime Environment (build 11.0.3-internal+0-adhoc..jdk11u-jdk-11.0.3-ga)
OpenJDK 64-Bit Server VM (build 11.0.3-internal+0-adhoc..jdk11u-jdk-11.0.3-ga, mixed mode)

PS.: The issue is gone when I test with dotty 0.19.0-RC1.
PPS: The issue is also present with openjdk 1.8.0_212 and scala 2.11.12.
PPPS:
Perhaps unsurprisingly, the issue is also present with precompiled .jar files:

$ scalac Types.scala
$ jar cvf types.jar Types*.class
added manifest
adding: Types$Child.class(in = 658) (out= 402)(deflated 38%)
adding: Types.class(in = 868) (out= 695)(deflated 19%)
adding: Types$.class(in = 387) (out= 281)(deflated 27%)
adding: Types$Leaf$.class(in = 480) (out= 331)(deflated 31%)
adding: Types$Parent.class(in = 192) (out= 151)(deflated 21%)
$ rm *.class
$ scalac -classpath types.jar Works.scala 
$ scalac -classpath types.jar Fails.scala 
Fails.scala:4: error: type mismatch;
 found   : Types.Child[String]
 required: Types.Aux[String]
    (which expands to)  Types.Parent{type T = String}
  val x: Aux[String] = new Child[String](Leaf)
                       ^
one error found
@SethTisue SethTisue changed the title Incremental compilation breaks with reflective call Separate compilation breaks with reflective call Oct 23, 2019
@SethTisue

This comment has been minimized.

Copy link
Member

@SethTisue SethTisue commented Oct 23, 2019

We call this "separate compilation", not "incremental compilation" (the latter is provided by zinc, and isn't a capability of plain scalac). I've edited the issue title and description to reflect this.

@JanBessai

This comment has been minimized.

Copy link
Author

@JanBessai JanBessai commented Oct 23, 2019

Thanks for the better terminology!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
2 participants
You can’t perform that action at this time.