@@ -56,6 +56,8 @@ trait Contexts { self: Analyzer =>
5656 LookupAmbiguous (s " it is imported twice in the same scope by \n $imp1\n and $imp2" )
5757 def ambiguousDefnAndImport (owner : Symbol , imp : ImportInfo ) =
5858 LookupAmbiguous (s " it is both defined in $owner and imported subsequently by \n $imp" )
59+ def ambiguousDefinitions (owner : Symbol , other : Symbol ) =
60+ LookupAmbiguous (s " it is both defined in $owner and available as ${other.fullLocationString}" )
5961
6062 private lazy val startContext = NoContext .make(
6163 Template (List (), noSelfType, List ()) setSymbol global.NoSymbol setType global.NoType ,
@@ -1410,15 +1412,17 @@ trait Contexts { self: Analyzer =>
14101412 }
14111413
14121414 // cx.scope eq null arises during FixInvalidSyms in Duplicators
1413- while (defSym == NoSymbol && (cx ne NoContext ) && (cx.scope ne null )) {
1414- pre = cx.enclClass.prefix
1415- defSym = lookupInScope(cx.owner, cx.enclClass.prefix, cx.scope) match {
1416- case NoSymbol => searchPrefix
1417- case found => found
1415+ def nextDefinition (): Unit =
1416+ while (defSym == NoSymbol && (cx ne NoContext ) && (cx.scope ne null )) {
1417+ pre = cx.enclClass.prefix
1418+ defSym = lookupInScope(cx.owner, cx.enclClass.prefix, cx.scope) match {
1419+ case NoSymbol => searchPrefix
1420+ case found => found
1421+ }
1422+ if (! defSym.exists) cx = cx.outer // push further outward
14181423 }
1419- if (! defSym.exists)
1420- cx = cx.outer // push further outward
1421- }
1424+ nextDefinition()
1425+
14221426 if (symbolDepth < 0 )
14231427 symbolDepth = cx.depth
14241428
@@ -1458,24 +1462,50 @@ trait Contexts { self: Analyzer =>
14581462 importCursor.advanceImp1Imp2()
14591463 }
14601464
1461- if ( defSym.exists && impSym.exists) {
1465+ val preferDef : Boolean = defSym.exists && ( ! impSym.exists || {
14621466 // 4) root imported symbols have same (lowest) precedence as package-owned symbols in different compilation units.
14631467 if (imp1.depth < symbolDepth && imp1.isRootImport && foreignDefined)
1464- impSym = NoSymbol
1468+ true
14651469 // 4) imported symbols have higher precedence than package-owned symbols in different compilation units.
14661470 else if (imp1.depth >= symbolDepth && foreignDefined)
1467- defSym = NoSymbol
1471+ false
14681472 // Defined symbols take precedence over erroneous imports.
14691473 else if (impSym.isError || impSym.name == nme.CONSTRUCTOR )
1470- impSym = NoSymbol
1474+ true
14711475 // Try to reconcile them before giving up, at least if the def is not visible
14721476 else if (foreignDefined && thisContext.reconcileAmbiguousImportAndDef(name, impSym, defSym))
1473- impSym = NoSymbol
1477+ true
14741478 // Otherwise they are irreconcilably ambiguous
14751479 else
14761480 return ambiguousDefnAndImport(defSym.alternatives.head.owner, imp1)
1481+ })
1482+
1483+ // If the defSym is at 4, and there is a def at 1 in scope, then the reference is ambiguous.
1484+ if (foreignDefined && ! defSym.isPackage) {
1485+ val defSym0 = defSym
1486+ val pre0 = pre
1487+ val cx0 = cx
1488+ while ((cx ne NoContext ) && cx.depth >= symbolDepth) cx = cx.outer
1489+ var done = false
1490+ while (! done) {
1491+ defSym = NoSymbol
1492+ nextDefinition()
1493+ done = (cx eq NoContext ) || defSym.exists && ! foreignDefined
1494+ if (! done && (cx ne NoContext )) cx = cx.outer
1495+ }
1496+ if (defSym.exists && (defSym ne defSym0)) {
1497+ val ambiguity =
1498+ if (preferDef) ambiguousDefinitions(owner = defSym.owner, defSym0)
1499+ else ambiguousDefnAndImport(owner = defSym.owner, imp1)
1500+ return ambiguity
1501+ }
1502+ defSym = defSym0
1503+ pre = pre0
1504+ cx = cx0
14771505 }
14781506
1507+ if (preferDef) impSym = NoSymbol else defSym = NoSymbol
1508+
14791509 // At this point only one or the other of defSym and impSym might be set.
14801510 if (defSym.exists) finishDefSym(defSym, pre)
14811511 else if (impSym.exists) {
0 commit comments