diff options
author | Martin Odersky <odersky@gmail.com> | 2006-08-14 15:37:17 +0000 |
---|---|---|
committer | Martin Odersky <odersky@gmail.com> | 2006-08-14 15:37:17 +0000 |
commit | 9a73f4c8d4e3079b8dd31e74913687faf0ca2bc5 (patch) | |
tree | 8f5ab97601eabdc7cc935b30523fc474f6bd7be3 /src | |
parent | 28113d4604f1a403aa7611028ab8fcc217c3449c (diff) | |
download | scala-9a73f4c8d4e3079b8dd31e74913687faf0ca2bc5.tar.gz scala-9a73f4c8d4e3079b8dd31e74913687faf0ca2bc5.tar.bz2 scala-9a73f4c8d4e3079b8dd31e74913687faf0ca2bc5.zip |
Diffstat (limited to 'src')
-rw-r--r-- | src/compiler/scala/tools/nsc/typechecker/RefChecks.scala | 30 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala | 13 |
2 files changed, 13 insertions, 30 deletions
diff --git a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala index 3bc224cc98..8e798b31c1 100644 --- a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala +++ b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala @@ -593,35 +593,9 @@ abstract class RefChecks extends InfoTransform { result = toConstructor else qual match { case Super(qualifier, mix) => - val base = currentOwner.enclClass; - if (sym hasFlag DEFERRED) { - val member = sym.overridingSymbol(base);//??? - if (mix != nme.EMPTY.toTypeName || member == NoSymbol || - !((member hasFlag ABSOVERRIDE) && member.isIncompleteIn(base))) - unit.error(tree.pos, "symbol accessed from super may not be abstract"); - } + val base = qual.symbol; //System.out.println("super: " + tree + " in " + base);//DEBUG - if (base.isTrait && sym.isTerm && mix == nme.EMPTY.toTypeName) { - val superAccName = nme.superName(sym.name); - val superAcc = base.info.decl(superAccName) suchThat (.alias.==(sym)); - val tree1 = Select(This(base), superAcc); - if (settings.debug.value) log("super-replacement: " + tree + "=>" + tree1); - result = atPos(tree.pos) { - Select(gen.mkAttributedThis(base), superAcc) setType superAcc.tpe - } - } -/* - case This(_) => - if ((sym hasFlag PARAMACCESSOR) && (sym.alias != NoSymbol)) { - result = typed { - Select( - Super(qual.symbol, qual.symbol.info.parents.head.symbol.name) setPos qual.pos, - sym.alias) setPos tree.pos - } - if (settings.debug.value) - System.out.println("alias replacement: " + tree + " ==> " + result);//debug - } -*/ + assert(!(base.isTrait && sym.isTerm && mix == nme.EMPTY.toTypeName)) // term should have been eliminated by super accessors case _ => } case _ => diff --git a/src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala b/src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala index 59dad92a0d..37163a18d8 100644 --- a/src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala +++ b/src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala @@ -12,6 +12,8 @@ import nsc.symtab.Flags._; * either appear in a trait or have as a target a member of some outer class. * It also replaces references to parameter accessors with aliases by super * references to these aliases. + * The phase also checks that symbols accessed from super are not abstract, + * or are overridden by an abstract override. */ abstract class SuperAccessors extends transform.Transform { // inherits abstract value `global' and class `Phase' from Transform @@ -23,9 +25,9 @@ abstract class SuperAccessors extends transform.Transform { /** the following two members override abstract members in Transform */ val phaseName: String = "superaccessors"; - protected def newTransformer(unit: CompilationUnit): Transformer = new SuperAccTransformer; + protected def newTransformer(unit: CompilationUnit): Transformer = new SuperAccTransformer(unit); - class SuperAccTransformer extends Transformer { + class SuperAccTransformer(unit: CompilationUnit) extends Transformer { private var validCurrentOwner = true; private var accDefs: List[Pair[Symbol, ListBuffer[Tree]]] = List(); @@ -61,6 +63,13 @@ abstract class SuperAccessors extends transform.Transform { case Select(sup @ Super(_, mix), name) => val sym = tree.symbol; val clazz = sup.symbol; + if (sym hasFlag DEFERRED) { + val member = sym.overridingSymbol(clazz); + if (mix != nme.EMPTY.toTypeName || member == NoSymbol || + !((member hasFlag ABSOVERRIDE) && member.isIncompleteIn(clazz))) + unit.error(tree.pos, ""+member+member.locationString+" is accessed from super. It may not be abstract "+ + "unless it is overridden by a member declared `abstract' and `override'"); + } if (tree.isTerm && mix == nme.EMPTY.toTypeName && (clazz.isTrait || clazz != currentOwner.enclClass || !validCurrentOwner)) { val supername = nme.superName(sym.name); |