How to resolve "Illegal cyclic inheritance" compilation error when using a Java enum in Scala?
Asked Answered
T

1

6

It looks like the Scala compiler can't handle enums that implement an interface with a static method that captures the enum type as a method parameter.

Consider the following interface:

//Identifiable.java
package com.example;

import java.util.Map;
import java.util.function.Function;
import java.util.stream.Stream;

import static java.util.stream.Collectors.toMap;

public interface Identifiable {
    String name();

    static <E extends Enum<E> & Identifiable> Map<String, E> valuesByName(final E[] values) {
        return Stream.of(values).collect(toMap(Identifiable::name, Function.identity()));
    }
}

And an enum that implements it:

//Size.java
package com.example;

public enum Size implements Identifiable {
    SMALL, MEDIUM, LARGE;
}

Finally, a Scala app that uses the Size enum:

//Broken.scala
package com.example

object Broken extends App {
  println(Size.SMALL)
}

The following compilation error occurs when attempting to build the classes (in 2.12.3):

Error:(4, 10) illegal cyclic inheritance involving class Size
println(Size.SMALL)

Am I missing something or is this a bug in the compiler?

Tabu answered 2/12, 2017 at 18:31 Comment(9)
I put the three source files in an empty directory, started sbt, and typed ++2.12.3 and then run, and it compiled fine and ran and printed SMALL.Andrea
@SethTisue, I can confirm that I see the same error using Scala 2.12.4. The error seems to go if I remove valuesByName from the Identifiable but I have no idea why.Ladida
@SethTisue i just tried compiling and running the same code from command line using SBT 1.0.3 and Scala 2.12.3 which resulted in the same error /blah/blah/blah/com/example/Broken.scala:4:10: illegal cyclic inheritance involving class SizeTabu
Here's a full transcript of my successful run. What am I doing differently? gist.github.com/SethTisue/d91427937cac4faa8bf9f2b9e68d8a82Andrea
@SethTisue i'm actually seeing inconsistencies. compilation fails on the first attempt, but succeeds on the second and all subsequent attempts. however, if i change the source of Broken.scala to force SBT to recompile it, the build fails again. basically if SBT attempts to compile the Scala file by itself - Compiling 1 Scala source to - (because the Java files are already compiled), it fails. but if it builds all three from scratch - Compiling 1 Scala source and 2 Java sources to - it succeeds...Tabu
@SethTisue seems like forcing the build order to JavaThenScala produces consistent compilation failures: compileOrder := CompileOrder.JavaThenScalaTabu
Aha — yes, seems like a bug to me. I'd suggest searching github.com/scala/bug to see if it's been reported before or notAndrea
@SethTisue it didn't look like there were any existing issues for this scenario, so i opened a new one: 10639Tabu
fixed in 2.12.9Coating
S
-1

Go to File >> Project Structure >> Global Libraries and point correct scala version as given in pom.xml

Spitzer answered 29/4 at 8:55 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.