scala / scala3

The Scala 3 compiler, also known as Dotty.
https://dotty.epfl.ch
Apache License 2.0
5.79k stars 1.04k forks source link

Compiler crash when annotated types contain certain trees #17939

Open mbovel opened 1 year ago

mbovel commented 1 year ago

Compiler version

348729e88e7

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 ( 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 { 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: during 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: : tree type: symbol: val call site: package in module class == 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

```scala > 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 #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`.
mbovel commented 1 year ago

Output when adding -Ydebug-tree-with-id 1029 (where 1029 is the ID of the block in the annotation):

``` run -Xprint:posttyper -Ystop-after:posttyper -Ximport-suggestion-timeout 0 -Yshow-tree-ids -Ydebug-tree-with-id 1029 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 -Ystop-after:posttyper -Ximport-suggestion-timeout 0 -Yshow-tree-ids -Ydebug-tree-with-id 1029 tests/pos/tasty-no-address.scala Debug tree (id=1029) creation Block(List(DefDef($anonfun,List(List(ValDef(x,Ident(Int),EmptyTree))),TypeTree[TypeRef(TermRef(ThisType(TypeRef(NoPrefix,module class )),object scala),class Boolean)],Apply(Select(Select(Apply(TypeApply(Select(New(Ident(Box)),),List(TypeTree[TypeVar(TypeParamRef(T) -> TypeRef(ThisType(TypeRef(NoPrefix,module class scala)),class Int))])),List(Literal(Constant(3)))),x),==),List(Literal(Constant(3)))))),Closure(List(),Ident($anonfun),EmptyTree)) java.lang.Exception: Stack trace at java.base/java.lang.Thread.dumpStack(Thread.java:1380) at dotty.tools.dotc.ast.Positioned.allocateId(Positioned.scala:38) at dotty.tools.dotc.ast.Positioned.(Positioned.scala:40) at dotty.tools.dotc.ast.Trees$Tree.(Trees.scala:51) at dotty.tools.dotc.ast.Trees$Block.(Trees.scala:565) at dotty.tools.dotc.ast.untpd$.Block(untpd.scala:386) at dotty.tools.dotc.ast.Trees$Instance$TreeCopier.Block(Trees.scala:1290) at dotty.tools.dotc.ast.tpd$TypedTreeCopier.Block(tpd.scala:678) at dotty.tools.dotc.ast.tpd$TreeMapWithPreciseStatContexts.transformBlock$$anonfun$1$$anonfun$1(tpd.scala:1249) at dotty.tools.dotc.ast.tpd$TreeMapWithPreciseStatContexts.loop$2(tpd.scala:1231) at dotty.tools.dotc.ast.tpd$TreeMapWithPreciseStatContexts.transformStats(tpd.scala:1244) at dotty.tools.dotc.transform.PostTyper$PostTyperTransformer.transformStats(PostTyper.scala:499) at dotty.tools.dotc.ast.tpd$TreeMapWithPreciseStatContexts.transformBlock(tpd.scala:1249) at dotty.tools.dotc.ast.Trees$Instance$TreeMap.transform(Trees.scala:1518) at dotty.tools.dotc.transform.MacroTransform$Transformer.transform(MacroTransform.scala:49) at dotty.tools.dotc.transform.PostTyper$PostTyperTransformer.transform(PostTyper.scala:490) at dotty.tools.dotc.ast.Trees$Instance$TreeMap.transform$$anonfun$1(Trees.scala:1605) at scala.collection.immutable.List.mapConserve(List.scala:472) at dotty.tools.dotc.ast.Trees$Instance$TreeMap.transform(Trees.scala:1605) at dotty.tools.dotc.transform.PostTyper$PostTyperTransformer.app1$1(PostTyper.scala:323) at dotty.tools.dotc.transform.PostTyper$PostTyperTransformer.transform$$anonfun$1(PostTyper.scala:335) at dotty.tools.dotc.transform.PostTyper$PostTyperTransformer.withNoCheckNews(PostTyper.scala:105) at dotty.tools.dotc.transform.PostTyper$PostTyperTransformer.transform(PostTyper.scala:335) at dotty.tools.dotc.transform.PostTyper$PostTyperTransformer.transformAnnot(PostTyper.scala:138) at dotty.tools.dotc.transform.PostTyper$PostTyperTransformer.transformAnnot(PostTyper.scala:143) at dotty.tools.dotc.transform.PostTyper$PostTyperTransformer.transform(PostTyper.scala:462) at dotty.tools.dotc.ast.Trees$Instance$TreeMap.transform(Trees.scala:1566) at dotty.tools.dotc.transform.MacroTransform$Transformer.transform(MacroTransform.scala:40) at dotty.tools.dotc.transform.PostTyper$PostTyperTransformer.transform(PostTyper.scala:381) at dotty.tools.dotc.ast.tpd$TreeMapWithPreciseStatContexts.loop$2(tpd.scala:1244) at dotty.tools.dotc.ast.tpd$TreeMapWithPreciseStatContexts.transformStats(tpd.scala:1244) at dotty.tools.dotc.transform.PostTyper$PostTyperTransformer.transformStats(PostTyper.scala:499) at dotty.tools.dotc.ast.tpd$TreeMapWithPreciseStatContexts.transformStats(tpd.scala:1246) at dotty.tools.dotc.transform.MacroTransform$Transformer.transform(MacroTransform.scala:47) at dotty.tools.dotc.transform.PostTyper$PostTyperTransformer.transform$$anonfun$4$$anonfun$1(PostTyper.scala:372) at dotty.tools.dotc.transform.SuperAccessors.wrapTemplate(SuperAccessors.scala:211) at dotty.tools.dotc.transform.PostTyper$PostTyperTransformer.transform$$anonfun$4(PostTyper.scala:372) at dotty.tools.dotc.transform.PostTyper$PostTyperTransformer.withNoCheckNews(PostTyper.scala:105) at dotty.tools.dotc.transform.PostTyper$PostTyperTransformer.transform(PostTyper.scala:374) at dotty.tools.dotc.ast.Trees$Instance$TreeMap.transform(Trees.scala:1572) at dotty.tools.dotc.transform.MacroTransform$Transformer.transform(MacroTransform.scala:40) at dotty.tools.dotc.transform.PostTyper$PostTyperTransformer.transform(PostTyper.scala:426) at dotty.tools.dotc.ast.tpd$TreeMapWithPreciseStatContexts.loop$2(tpd.scala:1244) at dotty.tools.dotc.ast.tpd$TreeMapWithPreciseStatContexts.transformStats(tpd.scala:1244) at dotty.tools.dotc.transform.PostTyper$PostTyperTransformer.transformStats(PostTyper.scala:499) at dotty.tools.dotc.ast.tpd$TreeMapWithPreciseStatContexts.transformStats(tpd.scala:1246) at dotty.tools.dotc.ast.Trees$Instance$TreeMap.transform(Trees.scala:1580) at dotty.tools.dotc.transform.MacroTransform$Transformer.transform(MacroTransform.scala:40) at dotty.tools.dotc.transform.PostTyper$PostTyperTransformer.transform(PostTyper.scala:490) at dotty.tools.dotc.transform.MacroTransform.run(MacroTransform.scala:18) 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.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) ```
mbovel commented 1 year ago

Could the culprit be the following?

https://github.com/lampepfl/dotty/blob/348729e88e780d8a5ee9860a2228631026552a4e/compiler/src/dotty/tools/dotc/transform/PostTyper.scala#L134-L140

Should we map symbols in this case?

mbovel commented 1 year ago

Just to see if it changes something, I tried to always map symbols to fresh ones in transformAnnot with:

diff --git a/compiler/src/dotty/tools/dotc/transform/PostTyper.scala b/compiler/src/dotty/tools/dotc/transform/PostTyper.scala
index ac3dc15092a..43409e5125b 100644
--- a/compiler/src/dotty/tools/dotc/transform/PostTyper.scala
+++ b/compiler/src/dotty/tools/dotc/transform/PostTyper.scala
@@ -19,6 +19,7 @@ import config.Feature
 import util.SrcPos
 import reporting._
 import NameKinds.WildcardParamName
+import dotty.tools.dotc.ast.TreeTypeMap

 object PostTyper {
   val name: String = "posttyper"
@@ -84,6 +85,12 @@ class PostTyper extends MacroTransform with IdentityDenotTransformer { thisPhase
   val synthMbr: SyntheticMembers = new SyntheticMembers(thisPhase)
   val beanProps: BeanProperties = new BeanProperties(thisPhase)

+  def withFreshSymbols(tree: Tree)(using Context): Tree =
+    val tm = new TreeTypeMap():
+      override def withMappedSyms(syms: List[Symbol]): TreeTypeMap =
+        withMappedSyms(syms, mapSymbols(syms, this, mapAlways = true))
+    tm(tree)
+
   private def newPart(tree: Tree): Option[New] = methPart(tree) match {
     case Select(nu: New, _) => Some(nu)
     case _ => None
@@ -135,7 +142,9 @@ class PostTyper extends MacroTransform with IdentityDenotTransformer { thisPhase
       val saved = inJavaAnnot
       inJavaAnnot = annot.symbol.is(JavaDefined)
       if (inJavaAnnot) checkValidJavaAnnotation(annot)
-      try transform(annot)
+      try
+        val res = transform(annot)
+        if res != annot then withFreshSymbols(res) else annot
       finally inJavaAnnot = saved
     }

With this change, the file compiles, but the pickling test fails:

$ diff before-pickling.txt after-pickling.txt                              
50,52c50,51
<               x: scala.Int@tests/pos/tasty-no-address.scala<149..152>@tests/pos/tasty-no-address.scala[146..152]@@(x=
<                 tests/pos/tasty-no-address.scala:<146..146>)
<             ): scala.Boolean =
---
>               x: scala.Int@tests/pos/tasty-no-address.scala<149..152>@tests/pos/tasty-no-address.scala<149..152>@@(x=?))
>               : scala.Boolean =
64,66c63,65
<                       tests/pos/tasty-no-address.scala<157..163>
<                   .x:scala.Int>@tests/pos/tasty-no-address.scala<157..165>
<                 .==:((x: scala.Int): scala.Boolean)>@tests/pos/tasty-no-address.scala<157..168>
---
>                       tests/pos/tasty-no-address.scala<157..162>
>                   .x:scala.Int>@tests/pos/tasty-no-address.scala<157..162>
>                 .==:((x: scala.Int): scala.Boolean)>@tests/pos/tasty-no-address.scala<157..162>
69,71c68,70
<             @tests/pos/tasty-no-address.scala[145..154..170]@@($anonfun=tests/pos/tasty-no-address.scala:<154..154>)
<             <closure(<$anonfun:(x: scala.Int): scala.Boolean>@tests/pos/tasty-no-address.scala<170..170>):scala.Int =>
<               scala.Boolean>@tests/pos/tasty-no-address.scala<170..170>
---
>             @tests/pos/tasty-no-address.scala<149..152>@@($anonfun=?)
>             <closure(<$anonfun:(x: scala.Int): scala.Boolean>@tests/pos/tasty-no-address.scala<152..152>):scala.Int =>
>               scala.Boolean>@tests/pos/tasty-no-address.scala<152..152>
73c72
<         :scala.Int => scala.Boolean>@tests/pos/tasty-no-address.scala<145..170>
---
>         :scala.Int => scala.Boolean>@tests/pos/tasty-no-address.scala<149..152>
mbovel commented 1 year ago

The TypeTree of the field private[this] val a is created by:

https://github.com/lampepfl/dotty/blob/348729e88e780d8a5ee9860a2228631026552a4e/compiler/src/dotty/tools/dotc/ast/Desugar.scala#L102-L130

Maybe we should special case the relocate map for AnnotatedType? I tried applying withFreshSymbols to its tree, but that doesn't help.

Sporarum commented 1 year ago

Minimizing a different failing case, I found the following, which I think is related:


import scala.annotation.Annotation
class myRefined(f: ? => Boolean) extends Annotation

def test(axes: Int) = true

trait Tensor:
  def mean(axes: Int): Int @myRefined(_ => test(axes))

class TensorImpl() extends Tensor:
  def mean(axes: Int) = ???

Both the lambda and the subclassing appear to be necessary

Here is the error:

Click to expand

``` [info] running (fork) dotty.tools.dotc.Main -classpath /home/quentin/.cache/coursier/v1/https/repo1.maven.org/maven2/org/scala-lang/scala-library/2.13.10/scala-library-2.13.10.jar:/home/quentin/Projects/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-custom-args/refinements/trying.scala Exception in thread "main" java.lang.AssertionError: assertion failed: unresolved symbols: parameter axes (line 7) #7891 when pickling tests/pos-custom-args/refinements/trying.scala at scala.runtime.Scala3RunTime$.assertFailed(Scala3RunTime.scala:8) at dotty.tools.dotc.core.tasty.TreePickler.pickle(TreePickler.scala:829) 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) unhandled exception while running pickler on tests/pos-custom-args/refinements/trying.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: during phase: mode: Mode(ImplicitsEnabled) library version: version 2.13.10 compiler version: version 3.3.2-RC1-bin-SNAPSHOT-nonbootstrapped-git-482dfeb settings: -classpath /home/quentin/.cache/coursier/v1/https/repo1.maven.org/maven2/org/scala-lang/scala-library/2.13.10/scala-library-2.13.10.jar:/home/quentin/Projects/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: : tree type: symbol: val call site: package in module class == Source file context for tree position == [error] Nonzero exit code returned from runner: 1 [error] (scala3-compiler / Compile / runMain) Nonzero exit code returned from runner: 1 [error] Total time: 2 s, completed Jun 8, 2023, 1:14:37 PM ```