Skip to content
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

AbstractMethodError when override using macro #8949

Open
scabug opened this issue Oct 30, 2014 · 4 comments
Open

AbstractMethodError when override using macro #8949

scabug opened this issue Oct 30, 2014 · 4 comments
Labels
Milestone

Comments

@scabug
Copy link

scabug commented Oct 30, 2014

Welcome to Scala version 2.10.4 (Java HotSpot(TM) 64-Bit Server VM, Java 1.7.0_67).
Type in expressions to have them evaluated.
Type :help for more information.
 
scala> :paste
// Entering paste mode (ctrl-D to finish)
 
import scala.language.experimental.macros
import scala.reflect.macros.Context
 
trait A{
  def x: Int = 1
}
 
 
object B {
  def impl(c: Context): c.Expr[Int] = {
    import c.universe._
    c.Expr[Int](Literal(Constant(2)))
  }
}
 
class B extends A {
  override def x: Int = macro B.impl
}
 
// Exiting paste mode, now interpreting.
 
import scala.language.experimental.macros
import scala.reflect.macros.Context
defined trait A
defined module B
defined class B
 
scala> val b = new B
b: B = B@47825164
 
scala> b.x
res0: Int = 2
 
scala> (b: A).x
java.lang.AbstractMethodError: B.x()I
        at .<init>(<console>:14)
        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:57)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:606)
        at scala.tools.nsc.interpreter.IMain$ReadEvalPrint.call(IMain.scala:734)
        at scala.tools.nsc.interpreter.IMain$Request.loadAndRun(IMain.scala:983)
        at scala.tools.nsc.interpreter.IMain.loadAndRunReq$1(IMain.scala:573)
        at scala.tools.nsc.interpreter.IMain.interpret(IMain.scala:604)
        at scala.tools.nsc.interpreter.IMain.interpret(IMain.scala:568)
        at scala.tools.nsc.interpreter.ILoop.reallyInterpret$1(ILoop.scala:760)
        at scala.tools.nsc.interpreter.ILoop.interpretStartingWith(ILoop.scala:805)
        at scala.tools.nsc.interpreter.ILoop.command(ILoop.scala:717)
        at scala.tools.nsc.interpreter.ILoop.processLine$1(ILoop.scala:581)
        at scala.tools.nsc.interpreter.ILoop.innerLoop$1(ILoop.scala:588)
        at scala.tools.nsc.interpreter.ILoop.loop(ILoop.scala:591)
        at scala.tools.nsc.interpreter.ILoop$$anonfun$process$1.apply$mcZ$sp(ILoop.scala:882)
        at scala.tools.nsc.interpreter.ILoop$$anonfun$process$1.apply(ILoop.scala:837)
        at scala.tools.nsc.interpreter.ILoop$$anonfun$process$1.apply(ILoop.scala:837)
        at scala.tools.nsc.util.ScalaClassLoader$.savingContextLoader(ScalaClassLoader.scala:135)
        at scala.tools.nsc.interpreter.ILoop.process(ILoop.scala:837)
        at scala.tools.nsc.MainGenericRunner.runTarget$1(MainGenericRunner.scala:83)
        at scala.tools.nsc.MainGenericRunner.process(MainGenericRunner.scala:96)
        at scala.tools.nsc.MainGenericRunner$.main(MainGenericRunner.scala:105)
        at scala.tools.nsc.MainGenericRunner.main(MainGenericRunner.scala)
Welcome to Scala version 2.11.4 (Java HotSpot(TM) 64-Bit Server VM, Java 1.7.0_67).
Type in expressions to have them evaluated.
Type :help for more information.
 
scala> :paste
// Entering paste mode (ctrl-D to finish)
 
import scala.language.experimental.macros
import scala.reflect.macros.Context
 
trait A{
  def x: Int = 1
}
 
 
object B {
  def impl(c: Context): c.Expr[Int] = {
    import c.universe._
    c.Expr[Int](Literal(Constant(2)))
  }
}
 
class B extends A {
  override def x: Int = macro B.impl
}
 
// Exiting paste mode, now interpreting.
 
warning: there was one deprecation warning; re-run with -deprecation for details
import scala.language.experimental.macros
import scala.reflect.macros.Context
defined trait A
defined object B
defined class B
 
scala> val b = new B
b: B = B@a7d060f
 
scala> b.x
res0: Int = 2
 
scala> (b: A).x
java.lang.AbstractMethodError: B.x()I
  ... 33 elided
@scabug
Copy link
Author

scabug commented Oct 30, 2014

Imported From: https://issues.scala-lang.org/browse/SI-8949?orig=1
Reporter: kenji yoshida
Affected Versions: 2.10.4, 2.11.4

@scabug
Copy link
Author

scabug commented Oct 30, 2014

@retronym said:
As recently discussed https://groups.google.com/forum/#!msg/scala-user/lo_OXRluQEQ/PTY87UGwJKgJ we might consider restricting macro declarations so that they can't override an existing method. There are use cases for this, however, so we have to be careful.

@scabug
Copy link
Author

scabug commented Oct 30, 2014

kenji yoshida said:
similar example

Welcome to Scala version 2.11.4 (Java HotSpot(TM) 64-Bit Server VM, Java 1.7.0_67).
Type in expressions to have them evaluated.
Type :help for more information.

scala> :paste
// Entering paste mode (ctrl-D to finish)

import scala.language.experimental.macros
import scala.reflect.macros.Context
 
object A {
  def impl(c: Context): c.Expr[Int] = {
    import c.universe._
    c.Expr[Int](Literal(Constant(2)))
  }
}

class A {
  def x: Int = macro A.impl
}


// Exiting paste mode, now interpreting.

warning: there was one deprecation warning; re-run with -deprecation for details
import scala.language.experimental.macros
import scala.reflect.macros.Context
defined object A
defined class A

scala> val a0 = new A
a0: A = A@34aad3ab

scala> a0.x
res0: Int = 2

scala> val a1: {def x: Int} = a0
a1: AnyRef{def x: Int} = A@34aad3ab

scala> a1.x
warning: there was one feature warning; re-run with -feature for details
java.lang.NoSuchMethodException: A.x()
  at java.lang.Class.getMethod(Class.java:1665)
  at .reflMethod$Method1(<console>:16)
  ... 33 elided

@scabug
Copy link
Author

scabug commented Nov 4, 2016

kenji yoshida said:
in Scala 2.12.0

Welcome to Scala 2.12.0 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_112).
Type in expressions for evaluation. Or try :help.

scala> :paste
// Entering paste mode (ctrl-D to finish)

import scala.language.experimental.macros
import scala.reflect.macros.Context
  
trait A{
  def x: Int = 1
}
  
  
object B {
  def impl(c: Context): c.Expr[Int] = {
    import c.universe._
    c.Expr[Int](Literal(Constant(2)))
  }
}
  
class B extends A {
  override def x: Int = macro B.impl
}

// Exiting paste mode, now interpreting.

<console>:20: warning: type Context in package macros is deprecated (since 2.11.0): use blackbox.Context or whitebox.Context instead
         def impl(c: Context): c.Expr[Int] = {
                     ^
import scala.language.experimental.macros
import scala.reflect.macros.Context
defined trait A
defined object B
defined class B

scala> val b = new B
b: B = B@552cede7

scala> b.x
res0: Int = 2

scala> (b: A).x
res1: Int = 1

@scabug scabug added the macros label Apr 7, 2017
@scabug scabug added this to the Backlog milestone Apr 7, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants