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

match in finally&static init causes VerifyError ("register 16 contains wrong type")

    Details

      Description

      I do not know how to boil this down to a small example, unfortunately. This happens when I try and compile ScalaTest under Scala 2.10.0-M4. I'm not sure this is a Scala 2.10 issues. May be some other fluke, but here's the stack trace and instructions on how to reproduce it:

      runtest:
      [scalatest] *** RUN ABORTED *** (21 seconds, 76 milliseconds)
      [scalatest] java.lang.VerifyError: (class: org/scalatest/BeforeAndAfterEachFunctions$class, method: runTest signature: (Lorg/scalatest/BeforeAndAfterEachFunctions;Ljava/lang/String;Lorg/scalatest/Reporter;Lorg/scalatest/Stopper;Lscala/collection/immutable/Map;Lorg/scalatest/Tracker;)V) Register 16 contains wrong type
      [scalatest] at org.scalatest.BeforeAndAfterFunctionsExtendingSuite.<init>(BeforeAndAfterFunctionsSuite.scala:415)
      [scalatest] at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
      [scalatest] at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)
      [scalatest] at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
      [scalatest] at java.lang.reflect.Constructor.newInstance(Constructor.java:513)
      [scalatest] at java.lang.Class.newInstance0(Class.java:355)
      [scalatest] at java.lang.Class.newInstance(Class.java:308)
      [scalatest] at org.scalatest.tools.DiscoverySuite$$anonfun$1.apply(DiscoverySuite.scala:40)
      [scalatest] at org.scalatest.tools.DiscoverySuite$$anonfun$1.apply(DiscoverySuite.scala:34)
      [scalatest] at scala.collection.TraversableLike$$anonfun$map$1.apply(TraversableLike.scala:239)
      [scalatest] ...

      To (attempt to) reproduce it, check out this branch:

      https://scalatest.googlecode.com/svn/branches/r18for210M4

      And type:

      ant compile; ant gencode; ant test

        Activity

        Hide
        Iulian Dragos added a comment -

        I tried to fix it as well, and implemented the solution I described. It fixes this case, but fails while compiling Predef.scala (genericArayOps).

        The invariant I was counting on was that, for all LabelDefs, ldef.symbol.info.params == ldef.params.map(_.symbol). So the symbols in the LabelDef tree (a list of Idents with symbols), are the same as the ones in the method type of the label symbol. It's not always the case

        I'll stop now.

        Show
        Iulian Dragos added a comment - I tried to fix it as well, and implemented the solution I described. It fixes this case, but fails while compiling Predef.scala (genericArayOps). The invariant I was counting on was that, for all LabelDefs, ldef.symbol.info.params == ldef.params.map(_.symbol). So the symbols in the LabelDef tree (a list of Idents with symbols), are the same as the ones in the method type of the label symbol. It's not always the case I'll stop now.
        Hide
        Iulian Dragos added a comment -
        Show
        Iulian Dragos added a comment - My semi-futile effort: https://github.com/dragos/scala/tree/issue/fix-5929
        Hide
        Paul Phillips added a comment -

        Oh good, hopefully I'll have better luck. Would anyone like to comment on the correctness of this just-written-and-untested piece of machinery?

          /** A foreach traverser which prunes anytime a new scope would be
           *  opened - that is, it doesn't recurse into Blocks, Templates,
           *  or catch/finally blocks.  (Am I missing anything?)
           *  You might use this if you wanted to traverse the statements of
           *  a DefDef body without running into trees which are not in scope
           *  for the whole body.
           */
          class ForeachTreeInScopeTraverser(f: Tree => Unit) extends Traverser {
            override def traverse(t: Tree) {
              f(t)
              t match {
                case Try(body, _, _)        => traverse(body)
                case _: Template | _: Block => // prune
                case _                      => super.traverse(t)
              }
            }
          }
        
        Show
        Paul Phillips added a comment - Oh good, hopefully I'll have better luck. Would anyone like to comment on the correctness of this just-written-and-untested piece of machinery? /** A foreach traverser which prunes anytime a new scope would be * opened - that is, it doesn't recurse into Blocks, Templates, * or catch/finally blocks. (Am I missing anything?) * You might use this if you wanted to traverse the statements of * a DefDef body without running into trees which are not in scope * for the whole body. */ class ForeachTreeInScopeTraverser(f: Tree => Unit) extends Traverser { override def traverse(t: Tree) { f(t) t match { case Try(body, _, _) => traverse(body) case _: Template | _: Block => // prune case _ => super.traverse(t) } } }
        Hide
        Paul Phillips added a comment -

        I withdraw my naive optimism. You guys will like what I'm really working on though, I promise.

        Show
        Paul Phillips added a comment - I withdraw my naive optimism. You guys will like what I'm really working on though, I promise.
        Show
        Adriaan Moors added a comment - https://github.com/scala/scala/pull/809

          People

          • Assignee:
            Iulian Dragos
            Reporter:
            Bill Venners
          • Votes:
            0 Vote for this issue
            Watchers:
            6 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved:

              Development