summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAdriaan Moors <adriaan.moors@typesafe.com>2016-05-26 20:10:47 -0700
committerAdriaan Moors <adriaan@lightbend.com>2016-08-11 10:59:15 -0700
commite26b4f49d80caa8f71a1986f604cca7f4714e3c3 (patch)
tree6c04be043061379186a9311d82d770a477678761 /src
parent1f6f7f8aa94c622665a35343de8108ea66a787b7 (diff)
downloadscala-e26b4f49d80caa8f71a1986f604cca7f4714e3c3.tar.gz
scala-e26b4f49d80caa8f71a1986f604cca7f4714e3c3.tar.bz2
scala-e26b4f49d80caa8f71a1986f604cca7f4714e3c3.zip
Uncurry's info transform: non-static module --> method
We do this during uncurry so we can insert the necessary applications to the empty argument list. Fields is too late. Refchecks is no longer an info transform.
Diffstat (limited to 'src')
-rw-r--r--src/compiler/scala/tools/nsc/Global.scala2
-rw-r--r--src/compiler/scala/tools/nsc/transform/Erasure.scala2
-rw-r--r--src/compiler/scala/tools/nsc/transform/UnCurry.scala7
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/RefChecks.scala26
-rw-r--r--src/compiler/scala/tools/reflect/ReflectGlobal.scala3
-rw-r--r--src/reflect/scala/reflect/internal/Phase.scala4
-rw-r--r--src/reflect/scala/reflect/internal/Types.scala6
-rw-r--r--src/reflect/scala/reflect/internal/transform/RefChecks.scala14
-rw-r--r--src/reflect/scala/reflect/internal/transform/Transforms.scala5
-rw-r--r--src/reflect/scala/reflect/internal/transform/UnCurry.scala7
10 files changed, 23 insertions, 53 deletions
diff --git a/src/compiler/scala/tools/nsc/Global.scala b/src/compiler/scala/tools/nsc/Global.scala
index c2d92ce7f9..af866e1a6f 100644
--- a/src/compiler/scala/tools/nsc/Global.scala
+++ b/src/compiler/scala/tools/nsc/Global.scala
@@ -456,7 +456,7 @@ class Global(var currentSettings: Settings, var reporter: Reporter)
} with Pickler
// phaseName = "refchecks"
- override object refChecks extends {
+ object refChecks extends {
val global: Global.this.type = Global.this
val runsAfter = List("pickler")
val runsRightAfter = None
diff --git a/src/compiler/scala/tools/nsc/transform/Erasure.scala b/src/compiler/scala/tools/nsc/transform/Erasure.scala
index 289ac0cc02..dc62b40578 100644
--- a/src/compiler/scala/tools/nsc/transform/Erasure.scala
+++ b/src/compiler/scala/tools/nsc/transform/Erasure.scala
@@ -508,7 +508,7 @@ abstract class Erasure extends AddInterfaces
// If `member` is a ModuleSymbol, the bridge should not also be a ModuleSymbol. Otherwise we
// end up with two module symbols with the same name in the same scope, which is surprising
// when implementing later phases.
- if (member.isModule) newFlags = (newFlags | METHOD) & ~(MODULE | lateMETHOD | STABLE)
+ if (member.isModule) newFlags = (newFlags | METHOD) & ~(MODULE | STABLE)
val bridge = other.cloneSymbolImpl(root, newFlags) setPos root.pos
debuglog("generating bridge from %s (%s): %s to %s: %s".format(
diff --git a/src/compiler/scala/tools/nsc/transform/UnCurry.scala b/src/compiler/scala/tools/nsc/transform/UnCurry.scala
index 374e8430d8..a337ab7359 100644
--- a/src/compiler/scala/tools/nsc/transform/UnCurry.scala
+++ b/src/compiler/scala/tools/nsc/transform/UnCurry.scala
@@ -510,8 +510,11 @@ abstract class UnCurry extends InfoTransform
case MethodType(_, _) => tree
case tp => tree setType MethodType(Nil, tp.resultType)
}
- if (tree.symbol.isMethod && !tree.tpe.isInstanceOf[PolyType])
- gen.mkApplyIfNeeded(removeNullary())
+ val sym = tree.symbol
+ // our info transformer may not have run yet, so duplicate flag logic instead of forcing it to run
+ val isMethodExitingUncurry = (sym hasFlag METHOD) || (sym hasFlag MODULE) && !sym.isStatic
+ if (isMethodExitingUncurry && !tree.tpe.isInstanceOf[PolyType])
+ gen.mkApplyIfNeeded(removeNullary()) // apply () if tree.tpe has zero-arg MethodType
else if (tree.isType)
TypeTree(tree.tpe) setPos tree.pos
else
diff --git a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala
index 46ad4b35a1..7021e12f1a 100644
--- a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala
@@ -14,7 +14,7 @@ import scala.tools.nsc.settings.ScalaVersion
import scala.tools.nsc.settings.NoScalaVersion
import symtab.Flags._
-import transform.InfoTransform
+import transform.Transform
/** <p>
@@ -43,7 +43,7 @@ import transform.InfoTransform
*
* @todo Check whether we always check type parameter bounds.
*/
-abstract class RefChecks extends InfoTransform with scala.reflect.internal.transform.RefChecks {
+abstract class RefChecks extends Transform {
val global: Global // need to repeat here because otherwise last mixin defines global as
// SymbolTable. If we had DOT this would not be an issue
@@ -54,31 +54,9 @@ abstract class RefChecks extends InfoTransform with scala.reflect.internal.trans
/** the following two members override abstract members in Transform */
val phaseName: String = "refchecks"
- override def phaseNewFlags: Long = lateMETHOD
def newTransformer(unit: CompilationUnit): RefCheckTransformer =
new RefCheckTransformer(unit)
- override def changesBaseClasses = false
-
- override def transformInfo(sym: Symbol, tp: Type): Type = {
- // !!! 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)
- }
val toJavaRepeatedParam = new SubstSymMap(RepeatedParamClass -> JavaRepeatedParamClass)
val toScalaRepeatedParam = new SubstSymMap(JavaRepeatedParamClass -> RepeatedParamClass)
diff --git a/src/compiler/scala/tools/reflect/ReflectGlobal.scala b/src/compiler/scala/tools/reflect/ReflectGlobal.scala
index e30d1ed7cd..b80524df2b 100644
--- a/src/compiler/scala/tools/reflect/ReflectGlobal.scala
+++ b/src/compiler/scala/tools/reflect/ReflectGlobal.scala
@@ -30,8 +30,7 @@ class ReflectGlobal(currentSettings: Settings, reporter: Reporter, override val
override def transformedType(sym: Symbol) =
postErasure.transformInfo(sym,
erasure.transformInfo(sym,
- uncurry.transformInfo(sym,
- refChecks.transformInfo(sym, sym.info))))
+ uncurry.transformInfo(sym, sym.info)))
override def isCompilerUniverse = true
diff --git a/src/reflect/scala/reflect/internal/Phase.scala b/src/reflect/scala/reflect/internal/Phase.scala
index f56c41d71c..eb193adbf2 100644
--- a/src/reflect/scala/reflect/internal/Phase.scala
+++ b/src/reflect/scala/reflect/internal/Phase.scala
@@ -47,7 +47,9 @@ abstract class Phase(val prev: Phase) {
final val specialized: Boolean = ((prev ne null) && (prev ne NoPhase)) && (prev.name == "specialize" || prev.specialized)
final val refChecked: Boolean = ((prev ne null) && (prev ne NoPhase)) && (prev.name == "refchecks" || prev.refChecked)
- // are we past the fields phase, so that we should allow writing to vals (as part of type checking trait setters)
+ // are we past the fields phase, so that:
+ // - we should allow writing to vals (as part of type checking trait setters)
+ // - modules have module accessors
final val assignsFields: Boolean = ((prev ne null) && (prev ne NoPhase)) && (prev.name == "fields" || prev.assignsFields)
/** This is used only in unsafeTypeParams, and at this writing is
diff --git a/src/reflect/scala/reflect/internal/Types.scala b/src/reflect/scala/reflect/internal/Types.scala
index fb78aa5009..7dda805378 100644
--- a/src/reflect/scala/reflect/internal/Types.scala
+++ b/src/reflect/scala/reflect/internal/Types.scala
@@ -3469,10 +3469,10 @@ trait Types
if (!sym.isOverridableMember || sym.owner == pre.typeSymbol) sym
else pre.nonPrivateMember(sym.name).suchThat { sym =>
// SI-7928 `isModuleNotMethod` is here to avoid crashing with spuriously "overloaded" module accessor and module symbols.
- // These appear after refchecks eliminates ModuleDefs that implement an interface.
+ // These appear after the fields phase eliminates ModuleDefs that implement an interface.
// Here, we exclude the module symbol, which allows us to bind to the accessor.
- // SI-8054 We must only do this after refchecks, otherwise we exclude the module symbol which does not yet have an accessor!
- val isModuleWithAccessor = phase.refChecked && sym.isModuleNotMethod
+ // SI-8054 We must only do this after fields, otherwise we exclude the module symbol which does not yet have an accessor!
+ val isModuleWithAccessor = phase.assignsFields && sym.isModuleNotMethod
sym.isType || (!isModuleWithAccessor && sym.isStable && !sym.hasVolatileType)
} orElse sym
}
diff --git a/src/reflect/scala/reflect/internal/transform/RefChecks.scala b/src/reflect/scala/reflect/internal/transform/RefChecks.scala
index 4ca114e781..e69de29bb2 100644
--- a/src/reflect/scala/reflect/internal/transform/RefChecks.scala
+++ b/src/reflect/scala/reflect/internal/transform/RefChecks.scala
@@ -1,14 +0,0 @@
-package scala
-package reflect
-package internal
-package transform
-
-trait RefChecks {
-
- val global: SymbolTable
- import global._
-
- def transformInfo(sym: Symbol, tp: Type): Type =
- if (sym.isModule && !sym.isStatic) NullaryMethodType(tp)
- else tp
-}
diff --git a/src/reflect/scala/reflect/internal/transform/Transforms.scala b/src/reflect/scala/reflect/internal/transform/Transforms.scala
index 0d2f355aa5..de5bfbd39a 100644
--- a/src/reflect/scala/reflect/internal/transform/Transforms.scala
+++ b/src/reflect/scala/reflect/internal/transform/Transforms.scala
@@ -23,12 +23,10 @@ trait Transforms { self: SymbolTable =>
}
}
- private val refChecksLazy = new Lazy(new { val global: Transforms.this.type = self } with RefChecks)
private val uncurryLazy = new Lazy(new { val global: Transforms.this.type = self } with UnCurry)
private val erasureLazy = new Lazy(new { val global: Transforms.this.type = self } with Erasure)
private val postErasureLazy = new Lazy(new { val global: Transforms.this.type = self } with PostErasure)
- def refChecks = refChecksLazy.force
def uncurry = uncurryLazy.force
def erasure = erasureLazy.force
def postErasure = postErasureLazy.force
@@ -36,8 +34,7 @@ trait Transforms { self: SymbolTable =>
def transformedType(sym: Symbol) =
postErasure.transformInfo(sym,
erasure.transformInfo(sym,
- uncurry.transformInfo(sym,
- refChecks.transformInfo(sym, sym.info))))
+ uncurry.transformInfo(sym, sym.info)))
def transformedType(tpe: Type) =
postErasure.elimErasedValueType(erasure.scalaErasure(uncurry.uncurry(tpe)))
diff --git a/src/reflect/scala/reflect/internal/transform/UnCurry.scala b/src/reflect/scala/reflect/internal/transform/UnCurry.scala
index 85e3ac60e8..a50084f40d 100644
--- a/src/reflect/scala/reflect/internal/transform/UnCurry.scala
+++ b/src/reflect/scala/reflect/internal/transform/UnCurry.scala
@@ -83,5 +83,10 @@ trait UnCurry {
* @MAT: starting with this phase, the info of every symbol will be normalized
*/
def transformInfo(sym: Symbol, tp: Type): Type =
- if (sym.isType) uncurryType(tp) else uncurry(tp)
+ if (sym.isType) uncurryType(tp)
+ else if ((sym hasFlag MODULE) && !sym.isStatic) { // see Fields::nonStaticModuleToMethod
+ sym setFlag METHOD | STABLE
+ MethodType(Nil, uncurry(tp))
+ }
+ else uncurry(tp)
}