Skip to content

Commit af03afb

Browse files
author
James Iry
committed
SI-6536 Cleanup code around determining accessor requirement
Moves the logic for the condition on requiring an accessor into a local method with a match to make thing cleaner. Also determines the mix type using a pattern match that logs but does not fail if the symbol isn't of the expected type. Finally fixes a typo in an assertion in GenICode. review @paulp
1 parent 2124b9d commit af03afb

File tree

2 files changed

+26
-12
lines changed

2 files changed

+26
-12
lines changed

src/compiler/scala/tools/nsc/backend/icode/GenICode.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -770,7 +770,7 @@ abstract class GenICode extends SubComponent {
770770
case Apply(fun @ Select(Super(qual, mix), _), args) =>
771771

772772
if (!qual.isInstanceOf[This]) {
773-
log("WARNING: super call where selector isn't 'this'. May generate invalid bytecode. Previous phases should have tansformed away this form of super.")
773+
log("WARNING: super call where selector isn't 'this'. May generate invalid bytecode. Previous phases should have transformed away this form of super.")
774774
}
775775
if (settings.debug.value)
776776
log("Call to super: " + tree)

src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala

Lines changed: 25 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,6 @@ abstract class SuperAccessors extends transform.Transform with transform.TypingT
110110
val Select(sup @ Super(_, mix), name) = sel
111111
val sym = sel.symbol
112112
val clazz = sup.symbol
113-
val SuperType(_, mixtpe) = sup.tpe
114113

115114
if (sym.isDeferred) {
116115
val member = sym.overridingSymbol(clazz);
@@ -120,20 +119,35 @@ abstract class SuperAccessors extends transform.Transform with transform.TypingT
120119
"unless it is overridden by a member declared `abstract' and `override'");
121120
}
122121

122+
// determine if the mix in clazz.super[mix].name is a trait
123+
def mixTpeIsTrait = sup.tpe match {
124+
case SuperType(_, mixTpe) => mixTpe.typeSymbol.isTrait
125+
case _ =>
126+
log("Warning: could not determine the type of mix " + mix + " by going through a Super node's "+
127+
"type because instead of a SuperType it was " + sup.tpe)
128+
false
129+
}
130+
123131
// we need an accessor to get to a super on an outer thing, but only if we can't call name more directly on
124132
// a trait implementation class. So this complicated condition is leaving alone cases where we don't need to do
125133
// anything special (i.e. we're getting a direct super class) or where a later transform will inject a call to
126134
// a trait implementation method directly.
127-
// So, we're looking for items of the form clazz.super[mix].name (or clazz.super.name wich is seen as clazz.super[EMPTY].name.
128-
// with some limitations. First, name has to be a term rather than a type.
129-
// Then there are a couple of cases. If mix is empty then we only need an accessor if clazz is a trait, it's not this current class,
130-
// or the validCurentOwner setting is false...which...ugh, is a mess.
131-
// If the mix is set then if it refers to a class and the clazz part isn't the current class
132-
// it's not just super[mix].name then we need to generate an accessor.
133-
// SI-6536 has more discussion about how this works.
134-
if (name.isTermName && (mix == tpnme.EMPTY && (clazz.isTrait || clazz != currentClass || !validCurrentOwner ))
135-
|| (mix != tpnme.EMPTY && !mixtpe.typeSymbol.isTrait && clazz != currentClass))
136-
ensureAccessor(sel)
135+
//
136+
// SI-6536 has more discussion about how this works.
137+
//
138+
// So, we're looking for items of the form clazz.super[mix].name (or clazz.super.name wich is seen as
139+
// clazz.super[EMPTY].name with some limitations. First, name has to be a term rather than a type.
140+
// Then there are a couple of cases.
141+
def requiresAccessor = name.isTermName && (mix match {
142+
// If mix is empty then we only need an accessor if clazz is a trait, it's not this current class,
143+
// or the validCurentOwner setting is false...which...ugh, is a mess.
144+
case tpnme.EMPTY => clazz.isTrait || clazz != currentClass || !validCurrentOwner
145+
// If the mix is set then if it refers to a class and the clazz part isn't the current class
146+
// it's not just super[mix].name then we need to generate an accessor.
147+
case _ => clazz != currentClass && !mixTpeIsTrait
148+
})
149+
150+
if (requiresAccessor) ensureAccessor(sel)
137151
else sel
138152
}
139153

0 commit comments

Comments
 (0)