summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala2
-rw-r--r--src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala2
-rw-r--r--src/compiler/scala/tools/nsc/transform/Mixin.scala4
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/RefChecks.scala17
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala4
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Typers.scala4
-rw-r--r--src/reflect/scala/reflect/internal/Symbols.scala33
7 files changed, 51 insertions, 15 deletions
diff --git a/src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala b/src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala
index 289508f903..db43e633fc 100644
--- a/src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala
+++ b/src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala
@@ -539,7 +539,7 @@ abstract class GenASM extends SubComponent with BytecodeWriters with GenJVMASM {
collectInnerClass(sym)
- val hasInternalName = (sym.isClass || (sym.isModule && !sym.isMethod))
+ val hasInternalName = sym.isClass || sym.isModuleNotMethod
val cachedJN = javaNameCache.getOrElseUpdate(sym, {
if (hasInternalName) { sym.javaBinaryName }
else { sym.javaSimpleName }
diff --git a/src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala b/src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala
index 1aa5f10738..95a1f50465 100644
--- a/src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala
+++ b/src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala
@@ -83,7 +83,7 @@ abstract class ExplicitOuter extends InfoTransform
else findOrElse(clazz.info.decls)(_.outerSource == clazz)(NoSymbol)
}
def newOuterAccessor(clazz: Symbol) = {
- val accFlags = SYNTHETIC | ARTIFACT | METHOD | STABLE | ( if (clazz.isTrait) DEFERRED else 0 )
+ val accFlags = SYNTHETIC | ARTIFACT | STABLE | ( if (clazz.isTrait) DEFERRED else 0 )
val sym = clazz.newMethod(nme.OUTER, clazz.pos, accFlags)
val restpe = if (clazz.isTrait) clazz.outerClass.tpe_* else clazz.outerClass.thisType
diff --git a/src/compiler/scala/tools/nsc/transform/Mixin.scala b/src/compiler/scala/tools/nsc/transform/Mixin.scala
index 8774390c8c..7fe7947239 100644
--- a/src/compiler/scala/tools/nsc/transform/Mixin.scala
+++ b/src/compiler/scala/tools/nsc/transform/Mixin.scala
@@ -34,7 +34,7 @@ abstract class Mixin extends InfoTransform with ast.TreeDSL {
/** A member of a trait is implemented statically if its implementation after the
* mixin transform is in the static implementation module. To be statically
* implemented, a member must be a method that belonged to the trait's implementation class
- * before (e.g. it is not abstract). Not statically implemented are
+ * before (i.e. it is not abstract). Not statically implemented are
* - non-private modules: these are implemented directly in the mixin composition class
* (private modules, on the other hand, are implemented statically, but their
* module variable is not. all such private modules are lifted, because
@@ -1037,7 +1037,7 @@ abstract class Mixin extends InfoTransform with ast.TreeDSL {
else if (!clazz.isTrait) {
// This needs to be a def to avoid sharing trees
def accessedRef = accessedReference(sym)
- if (sym.hasAccessorFlag && (!sym.isDeferred || sym.hasFlag(lateDEFERRED))) {
+ if (isConcreteAccessor(sym)) {
// add accessor definitions
addDefDef(sym, {
if (sym.isSetter) {
diff --git a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala
index c462b8f8ef..5ef54bfad1 100644
--- a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala
@@ -59,7 +59,22 @@ abstract class RefChecks extends InfoTransform with scala.reflect.internal.trans
override def changesBaseClasses = false
override def transformInfo(sym: Symbol, tp: Type): Type = {
- if (sym.isModule && !sym.isStatic) sym setFlag (lateMETHOD | STABLE)
+ // !!! This is a sketchy way to do things.
+ // It would be better to replace the module symbol with a method symbol
+ // rather than creating this module/method hybrid which must be special
+ // cased all over the place. Look for the call sites which use(d) some
+ // variation of "isMethod && !isModule", which to an observer looks like
+ // a nonsensical condition. (It is now "isModuleNotMethod".)
+ if (sym.isModule && !sym.isStatic) {
+ sym setFlag lateMETHOD | STABLE
+ // Note that this as far as we can see it works equally well
+ // to set the METHOD flag here and dump lateMETHOD, but it does
+ // mean that under separate compilation the typer will see
+ // modules as methods (albeit stable ones with singleton types.)
+ // So for now lateMETHOD lives while we try to convince ourselves
+ // we can live without it or deliver that info some other way.
+ log(s"Stabilizing module method for ${sym.fullLocationString}")
+ }
super.transformInfo(sym, tp)
}
diff --git a/src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala b/src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala
index e22dc73b53..75aa4c46e2 100644
--- a/src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala
@@ -64,8 +64,8 @@ abstract class SuperAccessors extends transform.Transform with transform.TypingT
debuglog(s"add super acc ${sym.fullLocationString} to $clazz")
val acc = clazz.newMethod(supername, sel.pos, SUPERACCESSOR | PRIVATE | ARTIFACT) setAlias sym
val tpe = clazz.thisType memberType sym match {
- case t if sym.isModule && !sym.isMethod => NullaryMethodType(t)
- case t => t
+ case t if sym.isModuleNotMethod => NullaryMethodType(t)
+ case t => t
}
acc setInfoAndEnter (tpe cloneInfo acc)
// Diagnostic for SI-7091
diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
index 6e26b12226..95a9cea066 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
@@ -599,7 +599,7 @@ trait Typers extends Adaptations with Tags {
if (sym.isValue) {
val tree1 = checkStable(tree)
// A module reference in a pattern has type Foo.type, not "object Foo"
- if (sym.isModule && !sym.isMethod) tree1 setType singleType(pre, sym)
+ if (sym.isModuleNotMethod) tree1 setType singleType(pre, sym)
else tree1
}
else fail()
@@ -607,7 +607,7 @@ trait Typers extends Adaptations with Tags {
fail()
} else {
if (sym.isStable && pre.isStable && !isByNameParamType(tree.tpe) &&
- (isStableContext(tree, mode, pt) || sym.isModule && !sym.isMethod))
+ (isStableContext(tree, mode, pt) || sym.isModuleNotMethod))
tree.setType(singleType(pre, sym))
// To fully benefit from special casing the return type of
// getClass, we have to catch it immediately so expressions
diff --git a/src/reflect/scala/reflect/internal/Symbols.scala b/src/reflect/scala/reflect/internal/Symbols.scala
index a87d002f25..7465a2e7ab 100644
--- a/src/reflect/scala/reflect/internal/Symbols.scala
+++ b/src/reflect/scala/reflect/internal/Symbols.scala
@@ -659,8 +659,29 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
final def hasGetter = isTerm && nme.isLocalName(name)
+ /** A little explanation for this confusing situation.
+ * Nested modules which have no static owner when ModuleDefs
+ * are eliminated (refchecks) are given the lateMETHOD flag,
+ * which makes them appear as methods after refchecks.
+ * Here's an example where one can see all four of FF FT TF TT
+ * for (isStatic, isMethod) at various phases.
+ *
+ * trait A1 { case class Quux() }
+ * object A2 extends A1 { object Flax }
+ * // -- namer object Quux in trait A1
+ * // -M flatten object Quux in trait A1
+ * // S- flatten object Flax in object A2
+ * // -M posterasure object Quux in trait A1
+ * // -M jvm object Quux in trait A1
+ * // SM jvm object Quux in object A2
+ *
+ * So "isModuleNotMethod" exists not for its achievement in
+ * brevity, but to encapsulate the relevant condition.
+ */
+ def isModuleNotMethod = isModule && !isMethod
+ def isStaticModule = isModuleNotMethod && isStatic
+
final def isInitializedToDefault = !isType && hasAllFlags(DEFAULTINIT | ACCESSOR)
- final def isStaticModule = isModule && isStatic && !isMethod
final def isThisSym = isTerm && owner.thisSym == this
final def isError = hasFlag(IS_ERROR)
final def isErroneous = isError || isInitialized && tpe_*.isErroneous
@@ -1110,12 +1131,13 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
new TermSymbol(this, pos, name) initFlags newFlags
final def newTermSymbol(name: TermName, pos: Position = NoPosition, newFlags: Long = 0L): TermSymbol = {
- if ((newFlags & METHOD) != 0)
- createMethodSymbol(name, pos, newFlags)
- else if ((newFlags & PACKAGE) != 0)
+ // Package before Module, Module before Method, or we might grab the wrong guy.
+ if ((newFlags & PACKAGE) != 0)
createPackageSymbol(name, pos, newFlags | PackageFlags)
else if ((newFlags & MODULE) != 0)
createModuleSymbol(name, pos, newFlags)
+ else if ((newFlags & METHOD) != 0)
+ createMethodSymbol(name, pos, newFlags)
else if ((newFlags & PARAM) != 0)
createValueParameterSymbol(name, pos, newFlags)
else
@@ -3027,8 +3049,7 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
* returned, otherwise, `NoSymbol` is returned.
*/
protected final def companionModule0: Symbol =
- flatOwnerInfo.decl(name.toTermName).suchThat(
- sym => sym.isModule && (sym isCoDefinedWith this) && !sym.isMethod)
+ flatOwnerInfo.decl(name.toTermName).suchThat(sym => sym.isModuleNotMethod && (sym isCoDefinedWith this))
override def companionModule = companionModule0
override def companionSymbol = companionModule0