Macros, Incremental Compilation, and Inheritance Type Errors

Hi All,

I have used Scala for a few years to develop research software. I have recently developed some macros for this project and have encountered a very specific and surprising compile error. I am looking for advice: is the issue described below caused by a bug or fundamental limitation in Scala macros, or is it an issue with my macro?

I am using a simplified example here, which I have made into a Gist and uploaded as a zipped IntelliJ project*. Please let me know if another format would be more convenient. Also let me know if there is another forum which is better for reporting this issue, I probably need help from a compiler dev. This code compiles, runs, and passes its test on a clean build, but fails to compile on an incremental recompile. I am trying to understand and fix the recompile error.

In this Gist, Annotate.scala creates an annotation macro @Annotate which assumes it is applied to an integer “val” definition and replaces the right-hand side with the literal integer 0.

The client code has a nontrivial inheritance pattern. AnnotateExample.scala has a trait AnnotateExampleTrait which uses the @Annotate macro annotation. Object AnnotateExample extends the trait, as does object InheritExample, which is in another file. The trait AnnotateExampleTrait mentions a value (but not type!) in InheritExample, so that there is cyclic reference.

When I change AnnotateExampleTrait.integer and recompile, I get:

Error:(8, 7) illegal cyclic reference involving trait AnnotateExampleTrait
    trait AnnotateExampleTrait {
Error:(6, 32) illegal inheritance;
     self-type example.AnnotateExample.type does not conform to example.AnnotateExampleTrait's 
     selftype example.AnnotateExampleTrait
     object AnnotateExample extends AnnotateExampleTrait
Error:(8, 7) illegal cyclic reference involving object InheritExample
    trait AnnotateExampleTrait {

This error is surprising because the code does not use self-types explicitly, the type of AnnotateExampleTrait does not mention InheritExample, and the error happens only on incremental recompiles. If I delete “import InheritExample._” on Line 4 of AnnotateExample.scala and change Line 12 to reference “InheritExample.otherInteger”, the error goes away. It also goes away if I remove the annotation, or if all the example classes are in the same file.

I suspect that when the @Annotate macro is applied, it somehow disturbs the typing metadata for AnnotateExampleTrait, which is then propagated to InheritExample. When AnnotateExample is incrementally recompiled, the inheritance check fails because type information for InheritExample is stale and InheritExample is not being incrementally recompiled. However, this is speculation and I could use expert help to get to the bottom of this.

Our project has a significant codebase and many of its dependencies have only been released for older Scala versions. For this reason I am not using the latest version of Scala, I am using Scala 2.12.8 with SBT 1.3.7. If this happens to be a compiler bug which has been fixed in more recent Scala releases, that would also be helpful to know. I have enabled the Macro Paradise plugin as is needed in Scala 2.12, and my macro is in a separate project from the client.

Thanks in advance.

*The SBT files in this project are a bit incorrect but the dependencies have been fixed up in project modules settings.