summaryrefslogtreecommitdiff
path: root/src/compiler/scala/tools/nsc
diff options
context:
space:
mode:
Diffstat (limited to 'src/compiler/scala/tools/nsc')
-rw-r--r--src/compiler/scala/tools/nsc/Global.scala122
-rw-r--r--src/compiler/scala/tools/nsc/ast/Trees.scala2
-rw-r--r--src/compiler/scala/tools/nsc/ast/parser/Scanners.scala2
-rw-r--r--src/compiler/scala/tools/nsc/ast/parser/SyntaxAnalyzer.scala2
-rw-r--r--src/compiler/scala/tools/nsc/backend/icode/GenICode.scala6
-rw-r--r--src/compiler/scala/tools/nsc/backend/icode/analysis/CopyPropagation.scala2
-rw-r--r--src/compiler/scala/tools/nsc/io/AbstractFile.scala2
-rw-r--r--src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala25
-rw-r--r--src/compiler/scala/tools/nsc/symtab/classfile/ICodeReader.scala6
-rw-r--r--src/compiler/scala/tools/nsc/transform/AddInterfaces.scala12
-rw-r--r--src/compiler/scala/tools/nsc/transform/Erasure.scala2
-rw-r--r--src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala4
-rw-r--r--src/compiler/scala/tools/nsc/transform/Mixin.scala2
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala6
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Contexts.scala2
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/MethodSynthesis.scala133
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/PatMatVirtualiser.scala6
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/RefChecks.scala2
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala2
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/SyntheticMethods.scala167
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/TreeCheckers.scala4
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/TypeDiagnostics.scala2
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Typers.scala18
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Unapplies.scala2
-rw-r--r--src/compiler/scala/tools/nsc/util/SourceFile.scala4
25 files changed, 302 insertions, 235 deletions
diff --git a/src/compiler/scala/tools/nsc/Global.scala b/src/compiler/scala/tools/nsc/Global.scala
index 426700f3b2..797ed7e047 100644
--- a/src/compiler/scala/tools/nsc/Global.scala
+++ b/src/compiler/scala/tools/nsc/Global.scala
@@ -13,7 +13,7 @@ import scala.tools.util.{ Profiling, PathResolver }
import scala.collection.{ mutable, immutable }
import io.{ SourceReader, AbstractFile, Path }
import reporters.{ Reporter, ConsoleReporter }
-import util.{ NoPosition, Exceptional, ClassPath, SourceFile, Statistics, StatisticsInfo, BatchSourceFile, ScriptSourceFile, ShowPickled, ScalaClassLoader, returning }
+import util.{ NoPosition, Exceptional, ClassPath, SourceFile, NoSourceFile, Statistics, StatisticsInfo, BatchSourceFile, ScriptSourceFile, ShowPickled, ScalaClassLoader, returning }
import scala.reflect.internal.pickling.{ PickleBuffer, PickleFormat }
import settings.{ AestheticSettings }
@@ -164,6 +164,23 @@ class Global(var currentSettings: Settings, var reporter: Reporter) extends Symb
if (opt.fatalWarnings) globalError(msg)
else reporter.warning(NoPosition, msg)
+ // Getting in front of Predef's asserts to supplement with more info.
+ // This has the happy side effect of masking the one argument forms
+ // of assert and require (but for now I've reproduced them here,
+ // because there are a million to fix.)
+ @inline final def assert(assertion: Boolean, message: => Any) {
+ Predef.assert(assertion, supplementErrorMessage("" + message))
+ }
+ @inline final def assert(assertion: Boolean) {
+ assert(assertion, "")
+ }
+ @inline final def require(requirement: Boolean, message: => Any) {
+ Predef.require(requirement, supplementErrorMessage("" + message))
+ }
+ @inline final def require(requirement: Boolean) {
+ require(requirement, "")
+ }
+
// Needs to call error to make sure the compile fails.
override def abort(msg: String): Nothing = {
error(msg)
@@ -375,10 +392,13 @@ class Global(var currentSettings: Settings, var reporter: Reporter) extends Symb
}
final def applyPhase(unit: CompilationUnit) {
+ if ((unit ne null) && unit.exists)
+ lastSeenSourceFile = unit.source
+
if (opt.echoFilenames)
inform("[running phase " + name + " on " + unit + "]")
- val unit0 = currentRun.currentUnit
+ val unit0 = currentUnit
try {
currentRun.currentUnit = unit
if (!cancelled(unit)) {
@@ -387,7 +407,7 @@ class Global(var currentSettings: Settings, var reporter: Reporter) extends Symb
}
currentRun.advanceUnit
} finally {
- //assert(currentRun.currentUnit == unit)
+ //assert(currentUnit == unit)
currentRun.currentUnit = unit0
}
}
@@ -781,9 +801,40 @@ class Global(var currentSettings: Settings, var reporter: Reporter) extends Symb
curRun = null
}
+ /** There are common error conditions where when the exception hits
+ * here, currentRun.currentUnit is null. This robs us of the knowledge
+ * of what file was being compiled when it broke. Since I really
+ * really want to know, this hack.
+ */
+ private var lastSeenSourceFile: SourceFile = NoSourceFile
+
/** The currently active run
*/
- def currentRun: Run = curRun
+ def currentRun: Run = curRun
+ def currentUnit: CompilationUnit = if (currentRun eq null) NoCompilationUnit else currentRun.currentUnit
+ def currentSource: SourceFile = if (currentUnit.exists) currentUnit.source else lastSeenSourceFile
+
+ /** Don't want to introduce new errors trying to report errors,
+ * so swallow exceptions.
+ */
+ override def supplementErrorMessage(errorMessage: String): String = try {
+ """|
+ | while compiling: %s
+ | current phase: %s
+ | library version: %s
+ | compiler version: %s
+ | reconstructed args: %s
+ |
+ |%s""".stripMargin.format(
+ currentSource.path,
+ phase,
+ scala.util.Properties.versionString,
+ Properties.versionString,
+ settings.recreateArgs.mkString(" "),
+ if (opt.debug) "Current unit body:\n" + currentUnit.body + "\n" + errorMessage else errorMessage
+ )
+ }
+ catch { case x: Exception => errorMessage }
/** The id of the currently active run
*/
@@ -798,10 +849,40 @@ class Global(var currentSettings: Settings, var reporter: Reporter) extends Symb
/** A Run is a single execution of the compiler on a sets of units
*/
class Run {
+ /** Have been running into too many init order issues with Run
+ * during erroneous conditions. Moved all these vals up to the
+ * top of the file so at least they're not trivially null.
+ */
var isDefined = false
+ /** The currently compiled unit; set from GlobalPhase */
+ var currentUnit: CompilationUnit = NoCompilationUnit
+
+ /** Counts for certain classes of warnings during this run. */
+ var deprecationWarnings: List[(Position, String)] = Nil
+ var uncheckedWarnings: List[(Position, String)] = Nil
+
+ /** A flag whether macro expansions failed */
+ var macroExpansionFailed = false
+
/** To be initialized from firstPhase. */
private var terminalPhase: Phase = NoPhase
+ private val unitbuf = new mutable.ListBuffer[CompilationUnit]
+ val compiledFiles = new mutable.HashSet[String]
+
+ /** A map from compiled top-level symbols to their source files */
+ val symSource = new mutable.HashMap[Symbol, AbstractFile]
+
+ /** A map from compiled top-level symbols to their picklers */
+ val symData = new mutable.HashMap[Symbol, PickleBuffer]
+
+ private var phasec: Int = 0 // phases completed
+ private var unitc: Int = 0 // units completed this phase
+ private var _unitbufSize = 0
+
+ def size = _unitbufSize
+ override def toString = "scalac Run for:\n " + compiledFiles.toList.sorted.mkString("\n ")
+
// Calculate where to stop based on settings -Ystop-before or -Ystop-after.
// Slightly complicated logic due to wanting -Ystop-before:parser to fail rather
// than mysteriously running to completion.
@@ -895,16 +976,6 @@ class Global(var currentSettings: Settings, var reporter: Reporter) extends Symb
// --------------- Miscellania -------------------------------
- /** The currently compiled unit; set from GlobalPhase */
- var currentUnit: CompilationUnit = _
-
- /** Counts for certain classes of warnings during this run. */
- var deprecationWarnings: List[(Position, String)] = Nil
- var uncheckedWarnings: List[(Position, String)] = Nil
-
- /** A flag whether macro expansions failed */
- var macroExpansionFailed = false
-
/** Progress tracking. Measured in "progress units" which are 1 per
* compilation unit per phase completed.
*
@@ -936,9 +1007,7 @@ class Global(var currentSettings: Settings, var reporter: Reporter) extends Symb
}
def cancel() { reporter.cancelled = true }
-
- private var phasec: Int = 0 // phases completed
- private var unitc: Int = 0 // units completed this phase
+
private def currentProgress = (phasec * size) + unitc
private def totalProgress = (phaseDescriptors.size - 1) * size // -1: drops terminal phase
private def refreshProgress() = if (size > 0) progress(currentProgress, totalProgress)
@@ -977,11 +1046,6 @@ class Global(var currentSettings: Settings, var reporter: Reporter) extends Symb
// ----------- Units and top-level classes and objects --------
- private val unitbuf = new mutable.ListBuffer[CompilationUnit]
- val compiledFiles = new mutable.HashSet[String]
-
- private var _unitbufSize = 0
- def size = _unitbufSize
/** add unit to be compiled in this run */
private def addUnit(unit: CompilationUnit) {
@@ -1005,12 +1069,6 @@ class Global(var currentSettings: Settings, var reporter: Reporter) extends Symb
*/
def units: Iterator[CompilationUnit] = unitbuf.iterator
- /** A map from compiled top-level symbols to their source files */
- val symSource = new mutable.HashMap[Symbol, AbstractFile]
-
- /** A map from compiled top-level symbols to their picklers */
- val symData = new mutable.HashMap[Symbol, PickleBuffer]
-
def registerPickle(sym: Symbol): Unit = {
// Convert all names to the type name: objects don't store pickled data
if (opt.showPhase && (opt.showNames exists (x => findNamedMember(x.toTypeName, sym) != NoSymbol))) {
@@ -1114,6 +1172,14 @@ class Global(var currentSettings: Settings, var reporter: Reporter) extends Symb
/** Compile list of units, starting with phase `fromPhase`
*/
def compileUnits(units: List[CompilationUnit], fromPhase: Phase) {
+ try compileUnitsInternal(units, fromPhase)
+ catch { case ex =>
+ globalError(supplementErrorMessage("uncaught exception during compilation: " + ex.getClass.getName))
+ throw ex
+ }
+ }
+
+ private def compileUnitsInternal(units: List[CompilationUnit], fromPhase: Phase) {
units foreach addUnit
if (opt.profileAll) {
inform("starting CPU profiling on compilation run")
diff --git a/src/compiler/scala/tools/nsc/ast/Trees.scala b/src/compiler/scala/tools/nsc/ast/Trees.scala
index 3a2c5f61b2..c80b07c44d 100644
--- a/src/compiler/scala/tools/nsc/ast/Trees.scala
+++ b/src/compiler/scala/tools/nsc/ast/Trees.scala
@@ -223,7 +223,7 @@ trait Trees extends reflect.internal.Trees { self: Global =>
try unit.body = transform(unit.body)
catch {
case ex: Exception =>
- println("unhandled exception while transforming "+unit)
+ println(supplementErrorMessage("unhandled exception while transforming "+unit))
throw ex
}
}
diff --git a/src/compiler/scala/tools/nsc/ast/parser/Scanners.scala b/src/compiler/scala/tools/nsc/ast/parser/Scanners.scala
index a2a577a7ab..4478fb6128 100644
--- a/src/compiler/scala/tools/nsc/ast/parser/Scanners.scala
+++ b/src/compiler/scala/tools/nsc/ast/parser/Scanners.scala
@@ -468,7 +468,7 @@ trait Scanners extends ScannersCommon {
nextChar()
getOperatorRest()
} else {
- syntaxError("illegal character")
+ syntaxError("illegal character '" + ("" + '\\' + 'u' + "%04x".format(ch: Int)) + "'")
nextChar()
}
}
diff --git a/src/compiler/scala/tools/nsc/ast/parser/SyntaxAnalyzer.scala b/src/compiler/scala/tools/nsc/ast/parser/SyntaxAnalyzer.scala
index b5ec0ceffb..e310611e68 100644
--- a/src/compiler/scala/tools/nsc/ast/parser/SyntaxAnalyzer.scala
+++ b/src/compiler/scala/tools/nsc/ast/parser/SyntaxAnalyzer.scala
@@ -24,7 +24,7 @@ abstract class SyntaxAnalyzer extends SubComponent with Parsers with MarkupParse
import global._
informProgress("parsing " + unit)
unit.body =
- if (unit.source.file.name.endsWith(".java")) new JavaUnitParser(unit).parse()
+ if (unit.isJava) new JavaUnitParser(unit).parse()
else if (reporter.incompleteHandled) new UnitParser(unit).parse()
else new UnitParser(unit).smartParse()
diff --git a/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala b/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala
index badf5d70d1..3d650ef753 100644
--- a/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala
+++ b/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala
@@ -179,7 +179,7 @@ abstract class GenICode extends SubComponent {
}
private def genThrow(expr: Tree, ctx: Context): (Context, TypeKind) = {
- require(expr.tpe <:< ThrowableClass.tpe)
+ require(expr.tpe <:< ThrowableClass.tpe, expr.tpe)
val thrownKind = toTypeKind(expr.tpe)
val ctx1 = genLoad(expr, ctx, thrownKind)
@@ -480,7 +480,7 @@ abstract class GenICode extends SubComponent {
*/
private def msil_genLoadZeroOfNonEnumValuetype(ctx: Context, kind: TypeKind, pos: Position, leaveAddressOnStackInstead: Boolean) {
val REFERENCE(clssym) = kind
- assert(loaders.clrTypes.isNonEnumValuetype(clssym))
+ assert(loaders.clrTypes.isNonEnumValuetype(clssym), clssym)
val local = ctx.makeLocal(pos, clssym.tpe, "tmp")
ctx.method.addLocal(local)
ctx.bb.emit(CIL_LOAD_LOCAL_ADDRESS(local), pos)
@@ -1064,7 +1064,7 @@ abstract class GenICode extends SubComponent {
var default: BasicBlock = afterCtx.bb
for (caze @ CaseDef(pat, guard, body) <- cases) {
- assert(guard == EmptyTree)
+ assert(guard == EmptyTree, guard)
val tmpCtx = ctx1.newBlock
pat match {
case Literal(value) =>
diff --git a/src/compiler/scala/tools/nsc/backend/icode/analysis/CopyPropagation.scala b/src/compiler/scala/tools/nsc/backend/icode/analysis/CopyPropagation.scala
index 229bbceb36..f5be82a776 100644
--- a/src/compiler/scala/tools/nsc/backend/icode/analysis/CopyPropagation.scala
+++ b/src/compiler/scala/tools/nsc/backend/icode/analysis/CopyPropagation.scala
@@ -199,7 +199,7 @@ abstract class CopyPropagation {
m foreachBlock { b =>
in(b) = lattice.bottom
out(b) = lattice.bottom
- assert(out.contains(b))
+ assert(out.contains(b), out)
log("Added point: " + b)
}
m.exh foreach { e =>
diff --git a/src/compiler/scala/tools/nsc/io/AbstractFile.scala b/src/compiler/scala/tools/nsc/io/AbstractFile.scala
index 494eb4d50b..b51cf1228c 100644
--- a/src/compiler/scala/tools/nsc/io/AbstractFile.scala
+++ b/src/compiler/scala/tools/nsc/io/AbstractFile.scala
@@ -211,7 +211,7 @@ abstract class AbstractFile extends AnyRef with Iterable[AbstractFile] {
var start = 0
while (true) {
val index = path.indexOf(separator, start)
- assert(index < 0 || start < index)
+ assert(index < 0 || start < index, ((path, directory, start, index)))
val name = path.substring(start, if (index < 0) length else index)
file = getFile(file, name, if (index < 0) directory else true)
if ((file eq null) || index < 0) return file
diff --git a/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala b/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala
index 811bb6ee05..ac6dca4422 100644
--- a/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala
+++ b/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala
@@ -392,7 +392,7 @@ abstract class ClassfileParser {
}
def getBytes(indices: List[Int]): Array[Byte] = {
- assert(!indices.isEmpty)
+ assert(!indices.isEmpty, indices)
var value = values(indices.head).asInstanceOf[Array[Byte]]
if (value eq null) {
val bytesBuffer = ArrayBuffer.empty[Byte]
@@ -679,7 +679,7 @@ abstract class ClassfileParser {
var index = 0
val end = sig.length
def accept(ch: Char) {
- assert(sig(index) == ch)
+ assert(sig(index) == ch, (sig(index), ch))
index += 1
}
def subName(isDelimiter: Char => Boolean): Name = {
@@ -736,7 +736,7 @@ abstract class ClassfileParser {
}
}
accept('>')
- assert(xs.length > 0)
+ assert(xs.length > 0, tp)
newExistentialType(existentials.toList, typeRef(pre, classSym, xs.toList))
} else if (classSym.isMonomorphicType) {
tp
@@ -750,7 +750,7 @@ abstract class ClassfileParser {
res
}
case tp =>
- assert(sig(index) != '<')
+ assert(sig(index) != '<', tp)
tp
}
@@ -776,7 +776,7 @@ abstract class ClassfileParser {
appliedType(definitions.ArrayClass.tpe, List(elemtp))
case '(' =>
// we need a method symbol. given in line 486 by calling getType(methodSym, ..)
- assert(sym ne null)
+ assert(sym ne null, sig)
val paramtypes = new ListBuffer[Type]()
while (sig(index) != ')') {
paramtypes += objToAny(sig2type(tparams, skiptvs))
@@ -809,7 +809,7 @@ abstract class ClassfileParser {
var tparams = classTParams
val newTParams = new ListBuffer[Symbol]()
if (sig(index) == '<') {
- assert(sym != null)
+ assert(sym != null, sig)
index += 1
val start = index
while (sig(index) != '>') {
@@ -974,18 +974,18 @@ abstract class ClassfileParser {
def parseScalaSigBytes: Option[ScalaSigBytes] = {
val tag = in.nextByte.toChar
- assert(tag == STRING_TAG)
+ assert(tag == STRING_TAG, tag)
Some(ScalaSigBytes(pool getBytes in.nextChar))
}
def parseScalaLongSigBytes: Option[ScalaSigBytes] = {
val tag = in.nextByte.toChar
- assert(tag == ARRAY_TAG)
+ assert(tag == ARRAY_TAG, tag)
val stringCount = in.nextChar
val entries =
for (i <- 0 until stringCount) yield {
val stag = in.nextByte.toChar
- assert(stag == STRING_TAG)
+ assert(stag == STRING_TAG, stag)
in.nextChar.toInt
}
Some(ScalaSigBytes(pool.getBytes(entries.toList)))
@@ -1208,7 +1208,12 @@ abstract class ClassfileParser {
atPhase(currentRun.typerPhase)(getMember(sym, innerName.toTypeName))
else
getMember(sym, innerName.toTypeName)
- assert(s ne NoSymbol, sym + "." + innerName + " linkedModule: " + sym.companionModule + sym.companionModule.info.members)
+
+ assert(s ne NoSymbol,
+ "" + ((externalName, outerName, innerName, sym.fullLocationString)) + " / " +
+ " while parsing " + ((in.file, busy)) +
+ sym + "." + innerName + " linkedModule: " + sym.companionModule + sym.companionModule.info.members
+ )
s
case None =>
diff --git a/src/compiler/scala/tools/nsc/symtab/classfile/ICodeReader.scala b/src/compiler/scala/tools/nsc/symtab/classfile/ICodeReader.scala
index 3c97122c9c..7d42dabc08 100644
--- a/src/compiler/scala/tools/nsc/symtab/classfile/ICodeReader.scala
+++ b/src/compiler/scala/tools/nsc/symtab/classfile/ICodeReader.scala
@@ -434,7 +434,7 @@ abstract class ICodeReader extends ClassfileParser {
val padding = if ((pc + size) % 4 != 0) 4 - ((pc + size) % 4) else 0
size += padding
in.bp += padding
- assert((pc + size % 4) != 0)
+ assert((pc + size % 4) != 0, pc)
/* var byte1 = in.nextByte; size += 1;
while (byte1 == 0) { byte1 = in.nextByte; size += 1; }
val default = byte1 << 24 | in.nextByte << 16 | in.nextByte << 8 | in.nextByte;
@@ -454,7 +454,7 @@ abstract class ICodeReader extends ClassfileParser {
val padding = if ((pc + size) % 4 != 0) 4 - ((pc + size) % 4) else 0
size += padding
in.bp += padding
- assert((pc + size % 4) != 0)
+ assert((pc + size % 4) != 0, pc)
val default = pc + in.nextInt; size += 4
val npairs = in.nextInt; size += 4
var tags: List[List[Int]] = Nil
@@ -988,7 +988,7 @@ abstract class ICodeReader extends ClassfileParser {
def enterParam(idx: Int, kind: TypeKind) = {
val sym = method.symbol.newVariable(newTermName("par" + idx)).setInfo(kind.toType)
val l = new Local(sym, kind, true)
- assert(!locals.isDefinedAt(idx))
+ assert(!locals.isDefinedAt(idx), locals(idx))
locals += (idx -> List((l, kind)))
l
}
diff --git a/src/compiler/scala/tools/nsc/transform/AddInterfaces.scala b/src/compiler/scala/tools/nsc/transform/AddInterfaces.scala
index 1c41e68532..e01bbccf13 100644
--- a/src/compiler/scala/tools/nsc/transform/AddInterfaces.scala
+++ b/src/compiler/scala/tools/nsc/transform/AddInterfaces.scala
@@ -84,8 +84,14 @@ abstract class AddInterfaces extends InfoTransform {
atPhase(implClassPhase) {
log("%s.implClass == %s".format(iface, iface.implClass))
val implName = nme.implClassName(iface.name)
- var impl = if (iface.owner.isClass) iface.owner.info.decl(implName) else NoSymbol
- impl.info
+ var impl = if (iface.owner.isClass) iface.owner.info.decl(implName) else NoSymbol
+
+ // !!! Why does forcing the impl's info here lead to a crash?
+ // See test case pos/trait-force-info.scala for a minimization.
+ // It crashes like this:
+ //
+ // [log lazyvals] trait ContextTrees.implClass == class ContextTrees$class
+ // error: java.lang.AssertionError: assertion failed: (scala.tools.nsc.typechecker.Contexts$NoContext$,scala.tools.nsc.typechecker.Contexts,NoContext$,trait Contexts in package typechecker) / while parsing (/scala/trunk/build/pack/lib/scala-compiler.jar(scala/tools/nsc/interactive/ContextTrees$class.class),Some(class ContextTrees$class))trait Contexts.NoContext$ linkedModule: <none>List()
val originalImpl = impl
val originalImplString = originalImpl.hasFlagsToString(-1L)
@@ -179,7 +185,7 @@ abstract class AddInterfaces extends InfoTransform {
)
def implType(tp: Type): Type = tp match {
case ClassInfoType(parents, decls, _) =>
- assert(phase == implClassPhase)
+ assert(phase == implClassPhase, tp)
ClassInfoType(
ObjectClass.tpe +: (parents.tail map mixinToImplClass filter (_.typeSymbol != ObjectClass)) :+ iface.tpe,
implDecls(sym, decls),
diff --git a/src/compiler/scala/tools/nsc/transform/Erasure.scala b/src/compiler/scala/tools/nsc/transform/Erasure.scala
index b342b95742..fe479a5375 100644
--- a/src/compiler/scala/tools/nsc/transform/Erasure.scala
+++ b/src/compiler/scala/tools/nsc/transform/Erasure.scala
@@ -797,7 +797,7 @@ abstract class Erasure extends AddInterfaces
// && (bridge.paramss.nonEmpty && bridge.paramss.head.nonEmpty && bridge.paramss.head.tail.isEmpty) // does the first argument list has exactly one argument -- for user-defined unapplies we can't be sure
&& !(atPhase(phase.next)(member.tpe <:< other.tpe))) { // no static guarantees (TODO: is the subtype test ever true?)
import CODE._
- val typeTest = gen.mkIsInstanceOf(REF(bridge.paramss.head.head), member.tpe.params.head.tpe, any = true, wrapInApply = true) // any = true since we're before erasure (?), wrapInapply is true since we're after uncurry
+ val typeTest = gen.mkIsInstanceOf(REF(bridge.firstParam), member.tpe.params.head.tpe, any = true, wrapInApply = true) // any = true since we're before erasure (?), wrapInapply is true since we're after uncurry
// println("unapp type test: "+ typeTest)
IF (typeTest) THEN bridgingCall ELSE REF(NoneModule)
} else bridgingCall
diff --git a/src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala b/src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala
index 14f3dc16fa..7f7f7e7b65 100644
--- a/src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala
+++ b/src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala
@@ -427,7 +427,7 @@ abstract class ExplicitOuter extends InfoTransform
}
val t = atPos(tree.pos) {
- val context = MatrixContext(currentRun.currentUnit, transform, localTyper, currentOwner, tree.tpe)
+ val context = MatrixContext(currentUnit, transform, localTyper, currentOwner, tree.tpe)
val t_untyped = handlePattern(nselector, ncases, checkExhaustive, context)
/* if @switch annotation is present, verify the resulting tree is a Match */
@@ -506,7 +506,7 @@ abstract class ExplicitOuter extends InfoTransform
val outerVal = atPos(tree.pos)(qual match {
// it's a call between constructors of same class
case _: This =>
- assert(outerParam != NoSymbol)
+ assert(outerParam != NoSymbol, tree)
outerValue
case _ =>
gen.mkAttributedQualifier(qual.tpe.prefix match {
diff --git a/src/compiler/scala/tools/nsc/transform/Mixin.scala b/src/compiler/scala/tools/nsc/transform/Mixin.scala
index bd29336703..b3b7596f9a 100644
--- a/src/compiler/scala/tools/nsc/transform/Mixin.scala
+++ b/src/compiler/scala/tools/nsc/transform/Mixin.scala
@@ -1053,7 +1053,7 @@ abstract class Mixin extends InfoTransform with ast.TreeDSL {
else accessedRef match {
case Literal(_) => accessedRef
case _ =>
- val init = Assign(accessedRef, Ident(sym.paramss.head.head))
+ val init = Assign(accessedRef, Ident(sym.firstParam))
val getter = sym.getter(clazz)
if (!needsInitFlag(getter)) init
diff --git a/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala b/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala
index a762e44bda..6ee09d064f 100644
--- a/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala
@@ -142,7 +142,7 @@ trait ContextErrors {
case _ =>
found
}
- assert(!found.isErroneous && !req.isErroneous)
+ assert(!found.isErroneous && !req.isErroneous, (found, req))
issueNormalTypeError(tree, withAddendum(tree.pos)(typeErrorMsg(found, req, infer.isPossiblyMissingArgs(found, req))) )
if (settings.explaintypes.value)
@@ -171,6 +171,8 @@ trait ContextErrors {
NormalTypeError(tree, "reference to " + name + " is ambiguous;\n" + msg)
def SymbolNotFoundError(tree: Tree, name: Name, owner: Symbol, startingIdentCx: Context) = {
+ /*** Disabled pending investigation of performance impact.
+
// This laborious determination arrived at to keep the tests working.
val calcSimilar = (
name.length > 2 && (
@@ -196,6 +198,8 @@ trait ContextErrors {
similarString("" + name, allowedStrings)
}
}
+ */
+ val similar = ""
NormalTypeError(tree, "not found: "+decodeWithKind(name, owner) + similar)
}
diff --git a/src/compiler/scala/tools/nsc/typechecker/Contexts.scala b/src/compiler/scala/tools/nsc/typechecker/Contexts.scala
index a1ade61dad..740acbd10f 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Contexts.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Contexts.scala
@@ -585,7 +585,7 @@ trait Contexts { self: Analyzer =>
debuglog("collect local implicits " + scope.toList)//DEBUG
collectImplicits(scope.toList, NoPrefix)
} else if (imports != nextOuter.imports) {
- assert(imports.tail == nextOuter.imports)
+ assert(imports.tail == nextOuter.imports, (imports, nextOuter.imports))
collectImplicitImports(imports.head)
} else if (owner.isPackageClass) {
// the corresponding package object may contain implicit members.
diff --git a/src/compiler/scala/tools/nsc/typechecker/MethodSynthesis.scala b/src/compiler/scala/tools/nsc/typechecker/MethodSynthesis.scala
index c6ca9870c3..0c32ff32c0 100644
--- a/src/compiler/scala/tools/nsc/typechecker/MethodSynthesis.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/MethodSynthesis.scala
@@ -17,6 +17,139 @@ trait MethodSynthesis {
import global._
import definitions._
+ import CODE._
+
+ object synthesisUtil {
+ type M[T] = Manifest[T]
+ type CM[T] = ClassManifest[T]
+
+ def ValOrDefDef(sym: Symbol, body: Tree) =
+ if (sym.isLazy) ValDef(sym, body)
+ else DefDef(sym, body)
+
+ def applyTypeInternal(manifests: List[M[_]]): Type = {
+ val symbols = manifests map manifestToSymbol
+ val container :: args = symbols
+ val tparams = container.typeConstructor.typeParams
+
+ // Conservative at present - if manifests were more usable this could do a lot more.
+ require(symbols forall (_ ne NoSymbol), "Must find all manifests: " + symbols)
+ require(container.owner.isPackageClass, "Container must be a top-level class in a package: " + container)
+ require(tparams.size == args.size, "Arguments must match type constructor arity: " + tparams + ", " + args)
+
+ typeRef(container.typeConstructor.prefix, container, args map (_.tpe))
+ }
+
+ def companionType[T](implicit m: M[T]) =
+ getRequiredModule(m.erasure.getName).tpe
+
+ // Use these like `applyType[List, Int]` or `applyType[Map, Int, String]`
+ def applyType[CC](implicit m1: M[CC]): Type =
+ applyTypeInternal(List(m1))
+
+ def applyType[CC[X1], X1](implicit m1: M[CC[_]], m2: M[X1]): Type =
+ applyTypeInternal(List(m1, m2))
+
+ def applyType[CC[X1, X2], X1, X2](implicit m1: M[CC[_,_]], m2: M[X1], m3: M[X2]): Type =
+ applyTypeInternal(List(m1, m2, m3))
+
+ def applyType[CC[X1, X2, X3], X1, X2, X3](implicit m1: M[CC[_,_,_]], m2: M[X1], m3: M[X2], m4: M[X3]): Type =
+ applyTypeInternal(List(m1, m2, m3, m4))
+
+ def newMethodType[F](owner: Symbol)(implicit m: Manifest[F]): Type = {
+ val fnSymbol = manifestToSymbol(m)
+ assert(fnSymbol isSubClass FunctionClass(m.typeArguments.size - 1), (owner, m))
+ val symbols = m.typeArguments map (m => manifestToSymbol(m))
+ val formals = symbols.init map (_.typeConstructor)
+ val params = owner newSyntheticValueParams formals
+
+ MethodType(params, symbols.last.typeConstructor)
+ }
+ }
+ import synthesisUtil._
+
+ class ClassMethodSynthesis(val clazz: Symbol, localTyper: Typer) {
+ private def isOverride(name: TermName) =
+ clazzMember(name).alternatives exists (sym => !sym.isDeferred && (sym.owner != clazz))
+
+ def newMethodFlags(name: TermName) = {
+ val overrideFlag = if (isOverride(name)) OVERRIDE else 0L
+ overrideFlag | SYNTHETIC
+ }
+ def newMethodFlags(method: Symbol) = {
+ val overrideFlag = if (isOverride(method.name)) OVERRIDE else 0L
+ (method.flags | overrideFlag | SYNTHETIC) & ~DEFERRED
+ }
+
+ private def finishMethod(method: Symbol, f: Symbol => Tree): Tree =
+ logResult("finishMethod")(localTyper typed ValOrDefDef(method, f(method)))
+
+ private def createInternal(name: Name, f: Symbol => Tree, info: Type): Tree = {
+ val m = clazz.newMethod(name.toTermName, clazz.pos.focus, newMethodFlags(name))
+ finishMethod(m setInfoAndEnter info, f)
+ }
+ private def createInternal(name: Name, f: Symbol => Tree, infoFn: Symbol => Type): Tree = {
+ val m = clazz.newMethod(name.toTermName, clazz.pos.focus, newMethodFlags(name))
+ finishMethod(m setInfoAndEnter infoFn(m), f)
+ }
+ private def cloneInternal(original: Symbol, f: Symbol => Tree, name: Name): Tree = {
+ val m = original.cloneSymbol(clazz, newMethodFlags(original)) setPos clazz.pos.focus
+ m.name = name
+ finishMethod(clazz.info.decls enter m, f)
+ }
+
+ private def cloneInternal(original: Symbol, f: Symbol => Tree): Tree =
+ cloneInternal(original, f, original.name)
+
+ def clazzMember(name: Name) = clazz.info nonPrivateMember name
+ def typeInClazz(sym: Symbol) = clazz.thisType memberType sym
+
+ /** Function argument takes the newly created method symbol of
+ * the same type as `name` in clazz, and returns the tree to be
+ * added to the template.
+ */
+ def overrideMethod(name: Name)(f: Symbol => Tree): Tree =
+ overrideMethod(clazzMember(name))(f)
+
+ def overrideMethod(original: Symbol)(f: Symbol => Tree): Tree =
+ cloneInternal(original, sym => f(sym setFlag OVERRIDE))
+
+ def deriveMethod(original: Symbol, nameFn: Name => Name)(f: Symbol => Tree): Tree =
+ cloneInternal(original, f, nameFn(original.name))
+
+ def createMethod(name: Name, paramTypes: List[Type], returnType: Type)(f: Symbol => Tree): Tree =
+ createInternal(name, f, (m: Symbol) => MethodType(m newSyntheticValueParams paramTypes, returnType))
+
+ def createMethod(name: Name, returnType: Type)(f: Symbol => Tree): Tree =
+ createInternal(name, f, NullaryMethodType(returnType))
+
+ def createMethod(original: Symbol)(f: Symbol => Tree): Tree =
+ createInternal(original.name, f, original.info)
+
+ def forwardMethod(original: Symbol, newMethod: Symbol)(transformArgs: List[Tree] => List[Tree]): Tree =
+ createMethod(original)(m => gen.mkMethodCall(newMethod, transformArgs(m.paramss.head map Ident)))
+
+ def createSwitchMethod(name: Name, range: Seq[Int], returnType: Type)(f: Int => Tree) = {
+ createMethod(name, List(IntClass.tpe), returnType) { m =>
+ val arg0 = Ident(m.firstParam)
+ val default = DEFAULT ==> THROW(IndexOutOfBoundsExceptionClass, arg0)
+ val cases = range.map(num => CASE(LIT(num)) ==> f(num)).toList :+ default
+
+ Match(arg0, cases)
+ }
+ }
+
+ // def foo() = constant
+ def constantMethod(name: Name, value: Any): Tree = {
+ val constant = Constant(value)
+ createMethod(name, Nil, constant.tpe)(_ => Literal(constant))
+ }
+ // def foo = constant
+ def constantNullary(name: Name, value: Any): Tree = {
+ val constant = Constant(value)
+ createMethod(name, constant.tpe)(_ => Literal(constant))
+ }
+ }
/** There are two key methods in here.
*
diff --git a/src/compiler/scala/tools/nsc/typechecker/PatMatVirtualiser.scala b/src/compiler/scala/tools/nsc/typechecker/PatMatVirtualiser.scala
index 73a43bf4a1..44579400ff 100644
--- a/src/compiler/scala/tools/nsc/typechecker/PatMatVirtualiser.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/PatMatVirtualiser.scala
@@ -81,7 +81,7 @@ trait PatMatVirtualiser extends ast.TreeDSL { self: Analyzer =>
// we don't transform after typers
// (that would require much more sophistication when generating trees,
// and the only place that emits Matches after typers is for exception handling anyway)
- assert(phase.id <= currentRun.typerPhase.id)
+ assert(phase.id <= currentRun.typerPhase.id, phase)
val scrutType = repeatedToSeq(elimAnonymousClass(scrut.tpe.widen))
@@ -876,7 +876,7 @@ defined class Foo */
private val reusedBy = new collection.mutable.HashSet[Test]
var reuses: Option[Test] = None
def registerReuseBy(later: Test): Unit = {
- assert(later.reuses.isEmpty)
+ assert(later.reuses.isEmpty, later.reuses)
reusedBy += later
later.reuses = Some(this)
}
@@ -1239,7 +1239,7 @@ defined class Foo */
case d : DefTree if (d.symbol != NoSymbol) && ((d.symbol.owner == NoSymbol) || (d.symbol.owner == origOwner)) => // don't indiscriminately change existing owners! (see e.g., pos/t3440, pos/t3534, pos/unapplyContexts2)
// println("def: "+ (d, d.symbol.ownerChain, currentOwner.ownerChain))
if(d.symbol.isLazy) { // for lazy val's accessor -- is there no tree??
- assert(d.symbol.lazyAccessor != NoSymbol && d.symbol.lazyAccessor.owner == d.symbol.owner)
+ assert(d.symbol.lazyAccessor != NoSymbol && d.symbol.lazyAccessor.owner == d.symbol.owner, d.symbol.lazyAccessor)
d.symbol.lazyAccessor.owner = currentOwner
}
if(d.symbol.moduleClass ne NoSymbol)
diff --git a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala
index 1a54b26307..a99d09173e 100644
--- a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala
@@ -1491,7 +1491,7 @@ abstract class RefChecks extends InfoTransform with reflect.internal.transform.R
def checkSuper(mix: Name) =
// term should have been eliminated by super accessors
- assert(!(qual.symbol.isTrait && sym.isTerm && mix == tpnme.EMPTY))
+ assert(!(qual.symbol.isTrait && sym.isTerm && mix == tpnme.EMPTY), (qual.symbol, sym, mix))
transformCaseApply(tree,
qual match {
diff --git a/src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala b/src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala
index b109d57554..0ab09b4fec 100644
--- a/src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala
@@ -453,7 +453,7 @@ abstract class SuperAccessors extends transform.Transform with transform.TypingT
if (referencingClass.isSubClass(sym.owner.enclClass)
|| referencingClass.thisSym.isSubClass(sym.owner.enclClass)
|| referencingClass.enclosingPackageClass == sym.owner.enclosingPackageClass) {
- assert(referencingClass.isClass)
+ assert(referencingClass.isClass, referencingClass)
referencingClass
} else if(referencingClass.owner.enclClass != NoSymbol)
hostForAccessorOf(sym, referencingClass.owner.enclClass)
diff --git a/src/compiler/scala/tools/nsc/typechecker/SyntheticMethods.scala b/src/compiler/scala/tools/nsc/typechecker/SyntheticMethods.scala
index 4e986dc5aa..4ea21b1c44 100644
--- a/src/compiler/scala/tools/nsc/typechecker/SyntheticMethods.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/SyntheticMethods.scala
@@ -36,158 +36,13 @@ trait SyntheticMethods extends ast.TreeDSL {
import definitions._
import CODE._
- private object util {
- private type CM[T] = ClassManifest[T]
-
- def ValOrDefDef(sym: Symbol, body: Tree) =
- if (sym.isLazy) ValDef(sym, body)
- else DefDef(sym, body)
-
- /** To avoid unchecked warnings on polymorphic classes.
- */
- def clazzTypeToTest(clazz: Symbol) = clazz.tpe.normalize match {
- case TypeRef(_, sym, args) if args.nonEmpty => newExistentialType(sym.typeParams, clazz.tpe)
- case tp => tp
- }
-
- def makeMethodPublic(method: Symbol): Symbol = (
- method setPrivateWithin NoSymbol resetFlag AccessFlags
- )
-
- def methodArg(method: Symbol, idx: Int): Tree = Ident(method.paramss.head(idx))
-
- private def applyTypeInternal(manifests: List[CM[_]]): Type = {
- val symbols = manifests map manifestToSymbol
- val container :: args = symbols
- val tparams = container.typeConstructor.typeParams
-
- // Overly conservative at present - if manifests were more usable
- // this could do a lot more.
- require(symbols forall (_ ne NoSymbol), "Must find all manifests: " + symbols)
- require(container.owner.isPackageClass, "Container must be a top-level class in a package: " + container)
- require(tparams.size == args.size, "Arguments must match type constructor arity: " + tparams + ", " + args)
- require(args forall (_.typeConstructor.typeParams.isEmpty), "Arguments must be unparameterized: " + args)
-
- typeRef(container.typeConstructor.prefix, container, args map (_.tpe))
- }
-
- def manifestToSymbol(m: CM[_]): Symbol = m match {
- case x: scala.reflect.AnyValManifest[_] => getMember(ScalaPackageClass, newTermName("" + x))
- case _ => getClassIfDefined(m.erasure.getName)
- }
- def companionType[T](implicit m: CM[T]) =
- getRequiredModule(m.erasure.getName).tpe
-
- // Use these like `applyType[List, Int]` or `applyType[Map, Int, String]`
- def applyType[M](implicit m1: CM[M]): Type =
- applyTypeInternal(List(m1))
-
- def applyType[M[X1], X1](implicit m1: CM[M[_]], m2: CM[X1]): Type =
- applyTypeInternal(List(m1, m2))
-
- def applyType[M[X1, X2], X1, X2](implicit m1: CM[M[_,_]], m2: CM[X1], m3: CM[X2]): Type =
- applyTypeInternal(List(m1, m2, m3))
-
- def applyType[M[X1, X2, X3], X1, X2, X3](implicit m1: CM[M[_,_,_]], m2: CM[X1], m3: CM[X2], m4: CM[X3]): Type =
- applyTypeInternal(List(m1, m2, m3, m4))
- }
- import util._
-
- class MethodSynthesis(val clazz: Symbol, localTyper: Typer) {
- private def isOverride(method: Symbol) =
- clazzMember(method.name).alternatives exists (sym => (sym != method) && !sym.isDeferred)
-
- private def setMethodFlags(method: Symbol): Symbol = {
- val overrideFlag = if (isOverride(method)) OVERRIDE else 0L
-
- method setFlag (overrideFlag | SYNTHETIC) resetFlag DEFERRED
- }
-
- private def finishMethod(method: Symbol, f: Symbol => Tree): Tree = {
- setMethodFlags(method)
- clazz.info.decls enter method
- logResult("finishMethod")(localTyper typed ValOrDefDef(method, f(method)))
- }
-
- private def createInternal(name: Name, f: Symbol => Tree, info: Type): Tree = {
- val m = clazz.newMethod(name.toTermName, clazz.pos.focus)
- m setInfo info
- finishMethod(m, f)
- }
- private def createInternal(name: Name, f: Symbol => Tree, infoFn: Symbol => Type): Tree = {
- val m = clazz.newMethod(name.toTermName, clazz.pos.focus)
- m setInfo infoFn(m)
- finishMethod(m, f)
- }
- private def cloneInternal(original: Symbol, f: Symbol => Tree, name: Name): Tree = {
- val m = original.cloneSymbol(clazz) setPos clazz.pos.focus
- m.name = name
- finishMethod(m, f)
- }
-
- private def cloneInternal(original: Symbol, f: Symbol => Tree): Tree =
- cloneInternal(original, f, original.name)
-
- def clazzMember(name: Name) = clazz.info nonPrivateMember name match {
- case NoSymbol => log("In " + clazz + ", " + name + " not found: " + clazz.info) ; NoSymbol
- case sym => sym
- }
- def typeInClazz(sym: Symbol) = clazz.thisType memberType sym
-
- /** Function argument takes the newly created method symbol of
- * the same type as `name` in clazz, and returns the tree to be
- * added to the template.
- */
- def overrideMethod(name: Name)(f: Symbol => Tree): Tree =
- overrideMethod(clazzMember(name))(f)
-
- def overrideMethod(original: Symbol)(f: Symbol => Tree): Tree =
- cloneInternal(original, sym => f(sym setFlag OVERRIDE))
-
- def deriveMethod(original: Symbol, nameFn: Name => Name)(f: Symbol => Tree): Tree =
- cloneInternal(original, f, nameFn(original.name))
-
- def createMethod(name: Name, paramTypes: List[Type], returnType: Type)(f: Symbol => Tree): Tree =
- createInternal(name, f, (m: Symbol) => MethodType(m newSyntheticValueParams paramTypes, returnType))
-
- def createMethod(name: Name, returnType: Type)(f: Symbol => Tree): Tree =
- createInternal(name, f, NullaryMethodType(returnType))
-
- def createMethod(original: Symbol)(f: Symbol => Tree): Tree =
- createInternal(original.name, f, original.info)
-
- def forwardMethod(original: Symbol, newMethod: Symbol)(transformArgs: List[Tree] => List[Tree]): Tree =
- createMethod(original)(m => gen.mkMethodCall(newMethod, transformArgs(m.paramss.head map Ident)))
-
- def createSwitchMethod(name: Name, range: Seq[Int], returnType: Type)(f: Int => Tree) = {
- createMethod(name, List(IntClass.tpe), returnType) { m =>
- val arg0 = methodArg(m, 0)
- val default = DEFAULT ==> THROW(IndexOutOfBoundsExceptionClass, arg0)
- val cases = range.map(num => CASE(LIT(num)) ==> f(num)).toList :+ default
-
- Match(arg0, cases)
- }
- }
-
- // def foo() = constant
- def constantMethod(name: Name, value: Any): Tree = {
- val constant = Constant(value)
- createMethod(name, Nil, constant.tpe)(_ => Literal(constant))
- }
- // def foo = constant
- def constantNullary(name: Name, value: Any): Tree = {
- val constant = Constant(value)
- createMethod(name, constant.tpe)(_ => Literal(constant))
- }
- }
-
/** Add the synthetic methods to case classes.
*/
def addSyntheticMethods(templ: Template, clazz0: Symbol, context: Context): Template = {
if (phase.erasedTypes)
return templ
- val synthesizer = new MethodSynthesis(
+ val synthesizer = new ClassMethodSynthesis(
clazz0,
newTyper( if (reporter.hasErrors) context makeSilent false else context )
)
@@ -212,11 +67,12 @@ trait SyntheticMethods extends ast.TreeDSL {
// like Manifests and Arrays which are not robust and infer things
// which they shouldn't.
val accessorLub = (
- if (opt.experimental)
+ if (opt.experimental) {
global.weakLub(accessors map (_.tpe.finalResultType))._1 match {
case RefinedType(parents, decls) if !decls.isEmpty => intersectionType(parents)
case tp => tp
}
+ }
else AnyClass.tpe
)
@@ -258,11 +114,10 @@ trait SyntheticMethods extends ast.TreeDSL {
/** The canEqual method for case classes.
* def canEqual(that: Any) = that.isInstanceOf[This]
*/
- def canEqualMethod: Tree = {
- createMethod(nme.canEqual_, List(AnyClass.tpe), BooleanClass.tpe)(m =>
- methodArg(m, 0) IS_OBJ clazzTypeToTest(clazz)
- )
- }
+ def canEqualMethod: Tree = (
+ createMethod(nme.canEqual_, List(AnyClass.tpe), BooleanClass.tpe)(m =>
+ Ident(m.firstParam) IS_OBJ typeCaseType(clazz))
+ )
/** The equality method for case classes.
* 0 args:
@@ -276,8 +131,8 @@ trait SyntheticMethods extends ast.TreeDSL {
* }
*/
def equalsClassMethod: Tree = createMethod(nme.equals_, List(AnyClass.tpe), BooleanClass.tpe) { m =>
- val arg0 = methodArg(m, 0)
- val thatTest = gen.mkIsInstanceOf(arg0, clazzTypeToTest(clazz), true, false)
+ val arg0 = Ident(m.firstParam)
+ val thatTest = gen.mkIsInstanceOf(arg0, typeCaseType(clazz), true, false)
val thatCast = gen.mkCast(arg0, clazz.tpe)
def argsBody: Tree = {
@@ -331,7 +186,7 @@ trait SyntheticMethods extends ast.TreeDSL {
Object_hashCode -> (() => constantMethod(nme.hashCode_, clazz.name.decode.hashCode)),
Object_toString -> (() => constantMethod(nme.toString_, clazz.name.decode))
// Not needed, as reference equality is the default.
- // Object_equals -> (() => createMethod(Object_equals)(m => This(clazz) ANY_EQ methodArg(m, 0)))
+ // Object_equals -> (() => createMethod(Object_equals)(m => This(clazz) ANY_EQ Ident(m.firstParam)))
)
/** If you serialize a singleton and then deserialize it twice,
@@ -381,7 +236,7 @@ trait SyntheticMethods extends ast.TreeDSL {
for (ddef @ DefDef(_, _, _, _, _, _) <- templ.body ; if isRewrite(ddef.symbol)) {
val original = ddef.symbol
val newAcc = deriveMethod(ddef.symbol, name => context.unit.freshTermName(name + "$")) { newAcc =>
- makeMethodPublic(newAcc)
+ newAcc.makePublic
newAcc resetFlag (ACCESSOR | PARAMACCESSOR)
ddef.rhs.duplicate
}
diff --git a/src/compiler/scala/tools/nsc/typechecker/TreeCheckers.scala b/src/compiler/scala/tools/nsc/typechecker/TreeCheckers.scala
index b0500776fe..ed263cbbef 100644
--- a/src/compiler/scala/tools/nsc/typechecker/TreeCheckers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/TreeCheckers.scala
@@ -142,11 +142,11 @@ abstract class TreeCheckers extends Analyzer {
result
}
def runWithUnit[T](unit: CompilationUnit)(body: => Unit): Unit = {
- val unit0 = currentRun.currentUnit
+ val unit0 = currentUnit
currentRun.currentUnit = unit
body
currentRun.advanceUnit
- assertFn(currentRun.currentUnit == unit, "currentUnit is " + currentRun.currentUnit + ", but unit is " + unit)
+ assertFn(currentUnit == unit, "currentUnit is " + currentUnit + ", but unit is " + unit)
currentRun.currentUnit = unit0
}
def check(unit: CompilationUnit) {
diff --git a/src/compiler/scala/tools/nsc/typechecker/TypeDiagnostics.scala b/src/compiler/scala/tools/nsc/typechecker/TypeDiagnostics.scala
index 8c434a8838..4f4087a953 100644
--- a/src/compiler/scala/tools/nsc/typechecker/TypeDiagnostics.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/TypeDiagnostics.scala
@@ -39,8 +39,6 @@ trait TypeDiagnostics {
import definitions._
import global.typer.{ infer, context }
- private def currentUnit = currentRun.currentUnit
-
/** The common situation of making sure nothing is erroneous could be
* nicer if Symbols, Types, and Trees all implemented some common interface
* in which isErroneous and similar would be placed.
diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
index 889c04a59b..770b55d6ab 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
@@ -455,14 +455,14 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser {
@inline
final def constrTyperIf(inConstr: Boolean): Typer =
if (inConstr) {
- assert(context.undetparams.isEmpty)
+ assert(context.undetparams.isEmpty, context.undetparams)
newTyper(context.makeConstructorContext)
} else this
@inline
final def withCondConstrTyper[T](inConstr: Boolean)(f: Typer => T): T =
if (inConstr) {
- assert(context.undetparams.isEmpty)
+ assert(context.undetparams.isEmpty, context.undetparams)
val c = context.makeConstructorContext
typerWithLocalContext(c)(f)
} else {
@@ -867,7 +867,7 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser {
}
def insertApply(): Tree = {
- assert(!inHKMode(mode)) //@M
+ assert(!inHKMode(mode), modeString(mode)) //@M
val qual = adaptToName(tree, nme.apply) match {
case id @ Ident(_) =>
val pre = if (id.symbol.owner.isPackageClass) id.symbol.owner.thisType
@@ -948,7 +948,7 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser {
applyPossible)
insertApply()
else if (!context.undetparams.isEmpty && !inPolyMode(mode)) { // (9)
- assert(!inHKMode(mode)) //@M
+ assert(!inHKMode(mode), modeString(mode)) //@M
if (inExprModeButNot(mode, FUNmode) && pt.typeSymbol == UnitClass)
instantiateExpectingUnit(tree, mode)
else
@@ -1239,7 +1239,7 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser {
})
val outercontext = context.outer
- assert(clazz != NoSymbol)
+ assert(clazz != NoSymbol, templ)
val cscope = outercontext.makeNewScope(constr, outercontext.owner)
val cbody2 = newTyper(cscope) // called both during completion AND typing.
.typePrimaryConstrBody(clazz,
@@ -1401,7 +1401,7 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser {
// attributes(cdef)
val clazz = cdef.symbol
val typedMods = removeAnnotations(cdef.mods)
- assert(clazz != NoSymbol)
+ assert(clazz != NoSymbol, cdef)
reenterTypeParams(cdef.tparams)
val tparams1 = cdef.tparams mapConserve (typedTypeDef)
val impl1 = typerReportAnyContextErrors(context.make(cdef.impl, clazz, newScope)) {
@@ -1611,7 +1611,7 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser {
(call, List())
}
val (superConstr, superArgs) = decompose(rhs)
- assert(superConstr.symbol ne null)//debug
+ assert(superConstr.symbol ne null, superConstr)//debug
val pending = ListBuffer[AbsTypeError]()
// an object cannot be allowed to pass a reference to itself to a superconstructor
@@ -2521,7 +2521,7 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser {
inferExprInstance(fun, tparams)
doTypedApply(tree, fun, args, mode, pt)
} else {
- assert(!inPatternMode(mode)) // this case cannot arise for patterns
+ assert(!inPatternMode(mode), modeString(mode)) // this case cannot arise for patterns
val lenientTargs = protoTypeArgs(tparams, formals, mt.resultApprox, pt)
val strictTargs = map2(lenientTargs, tparams)((targ, tparam) =>
if (targ == WildcardType) tparam.tpe else targ) //@M TODO: should probably be .tpeHK
@@ -4414,7 +4414,7 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser {
// whatever type to tree; we just have to survive until a real error message is issued.
tree setType AnyClass.tpe
case Import(expr, selectors) =>
- assert(forInteractive) // should not happen in normal circumstances.
+ assert(forInteractive, "!forInteractive") // should not happen in normal circumstances.
tree setType tree.symbol.tpe
case _ =>
abort("unexpected tree: " + tree.getClass + "\n" + tree)//debug
diff --git a/src/compiler/scala/tools/nsc/typechecker/Unapplies.scala b/src/compiler/scala/tools/nsc/typechecker/Unapplies.scala
index a7cd89621c..19b8632ed7 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Unapplies.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Unapplies.scala
@@ -25,7 +25,7 @@ trait Unapplies extends ast.TreeDSL
/** returns type list for return type of the extraction */
def unapplyTypeList(ufn: Symbol, ufntpe: Type) = {
- assert(ufn.isMethod)
+ assert(ufn.isMethod, ufn)
//Console.println("utl "+ufntpe+" "+ufntpe.typeSymbol)
ufn.name match {
case nme.unapply => unapplyTypeListFromReturnType(ufntpe)
diff --git a/src/compiler/scala/tools/nsc/util/SourceFile.scala b/src/compiler/scala/tools/nsc/util/SourceFile.scala
index 4405b3457b..e1ae96da8c 100644
--- a/src/compiler/scala/tools/nsc/util/SourceFile.scala
+++ b/src/compiler/scala/tools/nsc/util/SourceFile.scala
@@ -34,7 +34,7 @@ abstract class SourceFile {
* For regular source files, simply return the argument.
*/
def positionInUltimateSource(position: Position) = position
- override def toString(): String = file.name /* + ":" + content.length */
+ override def toString() = file.name
def dbg(offset: Int) = (new OffsetPosition(this, offset)).dbgString
def path = file.path
@@ -61,7 +61,7 @@ object NoSourceFile extends SourceFile {
def length = -1
def offsetToLine(offset: Int) = -1
def lineToOffset(index : Int) = -1
- override def toString = "NoSourceFile"
+ override def toString = "<no source file>"
}
object NoFile extends VirtualFile("<no file>", "<no file>")