Skip to content

Commit e6b4204

Browse files
committed
Moved inline logic before pickler.
The test case failed due to separate compilation. The problem was that we don't pickle the fact that the field was made public. Original patch by @odersky. Cleaned up by me. Changes I made: * removed stale test-case * reduced whitespace changes Supersedes #1089. Review by @odersky and @moors.
1 parent 7d3b2de commit e6b4204

File tree

6 files changed

+103
-76
lines changed

6 files changed

+103
-76
lines changed

src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -497,16 +497,7 @@ abstract class ExplicitOuter extends InfoTransform
497497
else atPos(tree.pos)(outerPath(outerValue, currentClass.outerClass, sym)) // (5)
498498

499499
case Select(qual, name) =>
500-
/** return closest enclosing method, unless shadowed by an enclosing class;
501-
* no use of closures here in the interest of speed.
502-
*/
503-
def closestEnclMethod(from: Symbol): Symbol =
504-
if (from.isSourceMethod) from
505-
else if (from.isClass) NoSymbol
506-
else closestEnclMethod(from.owner)
507-
508-
if (currentClass != sym.owner ||
509-
(closestEnclMethod(currentOwner) hasAnnotation ScalaInlineClass))
500+
if (currentClass != sym.owner)
510501
sym.makeNotPrivate(sym.owner)
511502

512503
val qsym = qual.tpe.widen.typeSymbol

src/compiler/scala/tools/nsc/transform/ExtensionMethods.scala

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,6 @@ abstract class ExtensionMethods extends Transform with TypingTransformers {
2828
/** the following two members override abstract members in Transform */
2929
val phaseName: String = "extmethods"
3030

31-
/** The following flags may be set by this phase: */
32-
override def phaseNewFlags: Long = notPRIVATE
33-
3431
def newTransformer(unit: CompilationUnit): Transformer =
3532
new Extender(unit)
3633

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

Lines changed: 80 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,9 @@ abstract class SuperAccessors extends transform.Transform with transform.TypingT
3434
/** the following two members override abstract members in Transform */
3535
val phaseName: String = "superaccessors"
3636

37+
/** The following flags may be set by this phase: */
38+
override def phaseNewFlags: Long = notPRIVATE
39+
3740
protected def newTransformer(unit: CompilationUnit): Transformer =
3841
new SuperAccTransformer(unit)
3942

@@ -192,9 +195,11 @@ abstract class SuperAccessors extends transform.Transform with transform.TypingT
192195
}
193196
}
194197
super.transform(tree)
198+
195199
case ModuleDef(_, _, _) =>
196200
checkCompanionNameClashes(sym)
197201
super.transform(tree)
202+
198203
case Template(_, _, body) =>
199204
val ownAccDefs = new ListBuffer[Tree]
200205
accDefs(currentOwner) = ownAccDefs
@@ -221,82 +226,92 @@ abstract class SuperAccessors extends transform.Transform with transform.TypingT
221226
typeDef.symbol.deSkolemize.setFlag(SPECIALIZED)
222227
typeDef
223228

224-
case sel @ Select(qual @ This(_), name) =>
225-
// warn if they are selecting a private[this] member which
226-
// also exists in a superclass, because they may be surprised
227-
// to find out that a constructor parameter will shadow a
228-
// field. See SI-4762.
229-
if (settings.lint.value) {
230-
if (sym.isPrivateLocal && sym.paramss.isEmpty) {
231-
qual.symbol.ancestors foreach { parent =>
232-
parent.info.decls filterNot (x => x.isPrivate || x.hasLocalFlag) foreach { m2 =>
233-
if (sym.name == m2.name && m2.isGetter && m2.accessed.isMutable) {
234-
unit.warning(sel.pos,
235-
sym.accessString + " " + sym.fullLocationString + " shadows mutable " + m2.name
236-
+ " inherited from " + m2.owner + ". Changes to " + m2.name + " will not be visible within "
237-
+ sym.owner + " - you may want to give them distinct names."
238-
)
229+
case sel @ Select(qual, name) =>
230+
/** return closest enclosing method, unless shadowed by an enclosing class;
231+
* no use of closures here in the interest of speed.
232+
*/
233+
def closestEnclMethod(from: Symbol): Symbol =
234+
if (from.isSourceMethod) from
235+
else if (from.isClass) NoSymbol
236+
else closestEnclMethod(from.owner)
237+
238+
if (closestEnclMethod(currentOwner) hasAnnotation definitions.ScalaInlineClass)
239+
sym.makeNotPrivate(sym.owner)
240+
241+
qual match {
242+
case This(_) =>
243+
// warn if they are selecting a private[this] member which
244+
// also exists in a superclass, because they may be surprised
245+
// to find out that a constructor parameter will shadow a
246+
// field. See SI-4762.
247+
if (settings.lint.value) {
248+
if (sym.isPrivateLocal && sym.paramss.isEmpty) {
249+
qual.symbol.ancestors foreach { parent =>
250+
parent.info.decls filterNot (x => x.isPrivate || x.hasLocalFlag) foreach { m2 =>
251+
if (sym.name == m2.name && m2.isGetter && m2.accessed.isMutable) {
252+
unit.warning(sel.pos,
253+
sym.accessString + " " + sym.fullLocationString + " shadows mutable " + m2.name
254+
+ " inherited from " + m2.owner + ". Changes to " + m2.name + " will not be visible within "
255+
+ sym.owner + " - you may want to give them distinct names.")
256+
}
257+
}
239258
}
240259
}
241260
}
242-
}
243-
}
244261

245-
// direct calls to aliases of param accessors to the superclass in order to avoid
246-
// duplicating fields.
247-
if (sym.isParamAccessor && sym.alias != NoSymbol) {
248-
val result = (localTyper.typedPos(tree.pos) {
249-
Select(Super(qual, tpnme.EMPTY) setPos qual.pos, sym.alias)
250-
}).asInstanceOf[Select]
251-
debuglog("alias replacement: " + tree + " ==> " + result);//debug
252-
localTyper.typed(gen.maybeMkAsInstanceOf(transformSuperSelect(result), sym.tpe, sym.alias.tpe, true))
253-
}
254-
else {
255-
/** A trait which extends a class and accesses a protected member
256-
* of that class cannot implement the necessary accessor method
257-
* because its implementation is in an implementation class (e.g.
258-
* Foo$class) which inherits nothing, and jvm access restrictions
259-
* require the call site to be in an actual subclass. So non-trait
260-
* classes inspect their ancestors for any such situations and
261-
* generate the accessors. See SI-2296.
262-
*/
263-
// FIXME - this should be unified with needsProtectedAccessor, but some
264-
// subtlety which presently eludes me is foiling my attempts.
265-
val shouldEnsureAccessor = (
266-
currentClass.isTrait
267-
&& sym.isProtected
268-
&& sym.enclClass != currentClass
269-
&& !sym.owner.isTrait
270-
&& (sym.owner.enclosingPackageClass != currentClass.enclosingPackageClass)
271-
&& (qual.symbol.info.member(sym.name) ne NoSymbol)
272-
)
273-
if (shouldEnsureAccessor) {
274-
log("Ensuring accessor for call to protected " + sym.fullLocationString + " from " + currentClass)
275-
ensureAccessor(sel)
276-
}
277-
else
278-
mayNeedProtectedAccessor(sel, List(EmptyTree), false)
279-
}
262+
// direct calls to aliases of param accessors to the superclass in order to avoid
263+
// duplicating fields.
264+
if (sym.isParamAccessor && sym.alias != NoSymbol) {
265+
val result = (localTyper.typedPos(tree.pos) {
266+
Select(Super(qual, tpnme.EMPTY) setPos qual.pos, sym.alias)
267+
}).asInstanceOf[Select]
268+
debuglog("alias replacement: " + tree + " ==> " + result); //debug
269+
localTyper.typed(gen.maybeMkAsInstanceOf(transformSuperSelect(result), sym.tpe, sym.alias.tpe, true))
270+
} else {
271+
/**
272+
* A trait which extends a class and accesses a protected member
273+
* of that class cannot implement the necessary accessor method
274+
* because its implementation is in an implementation class (e.g.
275+
* Foo$class) which inherits nothing, and jvm access restrictions
276+
* require the call site to be in an actual subclass. So non-trait
277+
* classes inspect their ancestors for any such situations and
278+
* generate the accessors. See SI-2296.
279+
*/
280+
// FIXME - this should be unified with needsProtectedAccessor, but some
281+
// subtlety which presently eludes me is foiling my attempts.
282+
val shouldEnsureAccessor = (
283+
currentClass.isTrait
284+
&& sym.isProtected
285+
&& sym.enclClass != currentClass
286+
&& !sym.owner.isTrait
287+
&& (sym.owner.enclosingPackageClass != currentClass.enclosingPackageClass)
288+
&& (qual.symbol.info.member(sym.name) ne NoSymbol))
289+
if (shouldEnsureAccessor) {
290+
log("Ensuring accessor for call to protected " + sym.fullLocationString + " from " + currentClass)
291+
ensureAccessor(sel)
292+
} else
293+
mayNeedProtectedAccessor(sel, List(EmptyTree), false)
294+
}
280295

281-
case sel @ Select(Super(_, mix), name) =>
282-
if (sym.isValue && !sym.isMethod || sym.hasAccessorFlag) {
283-
if (!settings.overrideVars.value)
284-
unit.error(tree.pos, "super may be not be used on "+ sym.accessedOrSelf)
285-
}
286-
else if (isDisallowed(sym)) {
287-
unit.error(tree.pos, "super not allowed here: use this." + name.decode + " instead")
296+
case Super(_, mix) =>
297+
if (sym.isValue && !sym.isMethod || sym.hasAccessorFlag) {
298+
if (!settings.overrideVars.value)
299+
unit.error(tree.pos, "super may be not be used on " + sym.accessedOrSelf)
300+
} else if (isDisallowed(sym)) {
301+
unit.error(tree.pos, "super not allowed here: use this." + name.decode + " instead")
302+
}
303+
transformSuperSelect(sel)
304+
305+
case _ =>
306+
mayNeedProtectedAccessor(sel, List(EmptyTree), true)
288307
}
289-
transformSuperSelect(sel)
290308

291309
case DefDef(mods, name, tparams, vparamss, tpt, rhs) if tree.symbol.isMethodWithExtension =>
292310
treeCopy.DefDef(tree, mods, name, tparams, vparamss, tpt, withInvalidOwner(transform(rhs)))
293311

294312
case TypeApply(sel @ Select(qual, name), args) =>
295313
mayNeedProtectedAccessor(sel, args, true)
296314

297-
case sel @ Select(qual, name) =>
298-
mayNeedProtectedAccessor(sel, List(EmptyTree), true)
299-
300315
case Assign(lhs @ Select(qual, name), rhs) =>
301316
if (lhs.symbol.isVariable &&
302317
lhs.symbol.isJavaDefined &&
@@ -311,10 +326,12 @@ abstract class SuperAccessors extends transform.Transform with transform.TypingT
311326
case Apply(fn, args) =>
312327
assert(fn.tpe != null, tree)
313328
treeCopy.Apply(tree, transform(fn), transformArgs(fn.tpe.params, args))
329+
314330
case Function(vparams, body) =>
315331
withInvalidOwner {
316332
treeCopy.Function(tree, vparams, transform(body))
317333
}
334+
318335
case _ =>
319336
super.transform(tree)
320337
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
-optimise -Xfatal-warnings -Yinline-warnings
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
package test
2+
3+
object A {
4+
5+
private var x: Int = 0
6+
7+
@inline def actOnX(f: Int => Int) = {
8+
x = f(x)
9+
}
10+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
package test
2+
3+
object Test {
4+
5+
def main(args: Array[String]) {
6+
7+
A.actOnX(_ + 1)
8+
9+
}
10+
11+
}

0 commit comments

Comments
 (0)