Skip to content

Bad owner of anonymous function after expandSAMs #23054

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

Open
jrlemieux opened this issue Apr 26, 2025 · 4 comments
Open

Bad owner of anonymous function after expandSAMs #23054

jrlemieux opened this issue Apr 26, 2025 · 4 comments

Comments

@jrlemieux
Copy link

jrlemieux commented Apr 26, 2025

Compiler version

3.6.4

Minimized code

object Bug:

  def m0(f: PartialFunction[Char, Unit]): Unit = ()

  def m1(): Unit =
    m0: x =>
      "abc".filter(_ == x) match
        case _ => ()

Output (click arrow to expand)

See bug.log (or the more readable bug-nocolor.log) in attached zip file.

files.zip

@jrlemieux jrlemieux added itype:bug itype:crash stat:needs triage Every issue needs to have an "area" and "itype" label labels Apr 26, 2025
@jrlemieux
Copy link
Author

jrlemieux commented Apr 26, 2025

Compiles without crash if m0 delcared as

  def m0(f: Char => Unit): Unit = ()

Also compiles without crash with this variation (m0 receives a function rather than a partial function, but there is no "match"):

  def m0(f: PartialFunction[Char, Unit]): Unit = ()

  def m1(): Unit =
    m0: x =>
      "abc".filter(_ == x)

And this variation also works (m0 receives a partial function):

  def m0(f: PartialFunction[Char, Unit]): Unit = ()

  def m1(): Unit =
    m0:
      case x =>
        "abc".filter(_ == x) match
          case _ => ()

@som-snytt
Copy link
Contributor

Relatedly #23002 does not help.

@Gedochao Gedochao added area:lambda-lift and removed stat:needs triage Every issue needs to have an "area" and "itype" label labels Apr 28, 2025
@KacperFKorban KacperFKorban changed the title Compiler crashes on simple code. Bad owner of anonymous function after expandSAMs May 1, 2025
@KacperFKorban
Copy link
Member

This is more likely a firstTransform/expandSAMs, since it fails with -Ycheck:all with:

checking wiadro/i23054.scala after phase MegaPhase{crossVersionChecks, firstTransform, checkReentrant, elimPackagePrefixes, cookComments, checkLoopingImplicits, betaReduce, inlineVals, expandSAMs, elimRepeated, refchecks, dropForMap}
*** error while checking wiadro/i23054.scala after phase MegaPhase{crossVersionChecks, firstTransform, checkReentrant, elimPackagePrefixes, cookComments, checkLoopingImplicits, betaReduce, inlineVals, expandSAMs, elimRepeated, refchecks, dropForMap} ***

  unhandled exception while running Ycheck on wiadro/i23054.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: wiadro/i23054.scala
        during phase: Ycheck
                mode: Mode(ImplicitsEnabled)
     library version: version 2.13.16
    compiler version: version 3.7.1-RC1-bin-20250430-c4531d4-NIGHTLY-git-c4531d4
            settings: -Vprint List(all) -Ycheck List(all) -classpath .cache/coursier/v1/https/repo1.maven.org/maven2/org/scala-lang/scala3-library_3/3.7.1-RC1-bin-20250430-c4531d4-NIGHTLY/scala3-library_3-3.7.1-RC1-bin-20250430-c4531d4-NIGHTLY.jar:.cache/coursier/v1/https/repo1.maven.org/maven2/org/scala-lang/scala-library/2.13.16/scala-library-2.13.16.jar -d wiadro/.scala-build/wiadro_5da420ddc5-c24cb85a9c/classes/main -sourceroot wiadro

Exception in thread "main" java.lang.AssertionError: assertion failed: bad owner; method $anonfun has owner method $anonfun, expected was method isDefinedAt
owner chain = method $anonfun, method $anonfun, method m1, object Bug, package <empty>, package <root>, ctxOwners = method isDefinedAt, method isDefinedAt, method isDefinedAt, method isDefinedAt, anonymous class scala.runtime.AbstractPartialFunction[Char, Unit] with 
  Serializable {...}, anonymous class scala.runtime.AbstractPartialFunction[Char, Unit] with 
  Serializable {...}, method m1, method m1, method m1, method m1, object Bug, object Bug, package <empty>, package <root>, package <root>, package <root>, package <root>, package <root>, package <root>, package <root>,  <none>,  <none>,  <none>,  <none>
	at scala.runtime.Scala3RunTime$.assertFailed(Scala3RunTime.scala:8)
	at dotty.tools.dotc.transform.TreeChecker$Checker.checkOwner(TreeChecker.scala:575)
	at dotty.tools.dotc.transform.TreeChecker$Checker.typedStats$$anonfun$1(TreeChecker.scala:687)
	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:334)
	at dotty.tools.dotc.transform.TreeChecker$Checker.typedStats(TreeChecker.scala:686)
	at dotty.tools.dotc.typer.Typer.typedBlockStats(Typer.scala:1486)
	at dotty.tools.dotc.typer.Typer.typedBlock(Typer.scala:1490)
	at dotty.tools.dotc.transform.TreeChecker$Checker.typedBlock$$anonfun$1$$anonfun$1(TreeChecker.scala:673)
	at dotty.tools.dotc.transform.TreeChecker$Checker.withDefinedSyms(TreeChecker.scala:278)
	at dotty.tools.dotc.transform.TreeChecker$Checker.typedBlock$$anonfun$1(TreeChecker.scala:673)
	at dotty.tools.dotc.transform.TreeChecker$Checker.withBlock(TreeChecker.scala:306)
	at dotty.tools.dotc.transform.TreeChecker$Checker.typedBlock(TreeChecker.scala:673)
	at dotty.tools.dotc.typer.Typer.typedUnnamed$1(Typer.scala:3570)
	at dotty.tools.dotc.typer.Typer.typedUnadapted(Typer.scala:3650)
	at dotty.tools.dotc.transform.TreeChecker$Checker.typedUnadapted(TreeChecker.scala:434)
	at dotty.tools.dotc.typer.ProtoTypes$FunProto.$anonfun$7(ProtoTypes.scala:536)
	at dotty.tools.dotc.typer.ProtoTypes$FunProto.cacheTypedArg(ProtoTypes.scala:459)
	at dotty.tools.dotc.typer.ProtoTypes$FunProto.typedArg(ProtoTypes.scala:537)
	at dotty.tools.dotc.typer.Applications$ApplyToUntyped.typedArg(Applications.scala:1047)
	at dotty.tools.dotc.typer.Applications$ApplyToUntyped.typedArg(Applications.scala:1047)
	at dotty.tools.dotc.typer.Applications$Application.addTyped$1(Applications.scala:727)
	at dotty.tools.dotc.typer.Applications$Application.matchArgs(Applications.scala:796)
	at dotty.tools.dotc.typer.Applications$Application.init(Applications.scala:606)
	at dotty.tools.dotc.typer.Applications$TypedApply.<init>(Applications.scala:922)
	at dotty.tools.dotc.typer.Applications$ApplyToUntyped.<init>(Applications.scala:1046)
	at dotty.tools.dotc.typer.Applications.ApplyTo(Applications.scala:1314)
	at dotty.tools.dotc.typer.Applications.ApplyTo$(Applications.scala:466)
	at dotty.tools.dotc.typer.Typer.ApplyTo(Typer.scala:154)
	at dotty.tools.dotc.typer.Applications.simpleApply$1(Applications.scala:1119)
	at dotty.tools.dotc.typer.Applications.$anonfun$15(Applications.scala:1228)
	at dotty.tools.dotc.typer.Typer$.tryEither(Typer.scala:127)
	at dotty.tools.dotc.typer.Applications.realApply$1(Applications.scala:1243)
	at dotty.tools.dotc.typer.Applications.typedApply(Applications.scala:1288)
	at dotty.tools.dotc.typer.Applications.typedApply$(Applications.scala:466)
	at dotty.tools.dotc.transform.TreeChecker$Checker.typedApply(TreeChecker.scala:543)
	at dotty.tools.dotc.typer.Typer.typedUnnamed$1(Typer.scala:3562)
	at dotty.tools.dotc.typer.Typer.typedUnadapted(Typer.scala:3650)
	at dotty.tools.dotc.transform.TreeChecker$Checker.typedUnadapted(TreeChecker.scala:434)
	at dotty.tools.dotc.typer.Typer.typed(Typer.scala:3727)
	at dotty.tools.dotc.typer.Typer.typed(Typer.scala:3732)
	at dotty.tools.dotc.transform.TreeChecker$Checker.typed(TreeChecker.scala:416)
	at dotty.tools.dotc.typer.Typer.typedExpr(Typer.scala:3843)
	at dotty.tools.dotc.typer.Typer.typedMatch(Typer.scala:2080)
	at dotty.tools.dotc.typer.Typer.typedUnnamed$1(Typer.scala:3577)
	at dotty.tools.dotc.typer.Typer.typedUnadapted(Typer.scala:3650)
	at dotty.tools.dotc.transform.TreeChecker$Checker.typedUnadapted(TreeChecker.scala:434)
	at dotty.tools.dotc.typer.Typer.typed(Typer.scala:3727)
	at dotty.tools.dotc.typer.Typer.typed(Typer.scala:3732)
	at dotty.tools.dotc.transform.TreeChecker$Checker.typed(TreeChecker.scala:416)
	at dotty.tools.dotc.typer.Typer.typedExpr(Typer.scala:3843)
	at dotty.tools.dotc.typer.Typer.$anonfun$66(Typer.scala:2954)
	at dotty.tools.dotc.inlines.PrepareInlineable$.dropInlineIfError(PrepareInlineable.scala:256)
	at dotty.tools.dotc.typer.Typer.typedDefDef(Typer.scala:2954)
	at dotty.tools.dotc.transform.TreeChecker$Checker.typedDefDef$$anonfun$1(TreeChecker.scala:648)
	at dotty.tools.dotc.transform.TreeChecker$Checker.withDefinedSyms(TreeChecker.scala:278)
	at dotty.tools.dotc.transform.TreeChecker$Checker.typedDefDef(TreeChecker.scala:651)
	at dotty.tools.dotc.typer.Typer.typedNamed$1(Typer.scala:3544)
	at dotty.tools.dotc.typer.Typer.typedUnadapted(Typer.scala:3649)
	at dotty.tools.dotc.transform.TreeChecker$Checker.typedUnadapted(TreeChecker.scala:434)
	at dotty.tools.dotc.typer.Typer.typed(Typer.scala:3727)
	at dotty.tools.dotc.typer.Typer.typed(Typer.scala:3732)
	at dotty.tools.dotc.transform.TreeChecker$Checker.typed(TreeChecker.scala:416)
	at dotty.tools.dotc.typer.Typer.traverse$1(Typer.scala:3754)
	at dotty.tools.dotc.typer.Typer.typedStats(Typer.scala:3800)
	at dotty.tools.dotc.transform.TreeChecker$Checker.typedStats(TreeChecker.scala:691)
	at dotty.tools.dotc.typer.Typer.typedClassDef(Typer.scala:3222)
	at dotty.tools.dotc.transform.TreeChecker$Checker.typedClassDef(TreeChecker.scala:618)
	at dotty.tools.dotc.typer.Typer.typedTypeOrClassDef$1(Typer.scala:3550)
	at dotty.tools.dotc.typer.Typer.typedNamed$1(Typer.scala:3554)
	at dotty.tools.dotc.typer.Typer.typedUnadapted(Typer.scala:3649)
	at dotty.tools.dotc.transform.TreeChecker$Checker.typedUnadapted(TreeChecker.scala:434)
	at dotty.tools.dotc.typer.Typer.typed(Typer.scala:3727)
	at dotty.tools.dotc.typer.Typer.typed(Typer.scala:3732)
	at dotty.tools.dotc.transform.TreeChecker$Checker.typed(TreeChecker.scala:416)
	at dotty.tools.dotc.typer.Typer.traverse$1(Typer.scala:3754)
	at dotty.tools.dotc.typer.Typer.typedStats(Typer.scala:3800)
	at dotty.tools.dotc.transform.TreeChecker$Checker.typedStats(TreeChecker.scala:691)
	at dotty.tools.dotc.typer.Typer.typedBlockStats(Typer.scala:1486)
	at dotty.tools.dotc.typer.Typer.typedBlock(Typer.scala:1490)
	at dotty.tools.dotc.transform.TreeChecker$Checker.typedBlock$$anonfun$1$$anonfun$1(TreeChecker.scala:673)
	at dotty.tools.dotc.transform.TreeChecker$Checker.withDefinedSyms(TreeChecker.scala:278)
	at dotty.tools.dotc.transform.TreeChecker$Checker.typedBlock$$anonfun$1(TreeChecker.scala:673)
	at dotty.tools.dotc.transform.TreeChecker$Checker.withBlock(TreeChecker.scala:306)
	at dotty.tools.dotc.transform.TreeChecker$Checker.typedBlock(TreeChecker.scala:673)
	at dotty.tools.dotc.typer.Typer.typedUnnamed$1(Typer.scala:3570)
	at dotty.tools.dotc.typer.Typer.typedUnadapted(Typer.scala:3650)
	at dotty.tools.dotc.transform.TreeChecker$Checker.typedUnadapted(TreeChecker.scala:434)
	at dotty.tools.dotc.typer.ProtoTypes$FunProto.$anonfun$7(ProtoTypes.scala:536)
	at dotty.tools.dotc.typer.ProtoTypes$FunProto.cacheTypedArg(ProtoTypes.scala:459)
	at dotty.tools.dotc.typer.ProtoTypes$FunProto.typedArg(ProtoTypes.scala:537)
	at dotty.tools.dotc.typer.Applications$ApplyToUntyped.typedArg(Applications.scala:1047)
	at dotty.tools.dotc.typer.Applications$ApplyToUntyped.typedArg(Applications.scala:1047)
	at dotty.tools.dotc.typer.Applications$Application.addTyped$1(Applications.scala:727)
	at dotty.tools.dotc.typer.Applications$Application.matchArgs(Applications.scala:796)
	at dotty.tools.dotc.typer.Applications$Application.init(Applications.scala:606)
	at dotty.tools.dotc.typer.Applications$TypedApply.<init>(Applications.scala:922)
	at dotty.tools.dotc.typer.Applications$ApplyToUntyped.<init>(Applications.scala:1046)
	at dotty.tools.dotc.typer.Applications.ApplyTo(Applications.scala:1314)
	at dotty.tools.dotc.typer.Applications.ApplyTo$(Applications.scala:466)
	at dotty.tools.dotc.typer.Typer.ApplyTo(Typer.scala:154)
	at dotty.tools.dotc.typer.Applications.simpleApply$1(Applications.scala:1119)
	at dotty.tools.dotc.typer.Applications.$anonfun$15(Applications.scala:1228)
	at dotty.tools.dotc.typer.Typer$.tryEither(Typer.scala:127)
	at dotty.tools.dotc.typer.Applications.realApply$1(Applications.scala:1243)
	at dotty.tools.dotc.typer.Applications.typedApply(Applications.scala:1288)
	at dotty.tools.dotc.typer.Applications.typedApply$(Applications.scala:466)
	at dotty.tools.dotc.transform.TreeChecker$Checker.typedApply(TreeChecker.scala:543)
	at dotty.tools.dotc.typer.Typer.typedUnnamed$1(Typer.scala:3562)
	at dotty.tools.dotc.typer.Typer.typedUnadapted(Typer.scala:3650)
	at dotty.tools.dotc.transform.TreeChecker$Checker.typedUnadapted(TreeChecker.scala:434)
	at dotty.tools.dotc.typer.Typer.typed(Typer.scala:3727)
	at dotty.tools.dotc.typer.Typer.typed(Typer.scala:3732)
	at dotty.tools.dotc.transform.TreeChecker$Checker.typed(TreeChecker.scala:416)
	at dotty.tools.dotc.typer.Typer.typedExpr(Typer.scala:3843)
	at dotty.tools.dotc.typer.Typer.$anonfun$66(Typer.scala:2954)
	at dotty.tools.dotc.inlines.PrepareInlineable$.dropInlineIfError(PrepareInlineable.scala:256)
	at dotty.tools.dotc.typer.Typer.typedDefDef(Typer.scala:2954)
	at dotty.tools.dotc.transform.TreeChecker$Checker.typedDefDef$$anonfun$1(TreeChecker.scala:648)
	at dotty.tools.dotc.transform.TreeChecker$Checker.withDefinedSyms(TreeChecker.scala:278)
	at dotty.tools.dotc.transform.TreeChecker$Checker.typedDefDef(TreeChecker.scala:651)
	at dotty.tools.dotc.typer.Typer.typedNamed$1(Typer.scala:3544)
	at dotty.tools.dotc.typer.Typer.typedUnadapted(Typer.scala:3649)
	at dotty.tools.dotc.transform.TreeChecker$Checker.typedUnadapted(TreeChecker.scala:434)
	at dotty.tools.dotc.typer.Typer.typed(Typer.scala:3727)
	at dotty.tools.dotc.typer.Typer.typed(Typer.scala:3732)
	at dotty.tools.dotc.transform.TreeChecker$Checker.typed(TreeChecker.scala:416)
	at dotty.tools.dotc.typer.Typer.traverse$1(Typer.scala:3754)
	at dotty.tools.dotc.typer.Typer.typedStats(Typer.scala:3800)
	at dotty.tools.dotc.transform.TreeChecker$Checker.typedStats(TreeChecker.scala:691)
	at dotty.tools.dotc.typer.Typer.typedClassDef(Typer.scala:3222)
	at dotty.tools.dotc.transform.TreeChecker$Checker.typedClassDef(TreeChecker.scala:618)
	at dotty.tools.dotc.typer.Typer.typedTypeOrClassDef$1(Typer.scala:3550)
	at dotty.tools.dotc.typer.Typer.typedNamed$1(Typer.scala:3554)
	at dotty.tools.dotc.typer.Typer.typedUnadapted(Typer.scala:3649)
	at dotty.tools.dotc.transform.TreeChecker$Checker.typedUnadapted(TreeChecker.scala:434)
	at dotty.tools.dotc.typer.Typer.typed(Typer.scala:3727)
	at dotty.tools.dotc.typer.Typer.typed(Typer.scala:3732)
	at dotty.tools.dotc.transform.TreeChecker$Checker.typed(TreeChecker.scala:416)
	at dotty.tools.dotc.typer.Typer.traverse$1(Typer.scala:3754)
	at dotty.tools.dotc.typer.Typer.typedStats(Typer.scala:3800)
	at dotty.tools.dotc.transform.TreeChecker$Checker.typedStats(TreeChecker.scala:691)
	at dotty.tools.dotc.typer.Typer.typedPackageDef(Typer.scala:3355)
	at dotty.tools.dotc.transform.TreeChecker$Checker.typedPackageDef(TreeChecker.scala:717)
	at dotty.tools.dotc.typer.Typer.typedUnnamed$1(Typer.scala:3596)
	at dotty.tools.dotc.typer.Typer.typedUnadapted(Typer.scala:3650)
	at dotty.tools.dotc.transform.TreeChecker$Checker.typedUnadapted(TreeChecker.scala:434)
	at dotty.tools.dotc.typer.Typer.typed(Typer.scala:3727)
	at dotty.tools.dotc.typer.Typer.typed(Typer.scala:3732)
	at dotty.tools.dotc.transform.TreeChecker$Checker.typed(TreeChecker.scala:416)
	at dotty.tools.dotc.typer.Typer.typedExpr(Typer.scala:3843)
	at dotty.tools.dotc.transform.TreeChecker.check(TreeChecker.scala:131)
	at dotty.tools.dotc.transform.TreeChecker.run(TreeChecker.scala:111)
	at dotty.tools.dotc.core.Phases$Phase.runOn$$anonfun$1(Phases.scala:383)
	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:334)
	at dotty.tools.dotc.core.Phases$Phase.runOn(Phases.scala:376)
	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)

@som-snytt
Copy link
Contributor

ExpandSAMs copies the Match but doesn't change owner the selector expression containing the anonfun (the filter). I took a look the other day but didn't get back to it. This is the dubious support of anything more than x for the selector for synthesizing the partial function. It might be an easy fix for someone or a learning exercise for someone else (as I already learned).

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

No branches or pull requests

4 participants