summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2009-09-30 09:57:20 +0000
committerMartin Odersky <odersky@gmail.com>2009-09-30 09:57:20 +0000
commit49bfcbe509f3d7db654be949b1f4d778b2baf23f (patch)
tree821e91435d83b0cb53471882e26dd394ab7709fa
parentc590eb86c61196b31b4a6f41fb25e92103d05cd9 (diff)
downloadscala-49bfcbe509f3d7db654be949b1f4d778b2baf23f.tar.gz
scala-49bfcbe509f3d7db654be949b1f4d778b2baf23f.tar.bz2
scala-49bfcbe509f3d7db654be949b1f4d778b2baf23f.zip
fixed #2311.
-rw-r--r--src/compiler/scala/tools/nsc/symtab/BaseTypeSeqs.scala47
-rw-r--r--src/compiler/scala/tools/nsc/symtab/Symbols.scala7
-rw-r--r--src/compiler/scala/tools/nsc/symtab/Types.scala46
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Infer.scala17
-rw-r--r--src/library/scala/collection/SortedSet.scala12
-rw-r--r--src/library/scala/collection/immutable/SortedSet.scala8
-rw-r--r--src/library/scala/collection/mutable/WrappedArray.scala3
-rw-r--r--test/files/run/bug627.check2
-rw-r--r--test/files/run/colltest1.check2
9 files changed, 95 insertions, 49 deletions
diff --git a/src/compiler/scala/tools/nsc/symtab/BaseTypeSeqs.scala b/src/compiler/scala/tools/nsc/symtab/BaseTypeSeqs.scala
index 949d1bf18f..6c29ab5cf3 100644
--- a/src/compiler/scala/tools/nsc/symtab/BaseTypeSeqs.scala
+++ b/src/compiler/scala/tools/nsc/symtab/BaseTypeSeqs.scala
@@ -30,6 +30,7 @@ trait BaseTypeSeqs {
import definitions._
class BaseTypeSeq(parents: List[Type], elems: Array[Type]) {
+ self =>
/** The number of types in the sequence */
def length: Int = elems.length
@@ -90,7 +91,7 @@ trait BaseTypeSeqs {
/** Return all evaluated types in this sequence as a list */
def toList: List[Type] = elems.toList
- private def copy(head: Type, offset: Int): BaseTypeSeq = {
+ protected def copy(head: Type, offset: Int): BaseTypeSeq = {
val arr = new Array[Type](elems.length + offset)
compat.Platform.arraycopy(elems, 0, arr, offset, elems.length)
arr(0) = head
@@ -117,39 +118,31 @@ trait BaseTypeSeqs {
new BaseTypeSeq(parents, arr)
}
+ def lateMap(f: Type => Type): BaseTypeSeq = new BaseTypeSeq(parents map f, elems) {
+ override def apply(i: Int) = f(self.apply(i))
+ override def rawElem(i: Int) = f(self.rawElem(i))
+ override def typeSymbol(i: Int) = self.typeSymbol(i)
+ override def toList = self.toList map f
+ override protected def copy(head: Type, offset: Int) = (self map f).copy(head, offset)
+ override def map(g: Type => Type) = lateMap(g)
+ override def lateMap(g: Type => Type) = self.lateMap(x => g(f(x)))
+ override def exists(p: Type => Boolean) = elems exists (x => p(f(x)))
+ override protected def maxDepthOfElems: Int = elems map (x => maxDpth(f(x))) max
+ override def toString = elems.mkString("MBTS(", ",", ")")
+ }
+
def exists(p: Type => Boolean): Boolean = elems exists p
-// (0 until length) exists (i => p(this(i)))
- def normalize(parents: List[Type]) {}
-/*
- var j = 0
- while (j < elems.length) {
- elems(j) match {
- case RefinedType(variants, decls) =>
- // can't assert decls.isEmpty; see t0764
- //if (!decls.isEmpty) assert(false, "computing closure of "+this+":"+this.isInstanceOf[RefinedType]+"/"+closureCache(j))
- //Console.println("compute closure of "+this+" => glb("+variants+")")
- elems(j) = mergePrefixAndArgs(variants, -1, maxBaseTypeSeqDepth(variants) + LubGlbMargin) match {
- case Some(tp0) => tp0
- case None => throw new TypeError(
- "the type intersection "+(parents mkString " with ")+" is malformed"+
- "\n --- because ---"+
- "\n no common type instance of base types "+(variants mkString ", and ")+" exists.")
- }
- case _ =>
- }
- j += 1
- }
- }
-*/
- lazy val maxDepth: Int = {
+ lazy val maxDepth: Int = maxDepthOfElems
+
+ protected def maxDepthOfElems = {
var d = 0
for (i <- 0 until length) d = Math.max(d, maxDpth(elems(i)))
d
}
/** The maximum depth of type `tp' */
- private def maxDpth(tp: Type): Int = tp match {
+ protected def maxDpth(tp: Type): Int = tp match {
case TypeRef(pre, sym, args) =>
max(maxDpth(pre), maxDpth(args) + 1)
case RefinedType(parents, decls) =>
@@ -190,7 +183,7 @@ trait BaseTypeSeqs {
def baseTypeSingletonSeq(tp: Type): BaseTypeSeq = new BaseTypeSeq(List(), Array(tp))
/** Create the base type sequence of a compound type wuth given tp.parents */
- def compoundBaseTypeSeq(tp: Type/*tsym: Symbol, parents: List[Type]*/): BaseTypeSeq = {
+ def compoundBaseTypeSeq(tp: Type): BaseTypeSeq = {
val tsym = tp.typeSymbol
val parents = tp.parents
// Console.println("computing baseTypeSeq of " + tsym.tpe + " " + parents)//DEBUG
diff --git a/src/compiler/scala/tools/nsc/symtab/Symbols.scala b/src/compiler/scala/tools/nsc/symtab/Symbols.scala
index e10ddb26d6..4aea770ff4 100644
--- a/src/compiler/scala/tools/nsc/symtab/Symbols.scala
+++ b/src/compiler/scala/tools/nsc/symtab/Symbols.scala
@@ -1729,9 +1729,10 @@ trait Symbols {
}
override def unpackLocation = origin
override def typeParams = info.typeParams //@M! (not deSkolemize.typeParams!!), also can't leave superclass definition: use info, not rawInfo
- override def cloneSymbolImpl(owner: Symbol): Symbol = {
- throw new Error("should not clone a type skolem")
- }
+
+ override def cloneSymbolImpl(owner: Symbol): Symbol =
+ new TypeSkolem(owner, pos, name, origin)
+
override def nameString: String =
if (settings.debug.value) (super.nameString + "&" + level)
else super.nameString
diff --git a/src/compiler/scala/tools/nsc/symtab/Types.scala b/src/compiler/scala/tools/nsc/symtab/Types.scala
index a359ec1c57..8bf9708c0c 100644
--- a/src/compiler/scala/tools/nsc/symtab/Types.scala
+++ b/src/compiler/scala/tools/nsc/symtab/Types.scala
@@ -265,6 +265,8 @@ trait Types {
def typeOfThis: Type = typeSymbol.typeOfThis
/** Map to a singleton type which is a subtype of this type.
+ * todo: change to singleton type of an existentgially defined variable
+ * of the right type instead of making this a `this` of a refined type.
*/
def narrow: Type =
if (phase.erasedTypes) this
@@ -1065,13 +1067,37 @@ trait Types {
if (period != currentPeriod) { // no caching in IDE
baseTypeSeqPeriod = currentPeriod
if (!isValidForBaseClasses(period)) {
- if (util.Statistics.enabled)
- compoundBaseTypeSeqCount += 1
- baseTypeSeqCache = undetBaseTypeSeq
- baseTypeSeqCache = memo(compoundBaseTypeSeq(this))(_.baseTypeSeq updateHead typeSymbol.tpe)
-// println("normalizing baseTypeSeq of "+typeSymbol+"/"+parents+": "+baseTypeSeqCache)//DEBUG
- baseTypeSeqCache.normalize(parents)
-// println("normalized baseTypeSeq of "+typeSymbol+"/"+parents+": "+baseTypeSeqCache)//DEBUG
+ if (parents.exists(_.exists(_.isInstanceOf[TypeVar]))) {
+ // rename type vars to fresh type params, take base type sequence of
+ // resulting type, and rename back allthe entries in thats sequence
+ var tvs = Set[TypeVar]()
+ for (p <- parents)
+ for (t <- p) t match {
+ case tv: TypeVar => tvs += tv
+ case _ =>
+ }
+ val varToParamMap = (Map[Type, Symbol]() /: tvs)((m, tv) => m + (tv -> tv.origin.typeSymbol.cloneSymbol))
+ val paramToVarMap = Map[Symbol, Type]() ++ (varToParamMap map { case (t, tsym) => (tsym -> t) })
+ val varToParam = new TypeMap {
+ def apply(tp: Type): Type = tp match {
+ case tv: TypeVar => varToParamMap(tp).tpe
+ case _ => mapOver(tp)
+ }
+ }
+ val paramToVar = new TypeMap {
+ def apply(tp: Type) = tp match {
+ case TypeRef(_, tsym, _) if paramToVarMap.isDefinedAt(tsym) => paramToVarMap(tsym)
+ case _ => mapOver(tp)
+ }
+ }
+ val bts = copyRefinedType(this.asInstanceOf[RefinedType], parents map varToParam, varToParam mapOver decls).baseTypeSeq
+ baseTypeSeqCache = bts lateMap paramToVar
+ } else {
+ if (util.Statistics.enabled)
+ compoundBaseTypeSeqCount += 1
+ baseTypeSeqCache = undetBaseTypeSeq
+ baseTypeSeqCache = memo(compoundBaseTypeSeq(this))(_.baseTypeSeq updateHead typeSymbol.tpe)
+ }
}
//Console.println("baseTypeSeq(" + typeSymbol + ") = " + baseTypeSeqCache.toList);//DEBUG
}
@@ -2543,7 +2569,7 @@ A type's typeSymbol should never be inspected directly.
}
/** Map this function over given scope */
- private def mapOver(scope: Scope): Scope = {
+ def mapOver(scope: Scope): Scope = {
val elems = scope.toList
val elems1 = mapOver(elems)
if (elems1 eq elems) scope
@@ -3787,7 +3813,7 @@ A type's typeSymbol should never be inspected directly.
secondTry
case _ =>
if (constr2.inst != NoType) tp1 <:< constr2.inst
- else isRelatable(tv2, tp1) && { constr2.lobounds = tp1 :: constr2.lobounds; true }
+ else isRelatable(tv2, tp1) && { assert(tp1 != tv2); constr2.lobounds = tp1 :: constr2.lobounds; true }
}
case _ =>
secondTry
@@ -3995,7 +4021,7 @@ A type's typeSymbol should never be inspected directly.
tp1 <:< bounds.hi
case (_, tv2 @ TypeVar(_, constr2)) =>
if (constr2.inst != NoType) tp1 <:< constr2.inst
- else isRelatable(tv2, tp1) && { constr2.lobounds = tp1 :: constr2.lobounds; true }
+ else isRelatable(tv2, tp1) && { assert(tp1 != tv2); constr2.lobounds = tp1 :: constr2.lobounds; true }
case (tv1 @ TypeVar(_, constr1), _) =>
if (constr1.inst != NoType) constr1.inst <:< tp2
else isRelatable(tv1, tp2) && { constr1.hibounds = tp2 :: constr1.hibounds; true }
diff --git a/src/compiler/scala/tools/nsc/typechecker/Infer.scala b/src/compiler/scala/tools/nsc/typechecker/Infer.scala
index d8f54760a1..6c3b6af081 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Infer.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Infer.scala
@@ -616,9 +616,17 @@ trait Infer {
* @throws NoInstance
*/
def methTypeArgs(tparams: List[Symbol], formals: List[Type], restpe: Type,
- argtpes: List[Type], pt: Type,
- uninstantiated: ListBuffer[Symbol]): List[Type] = {
+ argtpes: List[Type], pt: Type,
+ uninstantiated: ListBuffer[Symbol]): List[Type] = {
val tvars = tparams map freshVar
+ if (inferInfo)
+ println("methTypeArgs tparams = "+tparams+
+ ", formals = "+formals+
+ ", restpe = "+restpe+
+ ", argtpes = "+argtpes+
+ ", pt = "+pt+
+ ", uninstantiated = "+uninstantiated+
+ ", tvars = "+tvars+" "+(tvars map (_.constr)))
if (formals.length != argtpes.length) {
throw new NoInstance("parameter lists differ in length")
}
@@ -646,7 +654,8 @@ trait Infer {
}
()
}
-// println("solve "+tvars+" "+(tvars map (_.constr)))
+ if (inferInfo)
+ println("solve "+tvars+" "+(tvars map (_.constr)))
val targs = solvedTypes(tvars, tparams, tparams map varianceInTypes(formals),
false, lubDepth(formals) max lubDepth(argtpes))
// val res =
@@ -1194,11 +1203,9 @@ trait Infer {
val uninstantiated = new ListBuffer[Symbol]
val targs = methTypeArgs(undetparams, formals, restpe, argtpes, pt, uninstantiated)
checkBounds(fn.pos, NoPrefix, NoSymbol, undetparams, targs, "inferred ")
- //Console.println("UNAPPLY subst type "+undetparams+" to "+targs+" in "+fn+" ( "+args+ ")")
val treeSubst = new TreeTypeSubstituter(undetparams, targs)
treeSubst.traverse(fn)
treeSubst.traverseTrees(args)
- //Console.println("UNAPPLY gives "+fn+" ( "+args+ "), argtpes = "+argtpes+", pt = "+pt)
uninstantiated.toList
} catch {
case ex: NoInstance =>
diff --git a/src/library/scala/collection/SortedSet.scala b/src/library/scala/collection/SortedSet.scala
index 95d0e0d084..a1213a9dc4 100644
--- a/src/library/scala/collection/SortedSet.scala
+++ b/src/library/scala/collection/SortedSet.scala
@@ -9,6 +9,7 @@
// $Id$
package scala.collection
+import generic._
/** A sorted set.
*
@@ -21,3 +22,14 @@ trait SortedSet[A] extends Set[A] with SortedSetLike[A, SortedSet[A]] {
/** Needs to be overridden in subclasses. */
override def empty: SortedSet[A] = throw new UnsupportedOperationException("SortedMap.empty")
}
+
+/**
+ * @since 2.8
+ */
+object SortedSet extends ImmutableSortedSetFactory[immutable.SortedSet] {
+ implicit def builderFactory[A](implicit ord: Ordering[A]): BuilderFactory[A, SortedSet[A], Coll] = new SortedSetBuilderFactory[A]
+ def empty[A](implicit ord: Ordering[A]): immutable.SortedSet[A] = immutable.SortedSet.empty[A](ord)
+}
+
+
+
diff --git a/src/library/scala/collection/immutable/SortedSet.scala b/src/library/scala/collection/immutable/SortedSet.scala
index 2d02493b3e..0fd9365dd1 100644
--- a/src/library/scala/collection/immutable/SortedSet.scala
+++ b/src/library/scala/collection/immutable/SortedSet.scala
@@ -26,3 +26,11 @@ trait SortedSet[A] extends Set[A] with scala.collection.SortedSet[A] with Sorted
/** Needs to be overridden in subclasses. */
override def empty: SortedSet[A] = throw new UnsupportedOperationException("SortedMap.empty")
}
+
+/**
+ * @since 2.4
+ */
+object SortedSet extends ImmutableSortedSetFactory[SortedSet] {
+ implicit def builderFactory[A](implicit ord: Ordering[A]): BuilderFactory[A, SortedSet[A], Coll] = new SortedSetBuilderFactory[A]
+ def empty[A](implicit ord: Ordering[A]): SortedSet[A] = TreeSet.empty[A]
+}
diff --git a/src/library/scala/collection/mutable/WrappedArray.scala b/src/library/scala/collection/mutable/WrappedArray.scala
index faa1387714..f3f5596fd6 100644
--- a/src/library/scala/collection/mutable/WrappedArray.scala
+++ b/src/library/scala/collection/mutable/WrappedArray.scala
@@ -42,8 +42,7 @@ abstract class WrappedArray[T] extends Vector[T] with ArrayLike[T, WrappedArray[
/** The underlying array */
def array: Array[T]
-
- override def stringPrefix = "Array"
+ override def stringPrefix = "WrappedArray"
/** Creates new builder for this collection ==> move to subclasses
*/
diff --git a/test/files/run/bug627.check b/test/files/run/bug627.check
index f3304eb707..39e641d987 100644
--- a/test/files/run/bug627.check
+++ b/test/files/run/bug627.check
@@ -1 +1 @@
-Array(1, 2, 3, 4)
+WrappedArray(1, 2, 3, 4)
diff --git a/test/files/run/colltest1.check b/test/files/run/colltest1.check
index 4450726cc0..b76a7f324a 100644
--- a/test/files/run/colltest1.check
+++ b/test/files/run/colltest1.check
@@ -13,7 +13,7 @@ new test starting with Stream()
9: Stream(2, 3, 4, 5, 6, 7, 8, 9, 10)
1
Stream(1, ?)
-new test starting with Array()
+new test starting with WrappedArray()
10: ArrayBuffer(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
9: ArrayBuffer(2, 3, 4, 5, 6, 7, 8, 9, 10)
1