diff options
author | Paul Phillips <paulp@improving.org> | 2011-10-22 05:06:57 +0000 |
---|---|---|
committer | Paul Phillips <paulp@improving.org> | 2011-10-22 05:06:57 +0000 |
commit | c7ec0385c7841084634ab39625b3b77df0e7ae2d (patch) | |
tree | c34eb5327d8cf2f17cce0c4d20ff366ce0fb4c47 /src | |
parent | 3a195c71ba21a286d5f7c02ce15a0f22d1503b24 (diff) | |
download | scala-c7ec0385c7841084634ab39625b3b77df0e7ae2d.tar.gz scala-c7ec0385c7841084634ab39625b3b77df0e7ae2d.tar.bz2 scala-c7ec0385c7841084634ab39625b3b77df0e7ae2d.zip |
Warn about surprising shadowing.
It's hidden behind -Xlint and pretty specific, but makes me feel better
anyway. References SI-4762, no review.
Diffstat (limited to 'src')
-rw-r--r-- | src/compiler/scala/reflect/internal/Symbols.scala | 1 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala | 32 |
2 files changed, 27 insertions, 6 deletions
diff --git a/src/compiler/scala/reflect/internal/Symbols.scala b/src/compiler/scala/reflect/internal/Symbols.scala index bd9164cfc4..00e9200076 100644 --- a/src/compiler/scala/reflect/internal/Symbols.scala +++ b/src/compiler/scala/reflect/internal/Symbols.scala @@ -1923,6 +1923,7 @@ trait Symbols extends api.Symbols { self: SymbolTable => else if (owner.isRefinementClass) ExplicitFlags & ~OVERRIDE else ExplicitFlags + def accessString = hasFlagsToString(PRIVATE | PROTECTED | LOCAL) def defaultFlagString = hasFlagsToString(defaultFlagMask) private def defStringCompose(infoString: String) = compose( defaultFlagString, diff --git a/src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala b/src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala index 0beb01cc71..8e00c850ef 100644 --- a/src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala +++ b/src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala @@ -191,13 +191,33 @@ abstract class SuperAccessors extends transform.Transform with transform.TypingT mayNeedProtectedAccessor(sel, args, false) case sel @ Select(qual @ This(_), name) => - // direct calls to aliases of param accessors to the superclass in order to avoid - // duplicating fields. - if (sym.isParamAccessor && sym.alias != NoSymbol) { + // warn if they are selecting a private[this] member which + // also exists in a superclass, because they may be surprised + // to find out that a constructor parameter will shadow a + // field. See SI-4762. + if (settings.lint.value) { + if (sym.isPrivateLocal && sym.paramss.isEmpty) { + qual.symbol.ancestors foreach { parent => + parent.info.decls filterNot (x => x.isPrivate || x.hasLocalFlag) foreach { m2 => + if (sym.name == m2.name && m2.isGetter && m2.accessed.isMutable) { + unit.warning(sel.pos, + sym.accessString + " " + sym.fullLocationString + " shadows mutable " + m2.name + + " inherited from " + m2.owner + ". Changes to " + m2.name + " will not be visible within " + + sym.owner + " - you may want to give them distinct names." + ) + } + } + } + } + } + + // direct calls to aliases of param accessors to the superclass in order to avoid + // duplicating fields. + if (sym.isParamAccessor && sym.alias != NoSymbol) { val result = localTyper.typed { - Select( - Super(qual, tpnme.EMPTY/*qual.symbol.info.parents.head.symbol.name*/) setPos qual.pos, - sym.alias) setPos tree.pos + Select( + Super(qual, tpnme.EMPTY/*qual.symbol.info.parents.head.symbol.name*/) setPos qual.pos, + sym.alias) setPos tree.pos } debuglog("alias replacement: " + tree + " ==> " + result);//debug localTyper.typed(gen.maybeMkAsInstanceOf(transformSuperSelect(result), sym.tpe, sym.alias.tpe, true)) |