summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/compiler/scala/tools/nsc/backend/icode/GenICode.scala20
-rw-r--r--test/files/run/t4560b.check2
-rw-r--r--test/files/run/t4560b.scala28
3 files changed, 45 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 {
diff --git a/test/files/run/t4560b.check b/test/files/run/t4560b.check
new file mode 100644
index 0000000000..7ee6e19b28
--- /dev/null
+++ b/test/files/run/t4560b.check
@@ -0,0 +1,2 @@
+23
+SUCCESS
diff --git a/test/files/run/t4560b.scala b/test/files/run/t4560b.scala
new file mode 100644
index 0000000000..97fe00ce37
--- /dev/null
+++ b/test/files/run/t4560b.scala
@@ -0,0 +1,28 @@
+object Outer {
+ class Tester
+ private[Outer] trait B4 { _: Tester =>
+ protected val FREQ = 23
+ def fail() = {
+ println(FREQ)
+ }
+ }
+ object C4 extends Tester with B4
+}
+
+object Outer2 {
+ abstract class A5
+ private[Outer2] trait C5 {
+ def impl() { println("SUCCESS") }
+ }
+ trait B5 extends C5 { self: A5 =>
+ def fail() { impl() }
+ }
+ object Test5 extends A5 with B5 with C5
+}
+
+object Test {
+ def main(args: Array[String]): Unit = {
+ Outer.C4.fail()
+ Outer2.Test5.fail()
+ }
+}