Skip to content

Enum nested in a class causes a crash #9332

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

Closed
sir-wabbit opened this issue Jul 9, 2020 · 2 comments · Fixed by #10007
Closed

Enum nested in a class causes a crash #9332

sir-wabbit opened this issue Jul 9, 2020 · 2 comments · Fixed by #10007

Comments

@sir-wabbit
Copy link

Minimized code

class A {
  enum B extends java.lang.Enum[B] {
    case C
  }
}

Output (click arrow to expand)

an unexpected type representation reached the compiler backend while compiling test.scala: MethodType(List(), List(), TypeRef(ThisType(TypeRef(ThisType(TypeRef(NoPrefix,module class <empty>)),class A)),class A$B)). If possible, please file a bug on https://github.com/lampepfl/dotty/issues
Error while emitting test.scala
exception occurred while compiling test.scala
scala.MatchError: MethodType(List(), List(), TypeRef(ThisType(TypeRef(ThisType(TypeRef(NoPrefix,module class <empty>)),class A)),class A$B)) (of class dotty.tools.dotc.core.Types$CachedMethodType) while compiling test.scala
Exception in thread "main" scala.MatchError: MethodType(List(), List(), TypeRef(ThisType(TypeRef(ThisType(TypeRef(NoPrefix,module class <empty>)),class A)),class A$B)) (of class dotty.tools.dotc.core.Types$CachedMethodType)
	at dotty.tools.backend.jvm.BCodeHelpers.dotty$tools$backend$jvm$BCodeHelpers$$typeToTypeKind(BCodeHelpers.scala:842)
	at dotty.tools.backend.jvm.BCodeHelpers$BCInnerClassGen.toTypeKind(BCodeHelpers.scala:291)
	at dotty.tools.backend.jvm.BCodeSkelBuilder$PlainSkelBuilder.toTypeKind(BCodeSkelBuilder.scala:57)
	at dotty.tools.backend.jvm.BCodeSkelBuilder$PlainSkelBuilder.symInfoTK(BCodeSkelBuilder.scala:86)
	at dotty.tools.backend.jvm.BCodeSkelBuilder$PlainSkelBuilder.addClassFields$$anonfun$2(BCodeSkelBuilder.scala:267)
	at dotty.runtime.function.JProcedure1.apply(JProcedure1.java:15)
	at dotty.runtime.function.JProcedure1.apply(JProcedure1.java:10)
	at scala.collection.immutable.List.foreach(List.scala:333)
	at dotty.tools.backend.jvm.BCodeSkelBuilder$PlainSkelBuilder.addClassFields(BCodeSkelBuilder.scala:273)
	at dotty.tools.backend.jvm.BCodeSkelBuilder$PlainSkelBuilder.genPlainClass(BCodeSkelBuilder.scala:133)
	at dotty.tools.backend.jvm.GenBCodePipeline$Worker1.visit(GenBCode.scala:218)
	at dotty.tools.backend.jvm.GenBCodePipeline$Worker1.run(GenBCode.scala:185)
	at dotty.tools.backend.jvm.GenBCodePipeline.buildAndSendToDisk(GenBCode.scala:515)
	at dotty.tools.backend.jvm.GenBCodePipeline.run(GenBCode.scala:481)
	at dotty.tools.backend.jvm.GenBCode.run(GenBCode.scala:51)
	at dotty.tools.dotc.core.Phases$Phase.runOn$$anonfun$1(Phases.scala:318)
	at scala.collection.immutable.List.map(List.scala:246)
	at dotty.tools.dotc.core.Phases$Phase.runOn(Phases.scala:319)
	at dotty.tools.backend.jvm.GenBCode.runOn(GenBCode.scala:55)
	at dotty.tools.dotc.Run.runPhases$4$$anonfun$4(Run.scala:180)
	at dotty.runtime.function.JProcedure1.apply(JProcedure1.java:15)
	at dotty.runtime.function.JProcedure1.apply(JProcedure1.java:10)
	at scala.collection.ArrayOps$.foreach$extension(ArrayOps.scala:1323)
	at dotty.tools.dotc.Run.runPhases$5(Run.scala:190)
	at dotty.tools.dotc.Run.compileUnits$$anonfun$1(Run.scala:198)
	at dotty.runtime.function.JFunction0$mcV$sp.apply(JFunction0$mcV$sp.java:12)
	at dotty.tools.dotc.util.Stats$.maybeMonitored(Stats.scala:64)
	at dotty.tools.dotc.Run.compileUnits(Run.scala:205)
	at dotty.tools.dotc.Run.compileSources(Run.scala:142)
	at dotty.tools.dotc.Run.compile(Run.scala:124)
	at dotty.tools.dotc.Driver.doCompile(Driver.scala:38)
	at dotty.tools.dotc.Driver.process(Driver.scala:194)
	at dotty.tools.dotc.Driver.process(Driver.scala:163)
	at dotty.tools.dotc.Driver.process(Driver.scala:175)
	at dotty.tools.dotc.Driver.main(Driver.scala:202)
	at dotty.tools.dotc.Main.main(Main.scala)
@sir-wabbit
Copy link
Author

With -Ycheck:all it causes a different crash:

// AE-06c16b4f31ad07426c0d9f431f3ee3bf78f56e9d
// with -Ycheck:all
class A {
  enum B extends java.lang.Enum[B] {
    case C
  }
}

Output (click arrow to expand)

checking test.scala after phase typer
checking test.scala after phase inlinedPositions
checking test.scala after phase staging
checking test.scala after phase posttyper
checking test.scala after phase pickler
checking test.scala after phase reifyQuotes
checking test.scala after phase MegaPhase{firstTransform, checkReentrant, elimPackagePrefixes, cookComments, checkStatic, betaReduce}
checking test.scala after phase MegaPhase{elimRepeated, expandSAMs, protectedAccessors, extmethods, cacheAliasImplicits, byNameClosures, hoistSuperArgs, refchecks}
checking test.scala after phase MegaPhase{elimOpaque, tryCatchPatterns, patternMatcher, explicitOuter, explicitSelf, stringInterpolatorOpt, crossCast}
checking test.scala after phase MegaPhase{pruneErasedDefs, inlinePatterns, vcInlineMethods, seqLiterals, intercepted, getters, elimByName, liftTry, collectNullableFields, elimOuterSelect, augmentScala2Traits, resolveSuper, functionXXLForwarders, paramForwarding, genericTuples, letOverApply, arrayConstructors}
checking test.scala after phase erasure
checking test.scala after phase MegaPhase{elimErasedValueType, pureStats, vcElideAllocations, arrayApply, elimPolyFunction, tailrec, completeJavaEnums, mixin, lazyVals, memoize, nonLocalReturns, capturedVars}
exception while typing @scala.annotation.static() <static> val C: (): A.this.B = B.this.$outer.B.C of class class dotty.tools.dotc.ast.Trees$ValDef # 2221
exception while typing @scala.annotation.internal.Child[(A.B.C : (): A.this.B)]() sealed abstract class

B($outer: A, _$name: String, _$ordinal: Int) extends Enum, Enum {
  super(B.this._$name, B.this._$ordinal)
  def productIterator(): scala.collection.Iterator =
    super[Product].productIterator()
  def productPrefix(): String = super[Product].productPrefix()
  def productElementName(n: Int): String = super[Product].productElementName(n)
  def productElementNames(): scala.collection.Iterator =
    super[Product].productElementNames()
  private val $outer: A
  val _$name: String
  val _$ordinal: Int
  @scala.annotation.static() <static> val C: (): A.this.B = B.this.$outer.B.C
  final def A$B$$$outer(): A = B.this.$outer
} of class class dotty.tools.dotc.ast.Trees$TypeDef # 2269
exception while typing @scala.annotation.internal.SourceFile("test.scala") class A() extends Object {
  super()
  @scala.annotation.internal.Child[(A.B.C : (): A.this.B)]() sealed abstract
    class
   B($outer: A, _$name: String, _$ordinal: Int) extends Enum, Enum {
    super(B.this._$name, B.this._$ordinal)
    def productIterator(): scala.collection.Iterator =
      super[Product].productIterator()
    def productPrefix(): String = super[Product].productPrefix()
    def productElementName(n: Int): String =
      super[Product].productElementName(n)
    def productElementNames(): scala.collection.Iterator =
      super[Product].productElementNames()
    private val $outer: A
    val _$name: String
    val _$ordinal: Int
    @scala.annotation.static() <static> val C: (): A.this.B = B.this.$outer.B.C
    final def A$B$$$outer(): A = B.this.$outer
  }
  val B$lzy1: A.this.B$ = new A.this.B$(this)
  final lazy module def B(): A.this.B$ = this.B$lzy1
  final module class B$($outer: A) extends Object, java.io.Serializable,
    scala.deriving.Mirror.Sum
   {
    super()
    def values(): A.this.B[] =
      this.$values.values().toArray(
        scala.reflect.ClassTag.apply(classOf[A.this.B])
      ).asInstanceOf[A.this.B[]]
    private val $values: scala.runtime.EnumValues =
      new scala.runtime.EnumValues()
    def valueOf($name: String): A.this.B =
      try this.$values.fromName().apply($name).asInstanceOf[A.this.B] catch
        {
          case ex$ @ _:java.util.NoSuchElementException =>
            throw new IllegalArgumentException("key not found: ".concat($name))
        }
    private def $new(_$ordinal: Int, $name: String): A.this.B =
      {
        final class $anon($outer: A.this.B$) extends A.this.B,
          scala.runtime.EnumValue
        , scala.deriving.Mirror.Singleton {
          super(this.$outer.A$B$$$$outer(), $name, _$ordinal)
          override def canEqual(that: Object): Boolean =
            super[EnumValue].canEqual(that)
          override def productArity(): Int = super[EnumValue].productArity()
          override def productPrefix(): String =
            super[EnumValue].productPrefix()
          override def productElement(n: Int): Object =
            super[EnumValue].productElement(n)
          override def productElementName(n: Int): String =
            super[EnumValue].productElementName(n)
          def fromProduct(p: Product): scala.deriving.Mirror.Singleton =
            super[Singleton].fromProduct(p)
          def $ordinal(): Int = _$ordinal
          override def toString(): String = $name
          this.$outer.$values.register(this)
          private val $outer: A.this.B$
          final def A$B$_$$anon$$$outer(): A.this.B$ = $outer
          def fromProduct(p: Product): Object = this.fromProduct(p)
        }
        new
          A.this.B with scala.runtime.EnumValue with
            scala.deriving.Mirror.Singleton
           {...}
        (this):A.this.B
      }
    private val C: A.this.B = this.$new(0, "C")
    case def C(): A.this.B = this.C
    def ordinal(x$0: A.this.B): Int = x$0.ordinal()
    private val $outer: A
    final def A$B$$$$outer(): A = A.B.$outer
    def ordinal(x: Object): Int = this.ordinal(x.asInstanceOf[A.this.B])
  }
} of class class dotty.tools.dotc.ast.Trees$TypeDef # 2378
exception while typing package <empty> {
  @scala.annotation.internal.SourceFile("test.scala") class A() extends Object {
    super()
    @scala.annotation.internal.Child[(A.B.C : (): A.this.B)]() sealed abstract
      class
     B($outer: A, _$name: String, _$ordinal: Int) extends Enum, Enum {
      super(B.this._$name, B.this._$ordinal)
      def productIterator(): scala.collection.Iterator =
        super[Product].productIterator()
      def productPrefix(): String = super[Product].productPrefix()
      def productElementName(n: Int): String =
        super[Product].productElementName(n)
      def productElementNames(): scala.collection.Iterator =
        super[Product].productElementNames()
      private val $outer: A
      val _$name: String
      val _$ordinal: Int
      @scala.annotation.static() <static> val C: (): A.this.B =
        B.this.$outer.B.C
      final def A$B$$$outer(): A = B.this.$outer
    }
    val B$lzy1: A.this.B$ = new A.this.B$(this)
    final lazy module def B(): A.this.B$ = this.B$lzy1
    final module class B$($outer: A) extends Object, java.io.Serializable,
      scala.deriving.Mirror.Sum
     {
      super()
      def values(): A.this.B[] =
        this.$values.values().toArray(
          scala.reflect.ClassTag.apply(classOf[A.this.B])
        ).asInstanceOf[A.this.B[]]
      private val $values: scala.runtime.EnumValues =
        new scala.runtime.EnumValues()
      def valueOf($name: String): A.this.B =
        try this.$values.fromName().apply($name).asInstanceOf[A.this.B] catch
          {
            case ex$ @ _:java.util.NoSuchElementException =>
              throw
                new IllegalArgumentException("key not found: ".concat($name))
          }
      private def $new(_$ordinal: Int, $name: String): A.this.B =
        {
          final class $anon($outer: A.this.B$) extends A.this.B,
            scala.runtime.EnumValue
          , scala.deriving.Mirror.Singleton {
            super(this.$outer.A$B$$$$outer(), $name, _$ordinal)
            override def canEqual(that: Object): Boolean =
              super[EnumValue].canEqual(that)
            override def productArity(): Int = super[EnumValue].productArity()
            override def productPrefix(): String =
              super[EnumValue].productPrefix()
            override def productElement(n: Int): Object =
              super[EnumValue].productElement(n)
            override def productElementName(n: Int): String =
              super[EnumValue].productElementName(n)
            def fromProduct(p: Product): scala.deriving.Mirror.Singleton =
              super[Singleton].fromProduct(p)
            def $ordinal(): Int = _$ordinal
            override def toString(): String = $name
            this.$outer.$values.register(this)
            private val $outer: A.this.B$
            final def A$B$_$$anon$$$outer(): A.this.B$ = $outer
            def fromProduct(p: Product): Object = this.fromProduct(p)
          }
          new
            A.this.B with scala.runtime.EnumValue with
              scala.deriving.Mirror.Singleton
             {...}
          (this):A.this.B
        }
      private val C: A.this.B = this.$new(0, "C")
      case def C(): A.this.B = this.C
      def ordinal(x$0: A.this.B): Int = x$0.ordinal()
      private val $outer: A
      final def A$B$$$$outer(): A = A.B.$outer
      def ordinal(x: Object): Int = this.ordinal(x.asInstanceOf[A.this.B])
    }
  }
} of class class dotty.tools.dotc.ast.Trees$PackageDef # 2379
*** error while checking test.scala after phase capturedVars ***
exception occurred while compiling test.scala
java.lang.AssertionError: assertion failed: non member selection of getter C in object B from A.this.B.type in B.this.$outer.B.C while compiling test.scala
Exception in thread "main" java.lang.AssertionError: assertion failed: non member selection of getter C in object B from A.this.B.type in B.this.$outer.B.C
	at dotty.DottyPredef$.assertFail(DottyPredef.scala:17)
	at dotty.tools.dotc.transform.FirstTransform.checkPostCondition(FirstTransform.scala:69)
	at dotty.tools.dotc.transform.TreeChecker.dotty$tools$dotc$transform$TreeChecker$Checker$$_$typedUnadapted$$anonfun$1(TreeChecker.scala:346)
	at dotty.runtime.function.JProcedure1.apply(JProcedure1.java:15)
	at dotty.runtime.function.JProcedure1.apply(JProcedure1.java:10)
	at scala.collection.immutable.List.foreach(List.scala:333)
	at dotty.tools.dotc.transform.TreeChecker$Checker.typedUnadapted(TreeChecker.scala:346)
	at dotty.tools.dotc.typer.Typer.op$1(Typer.scala:2544)
	at dotty.tools.dotc.typer.Typer.typed(Typer.scala:2553)
	at dotty.tools.dotc.typer.Typer.typed(Typer.scala:2556)
	at dotty.tools.dotc.transform.TreeChecker$Checker.typed(TreeChecker.scala:313)
	at dotty.tools.dotc.typer.Typer.typedExpr(Typer.scala:2670)
	at dotty.tools.dotc.typer.Typer.typedValDef(Typer.scala:1895)
	at dotty.tools.dotc.typer.Typer.typedNamed$1(Typer.scala:2392)
	at dotty.tools.dotc.typer.Typer.typedUnadapted(Typer.scala:2477)
	at dotty.tools.dotc.typer.ReTyper.typedUnadapted(ReTyper.scala:124)
	at dotty.tools.dotc.transform.TreeChecker$Checker.typedUnadapted(TreeChecker.scala:329)
	at dotty.tools.dotc.typer.Typer.op$1(Typer.scala:2544)
	at dotty.tools.dotc.typer.Typer.typed(Typer.scala:2553)
	at dotty.tools.dotc.typer.Typer.typed(Typer.scala:2556)
	at dotty.tools.dotc.transform.TreeChecker$Checker.typed(TreeChecker.scala:313)
	at dotty.tools.dotc.typer.Typer.traverse$1(Typer.scala:2578)
	at dotty.tools.dotc.typer.Typer.typedStats(Typer.scala:2626)
	at dotty.tools.dotc.transform.TreeChecker$Checker.typedStats(TreeChecker.scala:512)
	at dotty.tools.dotc.typer.Typer.typedClassDef(Typer.scala:2076)
	at dotty.tools.dotc.transform.TreeChecker$Checker.typedClassDef(TreeChecker.scala:444)
	at dotty.tools.dotc.typer.Typer.typedTypeOrClassDef$2(Typer.scala:2406)
	at dotty.tools.dotc.typer.Typer.typedNamed$1(Typer.scala:2410)
	at dotty.tools.dotc.typer.Typer.typedUnadapted(Typer.scala:2477)
	at dotty.tools.dotc.typer.ReTyper.typedUnadapted(ReTyper.scala:124)
	at dotty.tools.dotc.transform.TreeChecker$Checker.typedUnadapted(TreeChecker.scala:329)
	at dotty.tools.dotc.typer.Typer.op$1(Typer.scala:2544)
	at dotty.tools.dotc.typer.Typer.typed(Typer.scala:2553)
	at dotty.tools.dotc.typer.Typer.typed(Typer.scala:2556)
	at dotty.tools.dotc.transform.TreeChecker$Checker.typed(TreeChecker.scala:313)
	at dotty.tools.dotc.typer.Typer.traverse$1(Typer.scala:2578)
	at dotty.tools.dotc.typer.Typer.typedStats(Typer.scala:2626)
	at dotty.tools.dotc.transform.TreeChecker$Checker.typedStats(TreeChecker.scala:512)
	at dotty.tools.dotc.typer.Typer.typedClassDef(Typer.scala:2076)
	at dotty.tools.dotc.transform.TreeChecker$Checker.typedClassDef(TreeChecker.scala:444)
	at dotty.tools.dotc.typer.Typer.typedTypeOrClassDef$2(Typer.scala:2406)
	at dotty.tools.dotc.typer.Typer.typedNamed$1(Typer.scala:2410)
	at dotty.tools.dotc.typer.Typer.typedUnadapted(Typer.scala:2477)
	at dotty.tools.dotc.typer.ReTyper.typedUnadapted(ReTyper.scala:124)
	at dotty.tools.dotc.transform.TreeChecker$Checker.typedUnadapted(TreeChecker.scala:329)
	at dotty.tools.dotc.typer.Typer.op$1(Typer.scala:2544)
	at dotty.tools.dotc.typer.Typer.typed(Typer.scala:2553)
	at dotty.tools.dotc.typer.Typer.typed(Typer.scala:2556)
	at dotty.tools.dotc.transform.TreeChecker$Checker.typed(TreeChecker.scala:313)
	at dotty.tools.dotc.typer.Typer.traverse$1(Typer.scala:2578)
	at dotty.tools.dotc.typer.Typer.typedStats(Typer.scala:2626)
	at dotty.tools.dotc.transform.TreeChecker$Checker.typedStats(TreeChecker.scala:512)
	at dotty.tools.dotc.typer.Typer.typedPackageDef(Typer.scala:2202)
	at dotty.tools.dotc.typer.Typer.typedUnnamed$1(Typer.scala:2450)
	at dotty.tools.dotc.typer.Typer.typedUnadapted(Typer.scala:2478)
	at dotty.tools.dotc.typer.ReTyper.typedUnadapted(ReTyper.scala:124)
	at dotty.tools.dotc.transform.TreeChecker$Checker.typedUnadapted(TreeChecker.scala:329)
	at dotty.tools.dotc.typer.Typer.op$1(Typer.scala:2544)
	at dotty.tools.dotc.typer.Typer.typed(Typer.scala:2553)
	at dotty.tools.dotc.typer.Typer.typed(Typer.scala:2556)
	at dotty.tools.dotc.transform.TreeChecker$Checker.typed(TreeChecker.scala:313)
	at dotty.tools.dotc.typer.Typer.typedExpr(Typer.scala:2670)
	at dotty.tools.dotc.transform.TreeChecker.check(TreeChecker.scala:148)
	at dotty.tools.dotc.transform.TreeChecker.run(TreeChecker.scala:121)
	at dotty.tools.dotc.core.Phases$Phase.runOn$$anonfun$1(Phases.scala:318)
	at scala.collection.immutable.List.map(List.scala:246)
	at dotty.tools.dotc.core.Phases$Phase.runOn(Phases.scala:319)
	at dotty.tools.dotc.Run.runPhases$4$$anonfun$4(Run.scala:180)
	at dotty.runtime.function.JProcedure1.apply(JProcedure1.java:15)
	at dotty.runtime.function.JProcedure1.apply(JProcedure1.java:10)
	at scala.collection.ArrayOps$.foreach$extension(ArrayOps.scala:1323)
	at dotty.tools.dotc.Run.runPhases$5(Run.scala:190)
	at dotty.tools.dotc.Run.compileUnits$$anonfun$1(Run.scala:198)
	at dotty.runtime.function.JFunction0$mcV$sp.apply(JFunction0$mcV$sp.java:12)
	at dotty.tools.dotc.util.Stats$.maybeMonitored(Stats.scala:64)
	at dotty.tools.dotc.Run.compileUnits(Run.scala:205)
	at dotty.tools.dotc.Run.compileSources(Run.scala:142)
	at dotty.tools.dotc.Run.compile(Run.scala:124)
	at dotty.tools.dotc.Driver.doCompile(Driver.scala:38)
	at dotty.tools.dotc.Driver.process(Driver.scala:194)
	at dotty.tools.dotc.Driver.process(Driver.scala:163)
	at dotty.tools.dotc.Driver.process(Driver.scala:175)
	at dotty.tools.dotc.Driver.main(Driver.scala:202)
	at dotty.tools.dotc.Main.main(Main.scala)

@griggt
Copy link
Contributor

griggt commented Sep 25, 2020

Fixed by #9678? Looks like a duplicate of #9579.

In any case, it no longer crashes in 0.28.0-bin-20200923-af1b4a0-NIGHTLY:

[info] Compiling 1 Scala source to /src/dotty-issues/i9332/target/scala-0.28/classes ...
[error] -- Error: /src/dotty-issues/i9332/src/main/scala/Main.scala:2:7 ----------------
[error] 2 |  enum B extends java.lang.Enum[B] {
[error]   |  ^
[error]   |  An enum extending java.lang.Enum must be declared in a static scope
[error] 3 |    case C
[error] 4 |  }
[error] one error found

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

Successfully merging a pull request may close this issue.

3 participants