summaryrefslogtreecommitdiff
path: root/src/reflect/scala/reflect/runtime/JavaUniverseForce.scala
diff options
context:
space:
mode:
authorJason Zaugg <jzaugg@gmail.com>2014-01-31 14:29:19 +0100
committerAdriaan Moors <adriaan.moors@typesafe.com>2014-02-10 14:39:18 -0800
commit8d96380caeb1f03da8916d494e878f57a363f459 (patch)
treec297c3e0e1348ecffd1cbb8d4b642e2dbf01a2d6 /src/reflect/scala/reflect/runtime/JavaUniverseForce.scala
parentaebe379a14ab7b2a3bce35a6faa9d9232c748154 (diff)
downloadscala-8d96380caeb1f03da8916d494e878f57a363f459.tar.gz
scala-8d96380caeb1f03da8916d494e878f57a363f459.tar.bz2
scala-8d96380caeb1f03da8916d494e878f57a363f459.zip
SI-7475 Private members are not inheritable
It turns out `findMembers` has been a bit sloppy in recent years and has returned private members from *anywhere* up the base class sequence. Access checks usually pick up the slack and eliminate the unwanted privates. But, in concert with the "concrete beats abstract" rule in `findMember`, the following mishap appeared: scala> :paste // Entering paste mode (ctrl-D to finish) trait T { def a: Int } trait B { private def a: Int = 0 } trait C extends T with B { a } // Exiting paste mode, now interpreting. <console>:9: error: method a in trait B cannot be accessed in C trait C extends T with B { a } ^ I noticed this when compiling Akka against JDK 8; a new private method in the bowels of the JDK was enough to break the build! It turns out that some finesse in needed to interpret SLS 5.2: > The private modifier can be used with any definition or declaration > in a template. They are not inherited by subclasses [...] So, can we simply exclude privates from all but the first base class? No, as that might be a refinement class! The following must be allowed: trait A { private def foo = 0; trait T { self: A => this.foo } } This commit: - tracks when the walk up the base class sequence passes the first non-refinement class, and excludes private members - ... except, if we are at a direct parent of a refinement class itself - Makes a corresponding change to OverridingPairs, to only consider private members if they are owned by the `base` Symbol under consideration. We don't need to deal with the subtleties of refinements there as that code is only used for bona-fide classes. - replaces use of `hasTransOwner` when considering whether a private[this] symbol is a member. The last condition was not grounded in the spec at all. The change is visible in cases like: // Old scala> trait A { private[this] val x = 0; class B extends A { this.x } } <console>:7: error: value x in trait A cannot be accessed in A.this.B trait A { private[this] val x = 0; class B extends A { this.x } } ^ // New scala> trait A { private[this] val x = 0; class B extends A { this.x } } <console>:8: error: value x is not a member of A.this.B trait A { private[this] val x = 0; class B extends A { this.x } } ^ Furthermore, we no longer give a `private[this]` member a free pass if it is sourced from the very first base class. trait Cake extends Slice { private[this] val bippy = () } trait Slice { self: Cake => bippy // BCS: Cake, Slice, AnyRef, Any } The different handling between `private` and `private[this]` still seems a bit dubious. The spec says: > An different form of qualification is private[this]. A member M > marked with this modifier can be accessed only from within the > object in which it is defined. That is, a selection p.M is only > legal if the prefix is this or O.this, for some class O enclosing > the reference. In addition, the restrictions for unqualified > private apply. This sounds like a question of access, not membership. If so, we should admit `private[this]` members from parents of refined types in `FindMember`. AFAICT, not too much rests on the distinction: do we get a "no such member", or "member foo inaccessible" error? I welcome scrutinee of the checkfile of `neg/t7475f.scala` to help put this last piece into the puzzle. One more thing: findMember does not have *any* code the corresponds to the last sentence of: > SLS 5.2 The modifier can be qualified with an identifier C > (e.g. private[C]) that must denote a class or package enclosing > the definition. Members labeled with such a modifier are accessible > respectively only from code inside the package C or only from code > inside the class C and its companion module (ยง5.4). > Such members are also inherited only from templates inside C. When I showed Martin this, he suggested it was an error in the spec, and we should leave the access checking to callers of that inherited qualified-private member.
Diffstat (limited to 'src/reflect/scala/reflect/runtime/JavaUniverseForce.scala')
-rw-r--r--src/reflect/scala/reflect/runtime/JavaUniverseForce.scala31
1 files changed, 0 insertions, 31 deletions
diff --git a/src/reflect/scala/reflect/runtime/JavaUniverseForce.scala b/src/reflect/scala/reflect/runtime/JavaUniverseForce.scala
index fb893cbff1..0fcf215580 100644
--- a/src/reflect/scala/reflect/runtime/JavaUniverseForce.scala
+++ b/src/reflect/scala/reflect/runtime/JavaUniverseForce.scala
@@ -27,27 +27,8 @@ trait JavaUniverseForce { self: runtime.JavaUniverse =>
this.settings
this.treeInfo
- // inaccessible: this.scala$reflect$runtime$Gil$$gil
- // inaccessible: this.uniqueLock
- // inaccessible: this._skolemizationLevel
- // inaccessible: this._undoLog
- // inaccessible: this._intersectionWitness
- // inaccessible: this._subsametypeRecursions
- // inaccessible: this._pendingSubTypes
- // inaccessible: this._basetypeRecursions
- // inaccessible: this._pendingBaseTypes
- // inaccessible: this._lubResults
- // inaccessible: this._glbResults
- // inaccessible: this._indent
- // inaccessible: this._toStringRecursions
- // inaccessible: this._toStringSubjects
- // inaccessible: this.atomicIds
- // inaccessible: this.atomicExistentialIds
- // inaccessible: this._recursionTable
- // inaccessible: this.mirrors
this.rootMirror
this.treeBuild
- // inaccessible: this.SimpleNameOrdering
this.traceSymbols
this.perRunCaches
this.FreshNameExtractor
@@ -60,7 +41,6 @@ trait JavaUniverseForce { self: runtime.JavaUniverse =>
this.SubpatternsAttachment
this.noPrint
this.typeDebug
- // inaccessible: this.maxFree
this.Range
// inaccessible: this.posAssigner
this.ConsoleWriter
@@ -116,7 +96,6 @@ trait JavaUniverseForce { self: runtime.JavaUniverse =>
this.pendingSuperCall
this.emptyValDef
this.EmptyTreeTypeSubstituter
- // inaccessible: this.duplicator
this.UnmappableAnnotArg
this.LiteralAnnotArg
this.ArrayAnnotArg
@@ -127,7 +106,6 @@ trait JavaUniverseForce { self: runtime.JavaUniverse =>
this.UnmappableAnnotation
this.ErroneousAnnotation
this.ThrownException
- // inaccessible: this.compactify
this.tpnme
this.fulltpnme
this.binarynme
@@ -147,7 +125,6 @@ trait JavaUniverseForce { self: runtime.JavaUniverse =>
this.ProperTypeKind
this.TypeConKind
this.inferKind
- // inaccessible: this.substTypeMapCache
this.UnmappableTree
this.ErrorType
this.WildcardType
@@ -184,9 +161,6 @@ trait JavaUniverseForce { self: runtime.JavaUniverse =>
this.unwrapToStableClass
this.unwrapWrapperTypes
this.RecoverableCyclicReference
- // inaccessible: this._undoLog
- // inaccessible: this.numericLoBound
- // inaccessible: this.numericHiBound
this.TypeConstraint
this.normalizeAliases
this.dropSingletonType
@@ -198,19 +172,16 @@ trait JavaUniverseForce { self: runtime.JavaUniverse =>
this.typeVarToOriginMap
this.ErroneousCollector
this.adaptToNewRunMap
- // inaccessible: this.commonOwnerMapObj
this.SubTypePair
this.SymbolKind
this.NoSymbol
this.CyclicReference
- // inaccessible: this.TypeHistory
this.SymbolOps
this.TermName
this.TypeName
this.Liftable
this.Unliftable
this.BooleanFlag
- // inaccessible: this.CachedNames
this.WeakTypeTag
this.TypeTag
this.Expr
@@ -427,14 +398,12 @@ trait JavaUniverseForce { self: runtime.JavaUniverse =>
definitions.languageFeatureModule
definitions.metaAnnotations
definitions.AnnotationDefaultAttr
- // inaccessible: definitions.erasurePhase
definitions.isPhantomClass
definitions.syntheticCoreClasses
definitions.syntheticCoreMethods
definitions.hijackedCoreClasses
definitions.symbolsNotPresentInBytecode
definitions.isPossibleSyntheticParent
- // inaccessible: definitions.boxedValueClassesSet
definitions.abbrvTag
definitions.numericWeight
definitions.boxedModule