Skip to content

Commit 9773b4f

Browse files
committed
Matching denotations should take infos into account
Whenchecking whether two denotations match it is not enough to look at the signatures. The signatures might match (on the parameters) but the actual parametre types might be different. The change always tests infos after signatures, effectively turning the signature test into a pre-filter.
1 parent 6bb6210 commit 9773b4f

File tree

5 files changed

+47
-42
lines changed

5 files changed

+47
-42
lines changed

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

Lines changed: 41 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -268,50 +268,52 @@ object Denotations {
268268
}
269269
case denot1: SingleDenotation =>
270270
if (denot1 eq denot2) denot1
271-
else if (denot1.signature matches denot2.signature) {
271+
else {
272272
val info1 = denot1.info
273273
val info2 = denot2.info
274-
val sym1 = denot1.symbol
275-
val sym2 = denot2.symbol
276-
val sym2Accessible = sym2.isAccessibleFrom(pre)
277-
278-
/** Does `sym1` come before `sym2` in the linearization of `pre`? */
279-
def precedes(sym1: Symbol, sym2: Symbol) = {
280-
def precedesIn(bcs: List[ClassSymbol]): Boolean = bcs match {
281-
case bc :: bcs1 => (sym1 eq bc) || !(sym2 eq bc) && precedesIn(bcs1)
282-
case Nil => true
274+
if (denot1.signature.matches(denot2.signature) &&
275+
denot1.info.matches(denot2.info)) {
276+
val sym1 = denot1.symbol
277+
val sym2 = denot2.symbol
278+
val sym2Accessible = sym2.isAccessibleFrom(pre)
279+
280+
/** Does `sym1` come before `sym2` in the linearization of `pre`? */
281+
def precedes(sym1: Symbol, sym2: Symbol) = {
282+
def precedesIn(bcs: List[ClassSymbol]): Boolean = bcs match {
283+
case bc :: bcs1 => (sym1 eq bc) || !(sym2 eq bc) && precedesIn(bcs1)
284+
case Nil => true
285+
}
286+
sym1.derivesFrom(sym2) ||
287+
!sym2.derivesFrom(sym1) && precedesIn(pre.baseClasses)
283288
}
284-
sym1.derivesFrom(sym2) ||
285-
!sym2.derivesFrom(sym1) && precedesIn(pre.baseClasses)
286-
}
287289

288-
/** Preference according to partial pre-order (isConcrete, precedes) */
289-
def preferSym(sym1: Symbol, sym2: Symbol) =
290-
sym1.eq(sym2) ||
291-
sym1.isAsConcrete(sym2) &&
292-
(!sym2.isAsConcrete(sym1) || precedes(sym1.owner, sym2.owner))
290+
/** Preference according to partial pre-order (isConcrete, precedes) */
291+
def preferSym(sym1: Symbol, sym2: Symbol) =
292+
sym1.eq(sym2) ||
293+
sym1.isAsConcrete(sym2) &&
294+
(!sym2.isAsConcrete(sym1) || precedes(sym1.owner, sym2.owner))
293295

294-
/** Sym preference provided types also override */
295-
def prefer(sym1: Symbol, sym2: Symbol, info1: Type, info2: Type) =
296-
preferSym(sym1, sym2) && info1.overrides(info2)
296+
/** Sym preference provided types also override */
297+
def prefer(sym1: Symbol, sym2: Symbol, info1: Type, info2: Type) =
298+
preferSym(sym1, sym2) && info1.overrides(info2)
297299

298-
if (sym2Accessible && prefer(sym2, sym1, info2, info1)) denot2
299-
else {
300-
val sym1Accessible = sym1.isAccessibleFrom(pre)
301-
if (sym1Accessible && prefer(sym1, sym2, info1, info2)) denot1
302-
else if (sym1Accessible && sym2.exists && !sym2Accessible) denot1
303-
else if (sym2Accessible && sym1.exists && !sym1Accessible) denot2
300+
if (sym2Accessible && prefer(sym2, sym1, info2, info1)) denot2
304301
else {
305-
val sym =
306-
if (!sym1.exists) sym2
307-
else if (!sym2.exists) sym1
308-
else if (preferSym(sym2, sym1)) sym2
309-
else sym1
310-
new JointRefDenotation(sym, info1 & info2, denot1.validFor & denot2.validFor)
302+
val sym1Accessible = sym1.isAccessibleFrom(pre)
303+
if (sym1Accessible && prefer(sym1, sym2, info1, info2)) denot1
304+
else if (sym1Accessible && sym2.exists && !sym2Accessible) denot1
305+
else if (sym2Accessible && sym1.exists && !sym1Accessible) denot2
306+
else {
307+
val sym =
308+
if (!sym1.exists) sym2
309+
else if (!sym2.exists) sym1
310+
else if (preferSym(sym2, sym1)) sym2
311+
else sym1
312+
new JointRefDenotation(sym, info1 & info2, denot1.validFor & denot2.validFor)
313+
}
311314
}
312-
}
315+
} else NoDenotation
313316
}
314-
else NoDenotation
315317
}
316318

317319
if (this eq that) this
@@ -333,7 +335,7 @@ object Denotations {
333335
def | (that: Denotation, pre: Type)(implicit ctx: Context): Denotation = {
334336

335337
def unionDenot(denot1: SingleDenotation, denot2: SingleDenotation): Denotation =
336-
if (denot1.signature matches denot2.signature) {
338+
if (denot1.matches(denot2)) {
337339
val sym1 = denot1.symbol
338340
val sym2 = denot2.symbol
339341
val info1 = denot1.info
@@ -472,6 +474,9 @@ object Denotations {
472474
if (sig matches situated.signature) this else NoDenotation
473475
}
474476

477+
def matches(other: SingleDenotation)(implicit ctx: Context): Boolean =
478+
signature.matches(other.signature) && info.matches(other.info)
479+
475480
// ------ Forming types -------------------------------------------
476481

477482
/** The TypeRef representing this type denotation at its original location. */

src/dotty/tools/dotc/typer/Checking.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -322,7 +322,7 @@ trait Checking {
322322
def checkDecl(decl: Symbol): Unit = {
323323
for (other <- seen(decl.name)) {
324324
typr.println(i"conflict? $decl $other")
325-
if (decl.signature matches other.signature) {
325+
if (decl.matches(other)) {
326326
def doubleDefError(decl: Symbol, other: Symbol): Unit = {
327327
def ofType = if (decl.isType) "" else d": ${other.info}"
328328
def explanation =

src/dotty/tools/dotc/typer/TypeAssigner.scala

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,8 @@ trait TypeAssigner {
6363
val parentType = info.instantiatedParents.reduceLeft(ctx.typeComparer.andType(_, _))
6464
def addRefinement(parent: Type, decl: Symbol) = {
6565
val inherited = parentType.findMember(decl.name, info.cls.thisType, Private)
66-
val inheritedInfo = inherited.atSignature(decl.info .signature).info
66+
val inheritedInfo = inherited.atSignature(decl.info.signature).info
67+
// @smarter atSignature probably wrong now; we are now missing out on types that refine the result type
6768
if (inheritedInfo.exists && decl.info <:< inheritedInfo && !(inheritedInfo <:< decl.info))
6869
typr.echo(
6970
i"add ref $parent $decl --> ",

test/dotc/tests.scala

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ class tests extends CompilerTest {
101101
@Test def neg_typedapply() = compileFile(negDir, "typedapply", xerrors = 4)
102102
@Test def neg_typedidents() = compileFile(negDir, "typedIdents", xerrors = 2)
103103
@Test def neg_assignments() = compileFile(negDir, "assignments", xerrors = 3)
104-
@Test def neg_typers() = compileFile(negDir, "typers", xerrors = 12)(allowDoubleBindings)
104+
@Test def neg_typers() = compileFile(negDir, "typers", xerrors = 10)(allowDoubleBindings)
105105
@Test def neg_privates() = compileFile(negDir, "privates", xerrors = 2)
106106
@Test def neg_rootImports = compileFile(negDir, "rootImplicits", xerrors = 2)
107107
@Test def neg_templateParents() = compileFile(negDir, "templateParents", xerrors = 3)
@@ -112,7 +112,6 @@ class tests extends CompilerTest {
112112
@Test def neg_overrides = compileFile(negDir, "overrides", xerrors = 11)
113113
@Test def neg_i39 = compileFile(negDir, "i39", xerrors = 2)
114114
@Test def neg_i50_volatile = compileFile(negDir, "i50-volatile", xerrors = 6)
115-
@Test def neg_t0273_doubledefs = compileFile(negDir, "t0273", xerrors = 1)
116115
@Test def neg_zoo = compileFile(negDir, "zoo", xerrors = 12)
117116

118117
val negTailcallDir = negDir + "tailcall/"

tests/neg/typers.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,11 @@ object typers {
2222
val z: Int
2323
def z(): String // error: double def
2424

25-
def f(x: Any) = () // error: double def
25+
def f(x: Any) = () // OK!
2626
def f(x: AnyRef): AnyRef
2727

2828
def g(x: Object): Unit
29-
def g[T](x: T): T = x // error: double def
29+
def g[T](x: T): T = x // OK!
3030
}
3131

3232

0 commit comments

Comments
 (0)