diff options
-rw-r--r-- | src/compiler/scala/tools/nsc/symtab/Symbols.scala | 22 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/symtab/Types.scala | 2 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/typechecker/RefChecks.scala | 6 |
3 files changed, 26 insertions, 4 deletions
diff --git a/src/compiler/scala/tools/nsc/symtab/Symbols.scala b/src/compiler/scala/tools/nsc/symtab/Symbols.scala index a0dd86c79f..4e1710284b 100644 --- a/src/compiler/scala/tools/nsc/symtab/Symbols.scala +++ b/src/compiler/scala/tools/nsc/symtab/Symbols.scala @@ -4,6 +4,7 @@ */ // $Id$ + package scala.tools.nsc.symtab import scala.collection.mutable.ListBuffer @@ -98,8 +99,27 @@ trait Symbols { /** Does this symbol have an attribute of the given class? */ def hasAttribute(cls: Symbol) = attributes exists { _.atp.typeSymbol == cls } + /** set when symbol has a modifier of the form private[X], NoSymbol otherwise. + * Here's some explanation how privateWithin gets combined with access flags: + * + * PRIVATE means class private, as in Java. + * PROTECTED means protected as in Java, except that access within + * the same package is not automatically allowed. + * LOCAL should only be set with PRIVATE or PROTECTED. + * It means that access is restricted to be from the same object. + * + * Besides these, there's the privateWithin field in Symbols which gives a visibility barrier, + * where privateWithin == NoSymbol means no barrier. privateWithin is incompatible with + * PRIVATE and LOCAL. If it is combined with PROTECTED, the two are additive. I.e. + * the symbol is then accessible from within the privateWithin region as well + * as from all subclasses. Here's a tanslation of Java's accessibility modifiers: + * Java private: PRIVATE flag set, privateWithin == NoSymbol + * Java package: no flag set, privateWithin == enclosing package + * Java protected: PROTECTED flag set, privateWithin == enclosing package + * Java public: no flag set, privateWithin == NoSymbol + */ var privateWithin: Symbol = _ - // set when symbol has a modifier of the form private[X], NoSymbol otherwise. + // Creators ------------------------------------------------------------------- diff --git a/src/compiler/scala/tools/nsc/symtab/Types.scala b/src/compiler/scala/tools/nsc/symtab/Types.scala index 599196ee01..d61d56474c 100644 --- a/src/compiler/scala/tools/nsc/symtab/Types.scala +++ b/src/compiler/scala/tools/nsc/symtab/Types.scala @@ -1055,7 +1055,7 @@ trait Types { if (util.Statistics.enabled) compoundBaseTypeSeqCount += 1 baseTypeSeqCache = undetBaseTypeSeq - baseTypeSeqCache = memo(compoundBaseTypeSeq(this/*typeSymbol, parents*/))(_.baseTypeSeq updateHead typeSymbol.tpe) + baseTypeSeqCache = memo(compoundBaseTypeSeq(this))(_.baseTypeSeq updateHead typeSymbol.tpe) // println("normalizing baseTypeSeq of "+typeSymbol+"/"+parents+": "+baseTypeSeqCache)//DEBUG baseTypeSeqCache.normalize(parents) // println("normalized baseTypeSeq of "+typeSymbol+"/"+parents+": "+baseTypeSeqCache)//DEBUG diff --git a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala index 28fea81d03..360ab6d09d 100644 --- a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala +++ b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala @@ -436,7 +436,7 @@ abstract class RefChecks extends InfoTransform { sym.isTerm && ((sym.isPrivateLocal || sym.isProtectedLocal) && !(escapedPrivateLocals contains sym))) state = AnyVariance else if (sym.isAliasType) - state = NoVariance + state = AnyVariance // was NoVariance, but now we always expand aliases. sym = sym.owner } state @@ -453,7 +453,9 @@ abstract class RefChecks extends InfoTransform { case SingleType(pre, sym) => validateVariance(pre, variance) case TypeRef(pre, sym, args) => - if (sym.variance != NoVariance) { + if (sym.isAliasType) + validateVariance(tp.normalize, variance) + else if (sym.variance != NoVariance) { val v = relativeVariance(sym); if (v != AnyVariance && sym.variance != v * variance) { //Console.println("relativeVariance(" + base + "," + sym + ") = " + v);//DEBUG |