summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorPaul Phillips <paulp@improving.org>2011-10-22 05:06:57 +0000
committerPaul Phillips <paulp@improving.org>2011-10-22 05:06:57 +0000
commitc7ec0385c7841084634ab39625b3b77df0e7ae2d (patch)
treec34eb5327d8cf2f17cce0c4d20ff366ce0fb4c47 /src
parent3a195c71ba21a286d5f7c02ce15a0f22d1503b24 (diff)
downloadscala-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.scala1
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala32
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))