diff options
Diffstat (limited to 'src/compiler/scala/tools/nsc')
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>") |