Skip to content
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

Crash with Match Types and unapplySeq #21841

Open
SimonGuilloud opened this issue Oct 24, 2024 · 2 comments
Open

Crash with Match Types and unapplySeq #21841

SimonGuilloud opened this issue Oct 24, 2024 · 2 comments
Assignees
Labels
area:match-types area:pattern-matching itype:bug itype:crash regression This worked in a previous version but doesn't anymore stat:needs bisection Need to use nightly builds and git bisect to find out the commit where this issue was introduced

Comments

@SimonGuilloud
Copy link

SimonGuilloud commented Oct 24, 2024

Compiler version

3.5.1, 3.5.2, 3.6.1

Minimized code

object Test {

  sealed trait T
  sealed trait Arrow[A, B]

  type ArgsTo[S1, Target] <: NonEmptyTuple = S1 match {
    case Arrow[a, Target] => Tuple1[Expr[a]]
    case Arrow[a, b] => Expr[a] *: ArgsTo[b, Target]
  }

  sealed trait Expr[S] :
    def unapplySeq[Target](e: Expr[Target]): Option[ArgsTo[S, Target]] = ???

  case class Variable[S](id: String) extends Expr[S]

  val v = Variable[Arrow[T, Arrow[T, T]]]("v")
  val e : Expr[T] = ???

  e match
    case v[T](l, r) => ()  //This line causes the crash
    case _ => ()
}

Output (click arrow to expand)

unhandled exception while running MegaPhase{protectedAccessors, extmethods, uncacheGivenAliases, checkStatic, elimByName, hoistSuperArgs, forwardDepChecks, specializeApplyMethods, tryCatchPatterns, patternMatcher} on Test.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: Test.scala
        during phase: MegaPhase{protectedAccessors, extmethods, uncacheGivenAliases, checkStatic, elimByName, hoistSuperArgs, forwardDepChecks, specializeApplyMethods, tryCatchPatterns, patternMatcher}
                mode: Mode(ImplicitsEnabled)
     library version: version 2.13.14
    compiler version: version 3.5.1
            settings: 

Exception in thread "main" java.util.NoSuchElementException: last of empty list
	at scala.collection.immutable.Nil$.last(List.scala:666)
	at scala.collection.immutable.Nil$.last(List.scala:662)
	at dotty.tools.dotc.transform.PatternMatcher$Translator.unapplyProductSeqPlan$1(PatternMatcher.scala:336)
	at dotty.tools.dotc.transform.PatternMatcher$Translator.$anonfun$12(PatternMatcher.scala:397)
	at dotty.tools.dotc.transform.PatternMatcher$Translator.letAbstract(PatternMatcher.scala:129)
	at dotty.tools.dotc.transform.PatternMatcher$Translator.unapplyPlan$1$$anonfun$1(PatternMatcher.scala:394)
	at dotty.tools.dotc.transform.PatternMatcher$Translator.letAbstract(PatternMatcher.scala:129)
	at dotty.tools.dotc.transform.PatternMatcher$Translator.unapplyPlan$1(PatternMatcher.scala:372)
	at dotty.tools.dotc.transform.PatternMatcher$Translator.patternPlan(PatternMatcher.scala:445)
	at dotty.tools.dotc.transform.PatternMatcher$Translator.caseDefPlan(PatternMatcher.scala:481)
	at dotty.tools.dotc.transform.PatternMatcher$Translator.matchPlan$$anonfun$1$$anonfun$1(PatternMatcher.scala:488)
	at scala.collection.immutable.List.foldRight(List.scala:353)
	at dotty.tools.dotc.transform.PatternMatcher$Translator.matchPlan$$anonfun$1(PatternMatcher.scala:487)
	at dotty.tools.dotc.transform.PatternMatcher$Translator.letAbstract(PatternMatcher.scala:129)
	at dotty.tools.dotc.transform.PatternMatcher$Translator.matchPlan(PatternMatcher.scala:485)
	at dotty.tools.dotc.transform.PatternMatcher$Translator.translateMatch(PatternMatcher.scala:1073)
	at dotty.tools.dotc.transform.PatternMatcher.transformMatch(PatternMatcher.scala:54)
	at dotty.tools.dotc.transform.MegaPhase.goMatch(MegaPhase.scala:816)
	at dotty.tools.dotc.transform.MegaPhase.transformUnnamed$1(MegaPhase.scala:383)
	at dotty.tools.dotc.transform.MegaPhase.transformTree(MegaPhase.scala:454)
	at dotty.tools.dotc.transform.MegaPhase.loop$1(MegaPhase.scala:465)
	at dotty.tools.dotc.transform.MegaPhase.transformStats(MegaPhase.scala:465)
	at dotty.tools.dotc.transform.MegaPhase.transformUnnamed$1(MegaPhase.scala:376)
	at dotty.tools.dotc.transform.MegaPhase.transformTree(MegaPhase.scala:454)
	at dotty.tools.dotc.transform.MegaPhase.transformNamed$1(MegaPhase.scala:272)
	at dotty.tools.dotc.transform.MegaPhase.transformTree(MegaPhase.scala:452)
	at dotty.tools.dotc.transform.MegaPhase.loop$1(MegaPhase.scala:465)
	at dotty.tools.dotc.transform.MegaPhase.transformStats(MegaPhase.scala:465)
	at dotty.tools.dotc.transform.MegaPhase.mapPackage$1(MegaPhase.scala:396)
	at dotty.tools.dotc.transform.MegaPhase.transformUnnamed$1(MegaPhase.scala:399)
	at dotty.tools.dotc.transform.MegaPhase.transformTree(MegaPhase.scala:454)
	at dotty.tools.dotc.transform.MegaPhase.transformUnit(MegaPhase.scala:481)
	at dotty.tools.dotc.transform.MegaPhase.run(MegaPhase.scala:493)
	at dotty.tools.dotc.core.Phases$Phase.runOn$$anonfun$1(Phases.scala:380)
	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:373)
	at dotty.tools.dotc.Run.runPhases$1$$anonfun$1(Run.scala:343)
	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:1323)
	at dotty.tools.dotc.Run.runPhases$1(Run.scala:336)
	at dotty.tools.dotc.Run.compileUnits$$anonfun$1(Run.scala:384)
	at dotty.tools.dotc.Run.compileUnits$$anonfun$adapted$1(Run.scala:396)
	at dotty.tools.dotc.util.Stats$.maybeMonitored(Stats.scala:69)
	at dotty.tools.dotc.Run.compileUnits(Run.scala:396)
	at dotty.tools.dotc.Run.compileSources(Run.scala:282)
	at dotty.tools.dotc.Run.compile(Run.scala:267)
	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.MainGenericCompiler$.run$1(MainGenericCompiler.scala:162)
	at dotty.tools.MainGenericCompiler$.main(MainGenericCompiler.scala:186)
	at dotty.tools.MainGenericCompiler.main(MainGenericCompiler.scala)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:566)
	at coursier.bootstrap.launcher.a.a(Unknown Source)
	at coursier.bootstrap.launcher.Launcher.main(Unknown Source)

More Infos

I know that I some point in my project, that was working as expected, and the type of l and r was correctly inferred (Expr[T]). However it seems I can't reliably reproduce a non-crashing behaviour, even from a fresh checkout of my project at a point where I remember it to be non-crashing. Maybe the presence of cached files or something was different and relevant.

@SimonGuilloud SimonGuilloud added itype:bug itype:crash stat:needs triage Every issue needs to have an "area" and "itype" label labels Oct 24, 2024
@SimonGuilloud
Copy link
Author

SimonGuilloud commented Oct 24, 2024

The similar but slightly different version:

  val v = Variable[Arrow[T, T]]("v")
  val e : Expr[T] = ???

  e match
    case v[T](l) => ()
    case _ => ()

produces instead the very different error:

undefined: x8.<none> # -1: TermRef(TermRef(NoPrefix,val x8),<none>) at preRecheck
1 error found

@SimonGuilloud SimonGuilloud changed the title Crash with Match Types and UnapplySeq Crash with Match Types and unapplySeq Oct 24, 2024
@Gedochao Gedochao added regression This worked in a previous version but doesn't anymore area:pattern-matching area:match-types and removed stat:needs triage Every issue needs to have an "area" and "itype" label labels Oct 28, 2024
@Gedochao
Copy link
Contributor

This doesn't crash for Scala 3.4.3, instead producing an error.

scala-cli compile repro.scala -S 3.4.3
# Compiling project (Scala 3.4.3, JVM (17))
# [error] ./repro.scala:20:10
# [error] Wrong number of argument patterns for Test.v[Test.T]; expected: (Test.Expr[Test.T])
# [error]     case v[T](l, r) => ()  //This line causes the crash
# [error]          ^^^^^^^^^^
# Error compiling project (Scala 3.4.3, JVM (17))

Last good stable version: 3.4.3
First bad stable version: 3.5.0

@Gedochao Gedochao added the stat:needs bisection Need to use nightly builds and git bisect to find out the commit where this issue was introduced label Oct 28, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area:match-types area:pattern-matching itype:bug itype:crash regression This worked in a previous version but doesn't anymore stat:needs bisection Need to use nightly builds and git bisect to find out the commit where this issue was introduced
Projects
None yet
Development

No branches or pull requests

3 participants