diff options
author | Martin Odersky <odersky@gmail.com> | 2015-09-29 17:29:53 +0200 |
---|---|---|
committer | Martin Odersky <odersky@gmail.com> | 2015-09-29 19:18:53 +0200 |
commit | 9c8e247d8900f3fb6f497bc5e269b68f6bc967b7 (patch) | |
tree | 1d95772bcf702e407b018eccec7913d7b6563a79 /src/dotty/tools/dotc/core/Denotations.scala | |
parent | 7d3a0064aba0cfe74f7eea7bb43b913cd2c224c7 (diff) | |
download | dotty-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.scala | 77 |
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. */ |