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

call to nullary, polymorphic macro without explicit type argument lead to NoSuchMethodError

    Details

    • Type: Bug Bug
    • Status: Closed
    • Priority: Major Major
    • Resolution: Fixed
    • Affects Version/s: Scala 2.10.0-M7, Scala 2.10.0
    • Fix Version/s: Scala 2.11.0-M2
    • Component/s: Macros
    • Labels:

      Description

      ~/code/scala ./build/quick/bin/scala
      Welcome to Scala version 2.10.0-20120422-061223-8c95273b70 (Java HotSpot(TM) 64-Bit Server VM, Java 1.6.0_29).
      
      scala> def impl[A](c: reflect.makro.Context) = c.reify(())
      impl: [A](c: scala.reflect.makro.Context)c.mirror.Expr[Unit]
      
      scala> def decl[A] = macro impl[A]
      decl: [A]=> Unit
      
      scala> decl[Any]
      
      scala> decl
      java.lang.NoSuchMethodError: .decl()V
      	at .<init>(<console>:12)
      	at .<clinit>(<console>)
      	at .<init>(<console>:7)
      	at .<clinit>(<console>)
      	at $print(<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.IMain$ReadEvalPrint.call(IMain.scala:776)
      	at scala.tools.nsc.interpreter.IMain$Request$$anonfun$16.apply(IMain.scala:1040)
      	at scala.tools.nsc.interpreter.Line.scala$tools$nsc$interpreter$Line$$runAndSetState(Line.scala:41)
      	at scala.tools.nsc.interpreter.Line$$anonfun$2.apply$mcV$sp(Line.scala:47)
      	at scala.tools.nsc.io.package$$anon$2.run(package.scala:22)
      	at java.lang.Thread.run(Thread.java:680)
      
      

        Activity

        Hide
        Eugene Burmako added a comment -

        There's another flavor of this bug, one that manifests when you write "val x = decl". Since macroExpand is mutually exclusive with instantiate, decl never gets a chance to instantiate. Instead it tries to expand, gets delayed because of undetParams, and ends up both polymorphic and not expanded.

        Show
        Eugene Burmako added a comment - There's another flavor of this bug, one that manifests when you write "val x = decl". Since macroExpand is mutually exclusive with instantiate, decl never gets a chance to instantiate. Instead it tries to expand, gets delayed because of undetParams, and ends up both polymorphic and not expanded.
        Hide
        Jason Zaugg added a comment -

        This now reports:

        scala> decl
        <console>:11: error: macro has not been expanded
                      decl
                      ^
        
        Show
        Jason Zaugg added a comment - This now reports: scala> decl <console>:11: error: macro has not been expanded decl ^
        Hide
        Eugene Burmako added a comment -

        That's expected.

        The original bug was caused by the fact that polymorphic expansions with undetermined params are delayed until params get inferred. This works in a lot of cases, except of this one that I overlooked.

        Interaction of undetParams and macros will be revised anyways, when I get to implicit macros (hopefully, before M4), so for now I added a "macro has not been expanded" sanity check akin to "erroneous or inaccessible type". Of course, this change doesn't prevent a bug, but at least it makes the bug apparent during compile-time, not during the runtime.

        Show
        Eugene Burmako added a comment - That's expected. The original bug was caused by the fact that polymorphic expansions with undetermined params are delayed until params get inferred. This works in a lot of cases, except of this one that I overlooked. Interaction of undetParams and macros will be revised anyways, when I get to implicit macros (hopefully, before M4), so for now I added a "macro has not been expanded" sanity check akin to "erroneous or inaccessible type". Of course, this change doesn't prevent a bug, but at least it makes the bug apparent during compile-time, not during the runtime.
        Hide
        Eugene Burmako added a comment - - edited

        Fixed in https://github.com/scala/scala/commit/ce67870e64afabf75363679bcee597812ad223e9
        Update. Actually I have no idea how exactly the linked commit fixes this issue. Probably I closed the wrong bug.

        Show
        Eugene Burmako added a comment - - edited Fixed in https://github.com/scala/scala/commit/ce67870e64afabf75363679bcee597812ad223e9 Update. Actually I have no idea how exactly the linked commit fixes this issue. Probably I closed the wrong bug.
        Hide
        Paolo G. Giarrusso added a comment - - edited

        Currently we still get the "macro has not been expanded" error, which is too cryptic and should be fixed. A correct error message should be "type parameter not specified". Given Eugene's comment, the plan was to change this error, but we're nearing release and that did not happen yet. So I'm reopening this bug.

        Below an updated REPL session (with a number of small changes due to updates to the macro API).

        scala> import language.experimental.macros
        import language.experimental.macros
        
        cala> def impl[A](c: reflect.macros.Context) = c.universe.reify(())
        impl: [A](c: scala.reflect.macros.Context)c.universe.Expr[Unit]
        
        scala> def decl[A] = macro impl[A]
        decl: [A]=> Unit
        
        scala> decl[Any]
        
        scala> decl
        <console>:11: error: macro has not been expanded
                      decl
                      ^
        
        Show
        Paolo G. Giarrusso added a comment - - edited Currently we still get the "macro has not been expanded" error, which is too cryptic and should be fixed. A correct error message should be "type parameter not specified". Given Eugene's comment, the plan was to change this error, but we're nearing release and that did not happen yet. So I'm reopening this bug. Below an updated REPL session (with a number of small changes due to updates to the macro API). scala> import language.experimental.macros import language.experimental.macros cala> def impl[A](c: reflect.macros.Context) = c.universe.reify(()) impl: [A](c: scala.reflect.macros.Context)c.universe.Expr[Unit] scala> def decl[A] = macro impl[A] decl: [A]=> Unit scala> decl[Any] scala> decl <console>:11: error: macro has not been expanded decl ^
        Hide
        Eugene Burmako added a comment -

        Thanks I'll look into it

        Show
        Eugene Burmako added a comment - Thanks I'll look into it
        Hide
        Eugene Burmako added a comment -

        Error message now looks better: https://github.com/scala/scala/pull/1329. However the underlying issue is still too fundamental to be fixed before 2.10.0-final. Therefore demoting back to major.

        Show
        Eugene Burmako added a comment - Error message now looks better: https://github.com/scala/scala/pull/1329 . However the underlying issue is still too fundamental to be fixed before 2.10.0-final. Therefore demoting back to major.
        Show
        Eugene Burmako added a comment - Fixed in https://github.com/scala/scala/commit/fe6028476931b031e712c37d3e570125b1d034ae

          People

          • Assignee:
            Eugene Burmako
            Reporter:
            Jason Zaugg
          • Votes:
            0 Vote for this issue
            Watchers:
            5 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved:

              Development