aboutsummaryrefslogtreecommitdiff
path: root/src/dotty/tools/dotc/core/Denotations.scala
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2016-05-02 15:51:41 +0200
committerMartin Odersky <odersky@gmail.com>2016-05-18 19:43:22 +0200
commit48b716012bd72486dbf4a2bd3b293ef212f4addd (patch)
tree22e3deb275d86a1ddaa6821a7740170f64f639be /src/dotty/tools/dotc/core/Denotations.scala
parent968f1ab0cd706de8833112741407f94a6a0b2677 (diff)
downloaddotty-48b716012bd72486dbf4a2bd3b293ef212f4addd.tar.gz
dotty-48b716012bd72486dbf4a2bd3b293ef212f4addd.tar.bz2
dotty-48b716012bd72486dbf4a2bd3b293ef212f4addd.zip
Issue MergeError exception for double def situations
When finding two symbols in the same class that have the same signature as seen from some prefix, issue a merge error. This is simpler and more robust than the alternative of producing an overloaded denotation and dealing with it afterwards.
Diffstat (limited to 'src/dotty/tools/dotc/core/Denotations.scala')
-rw-r--r--src/dotty/tools/dotc/core/Denotations.scala37
1 files changed, 29 insertions, 8 deletions
diff --git a/src/dotty/tools/dotc/core/Denotations.scala b/src/dotty/tools/dotc/core/Denotations.scala
index 8003e68ac..0bcb3198b 100644
--- a/src/dotty/tools/dotc/core/Denotations.scala
+++ b/src/dotty/tools/dotc/core/Denotations.scala
@@ -283,12 +283,7 @@ object Denotations {
val sym1 = denot1.symbol
val sym2 = denot2.symbol
- if (sym1.exists && sym2.exists &&
- (sym1 ne sym2) && (sym1.owner eq sym2.owner) &&
- !sym1.is(Bridge) && !sym2.is(Bridge))
- // double definition of two methods with same signature in one class;
- // don't merge them.
- return NoDenotation
+ if (isDoubleDef(sym1, sym2)) doubleDefError(denot1, denot2, pre)
val sym2Accessible = sym2.isAccessibleFrom(pre)
/** Does `sym1` come before `sym2` in the linearization of `pre`? */
@@ -425,8 +420,12 @@ object Denotations {
final def validFor = denot1.validFor & denot2.validFor
final def isType = false
final def signature(implicit ctx: Context) = Signature.OverloadedSignature
- def atSignature(sig: Signature, site: Type, relaxed: Boolean)(implicit ctx: Context): SingleDenotation =
- denot1.atSignature(sig, site, relaxed) orElse denot2.atSignature(sig, site, relaxed)
+ def atSignature(sig: Signature, site: Type, relaxed: Boolean)(implicit ctx: Context): SingleDenotation = {
+ val atSig1 = denot1.atSignature(sig, site, relaxed)
+ val atSig2 = denot2.atSignature(sig, site, relaxed)
+ if (isDoubleDef(atSig1.symbol, atSig2.symbol)) doubleDefError(atSig1, atSig2, site)
+ atSig1.orElse(atSig2)
+ }
def currentIfExists(implicit ctx: Context): Denotation =
derivedMultiDenotation(denot1.currentIfExists, denot2.currentIfExists)
def current(implicit ctx: Context): Denotation =
@@ -907,6 +906,28 @@ object Denotations {
*/
case class NoQualifyingRef(alts: List[SingleDenotation])(implicit ctx: Context) extends ErrorDenotation
+ /** A double defifinition
+ */
+ def isDoubleDef(sym1: Symbol, sym2: Symbol)(implicit ctx: Context): Boolean =
+ (sym1.exists && sym2.exists &&
+ (sym1 ne sym2) && (sym1.owner eq sym2.owner) &&
+ !sym1.is(Bridge) && !sym2.is(Bridge))
+
+ def doubleDefError(denot1: SingleDenotation, denot2: SingleDenotation, pre: Type)(implicit ctx: Context): Unit = {
+ val sym1 = denot1.symbol
+ val sym2 = denot2.symbol
+ def fromWhere = if (pre == NoPrefix) "" else i"\nwhen seen as members of $pre"
+ throw new MergeError(
+ i"""cannot merge
+ | $sym1: ${sym1.info} and
+ | $sym2: ${sym2.info};
+ |they are both defined in ${sym1.owner} but have matching signatures
+ | ${denot1.info} and
+ | ${denot2.info}$fromWhere""".stripMargin,
+ denot2.info, denot2.info)
+ }
+
+
// --------------- PreDenotations -------------------------------------------------
/** A PreDenotation represents a group of single denotations