summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAntonio Cunei <antonio.cunei@epfl.ch>2009-12-21 15:35:16 +0000
committerAntonio Cunei <antonio.cunei@epfl.ch>2009-12-21 15:35:16 +0000
commitd3e129a5fb36030d3a05ee59ccf353095125d622 (patch)
treef92ff3325831065b86de67d504a8da792c16c430
parent2ab456d13df1ac50539e4620f62f6e234f3c8446 (diff)
downloadscala-d3e129a5fb36030d3a05ee59ccf353095125d622.tar.gz
scala-d3e129a5fb36030d3a05ee59ccf353095125d622.tar.bz2
scala-d3e129a5fb36030d3a05ee59ccf353095125d622.zip
Merged revisions 20248,20250,20252-20256 via sv...
Merged revisions 20248,20250,20252-20256 via svnmerge from https://lampsvn.epfl.ch/svn-repos/scala/scala/trunk ........ r20248 | odersky | 2009-12-20 19:11:24 +0100 (Sun, 20 Dec 2009) | 2 lines Closed #2718 and #2765. review by extempore. ........ r20250 | extempore | 2009-12-21 01:05:03 +0100 (Mon, 21 Dec 2009) | 3 lines Minimally integrated the semi-orphaned immutable.Stack into the collections hierarchy and enabled it in the sequence tests. Closes #2822. review by community. ........ r20252 | rytz | 2009-12-21 12:20:43 +0100 (Mon, 21 Dec 2009) | 1 line close #2820 ........ r20253 | odersky | 2009-12-21 13:53:20 +0100 (Mon, 21 Dec 2009) | 1 line small cleanups. no review necessary. ........ r20254 | odersky | 2009-12-21 13:54:27 +0100 (Mon, 21 Dec 2009) | 1 line Fixed lift 2.8 beta RC4 build problem. The problem was that tailcalls assumed the wrong type for `this'. Review by dragos. Test in selftails.scala. ........ r20255 | odersky | 2009-12-21 13:59:36 +0100 (Mon, 21 Dec 2009) | 1 line Improved deprecated warnings. No review necessary. ........ r20256 | phaller | 2009-12-21 16:30:00 +0100 (Mon, 21 Dec 2009) | 1 line Documented scala.actors.Futures API. Closes #2506. Review by dubochet. ........
-rw-r--r--src/actors/scala/actors/Future.scala86
-rw-r--r--src/compiler/scala/tools/nsc/symtab/Types.scala6
-rw-r--r--src/compiler/scala/tools/nsc/transform/Erasure.scala30
-rw-r--r--src/compiler/scala/tools/nsc/transform/TailCalls.scala2
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala40
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Typers.scala29
-rw-r--r--src/library/scala/collection/immutable/List.scala32
-rw-r--r--src/library/scala/collection/immutable/Stack.scala66
-rw-r--r--test/files/pos/selftails.scala23
-rw-r--r--test/files/run/names-defaults.scala6
-rw-r--r--test/files/run/sequenceComparisons.scala2
11 files changed, 185 insertions, 137 deletions
diff --git a/src/actors/scala/actors/Future.scala b/src/actors/scala/actors/Future.scala
index d6dba36321..ea0c3a691f 100644
--- a/src/actors/scala/actors/Future.scala
+++ b/src/actors/scala/actors/Future.scala
@@ -10,21 +10,15 @@
package scala.actors
-import scheduler.DefaultThreadPoolScheduler
-
-/**
- * <p>
- * A <code>Future[T]</code> is a function of arity 0 that
- * returns a value of type <code>T</code>.
- * Applying a future blocks the current actor (<code>self</code>)
- * until the future's value is available.
- * </p>
- * <p>
- * A future can be queried to find out whether its value
- * is already available.
- * </p>
+/** A `Future[T]` is a function of arity 0 that returns
+ * a value of type `T`.
+ * Applying a future blocks the current actor (`Actor.self`)
+ * until the future's value is available.
*
- * @author Philipp Haller
+ * A future can be queried to find out whether its value
+ * is already available without blocking.
+ *
+ * @author Philipp Haller
*/
abstract class Future[+T](val inputChannel: InputChannel[T]) extends Responder[T] with Function0[T] {
private[actors] var fvalue: Option[Any] = None
@@ -35,18 +29,29 @@ abstract class Future[+T](val inputChannel: InputChannel[T]) extends Responder[T
@deprecated("this member is going to be removed in a future release")
protected def value_=(x: Option[Any]) { fvalue = x }
+ /** Tests whether the future's result is available.
+ *
+ * @return `true` if the future's result is available,
+ * `false` otherwise.
+ */
def isSet: Boolean
}
-/**
- * The <code>Futures</code> object contains methods that operate on Futures.
+/** The <code>Futures</code> object contains methods that operate on futures.
*
- * @author Philipp Haller
+ * @author Philipp Haller
*/
object Futures {
private case object Eval
+ /** Arranges for the asynchronous execution of `body`,
+ * returning a future representing the result.
+ *
+ * @param body the computation to be carried out asynchronously
+ * @return the future representing the result of the
+ * computation
+ */
def future[T](body: => T): Future[T] = {
val a = new DaemonActor {
def act() {
@@ -59,29 +64,50 @@ object Futures {
a !! (Eval, { case any => any.asInstanceOf[T] })
}
- def alarm(t: Long) = future {
- Actor.reactWithin(t) {
+ /** Creates a future that resolves after a given time span.
+ *
+ * @param timespan the time span in ms after which the future resolves
+ * @return the future
+ */
+ def alarm(timespan: Long) = future {
+ Actor.reactWithin(timespan) {
case TIMEOUT => {}
}
}
- def awaitEither[a, b](ft1: Future[a], ft2: Future[b]): Any = {
+ /** Waits for the first result returned by one of two
+ * given futures.
+ *
+ * @param ft1 the first future
+ * @param ft2 the second future
+ * @return the result of the future that resolves first
+ */
+ def awaitEither[A, B >: A](ft1: Future[A], ft2: Future[B]): B = {
val FutCh1 = ft1.inputChannel
val FutCh2 = ft2.inputChannel
Actor.receive {
- case FutCh1 ! arg1 => arg1
- case FutCh2 ! arg2 => arg2
+ case FutCh1 ! arg1 => arg1.asInstanceOf[B]
+ case FutCh2 ! arg2 => arg2.asInstanceOf[B]
}
}
- /**
- * <p>
- * Awaits all futures returning an option containing a list of replies,
- * or timeouts returning <code>None</code>.
- * </p>
- * <p>
- * Note that some of the futures might already have been awaited.
- * </p>
+ /** Waits until either all futures are resolved or a given
+ * time span has passed. Results are collected in a list of
+ * options. The result of a future that resolved during the
+ * time span is its value wrapped in `Some`. The result of a
+ * future that did not resolve during the time span is `None`.
+ *
+ * Note that some of the futures might already have been awaited,
+ * in which case their value is returned wrapped in `Some`.
+ * Passing a timeout of 0 causes `awaitAll` to return immediately.
+ *
+ * @param timeout the time span in ms after which waiting is
+ * aborted
+ * @param fts the futures to be awaited
+ * @return the list of optional future values
+ * @throws `java.lang.IllegalArgumentException` if timeout
+ * is negative, or timeout + `System.currentTimeMillis()`
+ * is negative.
*/
def awaitAll(timeout: Long, fts: Future[Any]*): List[Option[Any]] = {
val thisActor = Actor.self
diff --git a/src/compiler/scala/tools/nsc/symtab/Types.scala b/src/compiler/scala/tools/nsc/symtab/Types.scala
index 513ed34ff9..c4772b6407 100644
--- a/src/compiler/scala/tools/nsc/symtab/Types.scala
+++ b/src/compiler/scala/tools/nsc/symtab/Types.scala
@@ -139,8 +139,6 @@ trait Types {
}
}
-
-
/** A map from lists to compound types that have the given list as parents.
* This is used to avoid duplication in the computation of base type sequences and baseClasses.
* It makes use of the fact that these two operations depend only on the parents,
@@ -1763,7 +1761,7 @@ A type's typeSymbol should never be inspected directly.
packagePrefix + str
else if (sym.isModuleClass)
objectPrefix + str
- else if (sym.isAnonymousClass && sym.isInitialized && !settings.debug.value)
+ else if (sym.isAnonymousClass && sym.isInitialized && !settings.debug.value && !phase.erasedTypes)
thisInfo.parents.mkString(" with ") + {
if (sym.isStructuralRefinement)
((decls.toList filter { entry =>
@@ -1942,7 +1940,7 @@ A type's typeSymbol should never be inspected directly.
}
private def wildcardArgsString(available: Set[Symbol], args: List[Type]): List[String] = args match {
- case TypeRef(_, sym, _) :: args1 if (quantified contains sym) =>
+ case TypeRef(_, sym, _) :: args1 if (available contains sym) =>
("_"+sym.infoString(sym.info)) :: wildcardArgsString(available - sym, args1)
case arg :: args1 if !(quantified exists (arg contains _)) =>
arg.toString :: wildcardArgsString(available, args1)
diff --git a/src/compiler/scala/tools/nsc/transform/Erasure.scala b/src/compiler/scala/tools/nsc/transform/Erasure.scala
index 9db88af6c6..1fa81c8776 100644
--- a/src/compiler/scala/tools/nsc/transform/Erasure.scala
+++ b/src/compiler/scala/tools/nsc/transform/Erasure.scala
@@ -116,6 +116,22 @@ abstract class Erasure extends AddInterfaces with typechecker.Analyzer with ast.
* </ul>
*/
val erasure = new TypeMap {
+
+ // Compute the erasure of the intersection type with given `parents` according to new spec.
+ private def intersectionErasure(parents: List[Type]): Type =
+ if (parents.isEmpty) erasedTypeRef(ObjectClass)
+ else {
+ // implement new spec for erasure of refined types.
+ val psyms = parents map (_.typeSymbol)
+ def isUnshadowed(psym: Symbol) =
+ !(psyms exists (qsym => (psym ne qsym) && (qsym isNonBottomSubClass psym)))
+ val cs = parents.iterator.filter { p => // isUnshadowed is a bit expensive, so try classes first
+ val psym = p.typeSymbol
+ psym.isClass && !psym.isTrait && isUnshadowed(psym)
+ }
+ apply((if (cs.hasNext) cs else parents.iterator.filter(p => isUnshadowed(p.typeSymbol))).next())
+ }
+
def apply(tp: Type): Type = {
tp match {
case ConstantType(_) =>
@@ -129,6 +145,7 @@ abstract class Erasure extends AddInterfaces with typechecker.Analyzer with ast.
else typeRef(apply(pre), sym, args map this)
else if (sym == AnyClass || sym == AnyValClass || sym == SingletonClass) erasedTypeRef(ObjectClass)
else if (sym == UnitClass) erasedTypeRef(BoxedUnitClass)
+ else if (sym.isRefinementClass) intersectionErasure(tp.parents)
else if (sym.isClass) typeRef(apply(rebindInnerClass(pre, sym)), sym, List()) // #2585
else apply(sym.info) // alias type or abstract type
case PolyType(tparams, restpe) =>
@@ -145,18 +162,7 @@ abstract class Erasure extends AddInterfaces with typechecker.Analyzer with ast.
else
apply(restpe))
case RefinedType(parents, decls) =>
- if (parents.isEmpty) erasedTypeRef(ObjectClass)
- else {
- // implement new spec for erasure of refined types.
- val psyms = parents map (_.typeSymbol)
- def isUnshadowed(psym: Symbol) =
- !(psyms exists (qsym => (psym ne qsym) && (qsym isNonBottomSubClass psym)))
- val cs = parents.iterator.filter { p => // isUnshadowed is a bit expensive, so try classes first
- val psym = p.typeSymbol
- psym.isClass && !psym.isTrait && isUnshadowed(psym)
- }
- apply((if (cs.hasNext) cs else parents.iterator.filter(p => isUnshadowed(p.typeSymbol))).next())
- }
+ intersectionErasure(parents)
case AnnotatedType(_, atp, _) =>
apply(atp)
case ClassInfoType(parents, decls, clazz) =>
diff --git a/src/compiler/scala/tools/nsc/transform/TailCalls.scala b/src/compiler/scala/tools/nsc/transform/TailCalls.scala
index d911b22ebc..cf3b2db53b 100644
--- a/src/compiler/scala/tools/nsc/transform/TailCalls.scala
+++ b/src/compiler/scala/tools/nsc/transform/TailCalls.scala
@@ -193,7 +193,7 @@ abstract class TailCalls extends Transform
isTransformed = true
val newThis = newCtx.currentMethod
. newValue (tree.pos, nme.THIS)
- . setInfo (currentClass.tpe)
+ . setInfo (currentClass.typeOfThis)
. setFlag (Flags.SYNTHETIC)
typed(atPos(tree.pos)(Block(
diff --git a/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala b/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala
index 56625cc939..3009873735 100644
--- a/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala
@@ -7,8 +7,10 @@
package scala.tools.nsc
package typechecker
+import scala.tools.nsc.util.Position
+import symtab.Flags._
+
import scala.collection.mutable.ListBuffer
- import symtab.Flags._
/**
* @author Lukas Rytz
@@ -132,10 +134,17 @@ trait NamesDefaults { self: Analyzer =>
case TypeRef(pre, sym, args)
if (!args.forall(a => context.undetparams contains a.typeSymbol)) =>
args.map(TypeTree(_))
- case _ => Nil
+ case _ =>
+ Nil
}
(baseFun, Nil, targsInSource)
+ case Select(TypeApply(New(TypeTree()), targs), _) if isConstr =>
+ val targsInSource =
+ if (targs.forall(a => context.undetparams contains a.symbol)) Nil
+ else targs
+ (baseFun, Nil, targsInSource)
+
case _ => (baseFun, Nil, Nil)
}
@@ -170,28 +179,41 @@ trait NamesDefaults { self: Analyzer =>
b
}
+ def moduleQual(pos: Position, tree: Symbol => Tree) = {
+ val module = baseFun.symbol.owner.linkedModuleOfClass
+ if (module == NoSymbol) None
+ else Some(atPos(pos.focus)(tree(module)))
+ }
+
baseFun1 match {
// constructor calls
case Select(New(TypeTree()), _) if isConstr =>
blockWithoutQualifier(None)
+ case Select(TypeApply(New(TypeTree()), _), _) if isConstr =>
+ blockWithoutQualifier(None)
case Select(New(Ident(_)), _) if isConstr =>
blockWithoutQualifier(None)
+ case Select(TypeApply(New(Ident(_)), _), _) if isConstr =>
+ blockWithoutQualifier(None)
- case Select(nev @ New(sel @ Select(qual, typeName)), constr) if isConstr =>
- // #2057
- val module = baseFun.symbol.owner.linkedModuleOfClass
- val defaultQual =
- if (module == NoSymbol) None
- else Some(atPos(qual.pos.focus)(gen.mkAttributedSelect(qual.duplicate, module)))
+ case Select(New(Select(qual, _)), _) if isConstr =>
// in `new q.C()', q is always stable
assert(treeInfo.isPureExpr(qual), qual)
+ // #2057
+ val defaultQual = moduleQual(qual.pos, mod => gen.mkAttributedSelect(qual.duplicate, mod))
+ blockWithoutQualifier(defaultQual)
+
+ case Select(TypeApply(New(Select(qual, _)), _), _) if isConstr =>
+ assert(treeInfo.isPureExpr(qual), qual)
+ val defaultQual = moduleQual(qual.pos, mod => gen.mkAttributedSelect(qual.duplicate, mod))
blockWithoutQualifier(defaultQual)
// super constructor calls
case Select(Super(_, _), _) if isConstr =>
- blockWithoutQualifier(None)
+ val defaultQual = moduleQual(baseFun.pos, mod => gen.mkAttributedRef(mod))
+ blockWithoutQualifier(defaultQual)
// self constructor calls (in secondary constructors)
case Select(qual, name) if isConstr =>
diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
index 542b2d04c2..c43d9c8788 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
@@ -2474,9 +2474,17 @@ trait Typers { self: Analyzer =>
}
val (unappFormal, freeVars) = freshArgType(unappType)
val context1 = context.makeNewScope(context.tree, context.owner)
- freeVars foreach(sym => context1.scope.enter(sym))
+ freeVars foreach context1.scope.enter
val typer1 = newTyper(context1)
- arg.tpe = typer1.infer.inferTypedPattern(tree.pos, unappFormal, arg.tpe)
+ val pattp = typer1.infer.inferTypedPattern(tree.pos, unappFormal, arg.tpe)
+ // turn any unresolved type variables in freevars into existential skolems
+ val skolems = freeVars map { fv =>
+ val skolem = new TypeSkolem(context1.owner, fun.pos, fv.name, fv)
+ skolem.setInfo(fv.info.cloneInfo(skolem))
+ .setFlag(fv.flags | EXISTENTIAL).resetFlag(PARAM)
+ skolem
+ }
+ arg.tpe = pattp.substSym(freeVars, skolems)
//todo: replace arg with arg.asInstanceOf[inferTypedPattern(unappFormal, arg.tpe)] instead.
argDummy.setInfo(arg.tpe) // bq: this line fixed #1281. w.r.t. comment ^^^, maybe good enough?
}
@@ -2523,25 +2531,10 @@ trait Typers { self: Analyzer =>
if (formals1.length == args.length) {
val args1 = typedArgs(args, mode, formals0, formals1)
if (!isFullyDefined(pt)) assert(false, tree+" ==> "+UnApply(fun1, args1)+", pt = "+pt)
- // <pending-change>
- // this would be a better choice (from #1196), but fails due to (broken?) refinements
val itype = glb(List(pt, arg.tpe))
- // </pending-change>
// restore old type (arg is a dummy tree, just needs to pass typechecking)
arg.tpe = oldArgType
- UnApply(fun1, args1) setPos tree.pos setType itype //pt
- //
- // if you use the better itype, then the following happens.
- // the required type looks wrong...
- //
- ///files/pos/bug0646.scala [FAILED]
- //
- //failed with type mismatch;
- // found : scala.xml.NodeSeq{ ... }
- // required: scala.xml.NodeSeq{ ... } with scala.xml.NodeSeq{ ... } with scala.xml.Node on: temp3._data().==("Blabla").&&({
- // exit(temp0);
- // true
- //})
+ UnApply(fun1, args1) setPos tree.pos setType itype
} else {
errorTree(tree, "wrong number of arguments for "+treeSymTypeMsg(fun))
}
diff --git a/src/library/scala/collection/immutable/List.scala b/src/library/scala/collection/immutable/List.scala
index 9c5984db54..2c36161003 100644
--- a/src/library/scala/collection/immutable/List.scala
+++ b/src/library/scala/collection/immutable/List.scala
@@ -493,7 +493,7 @@ object List extends SeqFactory[List] {
* @param xss the list of lists that are to be concatenated
* @return the concatenation of all the lists
*/
- @deprecated("use `xss.flatten' instead")
+ @deprecated("use `xss.flatten' instead of `List.flatten(xss)'")
def flatten[A](xss: List[List[A]]): List[A] = {
val b = new ListBuffer[A]
for (xs <- xss) {
@@ -511,7 +511,7 @@ object List extends SeqFactory[List] {
* @param xs the list of pairs to unzip
* @return a pair of lists.
*/
- @deprecated("use `xs.unzip' instead")
+ @deprecated("use `xs.unzip' instead of `List.unzip(xs)'")
def unzip[A,B](xs: List[(A,B)]): (List[A], List[B]) = {
val b1 = new ListBuffer[A]
val b2 = new ListBuffer[B]
@@ -529,7 +529,7 @@ object List extends SeqFactory[List] {
* @param xs the iterable of pairs to unzip
* @return a pair of lists.
*/
- @deprecated("use `xs.unzip' instead")
+ @deprecated("use `xs.unzip' instead of `List.unzip(xs)'")
def unzip[A,B](xs: Iterable[(A,B)]): (List[A], List[B]) =
xs.foldRight[(List[A], List[B])]((Nil, Nil)) {
case ((x, y), (xs, ys)) => (x :: xs, y :: ys)
@@ -539,7 +539,7 @@ object List extends SeqFactory[List] {
* Returns the `Left` values in the given `Iterable`
* of `Either`s.
*/
- @deprecated("use `xs partialMap { case Left(x: A) => x }' instead")
+ @deprecated("use `xs partialMap { case Left(x: A) => x }' instead of `List.lefts(xs)'")
def lefts[A, B](es: Iterable[Either[A, B]]) =
es.foldRight[List[A]](Nil)((e, as) => e match {
case Left(a) => a :: as
@@ -549,7 +549,7 @@ object List extends SeqFactory[List] {
/**
* Returns the `Right` values in the given`Iterable` of `Either`s.
*/
- @deprecated("use `xs partialMap { case Right(x: B) => x }' instead")
+ @deprecated("use `xs partialMap { case Right(x: B) => x }' instead of `List.rights(xs)'")
def rights[A, B](es: Iterable[Either[A, B]]) =
es.foldRight[List[B]](Nil)((e, bs) => e match {
case Left(_) => bs
@@ -574,7 +574,7 @@ object List extends SeqFactory[List] {
* @return a list that contains the elements returned by successive
* calls to `it.next`
*/
- @deprecated("use `it.toList' instead")
+ @deprecated("use `it.toList' instead of `List.toList(it)'")
def fromIterator[A](it: Iterator[A]): List[A] = it.toList
/** Converts an array into a list.
@@ -583,7 +583,7 @@ object List extends SeqFactory[List] {
* @return a list that contains the same elements than `arr`
* in the same order
*/
- @deprecated("use `array.toList' instead")
+ @deprecated("use `array.toList' instead of `List.fromArray(array)'")
def fromArray[A](arr: Array[A]): List[A] = fromArray(arr, 0, arr.length)
/** Converts a range of an array into a list.
@@ -594,7 +594,7 @@ object List extends SeqFactory[List] {
* @return a list that contains the same elements than `arr`
* in the same order
*/
- @deprecated("use `array.view(start, end).toList' instead")
+ @deprecated("use `array.view(start, end).toList' instead of `List.fromArray(array, start, end)'")
def fromArray[A](arr: Array[A], start: Int, len: Int): List[A] = {
var res: List[A] = Nil
var i = start + len
@@ -612,7 +612,7 @@ object List extends SeqFactory[List] {
* @param separator the separator character
* @return the list of substrings
*/
- @deprecated("use `str.split(separator).toList' instead")
+ @deprecated("use `str.split(separator).toList' instead of `List.fromString(str, separator)'")
def fromString(str: String, separator: Char): List[String] = {
var words: List[String] = Nil
var pos = str.length()
@@ -630,7 +630,7 @@ object List extends SeqFactory[List] {
* @param xs the list to convert.
* @return the list in form of a string.
*/
- @deprecated("use `xs.mkString' instead")
+ @deprecated("use `xs.mkString' instead of `List.toString(xs)'")
def toString(xs: List[Char]): String = {
val sb = new StringBuilder()
var xc = xs
@@ -644,7 +644,7 @@ object List extends SeqFactory[List] {
/** Like xs map f, but returns `xs` unchanged if function
* `f` maps all elements to themselves.
*/
- @deprecated("use `xs.mapConserve(f)' instead")
+ @deprecated("use `xs.mapConserve(f)' instead of `List.mapConserve(xs, f)'")
def mapConserve[A <: AnyRef](xs: List[A])(f: A => A): List[A] = {
def loop(ys: List[A]): List[A] =
if (ys.isEmpty) xs
@@ -678,7 +678,7 @@ object List extends SeqFactory[List] {
* `[a0, ..., ak]`, `[b0, ..., bl]` and
* `n = min(k,l)`
*/
- @deprecated("use `(xs, ys).zipped.map(f)' instead")
+ @deprecated("use `(xs, ys).zipped.map(f)' instead of `List.map2(xs, ys)(f)'")
def map2[A,B,C](xs: List[A], ys: List[B])(f: (A, B) => C): List[C] = {
val b = new ListBuffer[C]
var xc = xs
@@ -702,7 +702,7 @@ object List extends SeqFactory[List] {
* `[c<sub>0</sub>, ..., c<sub>m</sub>]` and
* `n = min(k,l,m)`
*/
- @deprecated("use `(xs, ys, zs).zipped.map(f)' instead")
+ @deprecated("use `(xs, ys, zs).zipped.map(f)' instead of `List.map3(xs, ys, zs)(f)'")
def map3[A,B,C,D](xs: List[A], ys: List[B], zs: List[C])(f: (A, B, C) => D): List[D] = {
val b = new ListBuffer[D]
var xc = xs
@@ -727,7 +727,7 @@ object List extends SeqFactory[List] {
* `[b<sub>0</sub>, ..., b<sub>l</sub>]`
* and `n = min(k,l)`
*/
- @deprecated("use `(xs, ys).zipped.forall(f)' instead")
+ @deprecated("use `(xs, ys).zipped.forall(f)' instead of `List.forall2(xs, ys)(f)'")
def forall2[A,B](xs: List[A], ys: List[B])(f: (A, B) => Boolean): Boolean = {
var xc = xs
var yc = ys
@@ -749,7 +749,7 @@ object List extends SeqFactory[List] {
* `[b<sub>0</sub>, ..., b<sub>l</sub>]` and
* `n = min(k,l)`
*/
- @deprecated("use `(xs, ys).zipped.exists(f)' instead")
+ @deprecated("use `(xs, ys).zipped.exists(f)' instead of `List.exists2(xs, ys)(f)'")
def exists2[A,B](xs: List[A], ys: List[B])(f: (A, B) => Boolean): Boolean = {
var xc = xs
var yc = ys
@@ -767,7 +767,7 @@ object List extends SeqFactory[List] {
* @param xss the list of lists
* @return the transposed list of lists
*/
- @deprecated("use `xss.transpose' instead")
+ @deprecated("use `xss.transpose' instead of `List.transpose(xss)'")
def transpose[A](xss: List[List[A]]): List[List[A]] = {
val buf = new ListBuffer[List[A]]
var yss = xss
diff --git a/src/library/scala/collection/immutable/Stack.scala b/src/library/scala/collection/immutable/Stack.scala
index a49df4a0aa..a5d7e9515a 100644
--- a/src/library/scala/collection/immutable/Stack.scala
+++ b/src/library/scala/collection/immutable/Stack.scala
@@ -12,17 +12,19 @@
package scala.collection
package immutable
-import scala.annotation.tailrec
+import generic._
+import mutable.{ ArrayBuffer, Builder }
-object Stack {
- val Empty: Stack[Nothing] = new Stack(Nil)
- def apply[A](elems: A*) = new Stack(elems.toList)
+object Stack extends SeqFactory[Stack] {
+ implicit def canBuildFrom[A]: CanBuildFrom[Coll, A, Stack[A]] = new GenericCanBuildFrom[A]
+ def newBuilder[A]: Builder[A, Stack[A]] = new ArrayBuffer[A] mapResult (buf => new Stack(buf.toList))
+
+ @deprecated("Use Stack.empty instead")
+ val Empty: Stack[Nothing] = Stack()
}
/** This class implements immutable stacks using a list-based data
- * structure. Instances of <code>Stack</code> represent
- * empty stacks; they can be either created by calling the constructor
- * directly, or by applying the function <code>Stack.Empty</code>.
+ * structure.
*
* @note This class exists only for historical reason and as an
* analogue of mutable stacks
@@ -33,7 +35,10 @@ object Stack {
* @since 1
*/
@serializable @SerialVersionUID(1976480595012942526L)
-class Stack[+A] protected (protected val elems: List[A]) extends Seq[A] {
+class Stack[+A] protected (protected val elems: List[A]) extends LinearSeq[A]
+ with GenericTraversableTemplate[A, Stack]
+ with LinearSeqLike[A, Stack[A]] {
+ override def companion: GenericCompanion[Stack] = Stack
def this() = this(Nil)
@@ -43,9 +48,8 @@ class Stack[+A] protected (protected val elems: List[A]) extends Seq[A] {
*/
override def isEmpty: Boolean = elems.isEmpty
- /** The number of elements in the stack
- */
- def length: Int = elems.length
+ override def head = elems.head
+ override def tail = new Stack(elems.tail)
/** Push an element on the stack.
*
@@ -90,7 +94,7 @@ class Stack[+A] protected (protected val elems: List[A]) extends Seq[A] {
* @return the top element.
*/
def top: A =
- if (!elems.isEmpty) elems.head
+ if (!isEmpty) elems.head
else throw new NoSuchElementException("top of empty stack")
/** Removes the top element from the stack.
@@ -100,31 +104,14 @@ class Stack[+A] protected (protected val elems: List[A]) extends Seq[A] {
* @return the new stack without the former top element.
*/
def pop: Stack[A] =
- if (!elems.isEmpty) new Stack(elems.tail)
+ if (!isEmpty) new Stack(elems.tail)
else throw new NoSuchElementException("pop of empty stack")
def pop2: (A, Stack[A]) =
- if (!elems.isEmpty) (elems.head, new Stack(elems.tail))
+ if (!isEmpty) (elems.head, new Stack(elems.tail))
else throw new NoSuchElementException("pop of empty stack")
- /** Returns the n-th element of this stack. The bottom element has index
- * 0, elements above are indexed with increasing numbers.
- *
- * @throws Predef.NoSuchElementException
- * @param n the index number.
- * @return the n-th element on the stack.
- */
- def apply(n: Int): A = {
- @tailrec
- def walk(i: Int, xs: List[A]): A =
- (i == 0, xs.isEmpty) match {
- case (_, true) => throw new NoSuchElementException("index out of range")
- case (true, _) => xs.head
- case (false, _) => walk(i - 1, xs.tail)
- }
-
- walk(n, elems)
- }
+ override def reverse: Stack[A] = new Stack(elems.reverse)
/** Returns an iterator over all elements on the stack. The iterator
* issues elements in the reversed order they were inserted into the
@@ -132,23 +119,10 @@ class Stack[+A] protected (protected val elems: List[A]) extends Seq[A] {
*
* @return an iterator over all stack elements.
*/
- override def iterator: Iterator[A] = new Iterator[A] {
- private var cur = Stack.this
- def hasNext: Boolean = !cur.isEmpty
- def next: A = { val r = top; cur = cur.pop; r }
- }
-
- /** Returns the hash code for this stack.
- *
- * @return the hash code of the stack.
- */
- override def hashCode(): Int = //"Stack".hashCode
- if (isEmpty) 0
- else pop2 match { case (x,y) => x.hashCode + y.hashCode }
+ override def iterator: Iterator[A] = elems.iterator
/** Returns a string representation of this stack.
*/
override def toString() = elems.mkString("Stack(", ", ", ")")
-
}
diff --git a/test/files/pos/selftails.scala b/test/files/pos/selftails.scala
new file mode 100644
index 0000000000..a4253b80c7
--- /dev/null
+++ b/test/files/pos/selftails.scala
@@ -0,0 +1,23 @@
+package net.liftweb.util
+
+/**
+* This trait adds functionality to Scala standard types
+*/
+trait BasicTypesHelpers { self: StringHelpers with ControlHelpers =>
+
+ /**
+ * Compare two arrays of Byte for byte equality.
+ * @return true if two Byte arrays contain the same bytes
+ */
+ def isEq(a: Array[Byte], b: Array[Byte]) = {
+ def eq(a: Array[Byte], b: Array[Byte], pos: Int, len: Int): Boolean = {
+ if (pos == len) true
+ else if (a(pos) != b(pos)) false
+ else eq(a , b, pos + 1, len)
+ }
+ a.length == b.length && eq(a, b, 0, a.length)
+ }
+}
+
+trait StringHelpers
+trait ControlHelpers
diff --git a/test/files/run/names-defaults.scala b/test/files/run/names-defaults.scala
index 12176105cd..121ddcb3bc 100644
--- a/test/files/run/names-defaults.scala
+++ b/test/files/run/names-defaults.scala
@@ -283,6 +283,12 @@ object Test extends Application {
val one = t f (x = 1)
}
+ // #2820
+ class Test2820 {
+ class A[T](f: String = "ski!")
+ class C extends A
+ }
+
// DEFINITIONS
def test1(a: Int, b: String) = println(a +": "+ b)
def test2(u: Int, v: Int)(k: String, l: Int) = println(l +": "+ k +", "+ (u + v))
diff --git a/test/files/run/sequenceComparisons.scala b/test/files/run/sequenceComparisons.scala
index e674d55bf7..2b5833aacc 100644
--- a/test/files/run/sequenceComparisons.scala
+++ b/test/files/run/sequenceComparisons.scala
@@ -22,7 +22,7 @@ object Test {
// mutable.Queue(_: _*),
immutable.Seq(_: _*),
mutable.Seq(_: _*),
- // immutable.Stack(_: _*),
+ immutable.Stack(_: _*),
// mutable.Stack(_: _*),
immutable.IndexedSeq(_: _*), // was Vector
//mutable.Vector(_: _*),