summaryrefslogtreecommitdiff
path: root/src/compiler/scala/tools/nsc/typechecker
diff options
context:
space:
mode:
authorPaul Phillips <paulp@improving.org>2012-01-10 07:10:05 -0800
committerPaul Phillips <paulp@improving.org>2012-01-11 16:21:38 -0800
commit5f5029d2ac6348ecb07fc11f6656621c662ced92 (patch)
tree59f3946d2c5e2612cd2c36ca008c016b0c69b0d5 /src/compiler/scala/tools/nsc/typechecker
parentb00002f9049c034510438881b4a4449d73fe2f54 (diff)
downloadscala-5f5029d2ac6348ecb07fc11f6656621c662ced92.tar.gz
scala-5f5029d2ac6348ecb07fc11f6656621c662ced92.tar.bz2
scala-5f5029d2ac6348ecb07fc11f6656621c662ced92.zip
Optimizing TypeRef, starting with Symbols.
There are too many potential optimizations unavailable to us due to the lack of bright lines among different kinds of symbols. For instance the difference between a TypeSymbol which represents a type alias and one which represents an abstract type is only whether the DEFERRED flag is set. This creates issues. 1) There are many (many) places where tests are performed on every symbol which could be done more efficiently and (especially) more verifiably correctly with polymorphism. 2) TypeRefs based on those symbols are also checking that flag constantly, in perpetuity. A symbol created as an alias is never (to the best of my knowledge) going to intentionally morph into one representing an abstract type, nor vice versa. 3) One has no guarantees, because anyone can set or reset the DEFERRED flag at any time. So tackling more than one problem at once herein: 1) I created canonical symbol creation points which take the flags as an argument, so that there can be a difference between initializing a symbol's flags and setting/resetting them at arbitrary times. 2) I structured all the symbol creators to take arguments in the same order, which is: def newXXX(name: Name, ..., pos: Position = NoPosition, flags: Long = 0L) (Where "..." is for those symbols which require something beyond the name to create, such as a TypeSkolem's origin.) The name is first because it's the only always required argument. I left but deprecated the variations which take (pos, name). 3) I created subclasses of TypeRef based on the information which should be stable from creation time onward: - args or no args? - abstract type, type alias, or class? 2x3 == 6 and that's how many subclasses of TypeRef there are now. So now, for example, every TypeRef doesn't have to carry null symInfoCache and thisInfoCache fields for the benefit of the minority which use them. I still intend to realize the gain possible once we can evade the fields for pre and args without losing pattern matcher efficiency.
Diffstat (limited to 'src/compiler/scala/tools/nsc/typechecker')
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Infer.scala5
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/MethodSynthesis.scala6
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Namers.scala31
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala2
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/PatMatVirtualiser.scala4
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/RefChecks.scala1
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/SyntheticMethods.scala2
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/TypeDiagnostics.scala5
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Typers.scala12
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Unapplies.scala2
10 files changed, 30 insertions, 40 deletions
diff --git a/src/compiler/scala/tools/nsc/typechecker/Infer.scala b/src/compiler/scala/tools/nsc/typechecker/Infer.scala
index 295b66b17f..23dd28aac4 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Infer.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Infer.scala
@@ -363,10 +363,7 @@ trait Infer {
def makeFullyDefined(tp: Type): Type = {
val tparams = new ListBuffer[Symbol]
def addTypeParam(bounds: TypeBounds): Type = {
- val tparam =
- context.owner.newAbstractType(context.tree.pos.focus, newTypeName("_"+tparams.size))
- .setFlag(EXISTENTIAL)
- .setInfo(bounds)
+ val tparam = context.owner.newExistential(newTypeName("_"+tparams.size), context.tree.pos.focus) setInfo bounds
tparams += tparam
tparam.tpe
}
diff --git a/src/compiler/scala/tools/nsc/typechecker/MethodSynthesis.scala b/src/compiler/scala/tools/nsc/typechecker/MethodSynthesis.scala
index 62393befd2..29dffd99d6 100644
--- a/src/compiler/scala/tools/nsc/typechecker/MethodSynthesis.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/MethodSynthesis.scala
@@ -125,11 +125,7 @@ trait MethodSynthesis {
def keepClean = false // whether annotations whose definitions are not meta-annotated should be kept.
def validate() { }
def createAndEnterSymbol(): Symbol = {
- val sym = (
- owner.newMethod(tree.pos.focus, name)
- setFlag tree.mods.flags & flagsMask
- setFlag flagsExtra
- )
+ val sym = owner.newMethod(name, tree.pos.focus, (tree.mods.flags & flagsMask) | flagsExtra)
setPrivateWithin(tree, sym)
enterInScope(sym)
sym setInfo completer(sym)
diff --git a/src/compiler/scala/tools/nsc/typechecker/Namers.scala b/src/compiler/scala/tools/nsc/typechecker/Namers.scala
index 200191fa13..71c0de10ff 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Namers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Namers.scala
@@ -293,23 +293,22 @@ trait Namers extends MethodSynthesis {
private def createMemberSymbol(tree: MemberDef, name: Name, mask: Long): Symbol = {
val pos = tree.pos
val isParameter = tree.mods.isParameter
- val sym = tree match {
- case TypeDef(_, _, _, _) if isParameter => owner.newTypeParameter(pos, name.toTypeName)
- case TypeDef(_, _, _, _) => owner.newAliasType(pos, name.toTypeName)
- case DefDef(_, nme.CONSTRUCTOR, _, _, _, _) => owner.newConstructor(pos)
- case DefDef(_, _, _, _, _, _) => owner.newMethod(pos, name.toTermName)
- case ClassDef(_, _, _, _) => owner.newClass(pos, name.toTypeName)
- case ModuleDef(_, _, _) => owner.newModule(pos, name)
- case ValDef(_, _, _, _) if isParameter => owner.newValueParameter(pos, name)
+ val flags = tree.mods.flags & mask
+
+ tree match {
+ case TypeDef(_, _, _, _) if isParameter => owner.newTypeParameter(name.toTypeName, pos, flags)
+ case TypeDef(_, _, _, _) => owner.newTypeSymbol(name.toTypeName, pos, flags)
+ case DefDef(_, nme.CONSTRUCTOR, _, _, _, _) => owner.newConstructor(pos, flags)
+ case DefDef(_, _, _, _, _, _) => owner.newMethod(name.toTermName, pos, flags)
+ case ClassDef(_, _, _, _) => owner.newClassSymbol(name.toTypeName, pos, flags)
+ case ModuleDef(_, _, _) => owner.newModule(name, pos, flags)
+ case ValDef(_, _, _, _) if isParameter => owner.newValueParameter(name, pos, flags)
case PackageDef(pid, _) => createPackageSymbol(pos, pid)
- case ValDef(_, _, _, _) => owner.newValue(pos, name)
+ case ValDef(_, _, _, _) => owner.newValue(name, pos, flags)
}
- sym setFlag (tree.mods.flags & mask)
}
- private def createFieldSymbol(tree: ValDef): TermSymbol = (
- owner.newValue(tree.pos, nme.getterToLocal(tree.name))
- setFlag tree.mods.flags & FieldFlags | PrivateLocal
- )
+ private def createFieldSymbol(tree: ValDef): TermSymbol =
+ owner.newValue(nme.getterToLocal(tree.name), tree.pos, tree.mods.flags & FieldFlags | PrivateLocal)
private def createImportSymbol(tree: Tree) =
NoSymbol.newImport(tree.pos) setInfo completerOf(tree)
@@ -325,7 +324,7 @@ trait Namers extends MethodSynthesis {
if (existing.isPackage && pkgOwner == existing.owner)
existing
else {
- val pkg = pkgOwner.newPackage(pos, pid.name.toTermName)
+ val pkg = pkgOwner.newPackage(pid.name.toTermName, pos)
val pkgClass = pkg.moduleClass
val pkgClassInfo = new PackageClassInfoType(newPackageScope(pkgClass), pkgClass)
@@ -579,7 +578,7 @@ trait Namers extends MethodSynthesis {
// via "x$lzy" as can be seen in test #3927.
val sym = (
if (owner.isClass) createFieldSymbol(tree)
- else owner.newValue(tree.pos, tree.name append nme.LAZY_LOCAL) setFlag tree.mods.flags resetFlag IMPLICIT
+ else owner.newValue(tree.name append nme.LAZY_LOCAL, tree.pos, tree.mods.flags & ~IMPLICIT)
)
enterValSymbol(tree, sym setFlag MUTABLE setLazyAccessor lazyAccessor)
}
diff --git a/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala b/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala
index a8dfea02ec..07b08e52da 100644
--- a/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala
@@ -269,7 +269,7 @@ trait NamesDefaults { self: Analyzer =>
case _ =>
(seqType(arg.tpe), true)
} else (arg.tpe, false)
- val s = context.owner.newValue(arg.pos, unit.freshTermName("x$"))
+ val s = context.owner.newValue(unit.freshTermName("x$"), arg.pos)
val valType = if (byName) functionType(List(), argTpe)
else if (repeated) argTpe
else argTpe
diff --git a/src/compiler/scala/tools/nsc/typechecker/PatMatVirtualiser.scala b/src/compiler/scala/tools/nsc/typechecker/PatMatVirtualiser.scala
index b059e023e4..4104803194 100644
--- a/src/compiler/scala/tools/nsc/typechecker/PatMatVirtualiser.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/PatMatVirtualiser.scala
@@ -53,7 +53,7 @@ trait PatMatVirtualiser extends ast.TreeDSL { self: Analyzer =>
import typeDebug.{ ptTree, ptBlock, ptLine }
def solveContextBound(contextBoundTp: Type): (Tree, Type) = {
- val solSym = NoSymbol.newTypeParameter(NoPosition, newTypeName("SolveImplicit$"))
+ val solSym = NoSymbol.newTypeParameter(newTypeName("SolveImplicit$"))
val param = solSym.setInfo(contextBoundTp.typeSymbol.typeParams(0).info.cloneInfo(solSym)) // TypeBounds(NothingClass.typeConstructor, baseTp)
val pt = appliedType(contextBoundTp, List(param.tpeHK))
val savedUndets = context.undetparams
@@ -1245,7 +1245,7 @@ defined class Foo */
}
t match {
case Function(_, _) if t.symbol == NoSymbol =>
- t.symbol = currentOwner.newValue(t.pos, nme.ANON_FUN_NAME).setFlag(SYNTHETIC).setInfo(NoType)
+ t.symbol = currentOwner.newAnonymousFunctionValue(t.pos)
// println("new symbol for "+ (t, t.symbol.ownerChain))
case Function(_, _) if (t.symbol.owner == NoSymbol) || (t.symbol.owner == origOwner) =>
// println("fundef: "+ (t, t.symbol.ownerChain, currentOwner.ownerChain))
diff --git a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala
index 8f9cd46611..42a60666de 100644
--- a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala
@@ -444,6 +444,7 @@ abstract class RefChecks extends InfoTransform with reflect.internal.transform.R
// check a type alias's RHS corresponds to its declaration
// this overlaps somewhat with validateVariance
if(member.isAliasType) {
+ // println("checkKindBounds" + ((List(member), List(memberTp.normalize), self, member.owner)))
val kindErrors = typer.infer.checkKindBounds(List(member), List(memberTp.normalize), self, member.owner)
if(!kindErrors.isEmpty)
diff --git a/src/compiler/scala/tools/nsc/typechecker/SyntheticMethods.scala b/src/compiler/scala/tools/nsc/typechecker/SyntheticMethods.scala
index 92e4e257bf..1df7cd86d3 100644
--- a/src/compiler/scala/tools/nsc/typechecker/SyntheticMethods.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/SyntheticMethods.scala
@@ -282,7 +282,7 @@ trait SyntheticMethods extends ast.TreeDSL {
def argsBody: Tree = {
val otherName = context.unit.freshTermName(clazz.name + "$")
- val otherSym = m.newValue(m.pos, otherName) setInfo clazz.tpe setFlag SYNTHETIC
+ val otherSym = m.newValue(otherName, m.pos, SYNTHETIC) setInfo clazz.tpe
val pairwise = accessors map (acc => fn(Select(This(clazz), acc), acc.tpe member nme.EQ, Select(Ident(otherSym), acc)))
val canEq = gen.mkMethodCall(otherSym, nme.canEqual_, Nil, List(This(clazz)))
def block = Block(ValDef(otherSym, thatCast), AND(pairwise :+ canEq: _*))
diff --git a/src/compiler/scala/tools/nsc/typechecker/TypeDiagnostics.scala b/src/compiler/scala/tools/nsc/typechecker/TypeDiagnostics.scala
index 080a802272..02c6e86fde 100644
--- a/src/compiler/scala/tools/nsc/typechecker/TypeDiagnostics.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/TypeDiagnostics.scala
@@ -181,10 +181,7 @@ trait TypeDiagnostics {
val getter = if (member.isSetter) member.getter(member.owner) else member
val flags = if (getter.setter(member.owner) != NoSymbol) DEFERRED | MUTABLE else DEFERRED
- ( getter.owner.newValue(getter.pos, getter.name.toTermName)
- setInfo getter.tpe.resultType
- setFlag flags
- )
+ getter.owner.newValue(getter.name.toTermName, getter.pos, flags) setInfo getter.tpe.resultType
}
def treeSymTypeMsg(tree: Tree): String = {
diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
index 5ccf27ded9..6476244221 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
@@ -1659,7 +1659,7 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser {
case Some(repl) =>
silent(_.typedTypeConstructor(stringParser(repl).typ())) match {
case tpt: Tree =>
- val alias = enclClass.newAliasType(useCase.pos, name.toTypeName)
+ val alias = enclClass.newAliasType(name.toTypeName, useCase.pos)
val tparams = cloneSymbolsAtOwner(tpt.tpe.typeSymbol.typeParams, alias)
alias setInfo typeFun(tparams, appliedType(tpt.tpe, tparams map (_.tpe)))
context.scope.enter(alias)
@@ -1793,7 +1793,7 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser {
case ldef @ LabelDef(_, _, _) =>
if (ldef.symbol == NoSymbol)
ldef.symbol = namer.enterInScope(
- context.owner.newLabel(ldef.pos, ldef.name) setInfo MethodType(List(), UnitClass.tpe))
+ context.owner.newLabel(ldef.name, ldef.pos) setInfo MethodType(List(), UnitClass.tpe))
case _ =>
}
}
@@ -1814,7 +1814,7 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser {
} else {
context.scope.unlink(ldef.symbol)
val sym2 = namer.enterInScope(
- context.owner.newLabel(ldef.pos, ldef.name) setInfo MethodType(List(), restpe))
+ context.owner.newLabel(ldef.name, ldef.pos) setInfo MethodType(List(), restpe))
val rhs2 = typed(resetAllAttrs(ldef.rhs), restpe)
ldef.params foreach (param => param.tpe = param.symbol.tpe)
treeCopy.LabelDef(ldef, ldef.name, ldef.params, rhs2) setSymbol sym2 setType restpe
@@ -2529,7 +2529,7 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser {
val unapp = unapplyMember(otpe)
val unappType = otpe.memberType(unapp)
- val argDummy = context.owner.newValue(fun.pos, nme.SELECTOR_DUMMY) setFlag SYNTHETIC setInfo pt
+ val argDummy = context.owner.newValue(nme.SELECTOR_DUMMY, fun.pos, SYNTHETIC) setInfo pt
val arg = Ident(argDummy) setType pt
if (!isApplicableSafe(Nil, unappType, List(pt), WildcardType)) {
@@ -4098,8 +4098,8 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser {
case tree @ Function(_, _) =>
if (tree.symbol == NoSymbol)
- tree.symbol = context.owner.newValue(tree.pos, nme.ANON_FUN_NAME)
- .setFlag(SYNTHETIC).setInfo(NoType)
+ tree.symbol = context.owner.newAnonymousFunctionValue(tree.pos)
+
newTyper(context.makeNewScope(tree, tree.symbol)).typedFunction(tree, mode, pt)
case Assign(lhs, rhs) =>
diff --git a/src/compiler/scala/tools/nsc/typechecker/Unapplies.scala b/src/compiler/scala/tools/nsc/typechecker/Unapplies.scala
index fd6f972ffc..a7cd89621c 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Unapplies.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Unapplies.scala
@@ -21,7 +21,7 @@ trait Unapplies extends ast.TreeDSL
import CODE.{ CASE => _, _ }
import treeInfo.{ isRepeatedParamType, isByNameParamType }
- private val unapplyParamName = newTermName("x$0")
+ private val unapplyParamName = nme.x_0
/** returns type list for return type of the extraction */
def unapplyTypeList(ufn: Symbol, ufntpe: Type) = {