summaryrefslogtreecommitdiff
path: root/src/compiler
diff options
context:
space:
mode:
authorPaul Phillips <paulp@improving.org>2011-06-29 05:23:02 +0000
committerPaul Phillips <paulp@improving.org>2011-06-29 05:23:02 +0000
commite0a4bbdb39795ed43e487f5ef89e37518eeb6ee9 (patch)
tree45dcca7c2ff7041f70cb26f2892676b97a153aed /src/compiler
parent42fb66a2cbcad4fff0634dc935f135494f04be93 (diff)
downloadscala-e0a4bbdb39795ed43e487f5ef89e37518eeb6ee9.tar.gz
scala-e0a4bbdb39795ed43e487f5ef89e37518eeb6ee9.tar.bz2
scala-e0a4bbdb39795ed43e487f5ef89e37518eeb6ee9.zip
Profiler suggested it would be worthwhile to sh...
Profiler suggested it would be worthwhile to short-circuit allOverriddenSymbols.isEmpty, and one thing led to another. I don't know how much I accomplished performancewise, but the cosmetology is outstanding. Review by moors.
Diffstat (limited to 'src/compiler')
-rw-r--r--src/compiler/scala/reflect/internal/Symbols.scala47
-rw-r--r--src/compiler/scala/reflect/internal/Types.scala10
-rw-r--r--src/compiler/scala/tools/nsc/transform/Constructors.scala2
-rw-r--r--src/compiler/scala/tools/nsc/transform/Erasure.scala8
-rw-r--r--src/compiler/scala/tools/nsc/transform/Mixin.scala8
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/RefChecks.scala35
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Typers.scala137
7 files changed, 131 insertions, 116 deletions
diff --git a/src/compiler/scala/reflect/internal/Symbols.scala b/src/compiler/scala/reflect/internal/Symbols.scala
index 42d15f56ad..ff3677c104 100644
--- a/src/compiler/scala/reflect/internal/Symbols.scala
+++ b/src/compiler/scala/reflect/internal/Symbols.scala
@@ -293,6 +293,7 @@ trait Symbols /* extends reflect.generic.Symbols*/ { self: SymbolTable =>
override final def isTrait: Boolean = isClass && hasFlag(TRAIT | notDEFERRED) // A virtual class becomes a trait (part of DEVIRTUALIZE)
final def isAbstractClass = isClass && hasFlag(ABSTRACT)
+ final def isConcreteClass = isClass && !hasFlag(ABSTRACT | TRAIT)
final def isBridge = hasFlag(BRIDGE)
final def isContravariant = isType && hasFlag(CONTRAVARIANT)
final def isCovariant = isType && hasFlag(COVARIANT)
@@ -306,6 +307,8 @@ trait Symbols /* extends reflect.generic.Symbols*/ { self: SymbolTable =>
final def isModuleClass = isClass && hasFlag(MODULE)
final def isOverloaded = hasFlag(OVERLOADED)
final def isRefinementClass = isClass && name == tpnme.REFINE_CLASS_NAME
+ final def isRefinementMember = owner.isStructuralRefinement && isVisibleInRefinement && !hasAccessBoundary
+ final def isVisibleInRefinement = !(isConstructor || isOverridingSymbol || isPrivate)
final def isSourceMethod = isMethod && !hasFlag(STABLE) // exclude all accessors!!!
final def isTypeParameter = isType && isParameter && !isSkolem
@@ -395,6 +398,8 @@ trait Symbols /* extends reflect.generic.Symbols*/ { self: SymbolTable =>
nme.isReplWrapperName(name) // not isInterpreterWrapper due to nesting
)
+ def isFBounded = info.baseTypeSeq exists (_ contains this)
+
/** Is symbol a monomorphic type?
* assumption: if a type starts out as monomorphic, it will not acquire
* type parameters in later phases.
@@ -411,7 +416,10 @@ trait Symbols /* extends reflect.generic.Symbols*/ { self: SymbolTable =>
}
def isStrictFP = hasAnnotation(ScalaStrictFPAttr) || (enclClass hasAnnotation ScalaStrictFPAttr)
- def isSerializable = info.baseClasses.exists(p => p == SerializableClass || p == JavaSerializableClass) || hasAnnotation(SerializableAttr) // last part can be removed, @serializable annotation is deprecated
+ def isSerializable = (
+ info.baseClasses.exists(p => p == SerializableClass || p == JavaSerializableClass)
+ || hasAnnotation(SerializableAttr) // last part can be removed, @serializable annotation is deprecated
+ )
def isDeprecated = hasAnnotation(DeprecatedAttr)
def hasBridgeAnnotation = hasAnnotation(BridgeClass)
def deprecationMessage = getAnnotation(DeprecatedAttr) flatMap (_ stringArg 0)
@@ -445,12 +453,8 @@ trait Symbols /* extends reflect.generic.Symbols*/ { self: SymbolTable =>
(!hasFlag(METHOD | BYNAMEPARAM) || hasFlag(STABLE)) &&
!(tpe.isVolatile && !hasAnnotation(uncheckedStableClass))
- def isVirtualClass =
- hasFlag(DEFERRED) && isClass
-
- def isVirtualTrait =
- hasFlag(DEFERRED) && isTrait
-
+ // def isVirtualClass = hasFlag(DEFERRED) && isClass
+ // def isVirtualTrait = hasFlag(DEFERRED) && isTrait
def isLiftedMethod = isMethod && hasFlag(LIFTED)
def isCaseClass = isClass && isCase
@@ -532,7 +536,6 @@ trait Symbols /* extends reflect.generic.Symbols*/ { self: SymbolTable =>
final def isStructuralRefinement: Boolean =
(isClass || isType || isModule) && info.normalize/*.underlying*/.isStructuralRefinement
-
/** Is this symbol a member of class `clazz`? */
def isMemberOf(clazz: Symbol) =
clazz.info.member(name).alternatives contains this
@@ -1131,25 +1134,24 @@ trait Symbols /* extends reflect.generic.Symbols*/ { self: SymbolTable =>
// ------ overloaded alternatives ------------------------------------------------------
def alternatives: List[Symbol] =
- if (hasFlag(OVERLOADED)) info.asInstanceOf[OverloadedType].alternatives
+ if (isOverloaded) info.asInstanceOf[OverloadedType].alternatives
else List(this)
def filter(cond: Symbol => Boolean): Symbol =
- if (hasFlag(OVERLOADED)) {
- //assert(info.isInstanceOf[OverloadedType], "" + this + ":" + info);//DEBUG
+ if (isOverloaded) {
val alts = alternatives
val alts1 = alts filter cond
if (alts1 eq alts) this
else if (alts1.isEmpty) NoSymbol
else if (alts1.tail.isEmpty) alts1.head
else owner.newOverloaded(info.prefix, alts1)
- } else if (this == NoSymbol || cond(this)) {
- this
- } else NoSymbol
+ }
+ else if (cond(this)) this
+ else NoSymbol
def suchThat(cond: Symbol => Boolean): Symbol = {
val result = filter(cond)
- assert(!(result hasFlag OVERLOADED), result.alternatives)
+ assert(!result.isOverloaded, result.alternatives)
result
}
@@ -1526,6 +1528,20 @@ trait Symbols /* extends reflect.generic.Symbols*/ { self: SymbolTable =>
if (!owner.isClass) Nil
else owner.ancestors map overriddenSymbol filter (_ != NoSymbol)
+ /** Equivalent to allOverriddenSymbols.nonEmpty, but more efficient. */
+ def isOverridingSymbol = owner.isClass && (
+ owner.ancestors exists (cls => matchingSymbol(cls, owner.thisType) != NoSymbol)
+ )
+ /** Equivalent to allOverriddenSymbols.head (or NoSymbol if no overrides) but more efficient. */
+ def nextOverriddenSymbol: Symbol = {
+ if (owner.isClass) owner.ancestors foreach { base =>
+ val sym = overriddenSymbol(base)
+ if (sym != NoSymbol)
+ return sym
+ }
+ NoSymbol
+ }
+
/** Returns all symbols overridden by this symbol, plus all matching symbols
* defined in parents of the selftype.
*/
@@ -2250,6 +2266,7 @@ trait Symbols /* extends reflect.generic.Symbols*/ { self: SymbolTable =>
unlock()
validTo = currentPeriod
}
+ override def filter(cond: Symbol => Boolean) = this
override def defString: String = toString
override def locationString: String = ""
override def enclClass: Symbol = this
diff --git a/src/compiler/scala/reflect/internal/Types.scala b/src/compiler/scala/reflect/internal/Types.scala
index bc9eda760c..f0497ca37d 100644
--- a/src/compiler/scala/reflect/internal/Types.scala
+++ b/src/compiler/scala/reflect/internal/Types.scala
@@ -1410,8 +1410,7 @@ trait Types /*extends reflect.generic.Types*/ { self: SymbolTable =>
override def isNotNull: Boolean = parents exists (_.isNotNull)
override def isStructuralRefinement: Boolean =
- typeSymbol.isAnonOrRefinementClass &&
- (decls exists { entry => !entry.isConstructor && entry.allOverriddenSymbols.isEmpty })
+ typeSymbol.isAnonOrRefinementClass && decls.exists(_.isVisibleInRefinement)
// override def isNullable: Boolean =
// parents forall (p => p.isNullable && !p.typeSymbol.isAbstractType);
@@ -2019,11 +2018,8 @@ A type's typeSymbol should never be inspected directly.
else if (sym.isAnonymousClass && sym.isInitialized && !settings.debug.value && !phase.erasedTypes)
thisInfo.parents.mkString(" with ") + {
if (sym.isStructuralRefinement)
- ((decls filter { entry =>
- !entry.isConstructor && entry.allOverriddenSymbols.isEmpty && !entry.isPrivate
- }) map { entry => entry.defString }).mkString("{", "; ", "}")
- else
- ""
+ decls filter (_.isVisibleInRefinement) map (_.defString) mkString("{", "; ", "}")
+ else ""
}
else if (sym.isRefinementClass && sym.isInitialized)
thisInfo.toString
diff --git a/src/compiler/scala/tools/nsc/transform/Constructors.scala b/src/compiler/scala/tools/nsc/transform/Constructors.scala
index d84e754cc1..a333c7458d 100644
--- a/src/compiler/scala/tools/nsc/transform/Constructors.scala
+++ b/src/compiler/scala/tools/nsc/transform/Constructors.scala
@@ -215,7 +215,7 @@ abstract class Constructors extends Transform with ast.TreeDSL {
// the symbol is an outer accessor of a final class which does not override another outer accessor. )
def maybeOmittable(sym: Symbol) = sym.owner == clazz && (
sym.isParamAccessor && sym.isPrivateLocal ||
- sym.isOuterAccessor && sym.owner.isFinal && sym.allOverriddenSymbols.isEmpty &&
+ sym.isOuterAccessor && sym.owner.isFinal && !sym.isOverridingSymbol &&
!(clazz isSubClass DelayedInitClass)
)
diff --git a/src/compiler/scala/tools/nsc/transform/Erasure.scala b/src/compiler/scala/tools/nsc/transform/Erasure.scala
index 5452dc70a2..21bf696077 100644
--- a/src/compiler/scala/tools/nsc/transform/Erasure.scala
+++ b/src/compiler/scala/tools/nsc/transform/Erasure.scala
@@ -1102,7 +1102,7 @@ abstract class Erasure extends AddInterfaces
}
else {
def doDynamic(fn: Tree, qual: Tree): Tree = {
- if (fn.symbol.owner.isRefinementClass && fn.symbol.allOverriddenSymbols.isEmpty)
+ if (fn.symbol.owner.isRefinementClass && !fn.symbol.isOverridingSymbol)
ApplyDynamic(qual, args) setSymbol fn.symbol setPos tree.pos
else tree
}
@@ -1118,9 +1118,9 @@ abstract class Erasure extends AddInterfaces
val owner = tree.symbol.owner
// println("preXform: "+ (tree, tree.symbol, tree.symbol.owner, tree.symbol.owner.isRefinementClass))
if (owner.isRefinementClass) {
- val overridden = tree.symbol.allOverriddenSymbols
- assert(!overridden.isEmpty, tree.symbol)
- tree.symbol = overridden.head
+ val overridden = tree.symbol.nextOverriddenSymbol
+ assert(overridden != NoSymbol, tree.symbol)
+ tree.symbol = overridden
}
def isAccessible(sym: Symbol) = localTyper.context.isAccessible(sym, sym.owner.thisType)
if (!isAccessible(owner) && qual.tpe != null) {
diff --git a/src/compiler/scala/tools/nsc/transform/Mixin.scala b/src/compiler/scala/tools/nsc/transform/Mixin.scala
index c18bfb7929..0d7f1eb5cf 100644
--- a/src/compiler/scala/tools/nsc/transform/Mixin.scala
+++ b/src/compiler/scala/tools/nsc/transform/Mixin.scala
@@ -1063,12 +1063,8 @@ abstract class Mixin extends InfoTransform with ast.TreeDSL {
if (sym.isSetter) {
val isOverriddenSetter =
nme.isTraitSetterName(sym.name) && {
- sym.allOverriddenSymbols match {
- case other :: _ =>
- isOverriddenAccessor(other.getter(other.owner), clazz.info.baseClasses)
- case _ =>
- false
- }
+ val other = sym.nextOverriddenSymbol
+ (other != NoSymbol) && isOverriddenAccessor(other.getter(other.owner), clazz.info.baseClasses)
}
if (isOverriddenSetter) UNIT
else accessedRef match {
diff --git a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala
index a434af1175..d7aa7bc527 100644
--- a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala
@@ -217,10 +217,7 @@ abstract class RefChecks extends InfoTransform {
val self = clazz.thisType
def isAbstractTypeWithoutFBound(sym: Symbol) = // (part of DEVIRTUALIZE)
- sym.isAbstractType && !isFBounded(sym)
-
- def isFBounded(tsym: Symbol) =
- tsym.info.baseTypeSeq exists (_ contains tsym)
+ sym.isAbstractType && !sym.isFBounded
def infoString(sym: Symbol) = infoString0(sym, sym.owner != clazz)
def infoStringWithLocation(sym: Symbol) = infoString0(sym, true)
@@ -443,7 +440,7 @@ abstract class RefChecks extends InfoTransform {
printMixinOverrideErrors()
// Verifying a concrete class has nothing unimplemented.
- if (clazz.isClass && !clazz.isTrait && !(clazz hasFlag ABSTRACT) && !typesOnly) {
+ if (clazz.isConcreteClass && !typesOnly) {
val abstractErrors = new ListBuffer[String]
def abstractErrorMessage =
// a little formatting polish
@@ -470,11 +467,14 @@ abstract class RefChecks extends InfoTransform {
atPhase(currentRun.erasurePhase.next)(tp1 matches tp2)
})
- def ignoreDeferred(member: Symbol) =
- isAbstractTypeWithoutFBound(member) ||
- (member.isJavaDefined &&
- (currentRun.erasurePhase == NoPhase || // the test requires atPhase(erasurePhase.next) so shouldn't be done if the compiler has no erasure phase available
- javaErasedOverridingSym(member) != NoSymbol))
+ def ignoreDeferred(member: Symbol) = (
+ (member.isAbstractType && !member.isFBounded) || (
+ member.isJavaDefined &&
+ // the test requires atPhase(erasurePhase.next) so shouldn't be
+ // done if the compiler has no erasure phase available
+ (currentRun.erasurePhase == NoPhase || javaErasedOverridingSym(member) != NoSymbol)
+ )
+ )
// 2. Check that only abstract classes have deferred members
def checkNoAbstractMembers() = {
@@ -566,7 +566,7 @@ abstract class RefChecks extends InfoTransform {
//
// (3) is violated but not (2).
def checkNoAbstractDecls(bc: Symbol) {
- for (decl <- bc.info.decls.iterator) {
+ for (decl <- bc.info.decls) {
if (decl.isDeferred && !ignoreDeferred(decl)) {
val impl = decl.matchingSymbol(clazz.thisType, admit = VBRIDGE)
if (impl == NoSymbol || (decl.owner isSubClass impl.owner)) {
@@ -746,8 +746,7 @@ abstract class RefChecks extends InfoTransform {
// However, if `sym` does override a type in a base class
// we have to assume NoVariance, as there might then be
// references to the type parameter that are not variance checked.
- state = if (sym.allOverriddenSymbols.isEmpty) AnyVariance
- else NoVariance
+ state = if (sym.isOverridingSymbol) NoVariance else AnyVariance
}
sym = sym.owner
}
@@ -1070,10 +1069,12 @@ abstract class RefChecks extends InfoTransform {
}
)
transformTrees(cdef :: {
- if (sym.isStatic)
- if (sym.allOverriddenSymbols.isEmpty) Nil
- else List(createStaticModuleAccessor())
- else createInnerModuleAccessor(findOrCreateModuleVar)
+ if (!sym.isStatic)
+ createInnerModuleAccessor(findOrCreateModuleVar)
+ else if (sym.isOverridingSymbol)
+ List(createStaticModuleAccessor())
+ else
+ Nil
})
}
diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
index 84c9595e3c..a470e80449 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
@@ -1637,31 +1637,35 @@ trait Typers extends Modes {
}
}
- /** Check if a method is defined in such a way that it can be called.
- * A method cannot be called if it is a non-private member of a structural type
- * and if its parameter's types are not one of
- * - this.type
- * - a type member of the structural type
- * - an abstract type declared outside of the structural type. */
- def checkMethodStructuralCompatible(meth: Symbol): Unit =
- if (meth.owner.isStructuralRefinement && meth.allOverriddenSymbols.isEmpty && !(meth.isPrivate || meth.hasAccessBoundary)) {
- val tp: Type = meth.tpe match {
- case mt: MethodType => mt
- case NullaryMethodType(res) => res
- // TODO_NMT: drop NullaryMethodType from resultType?
- case pt: PolyType => pt.resultType
- case _ => NoType
- }
- for (paramType <- tp.paramTypes) {
- if (paramType.typeSymbol.isAbstractType && !(paramType.typeSymbol.hasTransOwner(meth.owner)))
- unit.error(meth.pos,"Parameter type in structural refinement may not refer to an abstract type defined outside that refinement")
- else if (paramType.typeSymbol.isAbstractType && !(paramType.typeSymbol.hasTransOwner(meth)))
- unit.error(meth.pos,"Parameter type in structural refinement may not refer to a type member of that refinement")
- else if (paramType.isInstanceOf[ThisType] && paramType.typeSymbol == meth.owner)
- unit.error(meth.pos,"Parameter type in structural refinement may not refer to the type of that refinement (self type)")
- }
+ /** Check if a structurally defined method violates implementation restrictions.
+ * A method cannot be called if it is a non-private member of a refinement type
+ * and if its parameter's types are any of:
+ * - this.type
+ * - a type member of the refinement
+ * - an abstract type declared outside of the refinement.
+ */
+ def checkMethodStructuralCompatible(meth: Symbol): Unit = {
+ def fail(msg: String) = unit.error(meth.pos, msg)
+ val tp: Type = meth.tpe match {
+ case mt @ MethodType(_, _) => mt
+ case NullaryMethodType(restpe) => restpe // TODO_NMT: drop NullaryMethodType from resultType?
+ case PolyType(_, restpe) => restpe
+ case _ => NoType
}
+ for (paramType <- tp.paramTypes) {
+ val sym = paramType.typeSymbol
+
+ if (sym.isAbstractType) {
+ if (!sym.hasTransOwner(meth.owner))
+ fail("Parameter type in structural refinement may not refer to an abstract type defined outside that refinement")
+ else if (!sym.hasTransOwner(meth))
+ fail("Parameter type in structural refinement may not refer to a type member of that refinement")
+ }
+ if (paramType.isInstanceOf[ThisType] && sym == meth.owner)
+ fail("Parameter type in structural refinement may not refer to the type of that refinement (self type)")
+ }
+ }
def typedUseCase(useCase: UseCase) {
def stringParser(str: String): syntaxAnalyzer.Parser = {
val file = new BatchSourceFile(context.unit.source.file, str) {
@@ -1774,7 +1778,8 @@ trait Typers extends Modes {
}
}
- checkMethodStructuralCompatible(meth)
+ if (meth.isRefinementMember)
+ checkMethodStructuralCompatible(meth)
treeCopy.DefDef(ddef, typedMods, ddef.name, tparams1, vparamss1, tpt1, rhs1) setType NoType
}
@@ -1862,51 +1867,51 @@ trait Typers extends Modes {
for (stat <- block.stats) enterLabelDef(stat)
if (phaseId(currentPeriod) <= currentRun.typerPhase.id) {
- // This is very tricky stuff, because we are navigating
- // the Skylla and Charybdis of anonymous classes and what to return
- // from them here. On the one hand, we cannot admit
- // every non-private member of an anonymous class as a part of
- // the structural type of the enclosing block. This runs afoul of
- // the restriction that a structural type may not refer to an enclosing
- // type parameter or abstract types (which in turn is necessitated
- // by what can be done in Java reflection. On the other hand,
- // making every term member private conflicts with private escape checking
- // see ticket #3174 for an example.
- // The cleanest way forward is if we would find a way to suppress
- // structural type checking for these members and maybe defer
- // type errors to the places where members are called. But that would
- // be a big refactoring and also a big departure from existing code.
- // The probably safest fix for 2.8 is to keep members of an anonymous
- // class that are not mentioned in a parent type private (as before)
- // but to disable escape checking for code that's in the same anonymous class.
- // That's what's done here.
- // We really should go back and think hard whether we find a better
- // way to address the problem of escaping idents on the one hand and well-formed
- // structural types on the other.
+ // This is very tricky stuff, because we are navigating the Skylla and Charybdis of
+ // anonymous classes and what to return from them here. On the one hand, we cannot admit
+ // every non-private member of an anonymous class as a part of the structural type of the
+ // enclosing block. This runs afoul of the restriction that a structural type may not
+ // refer to an enclosing type parameter or abstract types (which in turn is necessitated
+ // by what can be done in Java reflection). On the other hand, making every term member
+ // private conflicts with private escape checking - see ticket #3174 for an example.
+ //
+ // The cleanest way forward is if we would find a way to suppress structural type checking
+ // for these members and maybe defer type errors to the places where members are called.
+ // But that would be a big refactoring and also a big departure from existing code. The
+ // probably safest fix for 2.8 is to keep members of an anonymous class that are not
+ // mentioned in a parent type private (as before) but to disable escape checking for code
+ // that's in the same anonymous class. That's what's done here.
+ //
+ // We really should go back and think hard whether we find a better way to address the
+ // problem of escaping idents on the one hand and well-formed structural types on the
+ // other.
block match {
- case block @ Block(List(classDef @ ClassDef(_, _, _, _)), newInst @ Apply(Select(New(_), _), _)) =>
- // The block is an anonymous class definitions/instantiation pair
- // -> members that are hidden by the type of the block are made private
+ case Block(List(classDef @ ClassDef(_, _, _, _)), Apply(Select(New(_), _), _)) =>
+ val classDecls = classDef.symbol.info.decls
val visibleMembers = pt match {
- case WildcardType => classDef.symbol.info.decls.toList
- case BoundedWildcardType(TypeBounds(lo, hi)) => lo.members
- case _ => pt.members
+ case WildcardType => classDecls.toList
+ case BoundedWildcardType(TypeBounds(lo, _)) => lo.members
+ case _ => pt.members
}
- for (member <- classDef.symbol.info.decls
- if member.isTerm && !member.isConstructor &&
- member.allOverriddenSymbols.isEmpty &&
- (!member.isPrivate && !member.hasAccessBoundary) &&
- !(visibleMembers exists { visible =>
- visible.name == member.name &&
- member.tpe <:< visible.tpe.substThis(visible.owner, ThisType(classDef.symbol))
- })
- ) {
- member.resetFlag(PROTECTED)
- member.resetFlag(LOCAL)
- member.setFlag(PRIVATE | SYNTHETIC_PRIVATE)
- syntheticPrivates += member
- member.privateWithin = NoSymbol
+ def matchesVisibleMember(member: Symbol) = visibleMembers exists { vis =>
+ (member.name == vis.name) &&
+ (member.tpe <:< vis.tpe.substThis(vis.owner, ThisType(classDef.symbol)))
}
+ // The block is an anonymous class definitions/instantiation pair
+ // -> members that are hidden by the type of the block are made private
+ ( classDecls filter (member =>
+ member.isTerm
+ && member.isVisibleInRefinement
+ && !member.hasAccessBoundary
+ && !matchesVisibleMember(member)
+ )
+ foreach { member =>
+ member resetFlag (PROTECTED | LOCAL)
+ member setFlag (PRIVATE | SYNTHETIC_PRIVATE)
+ syntheticPrivates += member
+ member.privateWithin = NoSymbol
+ }
+ )
case _ =>
}
}
@@ -1917,7 +1922,7 @@ trait Typers extends Modes {
} finally {
// enable escaping privates checking from the outside and recycle
// transient flag
- for (sym <- syntheticPrivates) sym resetFlag SYNTHETIC_PRIVATE
+ syntheticPrivates foreach (_ resetFlag SYNTHETIC_PRIVATE)
}
}