@@ -16,6 +16,7 @@ class Bridges(root: ClassSymbol)(implicit ctx: Context) {
16
16
17
17
assert(ctx.phase == ctx.erasurePhase.next)
18
18
private val preErasureCtx = ctx.withPhase(ctx.erasurePhase)
19
+ private val elimErasedCtx = ctx.withPhase(ctx.elimErasedValueTypePhase.next)
19
20
20
21
private class BridgesCursor (implicit ctx : Context ) extends OverridingPairs .Cursor (root) {
21
22
@@ -35,31 +36,47 @@ class Bridges(root: ClassSymbol)(implicit ctx: Context) {
35
36
private val bridgesScope = newScope
36
37
private val bridgeTarget = newMutableSymbolMap[Symbol ]
37
38
39
+ def bridgePosFor (member : Symbol ) =
40
+ if (member.owner == root && member.pos.exists) member.pos else root.pos
41
+
38
42
/** Add a bridge between `member` and `other`, where `member` overrides `other`
39
43
* before erasure, if the following conditions are satisfied.
40
44
*
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`.
43
47
*
44
48
* 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
45
53
*/
46
54
private def addBridgeIfNeeded (member : Symbol , other : Symbol ) = {
47
55
def bridgeExists =
48
56
bridgesScope.lookupAll(member.name).exists(bridge =>
49
57
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)
51
68
addBridge(member, other)
52
69
}
53
70
54
71
/** Generate bridge between `member` and `other`
55
72
*/
56
73
private def addBridge (member : Symbol , other : Symbol ) = {
57
- val bridgePos = if (member.owner == root && member.pos.exists) member.pos else root.pos
58
74
val bridge = other.copy(
59
75
owner = root,
60
76
flags = (member.flags | Method | Bridge | Artifact ) &~
61
77
(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
63
80
64
81
ctx.debuglog(
65
82
i """ generating bridge from ${other.showLocated}: ${other.info}
0 commit comments