aboutsummaryrefslogtreecommitdiff
path: root/src/dotty/tools/dotc/core/Denotations.scala
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2015-09-30 14:39:59 +0200
committerMartin Odersky <odersky@gmail.com>2015-09-30 14:39:59 +0200
commit25431a96c849c878c577e7449d9f8eeec9f94328 (patch)
tree59febabe869069594c13c12bab8118f60167cdb1 /src/dotty/tools/dotc/core/Denotations.scala
parentee4e2e0178d0db6494f2a971f5a5b9d3c8f732db (diff)
downloaddotty-25431a96c849c878c577e7449d9f8eeec9f94328.tar.gz
dotty-25431a96c849c878c577e7449d9f8eeec9f94328.tar.bz2
dotty-25431a96c849c878c577e7449d9f8eeec9f94328.zip
Refinements to signature matching
1) Matching after erasure also takes wildcards into account (before it didn't). 2) Combine all signature matching operations into a single matchDegree method.
Diffstat (limited to 'src/dotty/tools/dotc/core/Denotations.scala')
-rw-r--r--src/dotty/tools/dotc/core/Denotations.scala87
1 files changed, 43 insertions, 44 deletions
diff --git a/src/dotty/tools/dotc/core/Denotations.scala b/src/dotty/tools/dotc/core/Denotations.scala
index 3bab19ea9..232206652 100644
--- a/src/dotty/tools/dotc/core/Denotations.scala
+++ b/src/dotty/tools/dotc/core/Denotations.scala
@@ -269,52 +269,49 @@ object Denotations {
}
case denot1: SingleDenotation =>
if (denot1 eq denot2) denot1
- else {
+ else if (denot1.matches(denot2)) {
val info1 = denot1.info
val info2 = denot2.info
- 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)
+ 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)
+ }
- /** 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
+ 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
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
- 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 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
@@ -472,14 +469,16 @@ object Denotations {
def atSignature(sig: Signature, site: Type, relaxed: Boolean)(implicit ctx: Context): SingleDenotation = {
val situated = if (site == NoPrefix) this else asSeenFrom(site)
- val matches =
- if (relaxed) sig.matches(situated.signature)
- else sig.matchesFully(situated.signature)
+ val matches = sig.matchDegree(situated.signature) >=
+ (if (relaxed) Signature.ParamMatch else Signature.FullMatch)
if (matches) this else NoDenotation
}
- def matches(other: SingleDenotation)(implicit ctx: Context): Boolean =
- signature.matches(other.signature) && info.matches(other.info)
+ def matches(other: SingleDenotation)(implicit ctx: Context): Boolean = {
+ val d = signature.matchDegree(other.signature)
+ d == Signature.FullMatch ||
+ d >= Signature.ParamMatch && info.matches(other.info)
+ }
// ------ Forming types -------------------------------------------
@@ -788,7 +787,7 @@ object Denotations {
final def toDenot(pre: Type)(implicit ctx: Context): Denotation = this
final def containsSym(sym: Symbol): Boolean = hasUniqueSym && (symbol eq sym)
final def containsSig(sig: Signature)(implicit ctx: Context) =
- exists && (signature matches sig)
+ exists && signature.matchDegree(sig) >= Signature.ParamMatch
final def filterWithPredicate(p: SingleDenotation => Boolean): SingleDenotation =
if (p(this)) this else NoDenotation
final def filterDisjoint(denots: PreDenotation)(implicit ctx: Context): SingleDenotation =