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

VerifyError in secondary constructor with forward reference to a local method as argument to this()

    Details

      Description

      === What steps will reproduce the problem (please be specific and use wikiformatting)? ===

      scala> class A(a: Any) { 
           |   def this() = {  
           |     this(b)       
           |     def b = new {}
           |   }
           | }
      defined class A
      
      

      === What is the expected behavior? ===

      Either a compile error or runtime success.

      === What do you see instead? ===

      scala> new A()           
      java.util.concurrent.ExecutionException: java.lang.reflect.InvocationTargetException
      	at java.util.concurrent.FutureTask$$Sync.innerGet(FutureTask.java:222)
      	at java.util.concurrent.FutureTask.get(FutureTask.java:83)
      	at scala.tools.nsc.Interpreter$$Request.loadAndRun(Interpreter.scala:1041)
      	at scala.tools.nsc.Interpreter.loadAndRunReq$$1(Interpreter.scala:616)
      	at scala.tools.nsc.Interpreter.interpret(Interpreter.scala:636)
      	at scala.tools.nsc.Interpreter.interpret(Interpreter.scala:613)
      	at scala.tools.nsc.InterpreterLoop.reallyInterpret$$1(InterpreterLoop.scala:472)
      	at scala.tools.nsc.InterpreterLoop.interpretStartingWith(InterpreterLoop.scala:515)
      	at scala.tools.nsc.InterpreterLoop.command(InterpreterLoop.scala:362)
      	at scala.tools.nsc.InterpreterLoop.processLine$$1(InterpreterLoop.scala:243)
      	at scala.tools.nsc.InterpreterLoop.repl(InterpreterLoop.scala:249)
      	at scala.tools.nsc.InterpreterLoop.main(InterpreterLoop.scala:559)
      	at xsbt.ConsoleInterface.run(ConsoleInterface.scala:26)
      	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 xsbt.AnalyzingCompiler.call(AnalyzingCompiler.scala:40)
      	at xsbt.AnalyzingCompiler.console(AnalyzingCompiler.scala:32)
      	at sbt.Console.console0$$1(Compile.scala:141)
      	at sbt.Console$$$$anonfun$$apply$$4$$$$anonfun$$apply$$5.apply(Compile.scala:142)
      	at sbt.Console$$$$anonfun$$apply$$4$$$$anonfun$$apply$$5.apply(Compile.scala:142)
      	at sbt.TrapExit$$.executeMain$$1(TrapExit.scala:33)
      	at sbt.TrapExit$$$$anon$$1.run(TrapExit.scala:42)
      Caused by: java.lang.reflect.InvocationTargetException
      	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.apply(Interpreter.scala:1036)
      	at scala.tools.nsc.Interpreter$$Request$$$$anonfun$$loadAndRun$$1.apply(Interpreter.scala:1036)
      	at scala.tools.nsc.io.package$$$$anon$$4.call(package.scala:13)
      	at java.util.concurrent.FutureTask$$Sync.innerRun(FutureTask.java:303)
      	at java.util.concurrent.FutureTask.run(FutureTask.java:138)
      	at java.util.concurrent.ThreadPoolExecutor$$Worker.runTask(ThreadPoolExecutor.java:886)
      	at java.util.concurrent.ThreadPoolExecutor$$Worker.run(ThreadPoolExecutor.java:908)
      	at java.lang.Thread.run(Thread.java:680)
      Caused by: java.lang.VerifyError: (class: A, method: b$$1 signature: ()Ljava/lang/Object;) Illegal local variable number
      	at .<init>(<console>:7)
      	at .<clinit>(<console>)
      	at RequestResult$$.<init>(<console>:9)
      	at RequestResult$$.<clinit>(<console>)
      	at RequestResult$$scala_repl_result(<console>)
      	... 12 more
      

      === Additional information ===
      http://bit.ly/f9O40B

      Same failure mode, but seemingly unrelated to http://lampsvn.epfl.ch/trac/scala/ticket/3648#comment:10

      === What versions of the following are you using? ===

      • Scala: 2.8.1, 2.9.0.r23614-b20101128020130
      • Java: 1.6
      • Operating system: Mac OS X

        Activity

        Hide
        Jason Zaugg added a comment -

        A variation, for good measure:

        class A(a: Any) { 
          def this() = {  
            this(b)       
            lazy val b = new {}
          }
        }
        

        Yields:

        
        while compiling:  <console>
               current phase:  lazyvals
             library version:  version 2.10.0-20120510-110850-63a53e3395
            compiler version:  version 2.10.0-20120510-110850-63a53e3395
          reconstructed args:  
        
        uncaught exception during compilation: scala.reflect.internal.Types$TypeError
        scala.reflect.internal.Types$TypeError: called constructor's definition must precede calling constructor's definition
        	at scala.tools.nsc.typechecker.Contexts$Context.issueCommon(Contexts.scala:363)
        
        
        Show
        Jason Zaugg added a comment - A variation, for good measure: class A(a: Any) { def this() = { this(b) lazy val b = new {} } } Yields: while compiling: <console> current phase: lazyvals library version: version 2.10.0-20120510-110850-63a53e3395 compiler version: version 2.10.0-20120510-110850-63a53e3395 reconstructed args: uncaught exception during compilation: scala.reflect.internal.Types$TypeError scala.reflect.internal.Types$TypeError: called constructor's definition must precede calling constructor's definition at scala.tools.nsc.typechecker.Contexts$Context.issueCommon(Contexts.scala:363)
        Hide
        Jason Zaugg added a comment - - edited

        Here's a patch to simply forbid the forward reference. Was I specific enough in the pattern match on the self constructor invocation?

          case Apply(Select(This(_), nme.CONSTRUCTOR), args) =>
        

        https://github.com/retronym/scala/compare/ticket/4098

        Show
        Jason Zaugg added a comment - - edited Here's a patch to simply forbid the forward reference. Was I specific enough in the pattern match on the self constructor invocation? case Apply(Select(This(_), nme.CONSTRUCTOR), args) => https://github.com/retronym/scala/compare/ticket/4098
        Hide
        Jason Zaugg added a comment -

        It's passing the tests, so I've submitted a pull request.

        https://github.com/scala/scala/pull/527

        Show
        Jason Zaugg added a comment - It's passing the tests, so I've submitted a pull request. https://github.com/scala/scala/pull/527
        Show
        Jason Zaugg added a comment - https://github.com/scala/scala/commit/d35e74eb6bc13f1f354029c9439cef35aecd972b

          People

          • Assignee:
            Iulian Dragos
            Reporter:
            Jason Zaugg
          • Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved:

              Development