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

resolveOverloaded thows ClassCastException if the alternatives contain objects #6066

Closed
scabug opened this issue Jul 11, 2012 · 4 comments
Closed
Assignees
Milestone

Comments

@scabug
Copy link

scabug commented Jul 11, 2012

Consider the following class with the overloaded symbol foo:

class B {
  object foo {
    def apply(x: Int) = 2
  }
}
class C extends B {
  def foo(x: Int) = 1
}

Invocation of method foo with an integer argument returns 1:

scala> new C().foo(42)
res0: Int = 1

Invocation of resolveOverload on the term symbol foo however throws a ClassCastExceptipon. The reason is, that resolveOverload currently only expects method symbols in the alternatives, but this is not guaranteed.

scala> import scala.reflect.runtime.universe._
import scala.reflect.runtime.universe._

scala> import scala.reflect.runtime.{ currentMirror => cm }
import scala.reflect.runtime.{currentMirror=>cm}

scala> class B {
     |   object foo {
     |     def apply(x: Int) = 2
     |   }
     | }
defined class B

scala> class C extends B {
     |   def foo(x: Int) = 1
     | }
defined class C

scala> val x = new C
x: C = C@3040c5

scala> x.foo(42)
res0: Int = 1

scala> val t = typeOf[C]
t: reflect.runtime.universe.Type = C

scala> val foo = t.member(newTermName("foo")).asTermSymbol
foo: reflect.runtime.universe.TermSymbol = value foo

scala> foo.alternatives.size
res1: Int = 2

scala> foo.alternatives.map(_.isMethod)
res2: List[Boolean] = List(true, false)

scala> foo.alternatives.map(_.isModule)
res3: List[Boolean] = List(false, true)

scala> val fooSym = foo.resolveOverloaded(posVargs = List(typeOf[Int]))
java.lang.ClassCastException: object foo
        at scala.reflect.base.Symbols$SymbolBase$class.asMethodSymbol(Symbols.scala:159)
        at scala.reflect.internal.Symbols$SymbolContextApiImpl.asMethodSymbol(Symbols.scala:62)
        at scala.reflect.internal.Symbols$SymbolContextApiImpl$$anonfun$21.apply(Symbols.scala:362)
        at scala.reflect.internal.Symbols$SymbolContextApiImpl$$anonfun$21.apply(Symbols.scala:362)
        at scala.collection.TraversableLike$$anonfun$map$1.apply(TraversableLike.scala:239)
        at scala.collection.TraversableLike$$anonfun$map$1.apply(TraversableLike.scala:239)
        at scala.collection.LinearSeqOptimized$class.foreach(LinearSeqOptimized.scala:59)
        at scala.collection.immutable.List.foreach(List.scala:77)
        at scala.collection.TraversableLike$class.map(TraversableLike.scala:239)
        at scala.collection.AbstractTraversable.map(Traversable.scala:105)
        at scala.reflect.internal.Symbols$SymbolContextApiImpl.resolveOverloaded(Symbols.scala:362)
        at scala.reflect.internal.Symbols$TermSymbol.resolveOverloaded(Symbols.scala:2543)
        at .<init>(<console>:15)
        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:736)
        at scala.tools.nsc.interpreter.IMain$Request.loadAndRun(IMain.scala:991)
        at scala.tools.nsc.interpreter.IMain.loadAndRunReq$1(IMain.scala:579)
        at scala.tools.nsc.interpreter.IMain.interpret(IMain.scala:610)
        at scala.tools.nsc.interpreter.IMain.interpret(IMain.scala:574)
        at scala.tools.nsc.interpreter.ILoop.reallyInterpret$1(ILoop.scala:742)
        at scala.tools.nsc.interpreter.ILoop.interpretStartingWith(ILoop.scala:787)
        at scala.tools.nsc.interpreter.ILoop.command(ILoop.scala:699)
        at scala.tools.nsc.interpreter.ILoop.processLine$1(ILoop.scala:563)
        at scala.tools.nsc.interpreter.ILoop.innerLoop$1(ILoop.scala:570)
        at scala.tools.nsc.interpreter.ILoop.loop(ILoop.scala:573)
        at scala.tools.nsc.interpreter.ILoop$$anonfun$process$1.apply$mcZ$sp(ILoop.scala:864)
        at scala.tools.nsc.interpreter.ILoop$$anonfun$process$1.apply(ILoop.scala:819)
        at scala.tools.nsc.interpreter.ILoop$$anonfun$process$1.apply(ILoop.scala:819)
        at scala.tools.nsc.util.ScalaClassLoader$.savingContextLoader(ScalaClassLoader.scala:135)
        at scala.tools.nsc.interpreter.ILoop.process(ILoop.scala:819)
        at scala.tools.nsc.MainGenericRunner.runTarget$1(MainGenericRunner.scala:79)
        at scala.tools.nsc.MainGenericRunner.process(MainGenericRunner.scala:92)
        at scala.tools.nsc.MainGenericRunner$.main(MainGenericRunner.scala:101)
        at scala.tools.nsc.MainGenericRunner.main(MainGenericRunner.scala){code}
In order to reproduce this bug use the following input:

import scala.reflect.runtime.universe._
import scala.reflect.runtime.{ currentMirror => cm }
class B {
object foo {
def apply(x: Int) = 2
}
}
class C extends B {
def foo(x: Int) = 1
}
val x = new C
x.foo(42)
val t = typeOf[C]
val foo = t.member(newTermName("foo")).asTermSymbol
foo.alternatives.size
foo.alternatives.map(.isMethod)
foo.alternatives.map(
.isModule)
val fooSym = foo.resolveOverloaded(posVargs = List(typeOf[Int]))
{code}

@scabug
Copy link
Author

scabug commented Jul 11, 2012

Imported From: https://issues.scala-lang.org/browse/SI-6066?orig=1
Reporter: @dgruntz
Affected Versions: 2.10.0

@scabug
Copy link
Author

scabug commented Jul 11, 2012

@dgruntz said:
Actually, I wanted to define object foo as an extension of Int => Int, but in this case the result in the alternatives list is also an object.

class B {
  object foo extends (Int => Int){
    def apply(x: Int) = 2
  }
}

@scabug
Copy link
Author

scabug commented Jul 12, 2012

@clhodapp said:
I am on vacation now, but I will definitely try to do something about this by next week.

@scabug
Copy link
Author

scabug commented Jul 24, 2012

@xeno-by said:
No longer critical, since resolveOverloaded is being removed from 2.10.0: scala/scala#960

@scabug scabug closed this as completed Jul 26, 2012
@scabug scabug added this to the 2.10.0 milestone Apr 7, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants