summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorPaul Phillips <paulp@improving.org>2012-07-24 16:54:07 -0700
committerPaul Phillips <paulp@improving.org>2012-07-24 20:45:01 -0700
commit6eb55d4b7ab804ba581157ed39df42ded885a12e (patch)
tree73e2c32c11695ea5e222a8f378261f1cdcd0e617 /src
parent392438b77ea4961c919e3115055336ce6fca85af (diff)
downloadscala-6eb55d4b7ab804ba581157ed39df42ded885a12e.tar.gz
scala-6eb55d4b7ab804ba581157ed39df42ded885a12e.tar.bz2
scala-6eb55d4b7ab804ba581157ed39df42ded885a12e.zip
Fix SI-4560, NoSuchMethodErrors involving self types.
Following this commit are reversions of three prior commits which introduced difficulties of their own, plus extra tests for this issue and SI-4601, all of which I pinched from jrudolph. Maybe there was a good reason for some of the complicated code related to this ticket. I took the naive position that if we avoided generating a method call to a particular receiver if the receiver has no such method, we would encounter fewer NoSuchMethodErrors. I would believe one can construct a scenario which this doesn't handle correctly, but it's hard to believe this isn't a big improvement. Review by @jrudolph, @odersky.
Diffstat (limited to 'src')
-rw-r--r--src/compiler/scala/tools/nsc/backend/icode/GenICode.scala20
1 files changed, 15 insertions, 5 deletions
diff --git a/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala b/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala
index 982267097b..c46b650949 100644
--- a/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala
+++ b/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala
@@ -73,6 +73,14 @@ abstract class GenICode extends SubComponent {
ctx1
}
+ /** If the selector type has a member with the right name,
+ * it is the host class; otherwise the symbol's owner.
+ */
+ def findHostClass(selector: Type, sym: Symbol) = selector member sym.name match {
+ case NoSymbol => log(s"Rejecting $selector as host class for $sym") ; sym.owner
+ case _ => selector.typeSymbol
+ }
+
/////////////////// Code generation ///////////////////////
def gen(tree: Tree, ctx: Context): Context = tree match {
@@ -949,13 +957,14 @@ abstract class GenICode extends SubComponent {
*/
fun match {
case Select(qual, _) =>
- val qualSym = qual.tpe.typeSymbol
+ val qualSym = findHostClass(qual.tpe, sym)
+
if (qualSym == ArrayClass) cm setTargetTypeKind toTypeKind(qual.tpe)
else cm setHostClass qualSym
- debuglog(
+ log(
if (qualSym == ArrayClass) "Stored target type kind " + toTypeKind(qual.tpe) + " for " + sym.fullName
- else "Set more precise host class for " + sym.fullName + " host: " + qualSym
+ else s"Set more precise host class for ${sym.fullName} hostClass: $qualSym"
)
case _ =>
}
@@ -1005,13 +1014,14 @@ abstract class GenICode extends SubComponent {
case Select(qualifier, selector) =>
val sym = tree.symbol
generatedType = toTypeKind(sym.info)
- val hostClass = qualifier.tpe.typeSymbol.orElse(sym.owner)
+ val hostClass = findHostClass(qualifier.tpe, sym)
+ log(s"Host class of $sym with qual $qualifier (${qualifier.tpe}) is $hostClass")
if (sym.isModule) {
genLoadModule(ctx, tree)
}
else if (sym.isStaticMember) {
- ctx.bb.emit(LOAD_FIELD(sym, true) setHostClass hostClass, tree.pos)
+ ctx.bb.emit(LOAD_FIELD(sym, true) setHostClass hostClass, tree.pos)
ctx
}
else {