@@ -19,6 +19,7 @@ import printing.Printer
1919import io .AbstractFile
2020import config .Feature .migrateTo3
2121import config .Config
22+ import config .Printers .overload
2223import util .common ._
2324import typer .ProtoTypes .NoViewsAllowed
2425import collection .mutable .ListBuffer
@@ -460,52 +461,54 @@ object Denotations {
460461 || sym1.is(Method ) && ! sym2.is(Method ))
461462 || sym1.info.isErroneous)
462463
463- def preferSymSimple (sym1 : Symbol , sym2 : Symbol ) =
464- sym1.is(Method ) && ! sym2.is(Method ) || sym1.info.isErroneous
465-
466464 /** Sym preference provided types also override */
467465 def prefer (sym1 : Symbol , sym2 : Symbol , info1 : Type , info2 : Type ) =
468466 preferSym(sym1, sym2) &&
469467 info1.overrides(info2, sym1.matchNullaryLoosely || sym2.matchNullaryLoosely, checkClassInfo = false )
470468
471- /** `sym1` comes before `sym2` in the ranking
469+ /** Handle conflict where we have either definitions coming from the same class
470+ * that have matching signatures as seen from the current prefix, or we have
471+ * definitions from different classes that have the same signature but
472+ * conflicting infos. In these cases, do a last minute disambiguation
473+ * by picking one alternative according to the ranking
474+ *
472475 * 1. Non-bridge methods
473476 * 2. non-methods
474477 * 3. bridges
475478 * 4. NoSymbol
479+ *
480+ * If that fails, return a MultiDenotation with both alternatives
481+ * and rely on overloading resolution to pick one of them.
476482 */
477- def preferMethod (sym1 : Symbol , sym2 : Symbol ): Boolean =
478- sym1.exists &&
479- (! sym2.exists
480- || sym2.is(Bridge ) && ! sym1.is(Bridge )
481- || sym1.is(Method ) && ! sym2.is(Method )
482- || sym1.info.isErroneous)
483-
484- def handleDoubleDef : Denotation =
483+ def handleConflict : Denotation =
484+
485+ def preferMethod (sym1 : Symbol , sym2 : Symbol ): Boolean =
486+ sym1.exists &&
487+ (! sym2.exists
488+ || sym2.is(Bridge ) && ! sym1.is(Bridge )
489+ || sym1.is(Method ) && ! sym2.is(Method )
490+ || sym1.info.isErroneous)
491+
485492 if preferMethod(sym1, sym2) then denot1
486493 else if preferMethod(sym2, sym1) then denot2
487- else MultiDenotation (denot1, denot2)
494+ else
495+ overload.println(i " overloaded with same signature: ${sym1.showLocated}: $info1 / ${sym2.showLocated}: $info2" )
496+ MultiDenotation (denot1, denot2)
497+ end handleConflict
488498
489499 if (sym2Accessible && prefer(sym2, sym1, info2, info1)) denot2
490500 else
491501 val sym1Accessible = sym1.isAccessibleFrom(pre)
492502 if (sym1Accessible && prefer(sym1, sym2, info1, info2)) denot1
493503 else if (sym1Accessible && sym2.exists && ! sym2Accessible) denot1
494504 else if (sym2Accessible && sym1.exists && ! sym1Accessible) denot2
495- else if ( isDoubleDef(sym1, sym2)) handleDoubleDef
496- else
505+ else if isDoubleDef(sym1, sym2) then handleConflict
506+ else try
497507 val sym = if preferSym(sym2, sym1) then sym2 else sym1
498- def jointRef (jointInfo : Type ) =
499- JointRefDenotation (sym, jointInfo, denot1.validFor & denot2.validFor, pre)
500- try jointRef(infoMeet(info1, info2, sym1, sym2, safeIntersection))
501- catch case ex : MergeError =>
502- if preferMethod(sym2, sym1) then jointRef(info2)
503- else if preferMethod(sym1, sym2) then jointRef(info1)
504- else if pre.widen.classSymbol.is(Scala2x ) || migrateTo3 then
505- jointRef(info1)
506- // follow Scala2 linearization -
507- // compare with way merge is performed in SymDenotation#computeMembersNamed
508- else MultiDenotation (denot1, denot2)
508+ val jointInfo = infoMeet(info1, info2, sym1, sym2, safeIntersection)
509+ JointRefDenotation (sym, jointInfo, denot1.validFor & denot2.validFor, pre)
510+ catch case ex : MergeError =>
511+ handleConflict
509512 end mergeSingleDenot
510513
511514 if (this eq that) this
0 commit comments