Skip to content

Compiler crash when annotated types contain certain trees #17939

Closed
@mbovel

Description

@mbovel

Compiler version

348729e

Minimized code

// tests/pos/tasty-no-address.scala
import scala.annotation.Annotation
class myRefined[T](f: T => Boolean) extends Annotation

class Box[T](val x: T)
class Box2(val x: Int)

class A(a: String @myRefined((x: Int) => Box(3).x == 3)) // crash
class A2(a2: String @myRefined((x: Int) => Box2(3).x == 3)) // works

Output (click arrow to expand)

> scalac tests/pos/tasty-no-address.scala
[info] running (fork) dotty.tools.dotc.Main -classpath /Users/mbovel/Library/Caches/Coursier/v1/https/repo1.maven.org/maven2/org/scala-lang/scala-library/2.13.10/scala-library-2.13.10.jar:/Users/mbovel/dotty/library/../out/bootstrap/scala3-library-bootstrapped/scala-3.3.2-RC1-bin-SNAPSHOT-nonbootstrapped/scala3-library_3-3.3.2-RC1-bin-SNAPSHOT.jar tests/pos/tasty-no-address.scala
error when pickling tree def $anonfun(x: Int): Boolean = new Box[Int](3).x.==(3)
error when pickling tree {
  def $anonfun(x: Int): Boolean = new Box[Int](3).x.==(3)
  closure($anonfun)
}
error when pickling tree new myRefined[Int](
  {
    def $anonfun(x: Int): Boolean = new Box[Int](3).x.==(3)
    closure($anonfun)
  }
)
error when pickling tree String @myRefined[Int](
  {
    def $anonfun(x: Int): Boolean = new Box[Int](3).x.==(3)
    closure($anonfun)
  }
)
error when pickling tree def <init>(
  a:
    String @myRefined[Int](
      {
        def $anonfun(x: Int): Boolean = new Box[Int](3).x.==(3)
        closure($anonfun)
      }
    )
): Unit
error when pickling tree (
  a:
    String @myRefined[Int](
      {
        def $anonfun(x: Int): Boolean = new Box[Int](3).x.==(3)
        closure($anonfun)
      }
    )
) extends Object() {
  private[this] val a:
    
      String @myRefined[Int](
        {
          def $anonfun(x: Int): Boolean = new Box[Int](3).x.==(3)
          closure($anonfun)
        }
      )
    
}
error when pickling tree @SourceFile("tests/pos/tasty-no-address.scala") class A(
  a:
    String @myRefined[Int](
      {
        def $anonfun(x: Int): Boolean = new Box[Int](3).x.==(3)
        closure($anonfun)
      }
    )
) extends Object() {
  private[this] val a:
    
      String @myRefined[Int](
        {
          def $anonfun(x: Int): Boolean = new Box[Int](3).x.==(3)
          closure($anonfun)
        }
      )
    
}
error when pickling tree package <empty> {
  import scala.annotation.Annotation
  @SourceFile("tests/pos/tasty-no-address.scala") class A(
    a:
      String @myRefined[Int](
        {
          def $anonfun(x: Int): Boolean = new Box[Int](3).x.==(3)
          closure($anonfun)
        }
      )
  ) extends Object() {
    private[this] val a:
      
        String @myRefined[Int](
          {
            def $anonfun(x: Int): Boolean = new Box[Int](3).x.==(3)
            closure($anonfun)
          }
        )
      
  }
}

  unhandled exception while running pickler on tests/pos/tasty-no-address.scala

  An unhandled exception was thrown in the compiler.
  Please file a crash report here:
  https://github.com/lampepfl/dotty/issues/new/choose

     while compiling: <no file>
        during phase: <no phase>
                mode: Mode(ImplicitsEnabled)
     library version: version 2.13.10
    compiler version: version 3.3.2-RC1-bin-SNAPSHOT-nonbootstrapped-git-348729e
            settings: -classpath /Users/mbovel/Library/Caches/Coursier/v1/https/repo1.maven.org/maven2/org/scala-lang/scala-library/2.13.10/scala-library-2.13.10.jar:/Users/mbovel/dotty/library/../out/bootstrap/scala3-library-bootstrapped/scala-3.3.2-RC1-bin-SNAPSHOT-nonbootstrapped/scala3-library_3-3.3.2-RC1-bin-SNAPSHOT.jar

                tree: EmptyTree
       tree position: :<unknown>
           tree type: <notype>
              symbol: val <none>
           call site: package <root> in module class <root>

  == Source file context for tree position ==


Exception in thread "main" java.lang.AssertionError: assertion failed: method $anonfun
        at scala.runtime.Scala3RunTime$.assertFailed(Scala3RunTime.scala:8)
        at dotty.tools.dotc.core.tasty.TreePickler.pickleDef(TreePickler.scala:328)
        at dotty.tools.dotc.core.tasty.TreePickler.pickleTree(TreePickler.scala:581)
        at dotty.tools.dotc.core.tasty.TreePickler.pickleTree$$anonfun$5(TreePickler.scala:490)
        at scala.runtime.function.JProcedure1.apply(JProcedure1.java:15)
        at scala.runtime.function.JProcedure1.apply(JProcedure1.java:10)
        at scala.collection.immutable.List.foreach(List.scala:333)
        at dotty.tools.dotc.core.tasty.TreePickler.pickleTree(TreePickler.scala:490)
        at dotty.tools.dotc.core.tasty.TreePickler.pickleTree$$anonfun$2(TreePickler.scala:448)
        at scala.runtime.function.JProcedure1.apply(JProcedure1.java:15)
        at scala.runtime.function.JProcedure1.apply(JProcedure1.java:10)
        at scala.collection.immutable.List.foreach(List.scala:333)
        at dotty.tools.dotc.core.tasty.TreePickler.pickleTree(TreePickler.scala:448)
        at dotty.tools.dotc.core.tasty.TreePickler.pickleTree(TreePickler.scala:654)
        at dotty.tools.dotc.core.tasty.TreePickler.pickleTpt(TreePickler.scala:319)
        at dotty.tools.dotc.core.tasty.TreePickler.pickleDef(TreePickler.scala:338)
        at dotty.tools.dotc.core.tasty.TreePickler.pickleParam(TreePickler.scala:361)
        at dotty.tools.dotc.core.tasty.TreePickler.pickleParams$$anonfun$2(TreePickler.scala:368)
        at scala.runtime.function.JProcedure1.apply(JProcedure1.java:15)
        at scala.runtime.function.JProcedure1.apply(JProcedure1.java:10)
        at scala.collection.immutable.List.foreach(List.scala:333)
        at dotty.tools.dotc.core.tasty.TreePickler.pickleParams(TreePickler.scala:368)
        at dotty.tools.dotc.core.tasty.TreePickler.pickleParamss$1(TreePickler.scala:574)
        at dotty.tools.dotc.core.tasty.TreePickler.pickleTree$$anonfun$15(TreePickler.scala:581)
        at dotty.tools.dotc.core.tasty.TreePickler.pickleTree$$anonfun$adapted$2(TreePickler.scala:581)
        at scala.Function0.apply$mcV$sp(Function0.scala:42)
        at dotty.tools.dotc.core.tasty.TreePickler.pickleDef(TreePickler.scala:335)
        at dotty.tools.dotc.core.tasty.TreePickler.pickleTree(TreePickler.scala:581)
        at dotty.tools.dotc.core.tasty.TreePickler.pickleStats$$anonfun$2(TreePickler.scala:373)
        at scala.runtime.function.JProcedure1.apply(JProcedure1.java:15)
        at scala.runtime.function.JProcedure1.apply(JProcedure1.java:10)
        at scala.collection.immutable.List.foreach(List.scala:333)
        at dotty.tools.dotc.core.tasty.TreePickler.pickleStats(TreePickler.scala:373)
        at dotty.tools.dotc.core.tasty.TreePickler.pickleTree(TreePickler.scala:607)
        at dotty.tools.dotc.core.tasty.TreePickler.pickleDef(TreePickler.scala:337)
        at dotty.tools.dotc.core.tasty.TreePickler.pickleTree(TreePickler.scala:583)
        at dotty.tools.dotc.core.tasty.TreePickler.pickleStats$$anonfun$2(TreePickler.scala:373)
        at scala.runtime.function.JProcedure1.apply(JProcedure1.java:15)
        at scala.runtime.function.JProcedure1.apply(JProcedure1.java:10)
        at scala.collection.immutable.List.foreach(List.scala:333)
        at dotty.tools.dotc.core.tasty.TreePickler.pickleStats(TreePickler.scala:373)
        at dotty.tools.dotc.core.tasty.TreePickler.pickleTree(TreePickler.scala:623)
        at dotty.tools.dotc.core.tasty.TreePickler.pickle$$anonfun$1(TreePickler.scala:817)
        at scala.runtime.function.JProcedure1.apply(JProcedure1.java:15)
        at scala.runtime.function.JProcedure1.apply(JProcedure1.java:10)
        at scala.collection.immutable.List.foreach(List.scala:333)
        at dotty.tools.dotc.core.tasty.TreePickler.pickle(TreePickler.scala:824)
        at dotty.tools.dotc.transform.Pickler.run$$anonfun$1$$anonfun$1(Pickler.scala:90)
        at scala.runtime.function.JProcedure1.apply(JProcedure1.java:15)
        at scala.runtime.function.JProcedure1.apply(JProcedure1.java:10)
        at scala.collection.immutable.List.foreach(List.scala:333)
        at dotty.tools.dotc.transform.Pickler.run$$anonfun$1(Pickler.scala:142)
        at scala.runtime.function.JProcedure1.apply(JProcedure1.java:15)
        at scala.runtime.function.JProcedure1.apply(JProcedure1.java:10)
        at scala.collection.immutable.List.foreach(List.scala:333)
        at dotty.tools.dotc.transform.Pickler.run(Pickler.scala:142)
        at dotty.tools.dotc.core.Phases$Phase.runOn$$anonfun$1(Phases.scala:327)
        at scala.collection.immutable.List.map(List.scala:246)
        at dotty.tools.dotc.core.Phases$Phase.runOn(Phases.scala:331)
        at dotty.tools.dotc.transform.Pickler.runOn(Pickler.scala:150)
        at dotty.tools.dotc.Run.runPhases$1$$anonfun$1(Run.scala:246)
        at scala.runtime.function.JProcedure1.apply(JProcedure1.java:15)
        at scala.runtime.function.JProcedure1.apply(JProcedure1.java:10)
        at scala.collection.ArrayOps$.foreach$extension(ArrayOps.scala:1321)
        at dotty.tools.dotc.Run.runPhases$1(Run.scala:262)
        at dotty.tools.dotc.Run.compileUnits$$anonfun$1(Run.scala:270)
        at dotty.tools.dotc.Run.compileUnits$$anonfun$adapted$1(Run.scala:279)
        at dotty.tools.dotc.util.Stats$.maybeMonitored(Stats.scala:67)
        at dotty.tools.dotc.Run.compileUnits(Run.scala:279)
        at dotty.tools.dotc.Run.compileSources(Run.scala:194)
        at dotty.tools.dotc.Run.compile(Run.scala:179)
        at dotty.tools.dotc.Driver.doCompile(Driver.scala:37)
        at dotty.tools.dotc.Driver.process(Driver.scala:197)
        at dotty.tools.dotc.Driver.process(Driver.scala:165)
        at dotty.tools.dotc.Driver.process(Driver.scala:177)
        at dotty.tools.dotc.Driver.main(Driver.scala:207)
        at dotty.tools.dotc.Main.main(Main.scala)

Trees with IDs after posttyper

> scalac -Xprint:posttyper -Ximport-suggestion-timeout 0 -Yshow-tree-ids tests/pos/tasty-no-address.scala
[info] running (fork) dotty.tools.dotc.Main -classpath /Users/mbovel/Library/Caches/Coursier/v1/https/repo1.maven.org/maven2/org/scala-lang/scala-library/2.13.10/scala-library-2.13.10.jar:/Users/mbovel/dotty/library/../out/bootstrap/scala3-library-bootstrapped/scala-3.3.2-RC1-bin-SNAPSHOT-nonbootstrapped/scala3-library_3-3.3.2-RC1-bin-SNAPSHOT.jar -Xprint:posttyper -Ximport-suggestion-timeout 0 -Yshow-tree-ids tests/pos/tasty-no-address.scala
[[syntax trees at end of                 posttyper]] // tests/pos/tasty-no-address.scala
package <empty>#195 {
  import scala#31.annotation#33.Annotation#38
  @SourceFile("tests/pos/tasty-no-address.scala"#1088) class myRefined[
    T >: Nothing#695 <: Any#697#699#702](f: T => Boolean#826#828) extends
    annotation.Annotation#56#848#849()#850 {
    T#700#852
    private[this] val f: T => Boolean#853#855
  }#858
  @SourceFile("tests/pos/tasty-no-address.scala"#1105) class Box[
    T >: Nothing#859 <: Any#861#863#866](x: T#64#231) extends Object#870#875#876
    ()#877 {
    T#864#879
    val x: T#880#882
  }#886
  @SourceFile("tests/pos/tasty-no-address.scala"#1110) class Box2(x: Int#77#248)
     extends Object#890#895#896()#897 {
    val x: Int#898#900
  }#904
  @SourceFile("tests/pos/tasty-no-address.scala"#1115) class A(
    a:
      String#90 @myRefined[Int#909](
        {
          def $anonfun(x: Int#100#105): Boolean#911 =
            new Box#953#954#955[Int#956]#1172(3#958)#1174.x#1176.==#1178(3#965)#
              1179
          #1181
          closure($anonfun#915)#916
        }#1182
      )#1187
    #1189
  ) extends Object#980#985#986()#987 {
    private[this] val a:
      
        String @myRefined[Int#909](
          {
            def $anonfun(x: Int#100#105): Boolean#911 =
              new Box#953#954#955[Int#956]#1192(3#958)#1194.x#1196.==#1198(3#965
                )#1199
            #1201
            closure($anonfun#915)#916
          }#1202
        )
      #1206
    #1208
  }#1212
  @SourceFile("tests/pos/tasty-no-address.scala"#1213) class A2(
    a2:
      String#143 @myRefined[Int#999](
        {
          def $anonfun(x: Int#153#158): Boolean#1001 =
            new Box2#1014#1018#1019(3#1020)#1022.x#1024.==#1028(3#1027)#1029#
            1031
          closure($anonfun#1005)#1006
        }#1032
      )#1222
    #1224
  ) extends Object#1042#1047#1048()#1049 {
    private[this] val a2:
      
        String @myRefined[Int#999](
          {
            def $anonfun(x: Int#153#158): Boolean#1001 =
              new Box2#1014#1018#1019(3#1020)#1022.x#1024.==#1028(3#1027)#1029#
              1031
            closure($anonfun#1005)#1006
          }#1032
        )
      #1230
    #1232
  }#1236
}#1237
...

Look at the blocks in the annotations in A: one has ID #1182 and one has the ID #1202, but the inner def $anonfun and associated symbol are the same, hence the problem. The types String @myRefined are also different.

In A2 however, both blocks have ID #1032 and both String @myRefined have id #1232.

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions