@@ -371,17 +371,14 @@ abstract class Erasure extends AddInterfaces
371371 val opc = enteringExplicitOuter {
372372 new overridingPairs.Cursor (root) {
373373 override def parents = List (root.info.firstParent)
374- override def exclude (sym : Symbol ) = ! sym.isMethod || sym.isPrivate || super .exclude(sym)
374+ override def exclude (sym : Symbol ) = ! sym.isMethod || super .exclude(sym)
375375 }
376376 }
377377
378378 def compute (): (List [Tree ], immutable.Set [Symbol ]) = {
379379 while (opc.hasNext) {
380- val member = opc.overriding
381- val other = opc.overridden
382- // println("bridge? " + member + ":" + member.tpe + member.locationString + " to " + other + ":" + other.tpe + other.locationString)//DEBUG
383- if (enteringExplicitOuter(! member.isDeferred))
384- checkPair(member, other)
380+ if (enteringExplicitOuter(! opc.low.isDeferred))
381+ checkPair(opc.currentPair)
385382
386383 opc.next()
387384 }
@@ -438,8 +435,15 @@ abstract class Erasure extends AddInterfaces
438435 noclash
439436 }
440437
441- def checkPair (member : Symbol , other : Symbol ) {
442- val otpe = specialErasure(root)(other.tpe)
438+ /** TODO - work through this logic with a fine-toothed comb, incorporating
439+ * into SymbolPairs where appropriate.
440+ */
441+ def checkPair (pair : SymbolPair ) {
442+ import pair ._
443+ val member = low
444+ val other = high
445+ val otpe = highErased
446+
443447 val bridgeNeeded = exitingErasure (
444448 ! member.isMacro &&
445449 ! (other.tpe =:= member.tpe) &&
@@ -844,88 +848,75 @@ abstract class Erasure extends AddInterfaces
844848
845849 /** The erasure transformer */
846850 class ErasureTransformer (unit : CompilationUnit ) extends Transformer {
847- /** Emit an error if there is a double definition. This can happen if:
848- *
849- * - A template defines two members with the same name and erased type.
850- * - A template defines and inherits two members `m` with different types,
851- * but their erased types are the same.
852- * - A template inherits two members `m` with different types,
853- * but their erased types are the same.
854- */
855- private def checkNoDoubleDefs (root : Symbol ) {
856- def doubleDefError (sym1 : Symbol , sym2 : Symbol ) {
857- // the .toString must also be computed at the earlier phase
858- val tpe1 = exitingRefchecks(root.thisType.memberType(sym1))
859- val tpe2 = exitingRefchecks(root.thisType.memberType(sym2))
860- if (! tpe1.isErroneous && ! tpe2.isErroneous)
861- unit.error(
862- if (sym1.owner == root) sym1.pos else root.pos,
863- (if (sym1.owner == sym2.owner) " double definition:\n "
864- else if (sym1.owner == root) " name clash between defined and inherited member:\n "
865- else " name clash between inherited members:\n " ) +
866- sym1 + " :" + exitingRefchecks(tpe1.toString) +
867- (if (sym1.owner == root) " " else sym1.locationString) + " and\n " +
868- sym2 + " :" + exitingRefchecks(tpe2.toString) +
869- (if (sym2.owner == root) " at line " + (sym2.pos).line else sym2.locationString) +
870- " \n have same type" +
871- (if (exitingRefchecks(tpe1 =:= tpe2)) " " else " after erasure: " + exitingPostErasure(sym1.tpe)))
872- sym1.setInfo(ErrorType )
851+ import overridingPairs .Cursor
852+
853+ private def doubleDefError (pair : SymbolPair ) {
854+ import pair ._
855+
856+ if (! pair.isErroneous) {
857+ val what = (
858+ if (low.owner == high.owner) " double definition"
859+ else if (low.owner == base) " name clash between defined and inherited member"
860+ else " name clash between inherited members"
861+ )
862+ val when = if (exitingRefchecks(lowType matches highType)) " " else " after erasure: " + exitingPostErasure(highType)
863+
864+ unit.error(pos,
865+ s """ | $what:
866+ | ${exitingRefchecks(highString)} and
867+ | ${exitingRefchecks(lowString)}
868+ |have same type $when""" .trim.stripMargin
869+ )
873870 }
871+ low setInfo ErrorType
872+ }
874873
875- val decls = root.info.decls
874+ /** TODO - adapt SymbolPairs so it can be used here. */
875+ private def checkNoDeclaredDoubleDefs (base : Symbol ) {
876+ val decls = base.info.decls
876877 var e = decls.elems
877878 while (e ne null ) {
878879 if (e.sym.isTerm) {
879- var e1 = decls. lookupNextEntry(e)
880+ var e1 = decls lookupNextEntry e
880881 while (e1 ne null ) {
881- if (exitingPostErasure(e1.sym.info =:= e.sym.info)) doubleDefError(e.sym, e1.sym)
882- e1 = decls.lookupNextEntry(e1)
882+ if (exitingPostErasure(e1.sym.info =:= e.sym.info))
883+ doubleDefError(new SymbolPair (base, e.sym, e1.sym))
884+
885+ e1 = decls lookupNextEntry e1
883886 }
884887 }
885888 e = e.next
886889 }
890+ }
887891
888- val opc = new overridingPairs.Cursor (root) {
892+ /** Emit an error if there is a double definition. This can happen if:
893+ *
894+ * - A template defines two members with the same name and erased type.
895+ * - A template defines and inherits two members `m` with different types,
896+ * but their erased types are the same.
897+ * - A template inherits two members `m` with different types,
898+ * but their erased types are the same.
899+ */
900+ private def checkNoDoubleDefs (root : Symbol ) {
901+ checkNoDeclaredDoubleDefs(root)
902+ object opc extends Cursor (root) {
903+ // specialized members have no type history before 'specialize', causing double def errors for curried defs
889904 override def exclude (sym : Symbol ): Boolean = (
890- ! sym.isTerm || sym.isPrivate || super .exclude(sym)
891- // specialized members have no type history before 'specialize', causing double def errors for curried defs
905+ sym.isType
906+ || sym.isPrivate
907+ || super .exclude(sym)
892908 || ! sym.hasTypeAt(currentRun.refchecksPhase.id)
893909 )
894-
895- override def matches (sym1 : Symbol , sym2 : Symbol ): Boolean =
896- exitingPostErasure(sym1.tpe =:= sym2.tpe)
910+ override def matches (sym1 : Symbol , sym2 : Symbol ) = true
897911 }
898- while (opc.hasNext) {
899- if (! exitingRefchecks(
900- root.thisType.memberType(opc.overriding) matches
901- root.thisType.memberType(opc.overridden))) {
902- debuglog(" " + opc.overriding.locationString + " " +
903- opc.overriding.infosString +
904- opc.overridden.locationString + " " +
905- opc.overridden.infosString)
906- doubleDefError(opc.overriding, opc.overridden)
907- }
908- opc.next()
912+ def sameTypeAfterErasure (pair : SymbolPair ) = {
913+ import pair ._
914+ log(s " Considering for erasure clash: \n $pair" )
915+ ! exitingRefchecks(lowType matches highType) && exitingPostErasure(low.tpe =:= high.tpe)
909916 }
917+ opc.iterator filter sameTypeAfterErasure foreach doubleDefError
910918 }
911919
912- /*
913- for (bc <- root.info.baseClasses.tail; other <- bc.info.decls.toList) {
914- if (other.isTerm && !other.isConstructor && !(other hasFlag (PRIVATE | BRIDGE))) {
915- for (member <- root.info.nonPrivateMember(other.name).alternatives) {
916- if (member != other &&
917- !(member hasFlag BRIDGE) &&
918- exitingErasure(member.tpe =:= other.tpe) &&
919- !exitingRefchecks(
920- root.thisType.memberType(member) matches root.thisType.memberType(other))) {
921- debuglog("" + member.locationString + " " + member.infosString + other.locationString + " " + other.infosString);
922- doubleDefError(member, other)
923- }
924- }
925- }
926- }
927- */
928-
929920 /** Add bridge definitions to a template. This means:
930921 *
931922 * If there is a concrete member `m` which overrides a member in a base
@@ -940,7 +931,6 @@ abstract class Erasure extends AddInterfaces
940931 */
941932 private def bridgeDefs (owner : Symbol ): (List [Tree ], immutable.Set [Symbol ]) = {
942933 assert(phase == currentRun.erasurePhase, phase)
943- debuglog(" computing bridges for " + owner)
944934 new ComputeBridges (unit, owner) compute()
945935 }
946936
0 commit comments