aboutsummaryrefslogtreecommitdiff
path: root/src/dotty/tools/dotc/core/Denotations.scala
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2015-09-29 17:29:53 +0200
committerMartin Odersky <odersky@gmail.com>2015-09-29 19:18:53 +0200
commit9c8e247d8900f3fb6f497bc5e269b68f6bc967b7 (patch)
tree1d95772bcf702e407b018eccec7913d7b6563a79 /src/dotty/tools/dotc/core/Denotations.scala
parent7d3a0064aba0cfe74f7eea7bb43b913cd2c224c7 (diff)
downloaddotty-9c8e247d8900f3fb6f497bc5e269b68f6bc967b7.tar.gz
dotty-9c8e247d8900f3fb6f497bc5e269b68f6bc967b7.tar.bz2
dotty-9c8e247d8900f3fb6f497bc5e269b68f6bc967b7.zip
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.
Diffstat (limited to 'src/dotty/tools/dotc/core/Denotations.scala')
-rw-r--r--src/dotty/tools/dotc/core/Denotations.scala77
1 files changed, 41 insertions, 36 deletions
diff --git a/src/dotty/tools/dotc/core/Denotations.scala b/src/dotty/tools/dotc/core/Denotations.scala
index 16a151e89..cd46918cf 100644
--- a/src/dotty/tools/dotc/core/Denotations.scala
+++ b/src/dotty/tools/dotc/core/Denotations.scala
@@ -268,50 +268,52 @@ object Denotations {
}
case denot1: SingleDenotation =>
if (denot1 eq denot2) denot1
- else if (denot1.signature matches denot2.signature) {
+ else {
val info1 = denot1.info
val info2 = denot2.info
- val sym1 = denot1.symbol
- val sym2 = denot2.symbol
- val sym2Accessible = sym2.isAccessibleFrom(pre)
-
- /** Does `sym1` come before `sym2` in the linearization of `pre`? */
- def precedes(sym1: Symbol, sym2: Symbol) = {
- def precedesIn(bcs: List[ClassSymbol]): Boolean = bcs match {
- case bc :: bcs1 => (sym1 eq bc) || !(sym2 eq bc) && precedesIn(bcs1)
- case Nil => true
+ if (denot1.signature.matches(denot2.signature) &&
+ denot1.info.matches(denot2.info)) {
+ val sym1 = denot1.symbol
+ val sym2 = denot2.symbol
+ val sym2Accessible = sym2.isAccessibleFrom(pre)
+
+ /** Does `sym1` come before `sym2` in the linearization of `pre`? */
+ def precedes(sym1: Symbol, sym2: Symbol) = {
+ def precedesIn(bcs: List[ClassSymbol]): Boolean = bcs match {
+ case bc :: bcs1 => (sym1 eq bc) || !(sym2 eq bc) && precedesIn(bcs1)
+ case Nil => true
+ }
+ sym1.derivesFrom(sym2) ||
+ !sym2.derivesFrom(sym1) && precedesIn(pre.baseClasses)
}
- sym1.derivesFrom(sym2) ||
- !sym2.derivesFrom(sym1) && precedesIn(pre.baseClasses)
- }
- /** Preference according to partial pre-order (isConcrete, precedes) */
- def preferSym(sym1: Symbol, sym2: Symbol) =
- sym1.eq(sym2) ||
- sym1.isAsConcrete(sym2) &&
- (!sym2.isAsConcrete(sym1) || precedes(sym1.owner, sym2.owner))
+ /** Preference according to partial pre-order (isConcrete, precedes) */
+ def preferSym(sym1: Symbol, sym2: Symbol) =
+ sym1.eq(sym2) ||
+ sym1.isAsConcrete(sym2) &&
+ (!sym2.isAsConcrete(sym1) || precedes(sym1.owner, sym2.owner))
- /** Sym preference provided types also override */
- def prefer(sym1: Symbol, sym2: Symbol, info1: Type, info2: Type) =
- preferSym(sym1, sym2) && info1.overrides(info2)
+ /** Sym preference provided types also override */
+ def prefer(sym1: Symbol, sym2: Symbol, info1: Type, info2: Type) =
+ preferSym(sym1, sym2) && info1.overrides(info2)
- if (sym2Accessible && prefer(sym2, sym1, info2, info1)) denot2
- else {
- val sym1Accessible = sym1.isAccessibleFrom(pre)
- if (sym1Accessible && prefer(sym1, sym2, info1, info2)) denot1
- else if (sym1Accessible && sym2.exists && !sym2Accessible) denot1
- else if (sym2Accessible && sym1.exists && !sym1Accessible) denot2
+ if (sym2Accessible && prefer(sym2, sym1, info2, info1)) denot2
else {
- val sym =
- if (!sym1.exists) sym2
- else if (!sym2.exists) sym1
- else if (preferSym(sym2, sym1)) sym2
- else sym1
- new JointRefDenotation(sym, info1 & info2, denot1.validFor & denot2.validFor)
+ val sym1Accessible = sym1.isAccessibleFrom(pre)
+ if (sym1Accessible && prefer(sym1, sym2, info1, info2)) denot1
+ else if (sym1Accessible && sym2.exists && !sym2Accessible) denot1
+ else if (sym2Accessible && sym1.exists && !sym1Accessible) denot2
+ else {
+ val sym =
+ if (!sym1.exists) sym2
+ else if (!sym2.exists) sym1
+ else if (preferSym(sym2, sym1)) sym2
+ else sym1
+ new JointRefDenotation(sym, info1 & info2, denot1.validFor & denot2.validFor)
+ }
}
- }
+ } else NoDenotation
}
- else NoDenotation
}
if (this eq that) this
@@ -333,7 +335,7 @@ object Denotations {
def | (that: Denotation, pre: Type)(implicit ctx: Context): Denotation = {
def unionDenot(denot1: SingleDenotation, denot2: SingleDenotation): Denotation =
- if (denot1.signature matches denot2.signature) {
+ if (denot1.matches(denot2)) {
val sym1 = denot1.symbol
val sym2 = denot2.symbol
val info1 = denot1.info
@@ -472,6 +474,9 @@ object Denotations {
if (sig matches situated.signature) this else NoDenotation
}
+ def matches(other: SingleDenotation)(implicit ctx: Context): Boolean =
+ signature.matches(other.signature) && info.matches(other.info)
+
// ------ Forming types -------------------------------------------
/** The TypeRef representing this type denotation at its original location. */