Scala Programming Language
  1. Scala Programming Language
  2. SI-3702

java.lang.VerifyError when defining extractors for traits which are subtypes

    Details

    • Type: Bug Bug
    • Status: Closed
    • Priority: Major Major
    • Resolution: Fixed
    • Affects Version/s: None
    • Fix Version/s: Scala 2.10.0
    • Component/s: Pattern Matcher
    • Labels:
      None

      Description

      When I have two traits, Test1 and Test2, and Test2 is a subtype of Test1, and I define two extractors for these traits, a java.lang.VerifyError is thrown at runtime when I try to use the extractors in a pattern match statement. Consider the REPL output:

      $$ scala
      Welcome to Scala version 2.8.0.r0-b20100714201327 (Java HotSpot(TM) Server VM, Java 1.6.0_20).
      Type in expressions to have them evaluated.
      Type :help for more information.
      
      scala> trait Test1 {
           | def f1: Int
           | }
      defined trait Test1
      
      scala> trait Test2 extends Test1 {
           | def f2: Int
           | }
      defined trait Test2
      
      scala> object Test1 {
           | def unapply(t1: Test1): Option[(Int)] = Some(t1.f1)
           | }
      defined module Test1
      
      scala> object Test2 {
           | def unapply(t2: Test2): Option[(Int,Int)] = Some(t2.f1, t2.f2)
           | }
      defined module Test2
      
      scala> case class Test2Impl() extends Test2{
           | def f1 = 1
           | def f2 = 2
           | }
      defined class Test2Impl
      
      scala> val a: AnyRef = Test2Impl()
      a: AnyRef = Test2Impl()
      
      scala> a match {
           | case Test2(a,b) => println("a: " + a)    
           | case Test1(a) => println(a)
           | }
      java.lang.VerifyError: (class: , method: <init> signature: ()V) Accessing value from uninitialized register 4
          at RequestResult$$.<init>(<console>:9)
          at RequestResult$$.<clinit>(<console>)
          at RequestResult$$scala_repl_result(<console>)
          at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
          at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
          at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
          at java.lang.reflect.Method.invoke(Method.java:597)
          at scala.tools.nsc.Interpreter$$Request$$$$anonfun$$loadAndRun$$1$$$$anonfun$$apply$$18.apply(Interpreter.scala:981)
          at scala.tools.nsc.Interpreter$$Request$$$$anonfun$$loadAndRun$$1$$$$anonfun$$apply$$18.apply(Interpreter.scala:981)
          at scala.util.control.Exception$$Catch.apply(Exception....
      scala> 
      

      This problem isn't just limited to the REPL, but also for compiled code. See the attached file (which is just this REPL session in a file)

      1. test_match2.scala
        0.3 kB
        Jira Admin
      2. testbug.scala
        0.5 kB
        Jira Admin

        Activity

        Hide
        Margus Freudenthal added a comment -

        I stumbled on a similar problem when trying to match parse tree produced by ANTLR treebuilder. The code runs under Scala 2.7 and fails under 2.8 (VerifyError). Interesting point: if I delete the line "g += " " + from + ".." + to", then the program runs correctly under Scala 2.8.

        See attachment test_match2.scala

        Show
        Margus Freudenthal added a comment - I stumbled on a similar problem when trying to match parse tree produced by ANTLR treebuilder. The code runs under Scala 2.7 and fails under 2.8 (VerifyError). Interesting point: if I delete the line "g += " " + from + ".." + to", then the program runs correctly under Scala 2.8. See attachment test_match2.scala
        Hide
        Paul Phillips added a comment -

        The test_match attachment minimized is:

          def foo(h: Any, t: List[Any]) = h match {
            case 5 :: _ => ()
            case List(from) => from
          }
        

        This one is a buzzkill because it looks to arise from the pattern matcher cheating on case List(...) in a way it doesn't with anything else so as to offer the same performance (i.e. not use unapplySeq.) Thus there is special code for treating List like it's a series of :: and someone, me we can presume, has broken that code.

        I'm not sure it's the same issue as the reporter's, except that the pattern matcher can legitimately be viewed as one giant issue.

        Show
        Paul Phillips added a comment - The test_match attachment minimized is: def foo(h: Any, t: List[Any]) = h match { case 5 :: _ => () case List(from) => from } This one is a buzzkill because it looks to arise from the pattern matcher cheating on case List(...) in a way it doesn't with anything else so as to offer the same performance (i.e. not use unapplySeq.) Thus there is special code for treating List like it's a series of :: and someone, me we can presume, has broken that code. I'm not sure it's the same issue as the reporter's, except that the pattern matcher can legitimately be viewed as one giant issue.
        Show
        Simon Ochsenreither added a comment - Fixed in https://github.com/scala/scala/commit/4c04213b991596aa73dec3aa34cb8816a277f538

          People

          • Assignee:
            Paul Phillips
            Reporter:
            Stephen Tu
            TracCC:
            Erik Engbrecht, Margus Freudenthal, Mikhail Vorozhtsov, Paul Phillips
          • Votes:
            1 Vote for this issue
            Watchers:
            4 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved:

              Development