diff options
author | Antonio Cunei <antonio.cunei@epfl.ch> | 2009-12-21 15:35:16 +0000 |
---|---|---|
committer | Antonio Cunei <antonio.cunei@epfl.ch> | 2009-12-21 15:35:16 +0000 |
commit | d3e129a5fb36030d3a05ee59ccf353095125d622 (patch) | |
tree | f92ff3325831065b86de67d504a8da792c16c430 | |
parent | 2ab456d13df1ac50539e4620f62f6e234f3c8446 (diff) | |
download | scala-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.scala | 86 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/symtab/Types.scala | 6 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/transform/Erasure.scala | 30 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/transform/TailCalls.scala | 2 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala | 40 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/typechecker/Typers.scala | 29 | ||||
-rw-r--r-- | src/library/scala/collection/immutable/List.scala | 32 | ||||
-rw-r--r-- | src/library/scala/collection/immutable/Stack.scala | 66 | ||||
-rw-r--r-- | test/files/pos/selftails.scala | 23 | ||||
-rw-r--r-- | test/files/run/names-defaults.scala | 6 | ||||
-rw-r--r-- | test/files/run/sequenceComparisons.scala | 2 |
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(_: _*), |