diff options
author | Som Snytt <som.snytt@gmail.com> | 2012-04-05 02:58:40 -0700 |
---|---|---|
committer | Paul Phillips <paulp@improving.org> | 2012-04-06 11:57:41 -0700 |
commit | 72f6f0e57ca490b36cef62a3be2a8b3261476cd2 (patch) | |
tree | e140ee692080bed185ba99122b5890b736c1e573 /src/compiler/scala/tools/nsc/transform/Mixin.scala | |
parent | 581a2e1a9653b06b6d2c431070e6b1d21383285d (diff) | |
download | scala-72f6f0e57ca490b36cef62a3be2a8b3261476cd2.tar.gz scala-72f6f0e57ca490b36cef62a3be2a8b3261476cd2.tar.bz2 scala-72f6f0e57ca490b36cef62a3be2a8b3261476cd2.zip |
SI-4134: abstract override crasher if lacking super impl
The example from the ticket is committed as a neg test.
The problem is that a super.m on an abstract override
member m has no concrete implementation, that is, the
trait T is not mixed in after a class C with a concrete m.
The error is noticed at phase mixin when the super accessor
is added to the concrete mixer. (Pun alert?) When super.m
is rebound, no concrete matching symbol is found up the
linearization.
Previously, it was asserted that such a symbol should
be found, but since this is our first opportunity to
detect that there is none, an error should be emitted
instead. The new message is of the form:
Member method f of mixin trait T2 is missing a concrete super implementation.
Additionally, a couple of flag tests were changed to use isAbstractOverride.
Diffstat (limited to 'src/compiler/scala/tools/nsc/transform/Mixin.scala')
-rw-r--r-- | src/compiler/scala/tools/nsc/transform/Mixin.scala | 11 |
1 files changed, 6 insertions, 5 deletions
diff --git a/src/compiler/scala/tools/nsc/transform/Mixin.scala b/src/compiler/scala/tools/nsc/transform/Mixin.scala index adbb7d43d0..d0bba1d3c6 100644 --- a/src/compiler/scala/tools/nsc/transform/Mixin.scala +++ b/src/compiler/scala/tools/nsc/transform/Mixin.scala @@ -121,7 +121,7 @@ abstract class Mixin extends InfoTransform with ast.TreeDSL { * @param member The symbol statically referred to by the superaccessor in the trait * @param mixinClass The mixin class that produced the superaccessor */ - private def rebindSuper(base: Symbol, member: Symbol, mixinClass: Symbol): Symbol = + private def rebindSuper(base: Symbol, member: Symbol, mixinClass: Symbol): Option[Symbol] = afterPickler { var bcs = base.info.baseClasses.dropWhile(mixinClass !=).tail var sym: Symbol = NoSymbol @@ -136,8 +136,7 @@ abstract class Mixin extends InfoTransform with ast.TreeDSL { sym = member.matchingSymbol(bcs.head, base.thisType).suchThat(sym => !sym.hasFlag(DEFERRED | BRIDGE)) bcs = bcs.tail } - assert(sym != NoSymbol, member) - sym + if (sym != NoSymbol) Some(sym) else None } // --------- type transformation ----------------------------------------------- @@ -339,8 +338,10 @@ abstract class Mixin extends InfoTransform with ast.TreeDSL { else if (mixinMember.isSuperAccessor) { // mixin super accessors val superAccessor = addMember(clazz, mixinMember.cloneSymbol(clazz)) setPos clazz.pos assert(superAccessor.alias != NoSymbol, superAccessor) - val alias1 = rebindSuper(clazz, mixinMember.alias, mixinClass) - superAccessor.asInstanceOf[TermSymbol] setAlias alias1 + rebindSuper(clazz, mixinMember.alias, mixinClass) match { + case Some(alias1) => superAccessor.asInstanceOf[TermSymbol] setAlias alias1 + case None => unit.error(clazz.pos, "Member "+ mixinMember.alias +" of mixin "+ mixinClass +" is missing a concrete super implementation.") + } } else if (mixinMember.isMethod && mixinMember.isModule && mixinMember.hasNoFlags(LIFTED | BRIDGE)) { // mixin objects: todo what happens with abstract objects? |