summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/compiler/scala/tools/nsc/backend/icode/GenICode.scala53
-rw-r--r--test/files/pos/t5604/ReplConfig.scala53
-rw-r--r--test/files/pos/t5604/ReplReporter.scala30
3 files changed, 112 insertions, 24 deletions
diff --git a/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala b/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala
index 41d9d93e7a..8e568eca79 100644
--- a/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala
+++ b/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala
@@ -944,11 +944,10 @@ abstract class GenICode extends SubComponent {
"Trying to access the this of another class: " +
"tree.symbol = " + tree.symbol + ", ctx.clazz.symbol = " + ctx.clazz.symbol + " compilation unit:"+unit)
if (tree.symbol.isModuleClass && tree.symbol != ctx.clazz.symbol) {
- debuglog("LOAD_MODULE from 'This': " + tree.symbol);
- assert(!tree.symbol.isPackageClass, "Cannot use package as value: " + tree)
- genLoadModule(ctx, tree.symbol, tree.pos)
+ genLoadModule(ctx, tree)
generatedType = REFERENCE(tree.symbol)
- } else {
+ }
+ else {
ctx.bb.emit(THIS(ctx.clazz.symbol), tree.pos)
generatedType = REFERENCE(
if (tree.symbol == ArrayClass) ObjectClass else ctx.clazz.symbol
@@ -961,11 +960,7 @@ abstract class GenICode extends SubComponent {
"Selection of non-module from empty package: " + tree +
" sym: " + tree.symbol + " at: " + (tree.pos)
)
- debuglog("LOAD_MODULE from Select(<emptypackage>): " + tree.symbol)
-
- assert(!tree.symbol.isPackageClass, "Cannot use package as value: " + tree)
- genLoadModule(ctx, tree.symbol, tree.pos)
- ctx
+ genLoadModule(ctx, tree)
case Select(qualifier, selector) =>
val sym = tree.symbol
@@ -973,14 +968,13 @@ abstract class GenICode extends SubComponent {
val hostClass = qualifier.tpe.typeSymbol.orElse(sym.owner)
if (sym.isModule) {
- debuglog("LOAD_MODULE from Select(qualifier, selector): " + sym)
- assert(!tree.symbol.isPackageClass, "Cannot use package as value: " + tree)
- genLoadModule(ctx, sym, tree.pos)
- ctx
- } else if (sym.isStaticMember) {
+ genLoadModule(ctx, tree)
+ }
+ else if (sym.isStaticMember) {
ctx.bb.emit(LOAD_FIELD(sym, true) setHostClass hostClass, tree.pos)
ctx
- } else {
+ }
+ else {
val ctx1 = genLoadQualifier(tree, ctx)
ctx1.bb.emit(LOAD_FIELD(sym, false) setHostClass hostClass, tree.pos)
ctx1
@@ -990,11 +984,10 @@ abstract class GenICode extends SubComponent {
val sym = tree.symbol
if (!sym.isPackage) {
if (sym.isModule) {
- debuglog("LOAD_MODULE from Ident(name): " + sym)
- assert(!sym.isPackageClass, "Cannot use package as value: " + tree)
- genLoadModule(ctx, sym, tree.pos)
+ genLoadModule(ctx, tree)
generatedType = toTypeKind(sym.info)
- } else {
+ }
+ else {
try {
val Some(l) = ctx.method.lookupLocal(sym)
ctx.bb.emit(LOAD_LOCAL(l), tree.pos)
@@ -1207,8 +1200,19 @@ abstract class GenICode extends SubComponent {
genLoad(arg, res, toTypeKind(tpe))
}
- private def genLoadModule(ctx: Context, sym: Symbol, pos: Position) {
- ctx.bb.emit(LOAD_MODULE(sym), pos)
+ private def genLoadModule(ctx: Context, tree: Tree): Context = {
+ // Working around SI-5604. Rather than failing the compile when we see
+ // a package here, check if there's a package object.
+ val sym = (
+ if (!tree.symbol.isPackageClass) tree.symbol
+ else tree.symbol.info.member(nme.PACKAGE) match {
+ case NoSymbol => assert(false, "Cannot use package as value: " + tree) ; NoSymbol
+ case s => Console.err.println("Bug: found package class where package object expected. Converting.") ; s.moduleClass
+ }
+ )
+ debuglog("LOAD_MODULE from %s: %s".format(tree.shortClass, sym))
+ ctx.bb.emit(LOAD_MODULE(sym), tree.pos)
+ ctx
}
def genConversion(from: TypeKind, to: TypeKind, ctx: Context, cast: Boolean) = {
@@ -1567,9 +1571,10 @@ abstract class GenICode extends SubComponent {
val ctx1 = genLoad(l, ctx, ObjectReference)
val ctx2 = genLoad(r, ctx1, ObjectReference)
- ctx2.bb.emit(CALL_METHOD(equalsMethod, if (settings.optimise.value) Dynamic else Static(false)))
- ctx2.bb.emit(CZJUMP(thenCtx.bb, elseCtx.bb, NE, BOOL))
- ctx2.bb.close
+ ctx2.bb.emitOnly(
+ CALL_METHOD(equalsMethod, if (settings.optimise.value) Dynamic else Static(false)),
+ CZJUMP(thenCtx.bb, elseCtx.bb, NE, BOOL)
+ )
}
else {
if (isNull(l))
diff --git a/test/files/pos/t5604/ReplConfig.scala b/test/files/pos/t5604/ReplConfig.scala
new file mode 100644
index 0000000000..8c589eba60
--- /dev/null
+++ b/test/files/pos/t5604/ReplConfig.scala
@@ -0,0 +1,53 @@
+/* NSC -- new Scala compiler
+ * Copyright 2005-2011 LAMP/EPFL
+ * @author Paul Phillips
+ */
+
+package scala.tools.nsc
+package interpreter
+
+import util.Exceptional.unwrap
+import util.stackTraceString
+
+trait ReplConfig {
+ lazy val replProps = new ReplProps
+
+ class TapMaker[T](x: T) {
+ def tapInfo(msg: => String): T = tap(x => replinfo(parens(x)))
+ def tapDebug(msg: => String): T = tap(x => repldbg(parens(x)))
+ def tapTrace(msg: => String): T = tap(x => repltrace(parens(x)))
+ def tap[U](f: T => U): T = {
+ f(x)
+ x
+ }
+ }
+
+ private def parens(x: Any) = "(" + x + ")"
+ private def echo(msg: => String) =
+ try Console println msg
+ catch { case x: AssertionError => Console.println("Assertion error printing debugging output: " + x) }
+
+ private[nsc] def repldbg(msg: => String) = if (isReplDebug) echo(msg)
+ private[nsc] def repltrace(msg: => String) = if (isReplTrace) echo(msg)
+ private[nsc] def replinfo(msg: => String) = if (isReplInfo) echo(msg)
+
+ private[nsc] def logAndDiscard[T](label: String, alt: => T): PartialFunction[Throwable, T] = {
+ case t =>
+ repldbg(label + ": " + unwrap(t))
+ repltrace(stackTraceString(unwrap(t)))
+ alt
+ }
+ private[nsc] def substituteAndLog[T](alt: => T)(body: => T): T =
+ substituteAndLog("" + alt, alt)(body)
+ private[nsc] def substituteAndLog[T](label: String, alt: => T)(body: => T): T = {
+ try body
+ catch logAndDiscard(label, alt)
+ }
+ private[nsc] def squashAndLog(label: String)(body: => Unit): Unit =
+ substituteAndLog(label, ())(body)
+
+ def isReplTrace: Boolean = replProps.trace
+ def isReplDebug: Boolean = replProps.debug || isReplTrace
+ def isReplInfo: Boolean = replProps.info || isReplDebug
+ def isReplPower: Boolean = replProps.power
+}
diff --git a/test/files/pos/t5604/ReplReporter.scala b/test/files/pos/t5604/ReplReporter.scala
new file mode 100644
index 0000000000..130af990ad
--- /dev/null
+++ b/test/files/pos/t5604/ReplReporter.scala
@@ -0,0 +1,30 @@
+/* NSC -- new Scala compiler
+ * Copyright 2002-2011 LAMP/EPFL
+ * @author Paul Phillips
+ */
+
+package scala.tools.nsc
+package interpreter
+
+import reporters._
+import IMain._
+
+class ReplReporter(intp: IMain) extends ConsoleReporter(intp.settings, Console.in, new ReplStrippingWriter(intp)) {
+ override def printMessage(msg: String) {
+ // Avoiding deadlock if the compiler starts logging before
+ // the lazy val is complete.
+ if (intp.isInitializeComplete) {
+ if (intp.totalSilence) {
+ if (isReplTrace)
+ super.printMessage("[silent] " + msg)
+ }
+ else super.printMessage(msg)
+ }
+ else Console.println("[init] " + msg)
+ }
+
+ override def displayPrompt() {
+ if (intp.totalSilence) ()
+ else super.displayPrompt()
+ }
+}