Skip to content

Commit dbc1e95

Browse files
committed
Don't throw merge errors when infos conflict
Wait until overloading resolution instead.
1 parent 4723f16 commit dbc1e95

File tree

2 files changed

+16
-22
lines changed

2 files changed

+16
-22
lines changed

compiler/src/dotty/tools/dotc/core/Denotations.scala

Lines changed: 14 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -407,7 +407,7 @@ object Denotations {
407407
}
408408

409409
/** Try to merge single-denotations. */
410-
def mergeSingleDenot(denot1: SingleDenotation, denot2: SingleDenotation): Denotation = {
410+
def mergeSingleDenot(denot1: SingleDenotation, denot2: SingleDenotation): Denotation =
411411
val info1 = denot1.info
412412
val info2 = denot2.info
413413
val sym1 = denot1.symbol
@@ -474,34 +474,28 @@ object Denotations {
474474
else MultiDenotation(denot1, denot2)
475475

476476
if (sym2Accessible && prefer(sym2, sym1, info2, info1)) denot2
477-
else {
477+
else
478478
val sym1Accessible = sym1.isAccessibleFrom(pre)
479479
if (sym1Accessible && prefer(sym1, sym2, info1, info2)) denot1
480480
else if (sym1Accessible && sym2.exists && !sym2Accessible) denot1
481481
else if (sym2Accessible && sym1.exists && !sym1Accessible) denot2
482482
else if (isDoubleDef(sym1, sym2)) handleDoubleDef
483-
else {
483+
else
484484
val sym =
485485
if (preferSym(sym2, sym1)) sym2
486486
else sym1
487-
val jointInfo =
488-
try infoMeet(info1, info2, sym1, sym2, safeIntersection)
489-
catch {
490-
case ex: MergeError =>
491-
// TODO: this picks one type over the other whereas it might be better
492-
// to return a MultiDenotation instead. But doing so would affect lots of
493-
// things, starting with the return type of this method.
494-
if (preferSym(sym2, sym1)) info2
495-
else if (preferSym(sym1, sym2)) info1
496-
else if (pre.widen.classSymbol.is(Scala2x) || migrateTo3)
497-
info1 // follow Scala2 linearization -
487+
def jointRef(jointInfo: Type) =
488+
JointRefDenotation(sym, jointInfo, denot1.validFor & denot2.validFor, pre)
489+
try jointRef(infoMeet(info1, info2, sym1, sym2, safeIntersection))
490+
catch case ex: MergeError =>
491+
if preferSymSimple(sym2, sym1) then jointRef(info2)
492+
else if preferSymSimple(sym1, sym2) then jointRef(info1)
493+
else if pre.widen.classSymbol.is(Scala2x) || migrateTo3 then
494+
jointRef(info1)
495+
// follow Scala2 linearization -
498496
// compare with way merge is performed in SymDenotation#computeMembersNamed
499-
else throw new MergeError(ex.sym1, ex.sym2, ex.tp1, ex.tp2, pre)
500-
}
501-
new JointRefDenotation(sym, jointInfo, denot1.validFor & denot2.validFor, pre)
502-
}
503-
}
504-
}
497+
else MultiDenotation(denot1, denot2)
498+
end mergeSingleDenot
505499

506500
if (this eq that) this
507501
else if (!this.exists) that

tests/neg/i7425.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,11 @@ class C { def f: Int = 0 }
22

33
trait D { def f(): Int = 0 }
44

5-
def foo1(x: C & D) = x.f // error: method f must be called with argument
5+
def foo1(x: C & D) = x.f // ok
66
def foo2(x: C | D) = x.f // error: value f is not a member of C | D
77
def foo3(x: D & C) = x.f // ok
88
def foo4(x: D | C) = x.f // error: value f is not a member of D | C
99
def foo5(x: C & D) = x.f() // ok
1010
def foo6(x: C | D) = x.f() // error: value f is not a member of C | D
11-
def foo7(x: D & C) = x.f() // error: method f in class C does not take parameters
11+
def foo7(x: D & C) = x.f() // ok
1212
def foo8(x: D | C) = x.f() // error: value f is not a member of D | C

0 commit comments

Comments
 (0)