@@ -16,6 +16,7 @@ class Bridges(root: ClassSymbol)(implicit ctx: Context) {
1616
1717 assert(ctx.phase == ctx.erasurePhase.next)
1818 private val preErasureCtx = ctx.withPhase(ctx.erasurePhase)
19+ private val elimErasedCtx = ctx.withPhase(ctx.elimErasedValueTypePhase.next)
1920
2021 private class BridgesCursor (implicit ctx : Context ) extends OverridingPairs .Cursor (root) {
2122
@@ -35,31 +36,47 @@ class Bridges(root: ClassSymbol)(implicit ctx: Context) {
3536 private val bridgesScope = newScope
3637 private val bridgeTarget = newMutableSymbolMap[Symbol ]
3738
39+ def bridgePosFor (member : Symbol ) =
40+ if (member.owner == root && member.pos.exists) member.pos else root.pos
41+
3842 /** Add a bridge between `member` and `other`, where `member` overrides `other`
3943 * before erasure, if the following conditions are satisfied.
4044 *
41- * - `member` and other have different signatures
42- * - there is not yet a bridge with the same name and signature in `root`
45+ * - `member` and ` other` have different signatures
46+ * - there is not yet a bridge with the same name and signature in `root`.
4347 *
4448 * The bridge has the erased info of `other` and forwards to `member`.
49+ * Additionally, if `member` and `other` do have the same signature,
50+ * but not the same type after erasure and before elimErasedValueTypes
51+ * issue an error: A bridge would be needed yet it would clash with the member itself.
52+ * See neg/i1905.scala
4553 */
4654 private def addBridgeIfNeeded (member : Symbol , other : Symbol ) = {
4755 def bridgeExists =
4856 bridgesScope.lookupAll(member.name).exists(bridge =>
4957 bridgeTarget(bridge) == member && bridge.signature == other.signature)
50- if (! (member.signature == other.signature || bridgeExists))
58+ def info (sym : Symbol )(implicit ctx : Context ) = sym.info
59+ def desc (sym : Symbol )= i " $sym${info(sym)(preErasureCtx)} in ${sym.owner}"
60+ if (member.signature == other.signature) {
61+ if (! member.info.matches(other.info))
62+ ctx.error(em """ bridge generated for member ${desc(member)}
63+ |which overrides ${desc(other)}
64+ |clashes with definition of the member itself; both have erased type ${info(member)(elimErasedCtx)}." """ ,
65+ bridgePosFor(member))
66+ }
67+ else if (! bridgeExists)
5168 addBridge(member, other)
5269 }
5370
5471 /** Generate bridge between `member` and `other`
5572 */
5673 private def addBridge (member : Symbol , other : Symbol ) = {
57- val bridgePos = if (member.owner == root && member.pos.exists) member.pos else root.pos
5874 val bridge = other.copy(
5975 owner = root,
6076 flags = (member.flags | Method | Bridge | Artifact ) &~
6177 (Accessor | ParamAccessor | CaseAccessor | Deferred | Lazy | Module ),
62- coord = bridgePos).enteredAfter(ctx.erasurePhase.asInstanceOf [DenotTransformer ]).asTerm
78+ coord = bridgePosFor(member))
79+ .enteredAfter(ctx.erasurePhase.asInstanceOf [DenotTransformer ]).asTerm
6380
6481 ctx.debuglog(
6582 i """ generating bridge from ${other.showLocated}: ${other.info}
0 commit comments