summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/compiler/scala/tools/nsc/ast/parser/Parsers.scala2
-rw-r--r--src/compiler/scala/tools/nsc/symtab/Types.scala114
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Infer.scala4
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Namers.scala12
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/TreeCheckers.scala1
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Typers.scala2
-rw-r--r--src/library/scala/collection/immutable/ListSet.scala9
-rw-r--r--src/library/scala/collection/immutable/Stack.scala6
-rw-r--r--src/library/scala/collection/mutable/LinkedList.scala7
-rw-r--r--src/library/scala/collection/mutable/PriorityQueue.scala12
-rw-r--r--src/library/scala/collection/mutable/Queue.scala12
-rw-r--r--src/library/scala/collection/mutable/Stack.scala12
-rw-r--r--src/library/scala/reflect/Print.scala24
-rw-r--r--src/library/scala/xml/Utility.scala5
-rwxr-xr-xtest/files/run/bug1220.scala14
15 files changed, 163 insertions, 73 deletions
diff --git a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala
index 68a34def62..eb176dca42 100644
--- a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala
+++ b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala
@@ -1159,7 +1159,7 @@ trait Parsers {
case USCORE =>
val pname = freshName("x$")
val pos = inSkipToken
- val param = makeSyntheticParam(pname) setPos pos
+ val param = atPos(pos){ makeSyntheticParam(pname) }
placeholderParams = param :: placeholderParams
t = atPos(pos) { Ident(pname) }
case LPAREN =>
diff --git a/src/compiler/scala/tools/nsc/symtab/Types.scala b/src/compiler/scala/tools/nsc/symtab/Types.scala
index 57c8e4e60b..55aa36c510 100644
--- a/src/compiler/scala/tools/nsc/symtab/Types.scala
+++ b/src/compiler/scala/tools/nsc/symtab/Types.scala
@@ -1389,8 +1389,10 @@ A type's typeSymbol should never be inspected directly.
if (isTupleType(this))
return args.mkString("(", ", ", if (args.length == 1) ",)" else ")")
}
- val str = (pre.prefixString + sym.nameString +
+ var str = (pre.prefixString + sym.nameString +
(if (args.isEmpty) "" else args.mkString("[", ",", "]")))
+ //if (sym.nameString startsWith "moduleType")
+ // str += ("_in_"+sym.ownerChain)
if (sym.isPackageClass)
packagePrefix + str
else if (sym.isModuleClass)
@@ -1574,8 +1576,9 @@ A type's typeSymbol should never be inspected directly.
/** A class representing a type variable
* Not used after phase `typer'.
*/
- case class TypeVar(origin: Type, constr: TypeConstraint) extends Type {
+ case class TypeVar(origin: Type, constr0: TypeConstraint) extends Type {
//constr.self = this //DEBUG
+ var constr = constr0
override def typeSymbol = origin.typeSymbol
@deprecated override def symbol = origin.symbol
override def toString: String =
@@ -1941,14 +1944,12 @@ A type's typeSymbol should never be inspected directly.
var lobounds: List[Type] = lo
var hibounds: List[Type] = hi
var inst: Type = NoType
-/* debug
- private var _inst: Type = NoType
- def inst = _inst
- def inst_=(tp: Type) {
- assert(tp == null || !(tp containsTp self), tp)
- _inst = tp
+
+ def duplicate = {
+ val tc = new TypeConstraint(lo, hi)
+ tc.inst = inst
+ tc
}
-*/
def instantiate(tp: Type): Boolean =
if (lobounds.forall(_ <:< tp) && hibounds.forall(tp <:< _)) {
@@ -2602,6 +2603,12 @@ A type's typeSymbol should never be inspected directly.
}
}
+ var undoLog: List[(TypeVar, TypeConstraint)] = List()
+
+ def snapShot(tv: TypeVar) {
+ undoLog = (tv, tv.constr.duplicate) :: undoLog
+ }
+
/** Do `tp1' and `tp2' denote equivalent types?
*
* @param tp1 ...
@@ -2687,12 +2694,12 @@ A type's typeSymbol should never be inspected directly.
bounds containsType tp2
case (_, BoundedWildcardType(bounds)) =>
bounds containsType tp1
- case (TypeVar(_, constr1), _) =>
+ case (tv1 @ TypeVar(_, constr1), _) =>
if (constr1.inst != NoType) constr1.inst =:= tp2
- else constr1 instantiate (wildcardToTypeVarMap(tp2))
- case (_, TypeVar(_, constr2)) =>
+ else { snapShot(tv1); constr1 instantiate wildcardToTypeVarMap(tp2) }
+ case (_, tv2 @ TypeVar(_, constr2)) =>
if (constr2.inst != NoType) tp1 =:= constr2.inst
- else constr2 instantiate (wildcardToTypeVarMap(tp1))
+ else { snapShot(tv2); constr2 instantiate wildcardToTypeVarMap(tp1) }
case (AnnotatedType(_,atp), _) =>
isSameType(atp, tp2)
case (_, AnnotatedType(_,atp)) =>
@@ -2725,27 +2732,58 @@ A type's typeSymbol should never be inspected directly.
def isSubType(tp1: Type, tp2: Type): Boolean = try {
stc = stc + 1
- if (stc >= LogPendingSubTypesThreshold) {
- val p = new SubTypePair(tp1, tp2)
- if (pendingSubTypes contains p)
- false
- else
- try {
- pendingSubTypes += p
- isSubType0(tp1, tp2)
- } finally {
- pendingSubTypes -= p
- }
- } else {
- isSubType0(tp1, tp2)
+ val lastUndoLog = undoLog
+ val result =
+ if (stc >= LogPendingSubTypesThreshold) {
+ val p = new SubTypePair(tp1, tp2)
+ if (pendingSubTypes contains p)
+ false
+ else
+ try {
+ pendingSubTypes += p
+ isSubType0(tp1, tp2)
+ } finally {
+ pendingSubTypes -= p
+ }
+ } else {
+ isSubType0(tp1, tp2)
+ }
+ if (!result) {
+ while (undoLog ne lastUndoLog) {
+ val (tv, constr) = undoLog.head
+ undoLog = undoLog.tail
+ tv.constr = constr
+ }
}
+ result
} finally {
stc = stc - 1
+ if (stc == 0) undoLog = List()
}
/** hook for IDE */
protected def trackTypeIDE(sym : Symbol) : Boolean = true;
+ def isTypeVar(tp: Type): Boolean = tp match {
+ case SingleType(pre, sym) =>
+ !(sym hasFlag PACKAGE) && isTypeVar(pre)
+ case TypeVar(_, constr) =>
+ constr.inst == NoType || isTypeVar(constr.inst)
+ case _ =>
+ false
+ }
+
+ def instTypeVar(tp: Type): Type = tp match {
+ case TypeRef(pre, sym, args) =>
+ typeRef(instTypeVar(pre), sym, args)
+ case SingleType(pre, sym) =>
+ singleType(instTypeVar(pre), sym)
+ case TypeVar(_, constr) =>
+ instTypeVar(constr.inst)
+ case _ =>
+ tp
+ }
+
/** Does type `tp1' conform to `tp2'?
*
* @param tp1 ...
@@ -2785,8 +2823,16 @@ A type's typeSymbol should never be inspected directly.
isSubArgs(tps1.tail, tps2.tail, tparams.tail)
);
(sym1 == sym2 &&
- (phase.erasedTypes || pre1 <:< pre2) &&
- (sym2 == AnyClass || isSubArgs(args1, args2, sym1.typeParams)) //@M: Any is kind-polymorphic
+ (phase.erasedTypes || pre1 <:< pre2) &&
+ (sym2 == AnyClass || isSubArgs(args1, args2, sym1.typeParams)) //@M: Any is kind-polymorphic
+/*
+ ||
+ sym1.name == sym2.name &&
+// (sym1.owner isSubClass sym2.owner) &&
+ (isTypeVar(pre1) || isTypeVar(pre2)) &&
+ pre1 =:= pre2 &&
+ instTypeVar(tp1) <:< instTypeVar(tp2)
+*/
||
sym1.isAbstractType && !(tp1 =:= tp1.bounds.hi) && (tp1.bounds.hi <:< tp2)
||
@@ -2816,12 +2862,12 @@ A type's typeSymbol should never be inspected directly.
bounds.lo <:< tp2
case (_, BoundedWildcardType(bounds)) =>
tp1 <:< bounds.hi
- case (_, TypeVar(_, constr2)) =>
+ case (_, tv2 @ TypeVar(_, constr2)) =>
if (constr2.inst != NoType) tp1 <:< constr2.inst
- else { constr2.lobounds = tp1 :: constr2.lobounds; true }
- case (TypeVar(_, constr1), _) =>
+ else { snapShot(tv2); constr2.lobounds = tp1 :: constr2.lobounds; true }
+ case (tv1 @ TypeVar(_, constr1), _) =>
if (constr1.inst != NoType) constr1.inst <:< tp2
- else { constr1.hibounds = tp2 :: constr1.hibounds; true }
+ else { snapShot(tv1); constr1.hibounds = tp2 :: constr1.hibounds; true }
case (AnnotatedType(_,atp1), _) =>
atp1 <:< tp2
case (_, AnnotatedType(_,atp2)) =>
@@ -2848,9 +2894,9 @@ A type's typeSymbol should never be inspected directly.
val tvars = tparams2 map (tparam => new TypeVar(tparam.tpe, new TypeConstraint))
val ires2 = res2.instantiateTypeParams(tparams2, tvars)
(tp1 <:< ires2) && {
-// println("solve: "+tparams2)
+ //println("solve: "+tparams2)
solve(tvars, tparams2, tparams2 map (x => 0), false)
-// println("check bounds: "+tparams2+" aginst "+(tvars map (_.constr.inst)))
+ //println("check bounds: "+tparams2+" aginst "+(tvars map (_.constr.inst)))
isWithinBounds(NoPrefix, NoSymbol, tparams2, tvars map (_.constr.inst))
}
case (RefinedType(parents1, ref1), _) =>
diff --git a/src/compiler/scala/tools/nsc/typechecker/Infer.scala b/src/compiler/scala/tools/nsc/typechecker/Infer.scala
index a18e2b80eb..8acb9173af 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Infer.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Infer.scala
@@ -490,13 +490,15 @@ trait Infer {
()
}
val targs = solvedTypes(tvars, tparams, tparams map varianceInTypes(formals), false)
+// val res =
List.map2(tparams, targs) {(tparam, targ) =>
if (targ.typeSymbol == AllClass && (varianceInType(restpe)(tparam) & COVARIANT) == 0) {
uninstantiated += tparam
tparam.tpe //@M TODO: might be affected by change to tpe in Symbol
} else targ.widen
}
-// println("meth type args "+", tparams = "+tparams+", formals = "+formals+", restpe = "+restpe+", argtpes = "+argtpes+", underlying = "+(argtpes map (_.widen))+", pt = "+pt+", uninstantiated = "+uninstantiated.toList+", result = "+res) //DEBUG
+// println("meth type args "+", tparams = "+tparams+", formals = "+formals+", restpe = "+restpe+", argtpes = "+argtpes+", underlying = "+(argtpes map (_.widen))+", pt = "+pt+", uninstantiated = "+uninstantiated.toList+", result = "+res) //DEBUG
+// res
}
/** Is there an instantiation of free type variables <code>undetparams</code>
diff --git a/src/compiler/scala/tools/nsc/typechecker/Namers.scala b/src/compiler/scala/tools/nsc/typechecker/Namers.scala
index 8bbc88c390..ff24719b18 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Namers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Namers.scala
@@ -358,6 +358,18 @@ trait Namers { self: Analyzer =>
override def complete(sym: Symbol) {
if (settings.debug.value) log("defining " + sym + Flags.flagsToString(sym.flags));
val tp = typeSig(tree)
+ // check that
+ tp match {
+ case TypeBounds(lo, hi) =>
+ // check that lower bound is not an F-bound
+ for (val t <- lo) {
+ t match {
+ case TypeRef(_, sym, _) => sym.initialize
+ case _ =>
+ }
+ }
+ case _ =>
+ }
sym.setInfo(tp)
if ((sym.isAliasType || sym.isAbstractType) && !(sym hasFlag PARAM) &&
!typer.checkNonCyclic(tree.pos, tp))
diff --git a/src/compiler/scala/tools/nsc/typechecker/TreeCheckers.scala b/src/compiler/scala/tools/nsc/typechecker/TreeCheckers.scala
index aac29e8875..dc05fc32ba 100644
--- a/src/compiler/scala/tools/nsc/typechecker/TreeCheckers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/TreeCheckers.scala
@@ -21,6 +21,7 @@ abstract class TreeCheckers extends Analyzer {
}
def check(unit: CompilationUnit) {
+ informProgress("checking "+unit)
val context = rootContext(unit)
context.checking = true
tpeOfTree.clear
diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
index 0fee0c07dc..bed72e52a9 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
@@ -1302,7 +1302,7 @@ trait Typers { self: Analyzer =>
var body1: Tree = typed(cdef.body, pt)
if (!context.savedTypeBounds.isEmpty) {
body1.tpe = context.restoreTypeBounds(body1.tpe)
- if (isFullyDefined(pt))
+ if (isFullyDefined(pt) && !(body1.tpe <:< pt))
// the following is a hack to make the pattern matcher work !!! (still needed?)
body1 =
typed {
diff --git a/src/library/scala/collection/immutable/ListSet.scala b/src/library/scala/collection/immutable/ListSet.scala
index 6bf4d5b626..3945612143 100644
--- a/src/library/scala/collection/immutable/ListSet.scala
+++ b/src/library/scala/collection/immutable/ListSet.scala
@@ -86,12 +86,13 @@ class ListSet[A] extends AnyRef with Set[A] {
/** Compares two sets for equality.
* Two set are equal iff they contain the same elements.
*/
- override def equals(obj: Any): Boolean =
- if (obj.isInstanceOf[scala.collection.Set[A]]) {
+ override def equals(obj: Any): Boolean = obj match {
+ case _: scala.collection.Set[_] =>
val that = obj.asInstanceOf[scala.collection.Set[A]]
- if (size != that.size) false else toList.forall(that.contains)
- } else
+ (size == that.size) && (toList forall that.contains)
+ case _ =>
false
+ }
/**
* @throws Predef.NoSuchElementException
diff --git a/src/library/scala/collection/immutable/Stack.scala b/src/library/scala/collection/immutable/Stack.scala
index 22f257b99f..75d6cb8b98 100644
--- a/src/library/scala/collection/immutable/Stack.scala
+++ b/src/library/scala/collection/immutable/Stack.scala
@@ -106,8 +106,10 @@ class Stack[+A] extends Seq[A] {
* @return true, iff the two stacks are equal; i.e. they contain the
* same elements in the same order.
*/
- override def equals(obj: Any): Boolean =
- obj.isInstanceOf[Stack[A]] && sameElements(obj.asInstanceOf[Stack[A]])
+ override def equals(obj: Any): Boolean = obj match {
+ case that: Stack[_] => this sameElements that
+ case _ => false
+ }
/** Returns the hash code for this stack.
*
diff --git a/src/library/scala/collection/mutable/LinkedList.scala b/src/library/scala/collection/mutable/LinkedList.scala
index bd5ae23532..0ed1a02889 100644
--- a/src/library/scala/collection/mutable/LinkedList.scala
+++ b/src/library/scala/collection/mutable/LinkedList.scala
@@ -22,9 +22,10 @@ class LinkedList[A](var elem: A, var next: LinkedList[A])
extends SingleLinkedList[A, LinkedList[A]]
{
- override def equals(obj: Any): Boolean =
- obj.isInstanceOf[LinkedList[A]] &&
- toList.equals((obj.asInstanceOf[LinkedList[A]]).toList)
+ override def equals(obj: Any): Boolean = obj match {
+ case that: LinkedList[_] => this.toList equals that.toList
+ case _ => false
+ }
override protected def stringPrefix: String = "LinkedList"
}
diff --git a/src/library/scala/collection/mutable/PriorityQueue.scala b/src/library/scala/collection/mutable/PriorityQueue.scala
index 0772c545e9..de615469d8 100644
--- a/src/library/scala/collection/mutable/PriorityQueue.scala
+++ b/src/library/scala/collection/mutable/PriorityQueue.scala
@@ -153,12 +153,14 @@ class PriorityQueue[A <% Ordered[A]] extends ResizableArray[A] with CloneableCol
*
* @return true, iff both queues contain the same sequence of elements.
*/
- override def equals(that: Any): Boolean =
- that.isInstanceOf[PriorityQueue[A]] &&
- { val other = that.asInstanceOf[PriorityQueue[A]]
- elements.zip(other.elements).forall {
+ override def equals(obj: Any): Boolean = obj match {
+ case that: PriorityQueue[_] =>
+ (this.elements zip that.elements) forall {
case (thiselem, thatelem) => thiselem == thatelem
- }}
+ }
+ case _ =>
+ false
+ }
/** The hashCode method always yields an error, since it is not
* safe to use mutable queues as keys in hash tables.
diff --git a/src/library/scala/collection/mutable/Queue.scala b/src/library/scala/collection/mutable/Queue.scala
index d654a82888..e7c80ae7b4 100644
--- a/src/library/scala/collection/mutable/Queue.scala
+++ b/src/library/scala/collection/mutable/Queue.scala
@@ -166,12 +166,14 @@ class Queue[A] extends MutableList[A] with CloneableCollection {
*
* @return true, iff both queues contain the same sequence of elements.
*/
- override def equals(that: Any): Boolean =
- that.isInstanceOf[Queue[A]] &&
- { val other = that.asInstanceOf[Queue[A]]
- elements.zip(other.elements).forall {
+ override def equals(obj: Any): Boolean = obj match {
+ case that: Queue[_] =>
+ (this.elements zip that.elements) forall {
case (thiselem, thatelem) => thiselem == thatelem
- }}
+ }
+ case _ =>
+ false
+ }
/** The hashCode method always yields an error, since it is not
* safe to use mutable queues as keys in hash tables.
diff --git a/src/library/scala/collection/mutable/Stack.scala b/src/library/scala/collection/mutable/Stack.scala
index be95aee1a5..8aa2f27115 100644
--- a/src/library/scala/collection/mutable/Stack.scala
+++ b/src/library/scala/collection/mutable/Stack.scala
@@ -107,12 +107,14 @@ class Stack[A] extends MutableList[A] with CloneableCollection {
*
* @return true, iff both stacks contain the same sequence of elements.
*/
- override def equals(that: Any): Boolean =
- that.isInstanceOf[Stack[A]] &&
- { val other = that.asInstanceOf[Stack[A]];
- elements.zip(other.elements).forall {
+ override def equals(obj: Any): Boolean = obj match {
+ case that: Stack[_] =>
+ (this.elements zip that.elements) forall {
case (thiselem, thatelem) => thiselem == thatelem
- }}
+ }
+ case _ =>
+ false
+ }
/** The hashCode method always yields an error, since it is not
* safe to use mutable stacks as keys in hash tables.
diff --git a/src/library/scala/reflect/Print.scala b/src/library/scala/reflect/Print.scala
index 789d112490..039160077c 100644
--- a/src/library/scala/reflect/Print.scala
+++ b/src/library/scala/reflect/Print.scala
@@ -13,18 +13,20 @@ package scala.reflect
object Print extends Function1[Any, String] {
- def apply(any: Any): String =
- if (any.isInstanceOf[Code[Any]])
- apply(any.asInstanceOf[Code[Any]])
- else if (any.isInstanceOf[Tree])
- apply(any.asInstanceOf[Tree])
- else if (any.isInstanceOf[Symbol])
- apply(any.asInstanceOf[Symbol])
- else if (any.isInstanceOf[Type])
- apply(any.asInstanceOf[Type])
- else "UnknownAny"
+ def apply(any: Any): String = any match {
+ case x: Code[_] =>
+ apply(x)
+ case x: Tree =>
+ apply(x)
+ case x: Symbol =>
+ apply(x)
+ case x: Type =>
+ apply(x)
+ case _ =>
+ "UnknownAny"
+ }
- def apply(code: Code[Any]): String =
+ def apply[A](code: Code[A]): String =
Print(code.tree)
def apply(tree: Tree): String = tree match {
diff --git a/src/library/scala/xml/Utility.scala b/src/library/scala/xml/Utility.scala
index 00f93b9ffc..3f3ac9d6e8 100644
--- a/src/library/scala/xml/Utility.scala
+++ b/src/library/scala/xml/Utility.scala
@@ -219,7 +219,10 @@ object Utility extends AnyRef with parsing.TokenTests {
sb: StringBuilder, stripComment: Boolean) {
if (children.isEmpty)
return
- else if (children forall { y => y.isInstanceOf[Atom[Any]] && !y.isInstanceOf[Text] }) { // add space
+ else if (children forall {
+ case y: Atom[_] => !y.isInstanceOf[Text]
+ case _ => false
+ }) { // add space
val it = children.elements
val f = it.next
toXML(f, f.scope, sb, stripComment)
diff --git a/test/files/run/bug1220.scala b/test/files/run/bug1220.scala
new file mode 100755
index 0000000000..a992e5f2a5
--- /dev/null
+++ b/test/files/run/bug1220.scala
@@ -0,0 +1,14 @@
+object Test extends Application {
+ class QSRichIterable[A](self:Iterable[A]) {
+ def filterMap[R](f: PartialFunction[A,R]) =
+ self filter (f.isDefinedAt) map f
+ }
+
+ object Un {
+ def unapply(i:int): Option[int] = Some(i)
+ }
+
+ val richIter = new QSRichIterable(List(0, 1, 2, 3, 4))
+
+ assert((richIter filterMap {case Un(3) => 7}) == List(7))
+}