Skip to content

Commit 5733fdb

Browse files
committed
Fix mergeDenot one more time.
It's easy to get this wrong. What happened was that when computing deferred members of a class a deferred member was preferred over a concrete one because the types did not match. Thsi should not happen. We now change the scheme to always prefer concrete over abstract, and subclass-owned over superclass-owned. But we pick a denotation only if the overrides relationship on types coincides with the preference on symbols.
1 parent cb2d81d commit 5733fdb

File tree

3 files changed

+10
-17
lines changed

3 files changed

+10
-17
lines changed

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

Lines changed: 10 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -274,24 +274,17 @@ object Denotations {
274274
val sym1 = denot1.symbol
275275
val sym2 = denot2.symbol
276276
val sym2Accessible = sym2.isAccessibleFrom(pre)
277-
def shadows(sym1: Symbol, sym2: Symbol) = {
278-
val owner1 = sym1.owner
279-
val owner2 = sym2.owner
280-
owner1.derivesFrom(owner2) && owner1.ne(owner2)
277+
def unshadowed(sym: Symbol, from: Symbol) = {
278+
val symOwner = sym.owner
279+
val fromOwner = from.owner
280+
!fromOwner.derivesFrom(symOwner) || fromOwner.eq(symOwner)
281281
}
282-
/** Preference according to order (overrides, isAsConcrete, shadows)*/
282+
/** Preference according to partial pre-order (isConcrete, unshadowed) */
283+
def preferSym(sym1: Symbol, sym2: Symbol) =
284+
sym1.isAsConcrete(sym2) && (!sym2.isAsConcrete(sym1) || unshadowed(sym1, sym2))
285+
/** Sym preference provided types also override */
283286
def prefer(info1: Type, sym1: Symbol, info2: Type, sym2: Symbol) =
284-
info1.overrides(info2) && (
285-
// non-standard ordering of tests for efficiency -
286-
// overrides is costlier to compute than the others, so its 2nd test comes last.
287-
sym1.isAsConcrete(sym2) && (
288-
!sym2.isAsConcrete(sym1)
289-
||
290-
shadows(sym1, sym2)
291-
)
292-
||
293-
!info2.overrides(info1)
294-
)
287+
preferSym(sym1, sym2) && info1.overrides(info2)
295288
if (sym2Accessible && prefer(info2, sym2, info1, sym1)) denot2
296289
else {
297290
val sym1Accessible = sym1.isAccessibleFrom(pre)
@@ -302,7 +295,7 @@ object Denotations {
302295
val sym =
303296
if (!sym1.exists) sym2
304297
else if (!sym2.exists) sym1
305-
else if (sym2 isAsConcrete sym1) sym2
298+
else if (preferSym(sym2, sym1)) sym2
306299
else sym1
307300
new JointRefDenotation(sym, info1 & info2, denot1.validFor & denot2.validFor)
308301
}
File renamed without changes.
File renamed without changes.

0 commit comments

Comments
 (0)