@@ -12,6 +12,7 @@ import DenotTransformers._
12
12
import NameOps ._
13
13
import NameKinds ._
14
14
import ResolveSuper ._
15
+ import reporting .diagnostic .messages .IllegalSuperAccessor
15
16
16
17
/** This phase adds super accessors and method overrides where
17
18
* linearization differs from Java's rule for default methods in interfaces.
@@ -100,65 +101,17 @@ object ResolveSuper {
100
101
val SuperAccessorName (memberName) = acc.name.unexpandedName
101
102
ctx.debuglog(i " starting rebindsuper from $base of ${acc.showLocated}: ${acc.info} in $bcs, name = $memberName" )
102
103
while (bcs.nonEmpty && sym == NoSymbol ) {
103
- val cur = bcs.head
104
- val other = cur.info.nonPrivateDecl(memberName)
105
- if (ctx.settings.Ydebug .value)
106
- ctx.log(i " rebindsuper ${bcs.head} $other deferred = ${other.symbol.is(Deferred )}" )
107
- val otherMember = other.matchingDenotation(base.thisType, base.thisType.memberInfo(acc))
108
- if (otherMember.exists) {
109
- sym = otherMember.symbol
104
+ val other = bcs.head.info.nonPrivateDecl(memberName)
105
+ .matchingDenotation(base.thisType, base.thisType.memberInfo(acc))
106
+ ctx.debuglog(i " rebindsuper ${bcs.head} $other deferred = ${other.symbol.is(Deferred )}" )
107
+ if (other.exists) {
108
+ sym = other.symbol
110
109
// Having a matching denotation is not enough: it should also be a subtype
111
110
// of the superaccessor's type, see i5433.scala for an example where this matters
112
- val otherTp = otherMember .asSeenFrom(base.typeRef).info
111
+ val otherTp = other .asSeenFrom(base.typeRef).info
113
112
val accTp = acc.asSeenFrom(base.typeRef).info
114
- if (! (otherTp <:< accTp)) {
115
- // The mixin containing a super-call that requires a super-accessor
116
- val mixin = acc.owner
117
- // The super-call in `mixin`
118
- val superCall = i " super. $memberName"
119
- // The super-call that we end up trying to call
120
- val resolvedSuperCall = i " super[ ${cur.name}]. $memberName"
121
- // The super-call that we would have called if `super` in traits behaved like it
122
- // does in classes, i.e. followed the linearization of the trait itself.
123
- val staticSuperCall = {
124
- val staticSuper = mixin.asClass.info.parents.reverse
125
- .find(_.nonPrivateMember(memberName).matchingDenotation(mixin.thisType, acc.info).exists)
126
- val staticSuperName = staticSuper match {
127
- case Some (parent) =>
128
- parent.classSymbol.name.show
129
- case None => // Might be reachable under separate compilation
130
- " SomeParent"
131
- }
132
- i " super[ $staticSuperName]. $memberName"
133
- }
134
- ctx.error(
135
- hl """ $base cannot be defined due to a conflict between its parents when
136
- |implementing a super-accessor for $memberName in $mixin:
137
- |
138
- |1. One of its parent ( $mixin) contains a call $superCall in its body,
139
- | and when a super-call in a trait is written without an explicit parent
140
- | listed in brackets, it is implemented by a generated super-accessor in
141
- | the class that extends this trait based on the linearization order of
142
- | the class.
143
- |2. Because ${cur.name} comes before ${mixin.name} in the linearization
144
- | order of ${base.name}, and because ${cur.name} overrides $memberName,
145
- | the super-accessor in ${base.name} is implemented as a call to
146
- | $resolvedSuperCall.
147
- |3. However,
148
- | ${otherTp.widenExpr} (the type of $resolvedSuperCall in ${base.name})
149
- | is not a subtype of
150
- | ${accTp.widenExpr} (the type of $memberName in $mixin).
151
- | Hence, the super-accessor that needs to be generated in ${base.name}
152
- | is illegal.
153
- |
154
- |Here are two possible ways to resolve this:
155
- |
156
- |1. Change the linearization order of ${base.name} such that
157
- | ${mixin.name} comes before ${cur.name}.
158
- |2. Alternatively, replace $superCall in the body of $mixin by a
159
- | super-call to a specific parent, e.g. $staticSuperCall
160
- | """ .stripMargin, base.sourcePos)
161
- }
113
+ if (! (otherTp <:< accTp))
114
+ ctx.error(IllegalSuperAccessor (base, memberName, acc, accTp, other.symbol, otherTp), base.sourcePos)
162
115
}
163
116
164
117
bcs = bcs.tail
0 commit comments