diff options
author | Martin Odersky <odersky@gmail.com> | 2014-03-31 15:42:52 +0200 |
---|---|---|
committer | Dmitry Petrashko <dmitry.petrashko@gmail.com> | 2014-04-08 16:55:49 +0200 |
commit | eb3df0db4a57d89c0d7370a9180742273db166b2 (patch) | |
tree | 6fc1d5db88e416b1df0bfa4a1deefab98550aa1e /src/dotty/tools/dotc | |
parent | 26185f6b17429d2af7686139dbb4d13ede4c9e99 (diff) | |
download | dotty-eb3df0db4a57d89c0d7370a9180742273db166b2.tar.gz dotty-eb3df0db4a57d89c0d7370a9180742273db166b2.tar.bz2 dotty-eb3df0db4a57d89c0d7370a9180742273db166b2.zip |
Corrected computations of union denotations.
Cannot discard a symbol simply because the other side's type is weaker.
If in (A | B)#m A and B resolve to different symbols `m`, the resulting denotation
cannot have either `m` as symbol; it must be NoSymbol instead.
Diffstat (limited to 'src/dotty/tools/dotc')
-rw-r--r-- | src/dotty/tools/dotc/core/Denotations.scala | 51 | ||||
-rw-r--r-- | src/dotty/tools/dotc/typer/Applications.scala | 4 |
2 files changed, 27 insertions, 28 deletions
diff --git a/src/dotty/tools/dotc/core/Denotations.scala b/src/dotty/tools/dotc/core/Denotations.scala index e9b9b20c4..0622829c5 100644 --- a/src/dotty/tools/dotc/core/Denotations.scala +++ b/src/dotty/tools/dotc/core/Denotations.scala @@ -273,35 +273,34 @@ object Denotations { def unionDenot(denot1: SingleDenotation, denot2: SingleDenotation): Denotation = if (denot1.signature matches denot2.signature) { + val sym1 = denot1.symbol + val sym2 = denot2.symbol val info1 = denot1.info val info2 = denot2.info - val sym2 = denot2.symbol - def sym2Accessible = sym2.isAccessibleFrom(pre) - if (info1 <:< info2 && sym2Accessible) denot2 + val sameSym = sym1 eq sym2 + if (sameSym && info1 <:< info2) denot2 + else if (sameSym && info2 <:< info1) denot1 else { - val sym1 = denot1.symbol - def sym1Accessible = sym1.isAccessibleFrom(pre) - if (info2 <:< info1 && sym1Accessible) denot1 - else { - val owner2 = if (sym2 ne NoSymbol) sym2.owner else NoSymbol - /** Determine a symbol which is overridden by both sym1 and sym2. - * Preference is given to accessible symbols. - */ - def lubSym(overrides: Iterator[Symbol], previous: Symbol): Symbol = - if (!overrides.hasNext) previous - else { - val candidate = overrides.next - if (owner2 derivesFrom candidate.owner) - if (candidate isAccessibleFrom pre) candidate - else lubSym(overrides, previous orElse candidate) - else - lubSym(overrides, previous) - } - new JointRefDenotation( - lubSym(sym1.allOverriddenSymbols, NoSymbol), - info1 | info2, - denot1.validFor & denot2.validFor) - } + val jointSym = + if (sameSym) sym1 + else { + val owner2 = if (sym2 ne NoSymbol) sym2.owner else NoSymbol + /** Determine a symbol which is overridden by both sym1 and sym2. + * Preference is given to accessible symbols. + */ + def lubSym(overrides: Iterator[Symbol], previous: Symbol): Symbol = + if (!overrides.hasNext) previous + else { + val candidate = overrides.next + if (owner2 derivesFrom candidate.owner) + if (candidate isAccessibleFrom pre) candidate + else lubSym(overrides, previous orElse candidate) + else + lubSym(overrides, previous) + } + lubSym(sym1.allOverriddenSymbols, NoSymbol) + } + new JointRefDenotation(jointSym, info1 | info2, denot1.validFor & denot2.validFor) } } else NoDenotation diff --git a/src/dotty/tools/dotc/typer/Applications.scala b/src/dotty/tools/dotc/typer/Applications.scala index 57f11480c..0f47336fc 100644 --- a/src/dotty/tools/dotc/typer/Applications.scala +++ b/src/dotty/tools/dotc/typer/Applications.scala @@ -794,8 +794,8 @@ trait Applications extends Compatibility { self: Typer => tp } - val owner1 = alt1.symbol.owner - val owner2 = alt2.symbol.owner + val owner1 = if (alt1.symbol.exists) alt1.symbol.owner else NoSymbol + val owner2 = if (alt2.symbol.exists) alt2.symbol.owner else NoSymbol val tp1 = stripImplicit(alt1.widen) val tp2 = stripImplicit(alt2.widen) |