summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Phillips <paulp@improving.org>2012-04-29 17:16:48 -0700
committerPaul Phillips <paulp@improving.org>2012-04-29 19:09:06 -0700
commit94c63f5da548996535cad43142758c9405118828 (patch)
treec888993eb3120cbc6e1e4acc45023d941f5bb4e6
parente6d5d22d280909dacf635a0a2398158a1b1a6ae1 (diff)
downloadscala-94c63f5da548996535cad43142758c9405118828.tar.gz
scala-94c63f5da548996535cad43142758c9405118828.tar.bz2
scala-94c63f5da548996535cad43142758c9405118828.zip
Fighting bitrot with typing.
if (false && settings.debug.value) { ... } Date: 7 years ago *** empty log message *** That's way past the sell-by date for 'if (false && condition)'.
-rw-r--r--src/compiler/scala/reflect/internal/Symbols.scala11
-rw-r--r--src/compiler/scala/reflect/runtime/SynchronizedSymbols.scala2
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Contexts.scala11
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Modes.scala2
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Namers.scala49
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala11
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/PatMatVirtualiser.scala11
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Typers.scala103
8 files changed, 81 insertions, 119 deletions
diff --git a/src/compiler/scala/reflect/internal/Symbols.scala b/src/compiler/scala/reflect/internal/Symbols.scala
index 37caa06fe9..c2ef633d58 100644
--- a/src/compiler/scala/reflect/internal/Symbols.scala
+++ b/src/compiler/scala/reflect/internal/Symbols.scala
@@ -1425,7 +1425,7 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
/** Reset symbol to initial state
*/
- def reset(completer: Type) {
+ def reset(completer: Type): this.type = {
resetFlags()
infos = null
_validTo = NoPeriod
@@ -2054,6 +2054,7 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
def sealedDescendants: Set[Symbol] = children.flatMap(_.sealedDescendants) + this
@inline final def orElse(alt: => Symbol): Symbol = if (this ne NoSymbol) this else alt
+ @inline final def andAlso(f: Symbol => Unit): Symbol = if (this eq NoSymbol) NoSymbol else { f(this) ; this }
// ------ toString -------------------------------------------------------------------
@@ -2636,10 +2637,11 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
info.baseTypeIndex(that) >= 0
)
- override def reset(completer: Type) {
+ override def reset(completer: Type): this.type = {
super.reset(completer)
tpePeriod = NoPeriod
tyconRunId = NoRunId
+ this
}
/*** example:
@@ -2822,9 +2824,10 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
else super.sourceFile
override def sourceFile_=(f: AbstractFileType) { source = f }
- override def reset(completer: Type) {
+ override def reset(completer: Type): this.type = {
super.reset(completer)
thissym = this
+ this
}
/** the type this.type in this class */
@@ -3022,7 +3025,7 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
override def ownerChain: List[Symbol] = List()
override def ownersIterator: Iterator[Symbol] = Iterator.empty
override def alternatives: List[Symbol] = List()
- override def reset(completer: Type) {}
+ override def reset(completer: Type): this.type = this
override def info: Type = NoType
override def existentialBound: Type = NoType
override def rawInfo: Type = NoType
diff --git a/src/compiler/scala/reflect/runtime/SynchronizedSymbols.scala b/src/compiler/scala/reflect/runtime/SynchronizedSymbols.scala
index 4048e94d0f..8378f1a892 100644
--- a/src/compiler/scala/reflect/runtime/SynchronizedSymbols.scala
+++ b/src/compiler/scala/reflect/runtime/SynchronizedSymbols.scala
@@ -46,7 +46,7 @@ trait SynchronizedSymbols extends internal.Symbols { self: SymbolTable =>
override def typeParams: List[Symbol] = synchronized { super.typeParams }
- override def reset(completer: Type) = synchronized { super.reset(completer) }
+ override def reset(completer: Type): this.type = synchronized { super.reset(completer) }
override def infosString: String = synchronized { super.infosString }
diff --git a/src/compiler/scala/tools/nsc/typechecker/Contexts.scala b/src/compiler/scala/tools/nsc/typechecker/Contexts.scala
index e2d4efab83..4584ba032d 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Contexts.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Contexts.scala
@@ -405,6 +405,17 @@ trait Contexts { self: Analyzer =>
case _ => outer.isLocal()
}
+ /** Fast path for some slow checks (ambiguous assignment in Refchecks, and
+ * existence of __match for MatchTranslation in virtpatmat.) This logic probably
+ * needs improvement.
+ */
+ def isNameInScope(name: Name) = (
+ enclosingContextChain exists (ctx =>
+ (ctx.scope.lookupEntry(name) != null)
+ || (ctx.owner.rawInfo.member(name) != NoSymbol)
+ )
+ )
+
// nextOuter determines which context is searched next for implicits
// (after `this`, which contributes `newImplicits` below.) In
// most cases, it is simply the outer context: if we're owned by
diff --git a/src/compiler/scala/tools/nsc/typechecker/Modes.scala b/src/compiler/scala/tools/nsc/typechecker/Modes.scala
index 48068b58d4..3eff5ef024 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Modes.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Modes.scala
@@ -105,7 +105,7 @@ trait Modes {
final def inFunMode(mode: Int) = (mode & FUNmode) != 0
final def inPolyMode(mode: Int) = (mode & POLYmode) != 0
final def inPatternMode(mode: Int) = (mode & PATTERNmode) != 0
-
+ final def inExprModeOr(mode: Int, others: Int) = (mode & (EXPRmode | others)) != 0
final def inExprModeButNot(mode: Int, prohibited: Int) =
(mode & (EXPRmode | prohibited)) == EXPRmode
diff --git a/src/compiler/scala/tools/nsc/typechecker/Namers.scala b/src/compiler/scala/tools/nsc/typechecker/Namers.scala
index ffd00751e0..45f7d7e618 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Namers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Namers.scala
@@ -139,16 +139,9 @@ trait Namers extends MethodSynthesis {
|| vd.symbol.isLazy
)
- def setPrivateWithin[Sym <: Symbol](tree: Tree, sym: Sym, mods: Modifiers): Sym =
+ def setPrivateWithin[T <: Symbol](tree: Tree, sym: T, mods: Modifiers): T =
if (sym.isPrivateLocal || !mods.hasAccessBoundary) sym
- else sym setPrivateWithin (
- typer.qualifyingClass(tree, mods.privateWithin, true) match {
- case None =>
- NoSymbol
- case Some(sym) =>
- sym
- }
- )
+ else sym setPrivateWithin typer.qualifyingClass(tree, mods.privateWithin, packageOK = true)
def setPrivateWithin(tree: MemberDef, sym: Symbol): Symbol =
setPrivateWithin(tree, sym, tree.mods)
@@ -160,24 +153,14 @@ trait Namers extends MethodSynthesis {
def moduleClassFlags(moduleFlags: Long) =
(moduleFlags & ModuleToClassFlags) | inConstructorFlag
- private def resetKeepingFlags(sym: Symbol, keeping: Long): Symbol = {
- val keep = sym.flags & keeping
- sym reset NoType
- sym setFlag keep
- }
-
def updatePosFlags(sym: Symbol, pos: Position, flags: Long): Symbol = {
debuglog("[overwrite] " + sym)
- resetKeepingFlags(sym, LOCKED)
- sym setFlag flags
- sym setPos pos
-
- if (sym.isModule && sym.moduleClass != NoSymbol)
- updatePosFlags(sym.moduleClass, pos, moduleClassFlags(flags))
+ val newFlags = (sym.flags & LOCKED) | flags
+ sym reset NoType setFlag newFlags setPos pos
+ sym.moduleClass andAlso (updatePosFlags(_, pos, moduleClassFlags(flags)))
if (sym.owner.isPackageClass) {
- val companion = companionSymbolOf(sym, context)
- if (companion != NoSymbol) {
+ companionSymbolOf(sym, context) andAlso { companion =>
val assignNoType = companion.rawInfo match {
case _: SymLoader => true
case tp => tp.isComplete && (runId(sym.validTo) != currentRunId)
@@ -400,9 +383,7 @@ trait Namers extends MethodSynthesis {
if (m.isModule && !m.isPackage && inCurrentScope(m) && (currentRun.canRedefine(m) || m.isSynthetic)) {
updatePosFlags(m, tree.pos, moduleFlags)
setPrivateWithin(tree, m)
- if (m.moduleClass != NoSymbol)
- setPrivateWithin(tree, m.moduleClass)
-
+ m.moduleClass andAlso (setPrivateWithin(tree, _))
context.unit.synthetics -= m
tree.symbol = m
}
@@ -475,8 +456,7 @@ trait Namers extends MethodSynthesis {
val defSym = context.prefix.member(to) filter (
sym => sym.exists && context.isAccessible(sym, context.prefix, false))
- if (defSym != NoSymbol)
- typer.permanentlyHiddenWarning(pos, to0, defSym)
+ defSym andAlso (typer.permanentlyHiddenWarning(pos, to0, _))
}
}
if (!tree.symbol.isSynthetic && expr.symbol != null && !expr.symbol.isInterpreterWrapper) {
@@ -669,10 +649,9 @@ trait Namers extends MethodSynthesis {
protected def enterExistingSym(sym: Symbol): Context = {
if (forInteractive && sym != null && sym.owner.isTerm) {
enterIfNotThere(sym)
- if (sym.isLazy) {
- val acc = sym.lazyAccessor
- if (acc != NoSymbol) enterIfNotThere(acc)
- }
+ if (sym.isLazy)
+ sym.lazyAccessor andAlso enterIfNotThere
+
defaultParametersOfMethod(sym) foreach { symRef => enterIfNotThere(symRef()) }
}
this.context
@@ -1547,13 +1526,13 @@ trait Namers extends MethodSynthesis {
* call this method?
*/
def companionSymbolOf(original: Symbol, ctx: Context): Symbol = {
- try original.companionSymbol match {
- case NoSymbol =>
+ try {
+ original.companionSymbol orElse {
ctx.lookup(original.name.companionName, original.owner).suchThat(sym =>
(original.isTerm || sym.hasModuleFlag) &&
(sym isCoDefinedWith original)
)
- case sym => sym
+ }
}
catch {
case e: InvalidCompanions =>
diff --git a/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala b/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala
index 3d9fc67389..898a9fee9f 100644
--- a/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala
@@ -444,21 +444,12 @@ trait NamesDefaults { self: Analyzer =>
}
}
- /** Fast path for ambiguous assignment check.
- */
- private def isNameInScope(context: Context, name: Name) = (
- context.enclosingContextChain exists (ctx =>
- (ctx.scope.lookupEntry(name) != null)
- || (ctx.owner.rawInfo.member(name) != NoSymbol)
- )
- )
-
/** A full type check is very expensive; let's make sure there's a name
* somewhere which could potentially be ambiguous before we go that route.
*/
private def isAmbiguousAssignment(typer: Typer, param: Symbol, arg: Tree) = {
import typer.context
- isNameInScope(context, param.name) && {
+ (context isNameInScope param.name) && {
// for named arguments, check whether the assignment expression would
// typecheck. if it does, report an ambiguous error.
val paramtpe = param.tpe.cloneInfo(param)
diff --git a/src/compiler/scala/tools/nsc/typechecker/PatMatVirtualiser.scala b/src/compiler/scala/tools/nsc/typechecker/PatMatVirtualiser.scala
index e5dc8e9ca9..e5b5746e8d 100644
--- a/src/compiler/scala/tools/nsc/typechecker/PatMatVirtualiser.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/PatMatVirtualiser.scala
@@ -55,10 +55,15 @@ trait PatMatVirtualiser extends ast.TreeDSL { self: Analyzer =>
def apply(typer: Typer): MatchTranslation with CodegenCore = {
import typer._
// typing `_match` to decide which MatchTranslator to create adds 4% to quick.comp.timer
- newTyper(context.makeImplicit(reportAmbiguousErrors = false)).silent(_.typed(Ident(vpmName._match), EXPRmode, WildcardType), reportAmbiguousErrors = false) match {
- case SilentResultValue(ms) => new PureMatchTranslator(typer, ms)
- case _ => new OptimizingMatchTranslator(typer)
+ val matchStrategy: Tree = (
+ if (!context.isNameInScope(vpmName._match)) null // fast path, avoiding the next line if there's no __match to be seen
+ else newTyper(context.makeImplicit(reportAmbiguousErrors = false)).silent(_.typed(Ident(vpmName._match), EXPRmode, WildcardType), reportAmbiguousErrors = false) match {
+ case SilentResultValue(ms) => ms
+ case _ => null
}
+ )
+ if (matchStrategy eq null) new OptimizingMatchTranslator(typer)
+ else new PureMatchTranslator(typer, matchStrategy)
}
}
diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
index 6234c05258..89c30590c9 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
@@ -458,13 +458,10 @@ trait Typers extends Modes with Adaptations with Taggings with PatMatVirtualiser
* of a this or super with prefix <code>qual</code>.
* packageOk is equal false when qualifying class symbol
*/
- def qualifyingClass(tree: Tree, qual: Name, packageOK: Boolean = false): Option[Symbol] =
+ def qualifyingClass(tree: Tree, qual: Name, packageOK: Boolean) =
context.enclClass.owner.ownerChain.find(o => qual.isEmpty || o.isClass && o.name == qual) match {
- case Some(c) if packageOK || !c.isPackageClass =>
- Some(c)
- case _ =>
- QualifyingClassError(tree, qual)
- None
+ case Some(c) if packageOK || !c.isPackageClass => c
+ case _ => QualifyingClassError(tree, qual) ; NoSymbol
}
/** The typer for an expression, depending on where we are. If we are before a superclass
@@ -4133,7 +4130,7 @@ trait Typers extends Modes with Adaptations with Taggings with PatMatVirtualiser
}
def convertToAssignment(fun: Tree, qual: Tree, name: Name, args: List[Tree]): Tree = {
- val prefix = name.subName(0, name.length - nme.EQL.length)
+ val prefix = name stripSuffix nme.EQL
def mkAssign(vble: Tree): Tree =
Assign(
vble,
@@ -4142,21 +4139,18 @@ trait Typers extends Modes with Adaptations with Taggings with PatMatVirtualiser
) setPos tree.pos
def mkUpdate(table: Tree, indices: List[Tree]) = {
- gen.evalOnceAll(table :: indices, context.owner, context.unit) { ts =>
- val tab = ts.head
- val is = ts.tail
- Apply(
- Select(tab(), nme.update) setPos table.pos,
- ((is map (i => i())) ::: List(
- Apply(
- Select(
- Apply(
- Select(tab(), nme.apply) setPos table.pos,
- is map (i => i())) setPos qual.pos,
- prefix) setPos fun.pos,
- args) setPos tree.pos)
- )
- ) setPos tree.pos
+ gen.evalOnceAll(table :: indices, context.owner, context.unit) {
+ case tab :: is =>
+ def mkCall(name: Name, extraArgs: Tree*) = (
+ Apply(
+ Select(tab(), name) setPos table.pos,
+ is.map(i => i()) ++ extraArgs
+ ) setPos tree.pos
+ )
+ mkCall(
+ nme.update,
+ Apply(Select(mkCall(nme.apply), prefix) setPos fun.pos, args) setPos tree.pos
+ )
}
}
@@ -4223,15 +4217,11 @@ trait Typers extends Modes with Adaptations with Taggings with PatMatVirtualiser
treeCopy.Super(tree, qual1, mix) setType SuperType(clazz.thisType, owntype)
}
- def typedThis(qual: Name) = {
- val qualifyingClassSym = if (tree.symbol != NoSymbol) Some(tree.symbol) else qualifyingClass(tree, qual)
- qualifyingClassSym match {
- case Some(clazz) =>
- tree setSymbol clazz setType clazz.thisType.underlying
- if (isStableContext(tree, mode, pt)) tree setType clazz.thisType
- tree
- case None => tree
- }
+ def typedThis(qual: Name) = tree.symbol orElse qualifyingClass(tree, qual, packageOK = false) match {
+ case NoSymbol => tree
+ case clazz =>
+ tree setSymbol clazz setType clazz.thisType.underlying
+ if (isStableContext(tree, mode, pt)) tree setType clazz.thisType else tree
}
/** Attribute a selection where <code>tree</code> is <code>qual.name</code>.
@@ -4242,34 +4232,19 @@ trait Typers extends Modes with Adaptations with Taggings with PatMatVirtualiser
* @return ...
*/
def typedSelect(qual: Tree, name: Name): Tree = {
- val sym =
- if (tree.symbol != NoSymbol) {
- if (phase.erasedTypes && qual.isInstanceOf[Super])
- qual.tpe = tree.symbol.owner.tpe
- if (false && settings.debug.value) { // todo: replace by settings.check.value?
- val alts = qual.tpe.member(tree.symbol.name).alternatives
- if (!(alts exists (alt =>
- alt == tree.symbol || alt.isTerm && (alt.tpe matches tree.symbol.tpe))))
- assert(false, "symbol "+tree.symbol+tree.symbol.locationString+" not in "+alts+" of "+qual.tpe+
- "\n members = "+qual.tpe.members+
- "\n type history = "+qual.tpe.termSymbol.infosString+
- "\n phase = "+phase)
- }
- tree.symbol
- } else {
- member(qual, name)
+ val sym = tree.symbol orElse member(qual, name) orElse {
+ // symbol not found? --> try to convert implicitly to a type that does have the required
+ // member. Added `| PATTERNmode` to allow enrichment in patterns (so we can add e.g., an
+ // xml member to StringContext, which in turn has an unapply[Seq] method)
+ if (name != nme.CONSTRUCTOR && inExprModeOr(mode, PATTERNmode)) {
+ val qual1 = adaptToMemberWithArgs(tree, qual, name, mode, true, true)
+ if (qual1 ne qual)
+ return typed(treeCopy.Select(tree, qual1, name), mode, pt)
}
-
- // symbol not found? --> try to convert implicitly to a type that does have the required member
- // added `| PATTERNmode` to allow enrichment in patterns (so we can add e.g., an xml member to StringContext, which in turn has an unapply[Seq] method)
- if (sym == NoSymbol && name != nme.CONSTRUCTOR && (mode & (EXPRmode | PATTERNmode)) != 0) {
- val qual1 =
- if (member(qual, name) != NoSymbol) qual
- else adaptToMemberWithArgs(tree, qual, name, mode, true, true)
-
- if (qual1 ne qual)
- return typed(treeCopy.Select(tree, qual1, name), mode, pt)
+ NoSymbol
}
+ if (phase.erasedTypes && qual.isInstanceOf[Super] && tree.symbol != NoSymbol)
+ qual.tpe = tree.symbol.owner.tpe
if (!reallyExists(sym)) {
if (context.owner.enclosingTopLevelClass.isJavaDefined && name.isTypeName) {
@@ -4284,14 +4259,12 @@ trait Typers extends Modes with Adaptations with Taggings with PatMatVirtualiser
case _ =>
}
- if (settings.debug.value) {
- log(
- "qual = "+qual+":"+qual.tpe+
- "\nSymbol="+qual.tpe.termSymbol+"\nsymbol-info = "+qual.tpe.termSymbol.info+
- "\nscope-id = "+qual.tpe.termSymbol.info.decls.hashCode()+"\nmembers = "+qual.tpe.members+
- "\nname = "+name+"\nfound = "+sym+"\nowner = "+context.enclClass.owner
- )
- }
+ debuglog(
+ "qual = "+qual+":"+qual.tpe+
+ "\nSymbol="+qual.tpe.termSymbol+"\nsymbol-info = "+qual.tpe.termSymbol.info+
+ "\nscope-id = "+qual.tpe.termSymbol.info.decls.hashCode()+"\nmembers = "+qual.tpe.members+
+ "\nname = "+name+"\nfound = "+sym+"\nowner = "+context.enclClass.owner
+ )
def makeInteractiveErrorTree = {
val tree1 = tree match {