Skip to content

Crash on missing parens around named tuple in custom extractor #23552

Open
@TomasMikula

Description

@TomasMikula

Compiler version

3.7.1

Minimized code

import NamedTuple.AnyNamedTuple

sealed trait Z
sealed trait S[n]

type TupleList[+A, N] <: AnyNamedTuple =
  N match
    case Z => NamedTuple.Empty
    case S[n] => (head: A, tail: TupleList[A, n])

sealed trait Vect[+A, N]:
  def ::[A1 >: A](a: A1): Vect[A1, S[N]] =
    Vect.Cons(a, this)

  def toTupleList: TupleList[A, N]

object Vect:
  case object Empty extends Vect[Nothing, Z]:
    override def toTupleList: TupleList[Nothing, Z] = NamedTuple.Empty

  case class Cons[A, N](head: A, tail: Vect[A, N]) extends Vect[A, S[N]]:
    override def toTupleList: TupleList[A, S[N]] = (head, tail.toTupleList)

object Foo:
  def unapply[A, N](as: Vect[A, N]): Some[TupleList[A, N]] =
    Some(as.toTupleList)

@main
def test: Unit =
  (1 :: 2 :: 3 :: Vect.Empty) match
    // missing parens around named tuple inside Foo causes compiler crash
    case Foo(head = h, tail = t) =>
      ()

Output (click arrow to expand)

% scalac test.scala

  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.16
    compiler version: version 3.7.1
            settings: 

Exception in thread "main" scala.MatchError: List() (of class scala.collection.immutable.Nil$)
	at dotty.tools.dotc.transform.PatternMatcher$Translator.matchArgsPatternPlan$1(PatternMatcher.scala:270)
	at dotty.tools.dotc.transform.PatternMatcher$Translator.matchArgsComponentsPlan$1(PatternMatcher.scala:265)
	at dotty.tools.dotc.transform.PatternMatcher$Translator.matchArgsPlan$1(PatternMatcher.scala:276)
	at dotty.tools.dotc.transform.PatternMatcher$Translator.$anonfun$13(PatternMatcher.scala:403)
	at dotty.tools.dotc.transform.PatternMatcher$Translator.letAbstract(PatternMatcher.scala:117)
	at dotty.tools.dotc.transform.PatternMatcher$Translator.unapplyPlan$1$$anonfun$1(PatternMatcher.scala:388)
	at dotty.tools.dotc.transform.PatternMatcher$Translator.letAbstract(PatternMatcher.scala:117)
	at dotty.tools.dotc.transform.PatternMatcher$Translator.unapplyPlan$1(PatternMatcher.scala:360)
	at dotty.tools.dotc.transform.PatternMatcher$Translator.patternPlan(PatternMatcher.scala:444)
	at dotty.tools.dotc.transform.PatternMatcher$Translator.caseDefPlan(PatternMatcher.scala:480)
	at dotty.tools.dotc.transform.PatternMatcher$Translator.matchPlan$$anonfun$1$$anonfun$1(PatternMatcher.scala:487)
	at scala.collection.immutable.List.foldRight(List.scala:353)
	at dotty.tools.dotc.transform.PatternMatcher$Translator.matchPlan$$anonfun$1(PatternMatcher.scala:486)
	at dotty.tools.dotc.transform.PatternMatcher$Translator.letAbstract(PatternMatcher.scala:117)
	at dotty.tools.dotc.transform.PatternMatcher$Translator.matchPlan(PatternMatcher.scala:484)
	at dotty.tools.dotc.transform.PatternMatcher$Translator.translateMatch(PatternMatcher.scala:1072)
	at dotty.tools.dotc.transform.PatternMatcher.transformMatch(PatternMatcher.scala:47)
	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.mapDefDef$1(MegaPhase.scala:265)
	at dotty.tools.dotc.transform.MegaPhase.transformNamed$1(MegaPhase.scala:268)
	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.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: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.MainGenericCompiler$.run$1(MainGenericCompiler.scala:162)
	at dotty.tools.MainGenericCompiler$.main(MainGenericCompiler.scala:186)
	at dotty.tools.MainGenericCompiler.main(MainGenericCompiler.scala)

Expectation

I'd expect the compiler to report an error about the pattern being wrong.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions