Skip to content

Pickling test crash on widened SkolemTypes inside annotation type arguments #23194

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
noti0na1 opened this issue May 20, 2025 · 2 comments · Fixed by #23236
Closed

Pickling test crash on widened SkolemTypes inside annotation type arguments #23194

noti0na1 opened this issue May 20, 2025 · 2 comments · Fixed by #23236

Comments

@noti0na1
Copy link
Member

Block #22909

Compiler version

nightly
3.7.2-RC1-bin-20250515-c481e91-NIGHTLY-git-c481e91

Minimized code

class R[T] extends annotation.StaticAnnotation

// the type param is necessary here to cause crash
class A[T]:
  val next: A[T] = null
  def f: (A[T] @R[this.type], A[T] @R[this.next.type]) = ???

def test =
  val (a, b) = A[String]().f

Output (click arrow to expand)

Run the test:

scala compile --server=false -S 3.nightly -Ytest-pickler Stest.scala
  exception occurred while compiling List(/dotty/Stest.scala)

  An unhandled exception was thrown in the compiler.
  Please file a crash report here:
  https://github.com/scala/scala3/issues/new/choose
  For non-enriched exceptions, compile with -Xno-enrich-error-messages.


     while compiling: <no file>
        during phase: parser
                mode: Mode(ImplicitsEnabled)
     library version: version 2.13.16
    compiler version: version 3.7.2-RC1-bin-20250515-c481e91-NIGHTLY-git-c481e91
            settings: ...

Exception in thread "main" scala.MatchError: AppliedType(TypeRef(ThisType(TypeRef(ThisType(TypeRef(NoPrefix,module class <root>)),module class <empty>)),A),List(TypeRef(TermRef(TermRef(ThisType(TypeRef(NoPrefix,module class <root>)),object scala),Predef),String))) (of class dotty.tools.dotc.core.Types$CachedAppliedType)
        at dotty.tools.dotc.core.tasty.TreeUnpickler$TreeReader.readPathTree$1(TreeUnpickler.scala:1267)
        at dotty.tools.dotc.core.tasty.TreeUnpickler$TreeReader.readSimpleTree$1(TreeUnpickler.scala:1344)
        at dotty.tools.dotc.core.tasty.TreeUnpickler$TreeReader.readTree(TreeUnpickler.scala:1687)
        at dotty.tools.dotc.core.tasty.TreeUnpickler$TreeReader.readSimpleTree$1(TreeUnpickler.scala:1336)
        at dotty.tools.dotc.core.tasty.TreeUnpickler$TreeReader.readTree(TreeUnpickler.scala:1687)
        at dotty.tools.dotc.core.tasty.TreeUnpickler$TreeReader.readTpt(TreeUnpickler.scala:1712)
        at dotty.tools.dotc.core.tasty.TreeUnpickler$TreeReader.$anonfun$46(TreeUnpickler.scala:1628)
        at dotty.tools.tasty.TastyReader.until(TastyReader.scala:135)
        at dotty.tools.dotc.core.tasty.TreeUnpickler$TreeReader.readLengthTree$1(TreeUnpickler.scala:1628)
        at dotty.tools.dotc.core.tasty.TreeUnpickler$TreeReader.readTree(TreeUnpickler.scala:1687)
        at dotty.tools.dotc.core.tasty.TreeUnpickler$TreeReader.readTpt(TreeUnpickler.scala:1712)
        at dotty.tools.dotc.core.tasty.TreeUnpickler$TreeReader.readSimpleTree$1(TreeUnpickler.scala:1332)
        at dotty.tools.dotc.core.tasty.TreeUnpickler$TreeReader.readTree(TreeUnpickler.scala:1687)
        at dotty.tools.dotc.core.tasty.TreeUnpickler$TreeReader.readLengthTree$1(TreeUnpickler.scala:1551)
        at dotty.tools.dotc.core.tasty.TreeUnpickler$TreeReader.readTree(TreeUnpickler.scala:1687)
        at dotty.tools.dotc.core.tasty.TreeUnpickler$TreeReader.readLengthTree$1(TreeUnpickler.scala:1486)
        at dotty.tools.dotc.core.tasty.TreeUnpickler$TreeReader.readTree(TreeUnpickler.scala:1687)
        at dotty.tools.dotc.core.tasty.TreeUnpickler$TreeReader.readLengthTree$1(TreeUnpickler.scala:1478)
        at dotty.tools.dotc.core.tasty.TreeUnpickler$TreeReader.readTree(TreeUnpickler.scala:1687)
        at dotty.tools.dotc.core.tasty.TreeUnpickler$TreeReader.readLengthType$1(TreeUnpickler.scala:420)
        at dotty.tools.dotc.core.tasty.TreeUnpickler$TreeReader.readType(TreeUnpickler.scala:504)
        at dotty.tools.dotc.core.tasty.TreeUnpickler$TreeReader.$anonfun$6(TreeUnpickler.scala:412)
        at dotty.tools.tasty.TastyReader.until(TastyReader.scala:135)
        at dotty.tools.dotc.core.tasty.TreeUnpickler$TreeReader.readLengthType$1(TreeUnpickler.scala:412)
        at dotty.tools.dotc.core.tasty.TreeUnpickler$TreeReader.readType(TreeUnpickler.scala:504)
        at dotty.tools.dotc.core.tasty.TreeUnpickler$TreeReader.readLengthType$1(TreeUnpickler.scala:420)
        at dotty.tools.dotc.core.tasty.TreeUnpickler$TreeReader.readType(TreeUnpickler.scala:504)
        at dotty.tools.dotc.core.tasty.TreeUnpickler$TreeReader.readTpt(TreeUnpickler.scala:1715)
        at dotty.tools.dotc.core.tasty.TreeUnpickler$TreeReader.readLengthTree$1(TreeUnpickler.scala:1495)
        at dotty.tools.dotc.core.tasty.TreeUnpickler$TreeReader.readTree(TreeUnpickler.scala:1687)
        at dotty.tools.dotc.core.tasty.TreeUnpickler$TreeReader.readLengthTree$1(TreeUnpickler.scala:1536)
        at dotty.tools.dotc.core.tasty.TreeUnpickler$TreeReader.readTree(TreeUnpickler.scala:1687)
        at dotty.tools.dotc.core.tasty.TreeUnpickler.readRhs$1$$anonfun$1$$anonfun$1(TreeUnpickler.scala:901)
        at dotty.tools.dotc.core.tasty.TreeUnpickler$LazyReader.complete(TreeUnpickler.scala:1827)
        at dotty.tools.dotc.ast.Trees$WithLazyFields.force(Trees.scala:1134)
        at dotty.tools.dotc.ast.Trees$WithLazyFields.force$(Trees.scala:1130)
        at dotty.tools.dotc.ast.Trees$ValOrDefDef.force(Trees.scala:417)
        at dotty.tools.dotc.ast.Trees$ValDef.forceFields(Trees.scala:929)
        at dotty.tools.dotc.ast.Trees$ValDef.rhs(Trees.scala:930)
        at dotty.tools.dotc.printing.RefinedPrinter.rhsValDef(RefinedPrinter.scala:1069)
        at dotty.tools.dotc.printing.RefinedPrinter.valDefToText$$anonfun$1$$anonfun$1(RefinedPrinter.scala:1003)
        at dotty.tools.dotc.printing.RefinedPrinter.withEnclosingDef(RefinedPrinter.scala:53)
        at dotty.tools.dotc.printing.RefinedPrinter.valDefToText$$anonfun$1(RefinedPrinter.scala:1003)
        at dotty.tools.dotc.printing.RefinedPrinter.dclTextOr(RefinedPrinter.scala:984)
        at dotty.tools.dotc.printing.RefinedPrinter.valDefToText(RefinedPrinter.scala:1004)
        at dotty.tools.dotc.printing.RefinedPrinter.toTextCore(RefinedPrinter.scala:660)
        at dotty.tools.dotc.printing.RefinedPrinter.toText$$anonfun$2(RefinedPrinter.scala:867)
        at dotty.tools.dotc.printing.MessageLimiter.controlled(MessageLimiter.scala:23)
        at dotty.tools.dotc.printing.PlainPrinter.controlled(PlainPrinter.scala:48)
        at dotty.tools.dotc.printing.RefinedPrinter.toText(RefinedPrinter.scala:938)
        at dotty.tools.dotc.ast.Trees$Tree.toText(Trees.scala:193)
        at dotty.tools.dotc.printing.Printer.toText$$anonfun$1(Printer.scala:188)
        at scala.collection.immutable.List.map(List.scala:247)
        at scala.collection.immutable.List.map(List.scala:79)
        at dotty.tools.dotc.printing.Printer.toText(Printer.scala:188)
        at dotty.tools.dotc.printing.RefinedPrinter.blockText(RefinedPrinter.scala:373)
        at dotty.tools.dotc.printing.RefinedPrinter.blockToText(RefinedPrinter.scala:369)
        at dotty.tools.dotc.printing.RefinedPrinter.toTextCore(RefinedPrinter.scala:547)
        at dotty.tools.dotc.printing.RefinedPrinter.toText$$anonfun$2(RefinedPrinter.scala:867)
        at dotty.tools.dotc.printing.MessageLimiter.controlled(MessageLimiter.scala:23)
        at dotty.tools.dotc.printing.PlainPrinter.controlled(PlainPrinter.scala:48)
        at dotty.tools.dotc.printing.RefinedPrinter.toText(RefinedPrinter.scala:938)
        at dotty.tools.dotc.printing.RefinedPrinter.optText(RefinedPrinter.scala:1192)
        at dotty.tools.dotc.printing.RefinedPrinter.rhsDefDef(RefinedPrinter.scala:1073)
        at dotty.tools.dotc.printing.RefinedPrinter.defDefToText$$anonfun$1$$anonfun$1(RefinedPrinter.scala:1062)
        at dotty.tools.dotc.printing.RefinedPrinter.withEnclosingDef(RefinedPrinter.scala:53)
        at dotty.tools.dotc.printing.RefinedPrinter.defDefToText$$anonfun$1(RefinedPrinter.scala:1063)
        at dotty.tools.dotc.printing.RefinedPrinter.dclTextOr(RefinedPrinter.scala:984)
        at dotty.tools.dotc.printing.RefinedPrinter.defDefToText(RefinedPrinter.scala:1064)
        at dotty.tools.dotc.printing.RefinedPrinter.toTextCore(RefinedPrinter.scala:662)
        at dotty.tools.dotc.printing.RefinedPrinter.toText$$anonfun$2(RefinedPrinter.scala:867)
        at dotty.tools.dotc.printing.MessageLimiter.controlled(MessageLimiter.scala:23)
        at dotty.tools.dotc.printing.PlainPrinter.controlled(PlainPrinter.scala:48)
        at dotty.tools.dotc.printing.RefinedPrinter.toText(RefinedPrinter.scala:938)
        at dotty.tools.dotc.ast.Trees$Tree.toText(Trees.scala:193)
        at dotty.tools.dotc.printing.Printer.toText$$anonfun$1(Printer.scala:188)
        at scala.collection.immutable.List.map(List.scala:251)
        at scala.collection.immutable.List.map(List.scala:79)
        at dotty.tools.dotc.printing.Printer.toText(Printer.scala:188)
        at dotty.tools.dotc.printing.Printer.toTextGlobal$$anonfun$2(Printer.scala:196)
        at dotty.tools.dotc.printing.Printer.atPrec(Printer.scala:44)
        at dotty.tools.dotc.printing.Printer.toTextGlobal(Printer.scala:196)
        at dotty.tools.dotc.printing.RefinedPrinter.toTextTemplate(RefinedPrinter.scala:1119)
        at dotty.tools.dotc.printing.RefinedPrinter.templateText$$anonfun$1(RefinedPrinter.scala:1130)
        at dotty.tools.dotc.printing.RefinedPrinter.withEnclosingDef(RefinedPrinter.scala:53)
        at dotty.tools.dotc.printing.RefinedPrinter.templateText(RefinedPrinter.scala:1130)
        at dotty.tools.dotc.printing.RefinedPrinter.recur$2(RefinedPrinter.scala:672)
        at dotty.tools.dotc.printing.RefinedPrinter.toTextCore(RefinedPrinter.scala:682)
        at dotty.tools.dotc.printing.RefinedPrinter.toText$$anonfun$2(RefinedPrinter.scala:867)
        at dotty.tools.dotc.printing.MessageLimiter.controlled(MessageLimiter.scala:23)
        at dotty.tools.dotc.printing.PlainPrinter.controlled(PlainPrinter.scala:48)
        at dotty.tools.dotc.printing.RefinedPrinter.toText(RefinedPrinter.scala:938)
        at dotty.tools.dotc.ast.Trees$Tree.toText(Trees.scala:193)
        at dotty.tools.dotc.printing.Printer.toText$$anonfun$1(Printer.scala:188)
        at scala.collection.immutable.List.map(List.scala:251)
        at scala.collection.immutable.List.map(List.scala:79)
        at dotty.tools.dotc.printing.Printer.toText(Printer.scala:188)
        at dotty.tools.dotc.printing.Printer.toTextGlobal$$anonfun$2(Printer.scala:196)
        at dotty.tools.dotc.printing.Printer.atPrec(Printer.scala:44)
        at dotty.tools.dotc.printing.Printer.toTextGlobal(Printer.scala:196)
        at dotty.tools.dotc.printing.RefinedPrinter.packageDefText(RefinedPrinter.scala:1142)
        at dotty.tools.dotc.printing.RefinedPrinter.toTextCore(RefinedPrinter.scala:692)
        at dotty.tools.dotc.printing.RefinedPrinter.toText$$anonfun$2(RefinedPrinter.scala:867)
        at dotty.tools.dotc.printing.MessageLimiter.controlled(MessageLimiter.scala:23)
        at dotty.tools.dotc.printing.PlainPrinter.controlled(PlainPrinter.scala:48)
        at dotty.tools.dotc.printing.RefinedPrinter.toText(RefinedPrinter.scala:938)
        at dotty.tools.dotc.ast.Trees$Tree.toText(Trees.scala:193)
        at dotty.tools.dotc.printing.Showable.show(Showable.scala:23)
        at dotty.tools.dotc.printing.Showable.show$(Showable.scala:9)
        at dotty.tools.dotc.ast.Trees$Tree.show(Trees.scala:55)
        at dotty.tools.dotc.core.Decorators$.tryToShow(Decorators.scala:286)
        at dotty.tools.dotc.printing.Formatting$ShownDef$Shown$.toStr(Formatting.scala:43)
        at dotty.tools.dotc.printing.Formatting$ShownDef$.dotty$tools$dotc$printing$Formatting$ShownDef$$$toStr(Formatting.scala:57)
        at dotty.tools.dotc.printing.Formatting$ShownDef$Show$given_Show_Seq$InlinedCtxShow$3.run$$anonfun$2(Formatting.scala:88)
        at scala.collection.immutable.List.map(List.scala:247)
        at scala.collection.immutable.List.map(List.scala:79)
        at dotty.tools.dotc.printing.Formatting$ShownDef$Show$given_Show_Seq$InlinedCtxShow$3.run(Formatting.scala:88)
        at dotty.tools.dotc.printing.Formatting$ShownDef$Shown$.runCtxShow(Formatting.scala:38)
        at dotty.tools.dotc.printing.Formatting$StringFormatter.treatArg(Formatting.scala:174)
        at dotty.tools.dotc.printing.Formatting$StringFormatter.$anonfun$3(Formatting.scala:195)
        at scala.collection.LazyZip2$$anon$1$$anon$2.next(LazyZipOps.scala:42)
        at scala.collection.mutable.Growable.addAll(Growable.scala:62)
        at scala.collection.mutable.Growable.addAll$(Growable.scala:57)
        at scala.collection.mutable.ArrayBuilder.addAll(ArrayBuilder.scala:75)
        at scala.collection.IterableOnceOps.toArray(IterableOnce.scala:1505)
        at scala.collection.IterableOnceOps.toArray$(IterableOnce.scala:1498)
        at scala.collection.AbstractIterable.toArray(Iterable.scala:935)
        at scala.Array$.from(Array.scala:73)
        at scala.collection.immutable.ArraySeq$.from(ArraySeq.scala:282)
        at scala.collection.immutable.ArraySeq$.from(ArraySeq.scala:273)
        at scala.collection.ClassTagIterableFactory$AnyIterableDelegate.from(Factory.scala:671)
        at scala.collection.BuildFromLowPriority2$$anon$11.fromSpecific(BuildFrom.scala:115)
        at scala.collection.BuildFromLowPriority2$$anon$11.fromSpecific(BuildFrom.scala:112)
        at scala.collection.LazyZip2.map(LazyZipOps.scala:37)
        at dotty.tools.dotc.printing.Formatting$StringFormatter.assemble(Formatting.scala:195)
        at dotty.tools.dotc.core.Decorators$.i(Decorators.scala:315)
        at dotty.tools.dotc.transform.Pickler.testUnpickler$$anonfun$2(Pickler.scala:461)
        at scala.runtime.function.JProcedure1.apply(JProcedure1.java:15)
        at scala.runtime.function.JProcedure1.apply(JProcedure1.java:10)
        at scala.collection.IterableOnceOps.foreach(IterableOnce.scala:619)
        at scala.collection.IterableOnceOps.foreach$(IterableOnce.scala:617)
        at scala.collection.AbstractIterable.foreach(Iterable.scala:935)
        at scala.collection.IterableOps$WithFilter.foreach(Iterable.scala:905)
        at dotty.tools.dotc.transform.Pickler.testUnpickler(Pickler.scala:442)
        at dotty.tools.dotc.transform.Pickler.runOn(Pickler.scala:412)
        at dotty.tools.dotc.Run.runPhases$1$$anonfun$1(Run.scala:368)
        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:1324)
        at dotty.tools.dotc.Run.runPhases$1(Run.scala:361)
        at dotty.tools.dotc.Run.compileUnits$$anonfun$1$$anonfun$2(Run.scala:408)
        at dotty.tools.dotc.Run.compileUnits$$anonfun$1$$anonfun$adapted$1(Run.scala:408)
        at scala.Function0.apply$mcV$sp(Function0.scala:42)
        at dotty.tools.dotc.Run.showProgress(Run.scala:470)
        at dotty.tools.dotc.Run.compileUnits$$anonfun$1(Run.scala:408)
        at dotty.tools.dotc.Run.compileUnits$$anonfun$adapted$1(Run.scala:420)
        at dotty.tools.dotc.util.Stats$.maybeMonitored(Stats.scala:69)
        at dotty.tools.dotc.Run.compileUnits(Run.scala:420)
        at dotty.tools.dotc.Run.compileSources(Run.scala:307)
        at dotty.tools.dotc.Run.compile(Run.scala:292)
        at dotty.tools.dotc.Driver.doCompile(Driver.scala:37)
        at dotty.tools.dotc.Driver.process(Driver.scala:201)
        at dotty.tools.dotc.Driver.process(Driver.scala:169)
        at dotty.tools.dotc.Driver.process(Driver.scala:181)
        at dotty.tools.dotc.Driver.main(Driver.scala:211)
        at dotty.tools.dotc.Main.main(Main.scala)
Compilation failed

Analysis

Before pickling, the match case contains SkolemTypes in the singleton types. When we unpickle the class, it tries to read a path from a singleton type, but it gets an applied type, which is widened from the original skolem type, so it crashes.

@noti0na1
Copy link
Member Author

A side note, is it possible to get rid of the patter matching here?

The generated

        val $1$: Tuple2 =
          matchResult1[Tuple2]: 
            {
              case val x1: Tuple2 = new A().f():Tuple2
              if x1 ne null then
                {
                  case val a: A = x1._1().asInstanceOf[A]
                  case val b: A = x1._2().asInstanceOf[A]
                  return[matchResult1] Tuple2.apply(a, b)
                }
               else ()
              throw new MatchError(x1)
            }
        val a: A = $1$._1().asInstanceOf[A]
        val b: A = $1$._2().asInstanceOf[A]

@noti0na1

This comment has been minimized.

tgodzik added a commit to scala/scala3-lts that referenced this issue May 27, 2025
Backport "Fix scala#23194: Try to handle SkolemTypes in SingletonTypeTree during pickling" to 3.3 LTS
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.

1 participant