aboutsummaryrefslogtreecommitdiff
path: root/src/dotty
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2014-03-31 15:42:52 +0200
committerDmitry Petrashko <dmitry.petrashko@gmail.com>2014-04-08 16:55:49 +0200
commiteb3df0db4a57d89c0d7370a9180742273db166b2 (patch)
tree6fc1d5db88e416b1df0bfa4a1deefab98550aa1e /src/dotty
parent26185f6b17429d2af7686139dbb4d13ede4c9e99 (diff)
downloaddotty-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')
-rw-r--r--src/dotty/tools/dotc/core/Denotations.scala51
-rw-r--r--src/dotty/tools/dotc/typer/Applications.scala4
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)