diff options
author | Martin Odersky <odersky@gmail.com> | 2016-05-02 15:51:41 +0200 |
---|---|---|
committer | Martin Odersky <odersky@gmail.com> | 2016-05-18 19:43:22 +0200 |
commit | 48b716012bd72486dbf4a2bd3b293ef212f4addd (patch) | |
tree | 22e3deb275d86a1ddaa6821a7740170f64f639be /src/dotty/tools/dotc/core/Denotations.scala | |
parent | 968f1ab0cd706de8833112741407f94a6a0b2677 (diff) | |
download | dotty-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.scala | 37 |
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 |