@@ -12,6 +12,7 @@ import DenotTransformers._
1212import NameOps ._
1313import NameKinds ._
1414import ResolveSuper ._
15+ import reporting .diagnostic .messages .IllegalSuperAccessor
1516
1617/** This phase adds super accessors and method overrides where
1718 * linearization differs from Java's rule for default methods in interfaces.
@@ -100,65 +101,17 @@ object ResolveSuper {
100101 val SuperAccessorName (memberName) = acc.name.unexpandedName
101102 ctx.debuglog(i " starting rebindsuper from $base of ${acc.showLocated}: ${acc.info} in $bcs, name = $memberName" )
102103 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
110109 // Having a matching denotation is not enough: it should also be a subtype
111110 // 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
113112 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)
162115 }
163116
164117 bcs = bcs.tail
0 commit comments