summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJosh Suereth <Joshua.Suereth@gmail.com>2012-07-29 07:16:23 -0700
committerJosh Suereth <Joshua.Suereth@gmail.com>2012-07-29 07:16:23 -0700
commite95691996d3df58499491db6c5b6d386b64cefdc (patch)
treed5aca3dfa840e452e0f74a2026e68d59e0afbdcc /src
parent9cf4dd6bbeccc6a1ec2e8dbdbcf9aaa59b5bf91f (diff)
parentcf709c2dd23b7f1f659e52bcb8beb098c5d02d50 (diff)
downloadscala-e95691996d3df58499491db6c5b6d386b64cefdc.tar.gz
scala-e95691996d3df58499491db6c5b6d386b64cefdc.tar.bz2
scala-e95691996d3df58499491db6c5b6d386b64cefdc.zip
Merge pull request #988 from paulp/issue/4560
Issue/4560
Diffstat (limited to 'src')
-rw-r--r--src/compiler/scala/tools/nsc/backend/icode/GenICode.scala20
-rw-r--r--src/compiler/scala/tools/nsc/transform/CleanUp.scala47
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Contexts.scala1
-rw-r--r--src/reflect/scala/reflect/internal/Types.scala8
4 files changed, 33 insertions, 43 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/src/compiler/scala/tools/nsc/transform/CleanUp.scala b/src/compiler/scala/tools/nsc/transform/CleanUp.scala
index e672f1914a..108c5ced6f 100644
--- a/src/compiler/scala/tools/nsc/transform/CleanUp.scala
+++ b/src/compiler/scala/tools/nsc/transform/CleanUp.scala
@@ -58,23 +58,6 @@ abstract class CleanUp extends Transform with ast.TreeDSL {
}
private def mkTerm(prefix: String): TermName = unit.freshTermName(prefix)
- /** Kludge to provide a safe fix for #4560:
- * If we generate a reference in an implementation class, we
- * watch out for embedded This(..) nodes that point to the interface.
- * These must be wrong. We fix them by setting symbol and type to
- * the enclosing implementation class instead.
- */
- def safeREF(sym: Symbol) = {
- def fix(tree: Tree): Unit = tree match {
- case Select(qual @ This(_), name) if qual.symbol != currentClass =>
- qual.setSymbol(currentClass).setType(currentClass.tpe)
- case _ =>
- }
- val tree = REF(sym)
- if (currentClass.isImplClass && sym.owner == currentClass) fix(tree)
- tree
- }
-
//private val classConstantMeth = new HashMap[String, Symbol]
//private val symbolStaticFields = new HashMap[String, (Symbol, Tree, Tree)]
@@ -164,7 +147,7 @@ abstract class CleanUp extends Transform with ast.TreeDSL {
val varDef = typedPos( VAL(varSym) === forInit )
newStaticMembers append transform(varDef)
- val varInit = typedPos( safeREF(varSym) === forInit )
+ val varInit = typedPos( REF(varSym) === forInit )
newStaticInits append transform(varInit)
varSym
@@ -200,7 +183,7 @@ abstract class CleanUp extends Transform with ast.TreeDSL {
addStaticVariableToClass(nme.reflParamsCacheName, arrayType(ClassClass.tpe), fromTypesToClassArrayLiteral(paramTypes), true)
addStaticMethodToClass((_, forReceiverSym) =>
- gen.mkMethodCall(REF(forReceiverSym), Class_getMethod, Nil, List(LIT(method), safeREF(reflParamsCacheSym)))
+ gen.mkMethodCall(REF(forReceiverSym), Class_getMethod, Nil, List(LIT(method), REF(reflParamsCacheSym)))
)
case MONO_CACHE =>
@@ -239,11 +222,11 @@ abstract class CleanUp extends Transform with ast.TreeDSL {
addStaticMethodToClass((_, forReceiverSym) =>
BLOCK(
IF (isCacheEmpty(forReceiverSym)) THEN BLOCK(
- safeREF(reflMethodCacheSym) === ((REF(forReceiverSym) DOT Class_getMethod)(LIT(method), safeREF(reflParamsCacheSym))) ,
- safeREF(reflClassCacheSym) === gen.mkSoftRef(REF(forReceiverSym)),
+ REF(reflMethodCacheSym) === ((REF(forReceiverSym) DOT Class_getMethod)(LIT(method), REF(reflParamsCacheSym))) ,
+ REF(reflClassCacheSym) === gen.mkSoftRef(REF(forReceiverSym)),
UNIT
) ENDIF,
- safeREF(reflMethodCacheSym)
+ REF(reflMethodCacheSym)
)
)
@@ -277,22 +260,22 @@ abstract class CleanUp extends Transform with ast.TreeDSL {
val reflPolyCacheSym: Symbol = (
addStaticVariableToClass(nme.reflPolyCacheName, SoftReferenceClass.tpe, mkNewPolyCache, false)
)
- def getPolyCache = gen.mkCast(fn(safeREF(reflPolyCacheSym), nme.get), MethodCacheClass.tpe)
+ def getPolyCache = gen.mkCast(fn(REF(reflPolyCacheSym), nme.get), MethodCacheClass.tpe)
addStaticMethodToClass((reflMethodSym, forReceiverSym) => {
val methodSym = reflMethodSym.newVariable(mkTerm("method"), ad.pos) setInfo MethodClass.tpe
BLOCK(
- IF (getPolyCache OBJ_EQ NULL) THEN (safeREF(reflPolyCacheSym) === mkNewPolyCache) ENDIF,
+ IF (getPolyCache OBJ_EQ NULL) THEN (REF(reflPolyCacheSym) === mkNewPolyCache) ENDIF,
VAL(methodSym) === ((getPolyCache DOT methodCache_find)(REF(forReceiverSym))) ,
IF (REF(methodSym) OBJ_!= NULL) .
THEN (Return(REF(methodSym)))
ELSE {
- def methodSymRHS = ((REF(forReceiverSym) DOT Class_getMethod)(LIT(method), safeREF(reflParamsCacheSym)))
+ def methodSymRHS = ((REF(forReceiverSym) DOT Class_getMethod)(LIT(method), REF(reflParamsCacheSym)))
def cacheRHS = ((getPolyCache DOT methodCache_add)(REF(forReceiverSym), REF(methodSym)))
BLOCK(
REF(methodSym) === (REF(ensureAccessibleMethod) APPLY (methodSymRHS)),
- safeREF(reflPolyCacheSym) === gen.mkSoftRef(cacheRHS),
+ REF(reflPolyCacheSym) === gen.mkSoftRef(cacheRHS),
Return(REF(methodSym))
)
}
@@ -400,7 +383,7 @@ abstract class CleanUp extends Transform with ast.TreeDSL {
def genDefaultCall = {
// reflective method call machinery
val invokeName = MethodClass.tpe member nme.invoke_ // reflect.Method.invoke(...)
- def cache = safeREF(reflectiveMethodCache(ad.symbol.name.toString, paramTypes)) // cache Symbol
+ def cache = REF(reflectiveMethodCache(ad.symbol.name.toString, paramTypes)) // cache Symbol
def lookup = Apply(cache, List(qual1() GETCLASS)) // get Method object from cache
def invokeArgs = ArrayValue(TypeTree(ObjectClass.tpe), params) // args for invocation
def invocation = (lookup DOT invokeName)(qual1(), invokeArgs) // .invoke(qual1, ...)
@@ -495,7 +478,7 @@ abstract class CleanUp extends Transform with ast.TreeDSL {
typedPos {
val sym = currentOwner.newValue(mkTerm("qual"), ad.pos) setInfo qual0.tpe
- qual = safeREF(sym)
+ qual = REF(sym)
BLOCK(
VAL(sym) === qual0,
@@ -678,7 +661,7 @@ abstract class CleanUp extends Transform with ast.TreeDSL {
val rhs = gen.mkMethodCall(Symbol_apply, arg :: Nil)
val staticFieldSym = getSymbolStaticField(tree.pos, symname, rhs, tree)
// create a reference to a static field
- val ntree = typedWithPos(tree.pos)(safeREF(staticFieldSym))
+ val ntree = typedWithPos(tree.pos)(REF(staticFieldSym))
super.transform(ntree)
// This transform replaces Array(Predef.wrapArray(Array(...)), <tag>)
@@ -711,7 +694,7 @@ abstract class CleanUp extends Transform with ast.TreeDSL {
// create field definition and initialization
val stfieldDef = theTyper.typedPos(pos)(VAL(stfieldSym) === rhs)
- val stfieldInit = theTyper.typedPos(pos)(safeREF(stfieldSym) === rhs)
+ val stfieldInit = theTyper.typedPos(pos)(REF(stfieldSym) === rhs)
// add field definition to new defs
newStaticMembers append stfieldDef
@@ -777,8 +760,8 @@ abstract class CleanUp extends Transform with ast.TreeDSL {
val stfieldDef = localTyper.typedPos(tree.pos)(VAL(stfieldSym) === EmptyTree)
val flattenedInit = fixedrhs match {
- case Block(stats, expr) => Block(stats, safeREF(stfieldSym) === expr)
- case rhs => safeREF(stfieldSym) === rhs
+ case Block(stats, expr) => Block(stats, REF(stfieldSym) === expr)
+ case rhs => REF(stfieldSym) === rhs
}
val stfieldInit = localTyper.typedPos(tree.pos)(flattenedInit)
diff --git a/src/compiler/scala/tools/nsc/typechecker/Contexts.scala b/src/compiler/scala/tools/nsc/typechecker/Contexts.scala
index 805f60ba87..0fc298e886 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Contexts.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Contexts.scala
@@ -552,7 +552,6 @@ trait Contexts { self: Analyzer =>
( (ab.isTerm || ab == rootMirror.RootClass)
|| (accessWithin(ab) || accessWithinLinked(ab)) &&
( !sym.hasLocalFlag
- || sym.owner.isImplClass // allow private local accesses to impl classes
|| sym.isProtected && isSubThisType(pre, sym.owner)
|| pre =:= sym.owner.thisType
)
diff --git a/src/reflect/scala/reflect/internal/Types.scala b/src/reflect/scala/reflect/internal/Types.scala
index 14a9fe6701..3a218c18f1 100644
--- a/src/reflect/scala/reflect/internal/Types.scala
+++ b/src/reflect/scala/reflect/internal/Types.scala
@@ -1392,11 +1392,9 @@ trait Types extends api.Types { self: SymbolTable =>
final class UniqueThisType(sym: Symbol) extends ThisType(sym) with UniqueType { }
object ThisType extends ThisTypeExtractor {
- def apply(sym: Symbol): Type = {
- if (!phase.erasedTypes) unique(new UniqueThisType(sym))
- else if (sym.isImplClass) sym.typeOfThis
- else sym.tpe
- }
+ def apply(sym: Symbol): Type =
+ if (phase.erasedTypes) sym.tpe
+ else unique(new UniqueThisType(sym))
}
/** A class for singleton types of the form `<prefix>.<sym.name>.type`.