Skip to content

Expanding a pattern match leads to "head of empty list" #1846

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
b-studios opened this issue Dec 21, 2016 · 3 comments · Fixed by #3810
Closed

Expanding a pattern match leads to "head of empty list" #1846

b-studios opened this issue Dec 21, 2016 · 3 comments · Fixed by #3810

Comments

@b-studios
Copy link
Contributor

When trying to compile this syntactically correct, but nonsensical program the compiler crashes:

object Bug {
  val x = 42
  x match {case {42}.toString => 42}
}

Beginning of the trace:

exception while transforming Bug.x match
  {
    case 42.toString() => 42
  } of class class dotty.tools.dotc.ast.Trees$Match # 79
exception while transforming () extends Object() {
  val x: Int = 42
  Bug.x match
    {
      case 42.toString() => 42
    }
} of class class dotty.tools.dotc.ast.Trees$Template # 81
exception while transforming @scala.annotation.internal.SourceFile("examples/bug.scala") final module class
  Bug$
() extends Object() {
  val x: Int = 42
  Bug.x match
    {
      case 42.toString() => 42
    }
} of class class dotty.tools.dotc.ast.Trees$TypeDef # 82
exception while transforming package <empty> {
  final lazy module val Bug: Bug$ = new Bug$()
  @scala.annotation.internal.SourceFile("examples/bug.scala") final module class

  Bug$() extends Object() {
    val x: Int = 42
    Bug.x match
      {
        case 42.toString() => 42
      }
  }
} of class class dotty.tools.dotc.ast.Trees$PackageDef # 83

exception occurred while compiling examples/bug.scala
Exception in thread "main" java.util.NoSuchElementException: head of empty list
	at scala.collection.immutable.Nil$.head(List.scala:420)
	at scala.collection.immutable.Nil$.head(List.scala:417)
	at dotty.tools.dotc.transform.PatternMatcher$Translator$ScalacPatternExpanders$ScalacPatternExpander$class.applyMethodTypes(PatternMatcher.scala:1863)
	at dotty.tools.dotc.transform.PatternMatcher$Translator$ScalacPatternExpanders$alignPatterns$.applyMethodTypes(PatternMatcher.scala:1904)
	at dotty.tools.dotc.transform.PatternMatcher$Translator$ScalacPatternExpanders$alignPatterns$.apply(PatternMatcher.scala:1955)
	at dotty.tools.dotc.transform.PatternMatcher$Translator$ScalacPatternExpanders$alignPatterns$.apply(PatternMatcher.scala:1978)
	at dotty.tools.dotc.transform.PatternMatcher$Translator$MatchTranslator$ExtractorCall$.apply(PatternMatcher.scala:1412)
	at dotty.tools.dotc.transform.PatternMatcher$Translator$MatchTranslator$BoundTree.extractor$lzycompute(PatternMatcher.scala:1127)
	at dotty.tools.dotc.transform.PatternMatcher$Translator$MatchTranslator$BoundTree.extractor(PatternMatcher.scala:1127)
	at dotty.tools.dotc.transform.PatternMatcher$Translator$MatchTranslator$BoundTree.paramType$1(PatternMatcher.scala:1185)
	at dotty.tools.dotc.transform.PatternMatcher$Translator$MatchTranslator$BoundTree.extractorStep(PatternMatcher.scala:1201)
	at dotty.tools.dotc.transform.PatternMatcher$Translator$MatchTranslator$BoundTree.nextStep(PatternMatcher.scala:1222)
	at dotty.tools.dotc.transform.PatternMatcher$Translator$MatchTranslator$BoundTree.translate(PatternMatcher.scala:1231)
	at dotty.tools.dotc.transform.PatternMatcher$Translator$MatchTranslator$class.translatePattern(PatternMatcher.scala:1338)
	at dotty.tools.dotc.transform.PatternMatcher$Translator$OptimizingMatchTranslator.translatePattern(PatternMatcher.scala:72)
	at dotty.tools.dotc.transform.PatternMatcher$Translator$MatchTranslator$class.translateCase(PatternMatcher.scala:1335)
	at dotty.tools.dotc.transform.PatternMatcher$Translator$OptimizingMatchTranslator.translateCase(PatternMatcher.scala:72)
	at dotty.tools.dotc.transform.PatternMatcher$Translator$MatchTranslator$$anonfun$29.apply(PatternMatcher.scala:1299)
	at dotty.tools.dotc.transform.PatternMatcher$Translator$MatchTranslator$$anonfun$29.apply(PatternMatcher.scala:1299)
	at scala.collection.immutable.List.map(List.scala:273)
@liufengyun
Copy link
Contributor

This is related to #1774 , blocks inside patterns is not well supported in Dotty. In Scalac, the code above is syntactically invalid, but the pattern matcher can handle blocks that are synthesized.

@b-studios
Copy link
Contributor Author

I guess the problem for this particular issue is that the grammar allows path selections and blocks at the same time. Is there any reason why you would want to select a member of a block? At least the examples in #1774 don't do that.

I could imagine an example like:

  x match { 
    case {
      object Even {
        def unapply(n: Int): Boolean = n % 2 == 0
      }
      object foo {
        val even = Even
      }
      foo
    }.even => 42 
  }

But here Dotty tells me:

-- [E008] Member Not Found Error: examples/bug.scala ---------------------------
 9 |    case {
10 |      object Even {
11 |        def unapply(n: Int): Boolean = n % 2 == 0
12 |      }
13 |      object foo {
14 |        val even = Even
15 |      }
16 |      foo
   |         ^
   |      value `even` is not a member of Object - did you mean `Object.eq`?

If we want to forbid selection of blocks, I guess we need to change the grammar to

 SimplePattern1    ::=  Path
                     |  `{' Block `}'
-                    |  SimplePattern1 `.' id

Other selections like Foo.Bar.Baz are already supported by Path.

@nicolasstucki
Copy link
Contributor

The current exception is

exception while typing 42.toString.unapply of class class dotty.tools.dotc.ast.Trees$Select # 89
exception while typing 42.toString() of class class dotty.tools.dotc.ast.Trees$Apply # 78
exception while typing Bug.x match
  {
    case 42.toString() => 42
  } of class class dotty.tools.dotc.ast.Trees$Match # 81
exception while typing
  final module
 class Bug() extends Object() {
  val x: Int = 42
  Bug.x match
    {
      case 42.toString() => 42
    }
} of class class dotty.tools.dotc.ast.Trees$TypeDef # 84
exception while typing package <empty> {
  final lazy module val Bug: Bug = new Bug()
  
    final module
   class Bug() extends Object() {
    val x: Int = 42
    Bug.x match
      {
        case 42.toString() => 42
      }
  }
} of class class dotty.tools.dotc.ast.Trees$PackageDef # 85

liufengyun added a commit to dotty-staging/dotty that referenced this issue Jan 11, 2018
liufengyun added a commit to dotty-staging/dotty that referenced this issue Jan 17, 2018
odersky added a commit that referenced this issue Jan 27, 2018
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.

4 participants