diff options
Diffstat (limited to 'src')
4 files changed, 56 insertions, 57 deletions
diff --git a/src/compiler/scala/tools/nsc/transform/OverridingPairs.scala b/src/compiler/scala/tools/nsc/transform/OverridingPairs.scala index 870eafbf20..bbd11efa7e 100644 --- a/src/compiler/scala/tools/nsc/transform/OverridingPairs.scala +++ b/src/compiler/scala/tools/nsc/transform/OverridingPairs.scala @@ -24,7 +24,12 @@ abstract class OverridingPairs extends SymbolPairs { /** Symbols to exclude: Here these are constructors and private/artifact symbols, * including bridges. But it may be refined in subclasses. */ - override protected def exclude(sym: Symbol) = sym.isPrivateLocal || sym.isArtifact || sym.isConstructor + override protected def exclude(sym: Symbol) = ( + sym.isPrivateLocal + || sym.isArtifact + || sym.isConstructor + || (sym.isPrivate && sym.owner != base) // Privates aren't inherited. Needed for pos/t7475a.scala + ) /** Types always match. Term symbols match if their member types * relative to `self` match. diff --git a/src/reflect/scala/reflect/internal/Types.scala b/src/reflect/scala/reflect/internal/Types.scala index 21ce5114e0..cf405ade03 100644 --- a/src/reflect/scala/reflect/internal/Types.scala +++ b/src/reflect/scala/reflect/internal/Types.scala @@ -244,18 +244,6 @@ trait Types } } - /** Same as a call to narrow unless existentials are visible - * after widening the type. In that case, narrow from the widened - * type instead of the proxy. This gives buried existentials a - * chance to make peace with the other types. See SI-5330. - */ - private[internal] def narrowForFindMember(tp: Type): Type = { - val w = tp.widen - // Only narrow on widened type when we have to -- narrow is expensive unless the target is a singleton type. - if ((tp ne w) && containsExistential(w)) w.narrow - else tp.narrow - } - /** The base class for all types */ abstract class Type extends TypeApiImpl with Annotatable[Type] { /** Types for which asSeenFrom always is the identity, no matter what diff --git a/src/reflect/scala/reflect/internal/tpe/FindMembers.scala b/src/reflect/scala/reflect/internal/tpe/FindMembers.scala index be5a3f0983..33eccd8bbd 100644 --- a/src/reflect/scala/reflect/internal/tpe/FindMembers.scala +++ b/src/reflect/scala/reflect/internal/tpe/FindMembers.scala @@ -17,6 +17,10 @@ trait FindMembers { protected val initBaseClasses: List[Symbol] = tpe.baseClasses // The first base class, or the symbol of the ThisType + // e.g in: + // trait T { self: C => } + // + // The selector class of `T.this.type` is `T`, and *not* the first base class, `C`. private[this] var _selectorClass: Symbol = null private def selectorClass: Symbol = { if (_selectorClass eq null) { @@ -68,6 +72,13 @@ trait FindMembers { // Has we seen a candidate deferred member? var deferredSeen = false + // All direct parents of refinement classes in the base class sequence + // from the current `walkBaseClasses` + var refinementParents: List[Symbol] = Nil + + // Has the current `walkBaseClasses` encountered a non-refinement class? + var seenFirstNonRefinementClass = false + while (!bcs.isEmpty) { val currentBaseClass = bcs.head val decls = currentBaseClass.info.decls @@ -80,7 +91,7 @@ trait FindMembers { if (meetsRequirements) { val excl: Long = flags & excluded val isExcluded: Boolean = excl != 0L - if (!isExcluded && isPotentialMember(sym, flags, currentBaseClass)) { + if (!isExcluded && isPotentialMember(sym, flags, currentBaseClass, seenFirstNonRefinementClass, refinementParents)) { if (shortCircuit(sym)) return false else addMemberIfNew(sym) } else if (excl == DEFERRED) { @@ -90,6 +101,17 @@ trait FindMembers { entry = if (findAll) entry.next else decls lookupNextEntry entry } + // SLS 5.2 The private modifier can be used with any definition or declaration in a template. + // They are not inherited by subclasses [...] + if (currentBaseClass.isRefinementClass) + // SLS 3.2.7 A compound type T1 with . . . with Tn {R } represents objects with members as given in + // the component types T1, ..., Tn and the refinement {R } + // + // => private members should be included from T1, ... Tn. (SI-7475) + refinementParents :::= currentBaseClass.parentSymbols + else if (currentBaseClass.isClass) + seenFirstNonRefinementClass = true // only inherit privates of refinement parents after this point + bcs = bcs.tail } deferredSeen @@ -105,28 +127,31 @@ trait FindMembers { // // Q. When does a potential member fail to be a an actual member? // A. if it is subsumed by an member in a subclass. - private def isPotentialMember(sym: Symbol, flags: Long, owner: Symbol): Boolean = { + private def isPotentialMember(sym: Symbol, flags: Long, owner: Symbol, + seenFirstNonRefinementClass: Boolean, refinementParents: List[Symbol]): Boolean = { // conservatively (performance wise) doing this with flags masks rather than `sym.isPrivate` // to avoid multiple calls to `Symbol#flags`. + val isPrivate = (flags & PRIVATE) == PRIVATE val isPrivateLocal = (flags & PrivateLocal) == PrivateLocal - def admitPrivateLocal(sym: Symbol): Boolean = - ( - (selectorClass == owner) - || !isPrivateLocal - || selectorClass.hasTransOwner(owner) // private[this] only a member from within the class (incorrect!) - ) - - // TODO first condition incorrect wrt self types! In neg/t7507, bippy should not be a member! - // The condition, or a close variant thereof, will still be needed to prevent inheritance of constructors. - owner == initBaseClasses.head || admitPrivateLocal(sym) && sym.name != nme.CONSTRUCTOR + // TODO Is the special handling of `private[this]` vs `private` backed up by the spec? + def admitPrivate(sym: Symbol): Boolean = + (selectorClass == owner) || ( + !isPrivateLocal // private[this] only a member from within the selector class. (Optimization only? Does the spec back this up?) + && ( + !seenFirstNonRefinementClass + || refinementParents.contains(owner) + ) + ) + + (!isPrivate || admitPrivate(sym)) && (sym.name != nme.CONSTRUCTOR || owner == initBaseClasses.head) } // True unless the already-found member of type `memberType` matches the candidate symbol `other`. protected def isNewMember(member: Symbol, other: Symbol): Boolean = ( (other ne member) && ( (member.owner eq other.owner) - || (other.flags & PRIVATE) != 0 + || (member.flags & PRIVATE) != 0 || !(memberTypeLow(member) matches memberTypeHi(other)) ) ) @@ -148,6 +173,18 @@ trait FindMembers { // member type of the LHS of `matches` call. This is an extension point to enable a cache in // FindMember. protected def memberTypeLow(sym: Symbol): Type = self.memberType(sym) + + /** Same as a call to narrow unless existentials are visible + * after widening the type. In that case, narrow from the widened + * type instead of the proxy. This gives buried existentials a + * chance to make peace with the other types. See SI-5330. + */ + private def narrowForFindMember(tp: Type): Type = { + val w = tp.widen + // Only narrow on widened type when we have to -- narrow is expensive unless the target is a singleton type. + if ((tp ne w) && containsExistential(w)) w.narrow + else tp.narrow + } } private[reflect] final class FindMembers(tpe: Type, excludedFlags: Long, requiredFlags: Long) 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 |