summaryrefslogtreecommitdiff
path: root/src/compiler
diff options
context:
space:
mode:
authorIulian Dragos <jaguarul@gmail.com>2006-12-12 11:06:03 +0000
committerIulian Dragos <jaguarul@gmail.com>2006-12-12 11:06:03 +0000
commit9551ed8f5854ddad14a759ae7c5268b2883155b8 (patch)
tree0bb6d77d016f17a69bb19007ff3a99b3b8ca51b2 /src/compiler
parent5916f8929a40b3409a9e7cc41257126d278ec92a (diff)
downloadscala-9551ed8f5854ddad14a759ae7c5268b2883155b8.tar.gz
scala-9551ed8f5854ddad14a759ae7c5268b2883155b8.tar.bz2
scala-9551ed8f5854ddad14a759ae7c5268b2883155b8.zip
Fixed bug 853, protected accessors crash with p...
Fixed bug 853, protected accessors crash with path dependent types.
Diffstat (limited to 'src/compiler')
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala29
1 files changed, 25 insertions, 4 deletions
diff --git a/src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala b/src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala
index e41da55549..51ed171076 100644
--- a/src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala
@@ -187,9 +187,12 @@ abstract class SuperAccessors extends transform.Transform with transform.TypingT
val hasArgs = sym.tpe.paramTypes != Nil
if (protAcc == NoSymbol) {
val argTypes = tree.tpe // transform(sym.tpe)
+ // if the result type depends on the this type of an enclosing class, the accessor
+ // has to take an object of exactly this type, otherwise it's more general
+ val objType = if (isThisType(argTypes.finalResultType)) clazz.thisType else clazz.typeOfThis
protAcc = clazz.newMethod(tree.pos, nme.protName(sym.originalName))
- .setInfo(MethodType(List(clazz.typeOfThis),argTypes))
+ .setInfo(MethodType(List(objType),argTypes))
clazz.info.decls.enter(protAcc);
val code = DefDef(protAcc, vparamss => {
val obj = vparamss.head.head
@@ -220,14 +223,17 @@ abstract class SuperAccessors extends transform.Transform with transform.TypingT
*/
private def makeArg(v: Symbol, obj: Symbol, expectedTpe: Type): Tree = {
val res = Ident(v)
- val sym = v.tpe.symbol
+ val sym = obj.tpe.symbol
+ var ownerClass: Symbol = NoSymbol
val isDependentType = expectedTpe match {
- case TypeRef(ThisType(outerSym), _, _) if (obj.isSubClass(outerSym)) => true
+ case TypeRef(path, _, _) =>
+ ownerClass = thisTypeOfPath(path)
+ if (sym.isSubClass(ownerClass)) true else false
case _ => false
}
if (isDependentType) {
- val preciseTpe = typeRef(singleType(NoPrefix, obj), v.tpe.symbol, List())
+ val preciseTpe = expectedTpe.asSeenFrom(singleType(NoPrefix, obj), ownerClass) //typeRef(singleType(NoPrefix, obj), v.tpe.symbol, List())
TypeApply(Select(res, definitions.Any_asInstanceOf),
List(TypeTree(preciseTpe)))
}
@@ -235,6 +241,13 @@ abstract class SuperAccessors extends transform.Transform with transform.TypingT
res
}
+ /** For a path-dependent type, return the this type. */
+ private def thisTypeOfPath(path: Type): Symbol = path match {
+ case ThisType(outerSym) => outerSym
+ case SingleType(rest, _) => thisTypeOfPath(rest)
+ case _ => NoSymbol
+ }
+
/** Add an accessor for field, if needed, and return a selection tree for it .
* The result is not typed.
*/
@@ -311,5 +324,13 @@ abstract class SuperAccessors extends transform.Transform with transform.TypingT
} else
hostForAccessorOf(sym, referencingClass.owner.enclClass)
}
+
+ /** Is 'tpe' the type of a member of an enclosing class? */
+ private def isThisType(tpe: Type): Boolean = tpe match {
+ case ThisType(sym) => (sym.isClass && !sym.isPackageClass)
+ case TypeRef(pref, _, _) => isThisType(pref)
+ case SingleType(pref, _) => isThisType(pref)
+ case _ => false
+ }
}
}