@@ -19,6 +19,7 @@ import printing.Printer
19
19
import io .AbstractFile
20
20
import config .Feature .migrateTo3
21
21
import config .Config
22
+ import config .Printers .overload
22
23
import util .common ._
23
24
import typer .ProtoTypes .NoViewsAllowed
24
25
import collection .mutable .ListBuffer
@@ -460,52 +461,54 @@ object Denotations {
460
461
|| sym1.is(Method ) && ! sym2.is(Method ))
461
462
|| sym1.info.isErroneous)
462
463
463
- def preferSymSimple (sym1 : Symbol , sym2 : Symbol ) =
464
- sym1.is(Method ) && ! sym2.is(Method ) || sym1.info.isErroneous
465
-
466
464
/** Sym preference provided types also override */
467
465
def prefer (sym1 : Symbol , sym2 : Symbol , info1 : Type , info2 : Type ) =
468
466
preferSym(sym1, sym2) &&
469
467
info1.overrides(info2, sym1.matchNullaryLoosely || sym2.matchNullaryLoosely, checkClassInfo = false )
470
468
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
+ *
472
475
* 1. Non-bridge methods
473
476
* 2. non-methods
474
477
* 3. bridges
475
478
* 4. NoSymbol
479
+ *
480
+ * If that fails, return a MultiDenotation with both alternatives
481
+ * and rely on overloading resolution to pick one of them.
476
482
*/
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
+
485
492
if preferMethod(sym1, sym2) then denot1
486
493
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
488
498
489
499
if (sym2Accessible && prefer(sym2, sym1, info2, info1)) denot2
490
500
else
491
501
val sym1Accessible = sym1.isAccessibleFrom(pre)
492
502
if (sym1Accessible && prefer(sym1, sym2, info1, info2)) denot1
493
503
else if (sym1Accessible && sym2.exists && ! sym2Accessible) denot1
494
504
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
497
507
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
509
512
end mergeSingleDenot
510
513
511
514
if (this eq that) this
0 commit comments