Skip to content

extension methods crash dotty when compiled with 2.13.4 snapshot #9358

Closed
@bishabosha

Description

@bishabosha

Minimized code

before scala/scala@6acc8ff (2.13.4 snapshot) implicit conversions for AnyVal classes came after the companion object in pickles.
As of that commit, they can come before the companion object, this causes a crash in dotty

compile with scalac on scala/scala@6acc8ff

package example

object MyPredef {
  implicit final class ArrowAssoc2[A](val self: A) extends AnyVal {
    @inline def <&> [B](y: B): (A, B) = (self, y)
  }
}

compile with dotty 0.25.0-RC1:

package example

import MyPredef._

@main def Main: Unit = {
  println(new ArrowAssoc2(1).<&>(""))
}

Output (click arrow to expand)

exception occurred while compiling Main.scala
java.lang.AssertionError: assertion failed: no extension method found for:

  method <&>:[B](y: B): (A, B) with signature Signature(List(1, java.lang.Object),scala.Tuple2) in  <none>

 Candidates:

 

 Candidates (signatures normalized):

  while compiling Main.scala
Exception in thread "main" java.lang.AssertionError: assertion failed: no extension method found for:

  method <&>:[B](y: B): (A, B) with signature Signature(List(1, java.lang.Object),scala.Tuple2) in  <none>

 Candidates:

 

 Candidates (signatures normalized):

 
	at dotty.DottyPredef$.assertFail(DottyPredef.scala:17)
	at dotty.tools.dotc.transform.ExtensionMethods$.extensionMethod(ExtensionMethods.scala:187)
	at dotty.tools.dotc.transform.VCInlineMethods.rewire(VCInlineMethods.scala:69)
	at dotty.tools.dotc.transform.VCInlineMethods.rewireIfNeeded(VCInlineMethods.scala:96)
	at dotty.tools.dotc.transform.VCInlineMethods.transformApply(VCInlineMethods.scala:106)
	at dotty.tools.dotc.transform.MegaPhase.goApply(MegaPhase.scala:611)
	at dotty.tools.dotc.transform.MegaPhase.goApply(MegaPhase.scala:612)
	at dotty.tools.dotc.transform.MegaPhase.goApply(MegaPhase.scala:612)
	at dotty.tools.dotc.transform.MegaPhase.transformUnnamed$1(MegaPhase.scala:272)
	at dotty.tools.dotc.transform.MegaPhase.transformTree(MegaPhase.scala:396)
	at dotty.tools.dotc.transform.MegaPhase.transformTrees$$anonfun$1(MegaPhase.scala:420)
	at scala.collection.immutable.List.mapConserve(List.scala:472)
	at dotty.tools.dotc.transform.MegaPhase.transformTrees(MegaPhase.scala:420)
	at dotty.tools.dotc.transform.MegaPhase.transformUnnamed$1(MegaPhase.scala:271)
	at dotty.tools.dotc.transform.MegaPhase.transformTree(MegaPhase.scala:396)
	at dotty.tools.dotc.transform.MegaPhase.transformStat$2(MegaPhase.scala:406)
	at dotty.tools.dotc.transform.MegaPhase.$anonfun$1(MegaPhase.scala:409)
	at scala.collection.immutable.List.mapConserve(List.scala:472)
	at dotty.tools.dotc.transform.MegaPhase.transformStats(MegaPhase.scala:409)
	at dotty.tools.dotc.transform.MegaPhase.transformUnnamed$1(MegaPhase.scala:339)
	at dotty.tools.dotc.transform.MegaPhase.transformTree(MegaPhase.scala:396)
	at dotty.tools.dotc.transform.MegaPhase.transformNamed$1(MegaPhase.scala:251)
	at dotty.tools.dotc.transform.MegaPhase.transformTree(MegaPhase.scala:394)
	at dotty.tools.dotc.transform.MegaPhase.transformStat$2(MegaPhase.scala:404)
	at dotty.tools.dotc.transform.MegaPhase.$anonfun$1(MegaPhase.scala:409)
	at scala.collection.immutable.List.mapConserve(List.scala:472)
	at dotty.tools.dotc.transform.MegaPhase.transformStats(MegaPhase.scala:409)
	at dotty.tools.dotc.transform.MegaPhase.mapPackage$1(MegaPhase.scala:356)
	at dotty.tools.dotc.transform.MegaPhase.transformUnnamed$1(MegaPhase.scala:359)
	at dotty.tools.dotc.transform.MegaPhase.transformTree(MegaPhase.scala:396)
	at dotty.tools.dotc.transform.MegaPhase.transformUnit(MegaPhase.scala:415)
	at dotty.tools.dotc.transform.MegaPhase.run(MegaPhase.scala:427)
	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)

comparison of pickles

commit scala/scala@f8a7132 (parent)

pickles
package example
object MyPredef extends scala.AnyRef {
  def this() = { /* compiled code */ }
  implicit final class ArrowAssoc2[A] extends scala.AnyVal {
    val self: A = { /* compiled code */ }
    def this(self: A) = { /* compiled code */ }
    @scala.inline
    def <&>[B](y: B): scala.Tuple2[A, B] = { /* compiled code */ }
    override def hashCode(): scala.Int = { /* compiled code */ }
    override def equals(x$1: scala.Any): scala.Boolean = { /* compiled code */ }
  }
  object ArrowAssoc2 extends scala.AnyRef {
    def this() = { /* compiled code */ }
    @scala.inline
    final def <&>$extension[B, A]($this: example.MyPredef.ArrowAssoc2[A])(y: B): scala.Tuple2[A, B] = { /* compiled code */ }
    final def hashCode$extension[A]($this: example.MyPredef.ArrowAssoc2[A])(): scala.Int = { /* compiled code */ }
    final def equals$extension[A]($this: example.MyPredef.ArrowAssoc2[A])(x$1: scala.Any): scala.Boolean = { /* compiled code */ }
  }
  implicit final def ArrowAssoc2[A](self: A): example.MyPredef.ArrowAssoc2[A] = { /* compiled code */ }
}

commit scala/scala@6acc8ff

pickles
package example
object MyPredef extends scala.AnyRef {
  def this() = { /* compiled code */ }
  implicit final class ArrowAssoc2[A] extends scala.AnyVal {
    val self: A = { /* compiled code */ }
    def this(self: A) = { /* compiled code */ }
    @scala.inline
    def <&>[B](y: B): scala.Tuple2[A, B] = { /* compiled code */ }
    override def hashCode(): scala.Int = { /* compiled code */ }
    override def equals(x$1: scala.Any): scala.Boolean = { /* compiled code */ }
  }
  implicit final def ArrowAssoc2[A](self: A): example.MyPredef.ArrowAssoc2[A] = { /* compiled code */ }
  object ArrowAssoc2 extends scala.AnyRef {
    def this() = { /* compiled code */ }
    @scala.inline
    final def <&>$extension[B, A]($this: example.MyPredef.ArrowAssoc2[A])(y: B): scala.Tuple2[A, B] = { /* compiled code */ }
    final def hashCode$extension[A]($this: example.MyPredef.ArrowAssoc2[A])(): scala.Int = { /* compiled code */ }
    final def equals$extension[A]($this: example.MyPredef.ArrowAssoc2[A])(x$1: scala.Any): scala.Boolean = { /* compiled code */ }
  }
}

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions