summaryrefslogtreecommitdiff
path: root/src/compiler
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2009-10-02 13:19:34 +0000
committerMartin Odersky <odersky@gmail.com>2009-10-02 13:19:34 +0000
commit321338da04a6ca9bcc9b77ae663ed27f26a67d85 (patch)
tree4cea0a435568b760b688740f5d559a4033cf7962 /src/compiler
parent1bc50a7c84b0abc53299b3efcfec4f6a77c759e6 (diff)
downloadscala-321338da04a6ca9bcc9b77ae663ed27f26a67d85.tar.gz
scala-321338da04a6ca9bcc9b77ae663ed27f26a67d85.tar.bz2
scala-321338da04a6ca9bcc9b77ae663ed27f26a67d85.zip
Fixed #1939,plus some moving things around.
Diffstat (limited to 'src/compiler')
-rw-r--r--src/compiler/scala/tools/nsc/symtab/Symbols.scala19
-rw-r--r--src/compiler/scala/tools/nsc/symtab/Types.scala59
-rw-r--r--src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala2
-rw-r--r--src/compiler/scala/tools/nsc/transform/OverridingPairs.scala9
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Typers.scala2
5 files changed, 50 insertions, 41 deletions
diff --git a/src/compiler/scala/tools/nsc/symtab/Symbols.scala b/src/compiler/scala/tools/nsc/symtab/Symbols.scala
index 4aea770ff4..9dfe0777ef 100644
--- a/src/compiler/scala/tools/nsc/symtab/Symbols.scala
+++ b/src/compiler/scala/tools/nsc/symtab/Symbols.scala
@@ -36,6 +36,12 @@ trait Symbols {
/** Used to keep track of the recursion depth on locked symbols */
private var recursionTable = Map.empty[Symbol, Int]
+ private var nextexid = 0
+ private def freshExistentialName() = {
+ nextexid += 1
+ "_"+nextexid
+ }
+
/*
type Position;
def NoPos : Position;
@@ -252,6 +258,19 @@ trait Symbols {
argtypess map (_.map(param))
}
+ /** Make an existential variable.
+ * @param name suffix to be appended to the freshly generated name
+ * It's ususally "", except for type variables abstracting
+ * over values, where it is ".type".
+ * @param owner The owner of the variable
+ * @param bounds The variable's bounds
+ */
+ final def newExistential(pos: Position, name: Name): Symbol =
+ newAbstractType(pos, name.toTypeName).setFlag(EXISTENTIAL)
+
+ final def freshExistential(suffix: String): Symbol =
+ newExistential(pos, freshExistentialName()+suffix)
+
/** Synthetic value parameters when parameter symbols are not available.
* Calling this method multiple times will re-use the same parameter names.
*/
diff --git a/src/compiler/scala/tools/nsc/symtab/Types.scala b/src/compiler/scala/tools/nsc/symtab/Types.scala
index 157ead1f35..9fdb446ad8 100644
--- a/src/compiler/scala/tools/nsc/symtab/Types.scala
+++ b/src/compiler/scala/tools/nsc/symtab/Types.scala
@@ -77,6 +77,8 @@ trait Types {
private var explainSwitch = false
+ private final val alternativeNarrow = false
+
private final val LogPendingSubTypesThreshold = 50
private final val LogPendingBaseTypesThreshold = 50
@@ -270,7 +272,10 @@ trait Types {
*/
def narrow: Type =
if (phase.erasedTypes) this
- else {
+ else if (alternativeNarrow) { // investigate why this does not work!
+ val tparam = commonOwner(this) freshExistential ".type" setInfo singletonBounds(this)
+ tparam.tpe
+ } else {
val cowner = commonOwner(this)
refinedType(List(this), cowner, EmptyScope, cowner.pos).narrow
}
@@ -2687,26 +2692,9 @@ A type's typeSymbol should never be inspected directly.
private val emptySymMap = scala.collection.immutable.Map[Symbol, Symbol]()
private val emptySymCount = scala.collection.immutable.Map[Symbol, Int]()
- /** Make an existential variable.
- * [martin:] this should get moved to Symbols where the other symbols are created.
- * @param name suffix to be appended to the freshly generated name
- * It's ususally "", except for type variables abstracting
- * over values, where it is ".type".
- * @param owner The owner of the variable
- * @param bounds The variable's bounds
- */
- def makeExistential(name: String, owner: Symbol, bounds: TypeBounds): Symbol =
- recycle(
- owner.newAbstractType(owner.pos, newTypeName(name)).setFlag(EXISTENTIAL)
- ).setInfo(bounds)
-
- /** Make an existential variable with a fresh name. */
- def makeFreshExistential(suffix: String, owner: Symbol, bounds: TypeBounds): Symbol =
- makeExistential(freshName()+suffix, owner, bounds)
-
def typeParamsToExistentials(clazz: Symbol, tparams: List[Symbol]): List[Symbol] = {
val eparams = for ((tparam, i) <- tparams.zipWithIndex) yield {
- makeExistential("?"+i, clazz, tparam.info.bounds)
+ clazz.newExistential(clazz.pos, "?"+i).setInfo(tparam.info.bounds)
}
for (tparam <- eparams) tparam setInfo tparam.info.substSym(tparams, eparams)
eparams
@@ -2787,7 +2775,7 @@ A type's typeSymbol should never be inspected directly.
def stabilize(pre: Type, clazz: Symbol): Type = {
capturedPre get clazz match {
case None =>
- val qvar = makeFreshExistential(".type", clazz, singletonBounds(pre))
+ val qvar = clazz freshExistential ".type" setInfo singletonBounds(pre)
capturedPre += (clazz -> qvar)
capturedParams = qvar :: capturedParams
qvar
@@ -3061,13 +3049,9 @@ A type's typeSymbol should never be inspected directly.
val symowner = oldSym.owner // what should be used??
val bound = singletonBounds(actuals(actualIdx))
- val sym =
- symowner.newAbstractType(oldSym.pos, oldSym.name+".type")
-
+ val sym = symowner.newExistential(oldSym.pos, oldSym.name+".type")
sym.setInfo(bound)
sym.setFlag(oldSym.flags)
- sym.setFlag(EXISTENTIAL)
-
existSyms = existSyms + (actualIdx -> sym)
sym
@@ -3360,12 +3344,6 @@ A type's typeSymbol should never be inspected directly.
// Helper Methods -------------------------------------------------------------
- private var nextid = 0
- private def freshName() = {
- nextid += 1
- "_"+nextid
- }
-
final val LubGlbMargin = 0
/** The maximum allowable depth of lubs or glbs over types `ts'
@@ -3502,7 +3480,7 @@ A type's typeSymbol should never be inspected directly.
private var subsametypeRecursions: Int = 0
private def isUnifiable(pre1: Type, pre2: Type) =
- (beginsWithTypeVar(pre1) || beginsWithTypeVar(pre2)) && (pre1 =:= pre2)
+ (beginsWithTypeVarOrIsRefined(pre1) || beginsWithTypeVarOrIsRefined(pre2)) && (pre1 =:= pre2)
private def equalSymsAndPrefixes(sym1: Symbol, pre1: Type, sym2: Symbol, pre2: Type): Boolean =
if (sym1 == sym2) phase.erasedTypes || pre1 =:= pre2
@@ -3700,12 +3678,18 @@ A type's typeSymbol should never be inspected directly.
if (subsametypeRecursions == 0) undoLog = List()
}
- /** Does this type have a prefix that begins with a type variable */
- def beginsWithTypeVar(tp: Type): Boolean = tp match {
+ /** Does this type have a prefix that begins with a type variable,
+ * or is it a refinement type? For type prefixes that fulfil this condition,
+ * type selections with the same name of equal (wrt) =:= prefixes are
+ * considered equal wrt =:=
+ */
+ def beginsWithTypeVarOrIsRefined(tp: Type): Boolean = tp match {
case SingleType(pre, sym) =>
- !(sym hasFlag PACKAGE) && beginsWithTypeVar(pre)
+ !(sym hasFlag PACKAGE) && beginsWithTypeVarOrIsRefined(pre)
case TypeVar(_, constr) =>
- constr.inst == NoType || beginsWithTypeVar(constr.inst)
+ constr.inst == NoType || beginsWithTypeVarOrIsRefined(constr.inst)
+ case RefinedType(_, _) =>
+ true
case _ =>
false
}
@@ -4657,8 +4641,7 @@ A type's typeSymbol should never be inspected directly.
else { // Martin: I removed this, because incomplete. Not sure there is a good way to fix it. For the moment we
// just err on the conservative side, i.e. with a bound that is too high.
// if(!(tparam.info.bounds contains tparam)){ //@M can't deal with f-bounds, see #2251
- val owner = commonOwner(as)
- val qvar = makeFreshExistential("", commonOwner(as), mkTypeBounds(g, l))
+ val qvar = commonOwner(as) freshExistential "" setInfo mkTypeBounds(g, l)
capturedParams += qvar
qvar.tpe
}
diff --git a/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala b/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala
index 904983a80f..c4283652ec 100644
--- a/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala
+++ b/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala
@@ -608,7 +608,7 @@ abstract class ClassfileParser {
case '*' => mkTypeBounds(definitions.NothingClass.tpe,
definitions.AnyClass.tpe)
}
- val newtparam = makeExistential("?"+i, sym, bounds)
+ val newtparam = sym.newExistential(sym.pos, "?"+i) setInfo bounds
existentials += newtparam
xs += newtparam.tpe
i += 1
diff --git a/src/compiler/scala/tools/nsc/transform/OverridingPairs.scala b/src/compiler/scala/tools/nsc/transform/OverridingPairs.scala
index cad86ea024..6cf9020520 100644
--- a/src/compiler/scala/tools/nsc/transform/OverridingPairs.scala
+++ b/src/compiler/scala/tools/nsc/transform/OverridingPairs.scala
@@ -172,7 +172,14 @@ abstract class OverridingPairs {
do {
do {
nextEntry = decls.lookupNextEntry(nextEntry);
- } while ((nextEntry ne null) &&
+ /* DEBUG
+ if ((nextEntry ne null) &&
+ !(nextEntry.sym hasFlag PRIVATE) &&
+ !(overriding.owner == nextEntry.sym.owner) &&
+ !matches(overriding, nextEntry.sym))
+ println("skipping "+overriding+":"+self.memberType(overriding)+overriding.locationString+" to "+nextEntry.sym+":"+self.memberType(nextEntry.sym)+nextEntry.sym.locationString)
+ */
+ } while ((nextEntry ne null) &&
((nextEntry.sym hasFlag PRIVATE) ||
(overriding.owner == nextEntry.sym.owner) ||
(!matches(overriding, nextEntry.sym)) ||
diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
index 030028fcf6..52f4952060 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
@@ -3589,7 +3589,7 @@ trait Typers { self: Analyzer =>
def subArrayType(pt: Type) =
if (isValueClass(pt.typeSymbol) || !isFullyDefined(pt)) arrayType(pt)
else {
- val tparam = makeFreshExistential("", context.owner, TypeBounds(NothingClass.tpe, pt))
+ val tparam = context.owner freshExistential "" setInfo TypeBounds(NothingClass.tpe, pt)
ExistentialType(List(tparam), arrayType(tparam.tpe))
}
val (expr1, baseClass) =