diff options
author | Iulian Dragos <jaguarul@gmail.com> | 2009-06-18 17:19:55 +0000 |
---|---|---|
committer | Iulian Dragos <jaguarul@gmail.com> | 2009-06-18 17:19:55 +0000 |
commit | 3ee6b3653f8c25d7d6b19b9f5d4af7fa082146a8 (patch) | |
tree | e97b8c0dd8d61e82f825f528f98842f777621f7a /test | |
parent | be8e3c69114da5bc3020d5363b338b1c83aa22ef (diff) | |
download | scala-3ee6b3653f8c25d7d6b19b9f5d4af7fa082146a8.tar.gz scala-3ee6b3653f8c25d7d6b19b9f5d4af7fa082146a8.tar.bz2 scala-3ee6b3653f8c25d7d6b19b9f5d4af7fa082146a8.zip |
Specialization landed in trunk.
Diffstat (limited to 'test')
41 files changed, 1532 insertions, 0 deletions
diff --git a/test/files/pos/annotations.scala b/test/files/pos/annotations.scala index 5492d89351..d1bd6ba264 100644 --- a/test/files/pos/annotations.scala +++ b/test/files/pos/annotations.scala @@ -1,5 +1,14 @@ class ann(i: Int) extends Annotation +// annotations on abstract types +abstract class C1[@serializable @cloneable +T, U, V[_]] +abstract class C2[@deprecated + @ann(1) T <: Number, + V] +abstract class C3 { + @ann(2) type X <: Number +} + object Test { // bug #1028 @@ -10,6 +19,7 @@ object Test { def c: Int @ann(x) = 1 def d: String @ann({val z = 0; z - 1}) = "2" + def e[@deprecated T, U](x: T) = x //bug #1214 val y = new (Integer @ann(0))(2) diff --git a/test/files/pos/spec-Function1.flags b/test/files/pos/spec-Function1.flags new file mode 100644 index 0000000000..973517e1c9 --- /dev/null +++ b/test/files/pos/spec-Function1.flags @@ -0,0 +1 @@ +-Yspecialize diff --git a/test/files/pos/spec-Function1.scala b/test/files/pos/spec-Function1.scala new file mode 100644 index 0000000000..b749be0ba7 --- /dev/null +++ b/test/files/pos/spec-Function1.scala @@ -0,0 +1,50 @@ + +/* __ *\ +** ________ ___ / / ___ Scala API ** +** / __/ __// _ | / / / _ | (c) 2002-2009, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** +** /____/\___/_/ |_/____/_/ | | ** +** |/ ** +\* */ + +// $Id: Function1.scala 17163 2009-02-20 08:05:31Z dragos $ + +// generated by genprod on Wed Apr 23 10:06:16 CEST 2008 (with fancy comment) (with extra methods) + +package scala + + +/** <p> + * Function with 1 parameters. + * </p> + * <p> + In the following example the definition of + * <code>succ</code> is a shorthand for the anonymous class definition + * <code>anonfun1</code>: + * </p> + * <pre> + * <b>object</b> Main <b>extends</b> Application { + * + * <b>val</b> succ = (x: Int) => x + 1 + * + * <b>val</b> anonfun1 = <b>new</b> Function1[Int, Int] { + * <b>def</b> apply(x: Int): Int = x + 1 + * } + * + * println(succ(0)) + * println(anonfun1(0)) + * }</pre> + */ +trait Function1[@specialized -T1, @specialized +R] extends AnyRef { self => + def apply(v1:T1): R + override def toString() = "<function>" + + /** (f compose g)(x) == f(g(x)) + */ + def compose[A](g: A => T1): A => R = { x => apply(g(x)) } + + /** (f andThen g)(x) == g(f(x)) + */ + def andThen[A](g: R => A): T1 => A = { x => g(apply(x)) } + +} diff --git a/test/files/pos/spec-List.flags b/test/files/pos/spec-List.flags new file mode 100644 index 0000000000..973517e1c9 --- /dev/null +++ b/test/files/pos/spec-List.flags @@ -0,0 +1 @@ +-Yspecialize diff --git a/test/files/pos/spec-List.scala b/test/files/pos/spec-List.scala new file mode 100644 index 0000000000..49658ecf63 --- /dev/null +++ b/test/files/pos/spec-List.scala @@ -0,0 +1,864 @@ +/* __ *\ +** ________ ___ / / ___ Scala API ** +** / __/ __// _ | / / / _ | (c) 2003-2009, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** +** /____/\___/_/ |_/____/_/ | | ** +** |/ ** +\* */ + +// $Id: List.scala 16287 2008-10-18 13:41:36Z nielsen $ + + +package scala.collection.immutable + +import mutable.ListBuffer +import generic._ + +/** A class representing an ordered collection of elements of type + * <code>a</code>. This class comes with two implementing case + * classes <code>scala.Nil</code> and <code>scala.::</code> that + * implement the abstract members <code>isEmpty</code>, + * <code>head</code> and <code>tail</code>. + * + * @author Martin Odersky and others + * @version 2.8 + */ +sealed abstract class List[@specialized +A] extends LinearSequence[A] + with Product + with TraversableClass[A, List] + with LinearSequenceTemplate[A, List[A]] { + override def companion: Companion[List] = List + + import collection.{Iterable, Traversable, Sequence, Vector} + + /** Returns true if the list does not contain any elements. + * @return <code>true</code>, iff the list is empty. + */ + def isEmpty: Boolean + + /** Returns this first element of the list. + * + * @return the first element of this list. + * @throws Predef.NoSuchElementException if the list is empty. + */ + def head: A + + /** Returns this list without its first element. + * + * @return this list without its first element. + * @throws Predef.NoSuchElementException if the list is empty. + */ + def tail: List[A] + + // New methods in List + + /** <p> + * Add an element <code>x</code> at the beginning of this list. + * </p> + * + * @param x the element to prepend. + * @return the list with <code>x</code> added at the beginning. + * @ex <code>1 :: List(2, 3) = List(2, 3).::(1) = List(1, 2, 3)</code> + */ + def ::[@specialized B >: A] (x: B): List[B] = + new scala.collection.immutable.::(x, this) + + /** <p> + * Returns a list resulting from the concatenation of the given + * list <code>prefix</code> and this list. + * </p> + * + * @param prefix the list to concatenate at the beginning of this list. + * @return the concatenation of the two lists. + * @ex <code>List(1, 2) ::: List(3, 4) = List(3, 4).:::(List(1, 2)) = List(1, 2, 3, 4)</code> + */ + def :::[B >: A](prefix: List[B]): List[B] = + if (isEmpty) prefix + else (new ListBuffer[B] ++= prefix).prependToList(this) + + /** Reverse the given prefix and append the current list to that. + * This function is equivalent to an application of <code>reverse</code> + * on the prefix followed by a call to <code>:::</code>, but is more + * efficient. + * + * @param prefix the prefix to reverse and then prepend + * @return the concatenation of the reversed prefix and the current list. + */ + def reverse_:::[B >: A](prefix: List[B]): List[B] = { + var these: List[B] = this + var pres = prefix + while (!pres.isEmpty) { + these = pres.head :: these + pres = pres.tail + } + these + } + + /** Apply a function to all the elements of the list, and return the + * reversed list of results. This is equivalent to a call to <code>map</code> + * followed by a call to <code>reverse</code>, but more efficient. + * !!! should we deprecate this? Why have reverseMap, but not filterMap or reverseFilter, say? + * @param f the function to apply to each elements. + * @return the reversed list of results. + */ + def reverseMap[B](f: A => B): List[B] = { + def loop(l: List[A], res: List[B]): List[B] = l match { + case Nil => res + case head :: tail => loop(tail, f(head) :: res) + } + loop(this, Nil) + } + + /** Like xs map f, but returns <code>xs</code> unchanged if function + * <code>f</code> maps all elements to themselves (wrt ==). + * @note Unlike `map`, `mapConserve` is not tail-recursive. + */ + def mapConserve[B >: A] (f: A => B): List[B] = { + def loop(ys: List[A]): List[B] = + if (ys.isEmpty) this + else { + val head0 = ys.head + val head1 = f(head0) + if (head1 == head0) { + loop(ys.tail) + } else { + val ys1 = head1 :: ys.tail.mapConserve(f) + if (this eq ys) ys1 + else { + val b = new ListBuffer[B] + var xc = this + while (xc ne ys) { + b += xc.head + xc = xc.tail + } + b.prependToList(ys1) + } + } + } + loop(this) + } + + // Overridden methods from IterableTemplate or overloaded variants of such methods + + /** Create a new list which contains all elements of this list + * followed by all elements of Traversable `that' + */ + override def ++[B >: A, That](that: Traversable[B])(implicit bf: BuilderFactory[B, That, List[A]]): That = { + val b = bf(this) + if (b.isInstanceOf[ListBuffer[_]]) (this ::: that.toList).asInstanceOf[That] + else super.++(that) + } + + /** Create a new list which contains all elements of this list + * followed by all elements of Iterator `that' + */ + override def ++[B >: A, That](that: Iterator[B])(implicit bf: BuilderFactory[B, That, List[A]]): That = + this ++ that.toList + + /** Overrides the method in Iterable for efficiency. + * + * @return the list itself + */ + override def toList: List[A] = this + + /** Returns the <code>n</code> first elements of this list, or else the whole + * list, if it has less than <code>n</code> elements. + + * @param n the number of elements to take. + * @return the <code>n</code> first elements of this list. + */ + override def take(n: Int): List[A] = { + val b = new ListBuffer[A] + var i = 0 + var these = this + while (!these.isEmpty && i < n) { + i += 1 + b += these.head + these = these.tail + } + if (these.isEmpty) this + else b.toList + } + + /** Returns the list without its <code>n</code> first elements. + * If this list has less than <code>n</code> elements, the empty list is returned. + * + * @param n the number of elements to drop. + * @return the list without its <code>n</code> first elements. + */ + override def drop(n: Int): List[A] = { + var these = this + var count = n + while (!these.isEmpty && count > 0) { + these = these.tail + count -= 1 + } + these + } + + /** Returns the list with elements belonging to the given index range. + * + * @param start the start position of the list slice. + * @param end the end position (exclusive) of the list slice. + * @return the list with elements belonging to the given index range. + */ + override def slice(start: Int, end: Int): List[A] = { + var len = end + if (start > 0) len -= start + drop(start) take len + } + + /** Returns the rightmost <code>n</code> elements from this list. + * + * @param n the number of elements to take + * @return the suffix of length <code>n</code> of the list + */ + override def takeRight(n: Int): List[A] = { + def loop(lead: List[A], lag: List[A]): List[A] = lead match { + case Nil => lag + case _ :: tail => loop(tail, lag.tail) + } + loop(drop(n), this) + } + + // dropRight is inherited from Stream + + /** Split the list at a given point and return the two parts thus + * created. + * + * @param n the position at which to split + * @return a pair of lists composed of the first <code>n</code> + * elements, and the other elements. + */ + override def splitAt(n: Int): (List[A], List[A]) = { + val b = new ListBuffer[A] + var i = 0 + var these = this + while (!these.isEmpty && i < n) { + i += 1 + b += these.head + these = these.tail + } + (b.toList, these) + } + + /** Returns the longest prefix of this list whose elements satisfy + * the predicate <code>p</code>. + * + * @param p the test predicate. + * @return the longest prefix of this list whose elements satisfy + * the predicate <code>p</code>. + */ + override def takeWhile(p: A => Boolean): List[A] = { + val b = new ListBuffer[A] + var these = this + while (!these.isEmpty && p(these.head)) { + b += these.head + these = these.tail + } + b.toList + } + + /** Returns the longest suffix of this list whose first element + * does not satisfy the predicate <code>p</code>. + * + * @param p the test predicate. + * @return the longest suffix of the list whose first element + * does not satisfy the predicate <code>p</code>. + */ + override def dropWhile(p: A => Boolean): List[A] = + if (isEmpty || !p(head)) this + else tail dropWhile p + + /** Returns the longest prefix of the list whose elements all satisfy + * the given predicate, and the rest of the list. + * + * @param p the test predicate + * @return a pair consisting of the longest prefix of the list whose + * elements all satisfy <code>p</code>, and the rest of the list. + */ + override def span(p: A => Boolean): (List[A], List[A]) = { + val b = new ListBuffer[A] + var these = this + while (!these.isEmpty && p(these.head)) { + b += these.head + these = these.tail + } + (b.toList, these) + } + + /** A list consisting of all elements of this list in reverse order. + */ + override def reverse: List[A] = { + var result: List[A] = Nil + var these = this + while (!these.isEmpty) { + result = these.head :: result + these = these.tail + } + result + } + + override def stringPrefix = "List" + + override def toStream : Stream[A] = + if (isEmpty) Stream.Empty + else new Stream.Cons(head, tail.toStream) + + // !!! todo: work in patch + + /** Computes the difference between this list and the given list + * <code>that</code>. + * + * @param that the list of elements to remove from this list. + * @return this list without the elements of the given list + * <code>that</code>. + */ + @deprecated("use `diff' instead") + def -- [B >: A](that: List[B]): List[B] = { + val b = new ListBuffer[B] + var these = this + while (!these.isEmpty) { + if (!that.contains(these.head)) b += these.head + these = these.tail + } + b.toList + } + + /** Computes the difference between this list and the given object + * <code>x</code>. + * + * @param x the object to remove from this list. + * @return this list without occurrences of the given object + * <code>x</code>. + */ + @deprecated("use `diff' instead") + def - [B >: A](x: B): List[B] = { + val b = new ListBuffer[B] + var these = this + while (!these.isEmpty) { + if (these.head != x) b += these.head + these = these.tail + } + b.toList + } + + /** <p> + * Sort the list according to the comparison function + * <code><(e1: a, e2: a) => Boolean</code>, + * which should be true iff <code>e1</code> is smaller than + * <code>e2</code>. + * !!! todo: move sorting to IterableTemplate + * </p> + * + * @param lt the comparison function + * @return a list sorted according to the comparison function + * <code><(e1: a, e2: a) => Boolean</code>. + * @ex <pre> + * List("Steve", "Tom", "John", "Bob") + * .sort((e1, e2) => (e1 compareTo e2) < 0) = + * List("Bob", "John", "Steve", "Tom")</pre> + */ + @deprecated("use `sortWith' instead") + def sort(lt : (A,A) => Boolean): List[A] = { + /** Merge two already-sorted lists */ + def merge(l1: List[A], l2: List[A]): List[A] = { + val res = new ListBuffer[A] + var left1 = l1 + var left2 = l2 + + while (!left1.isEmpty && !left2.isEmpty) { + if(lt(left1.head, left2.head)) { + res += left1.head + left1 = left1.tail + } else { + res += left2.head + left2 = left2.tail + } + } + + res ++= left1 + res ++= left2 + + res.toList + } + + /** Split a list into two lists of about the same size */ + def split(lst: List[A]) = { + val res1 = new ListBuffer[A] + val res2 = new ListBuffer[A] + var left = lst + + while (!left.isEmpty) { + res1 += left.head + left = left.tail + if (!left.isEmpty) { + res2 += left.head + left = left.tail + } + } + + (res1.toList, res2.toList) + } + + + /** Merge-sort the specified list */ + def ms(lst: List[A]): List[A] = + lst match { + case Nil => lst + case x :: Nil => lst + case x :: y :: Nil => + if (lt(x,y)) + lst + else + y :: x :: Nil + + case lst => + val (l1, l2) = split(lst) + val l1s = ms(l1) + val l2s = ms(l2) + merge(l1s, l2s) + } + + ms(this) + } + +} + +/** The empty list. + * + * @author Martin Odersky + * @version 1.0, 15/07/2003 + */ +@SerialVersionUID(0 - 8256821097970055419L) +case object Nil extends List[Nothing] { + override def isEmpty = true + override def head: Nothing = + throw new NoSuchElementException("head of empty list") + override def tail: List[Nothing] = + throw new NoSuchElementException("tail of empty list") + override def equals(that: Any) = that match { + case that1: Sequence[_] => that1.isEmpty + case _ => false + } +} + +/** A non empty list characterized by a head and a tail. + * + * @author Martin Odersky + * @version 1.0, 15/07/2003 + */ +@SerialVersionUID(0L - 8476791151983527571L) +final case class ::[@specialized B](private var hd: B, private[scala] var tl: List[B]) extends List[B] { + override def head : B = hd + override def tail : List[B] = tl + override def isEmpty: Boolean = false + + import java.io._ + + private def writeObject(out: ObjectOutputStream) { + var xs: List[B] = this + while (!xs.isEmpty) { out.writeObject(xs.head); xs = xs.tail } + out.writeObject(ListSerializeEnd) + } + + private def readObject(in: ObjectInputStream) { + hd = in.readObject.asInstanceOf[B] + assert(hd != ListSerializeEnd) + var current: ::[B] = this + while (true) in.readObject match { + case ListSerializeEnd => + current.tl = Nil + return + case a : Any => + val list : ::[B] = new ::(a.asInstanceOf[B], Nil) + current.tl = list + current = list + } + } +} + +/** This object provides methods for creating specialized lists, and for + * transforming special kinds of lists (e.g. lists of lists). + * + * @author Martin Odersky + * @version 2.8 + */ +object List extends SequenceFactory[List] { + + import collection.{Iterable, Sequence, Vector} + + implicit def builderFactory[A]: BuilderFactory[A, List[A], Coll] = new VirtualBuilderFactory[A] + def newBuilder[A]: Builder[A, List[A]] = new ListBuffer[A] + + override def empty[A]: List[A] = Nil + + override def apply[A](xs: A*): List[A] = xs.toList + + /** Create a sorted list with element values + * <code>v<sub>n+1</sub> = step(v<sub>n</sub>)</code> + * where <code>v<sub>0</sub> = start</code> + * and elements are in the range between <code>start</code> (inclusive) + * and <code>end</code> (exclusive) + * + * @param start the start value of the list + * @param end the end value of the list + * @param step the increment function of the list, which given <code>v<sub>n</sub></code>, + * computes <code>v<sub>n+1</sub></code>. Must be monotonically increasing + * or decreasing. + * @return the sorted list of all integers in range [start;end). + */ + @deprecated("use `iterate' instead") + def range(start: Int, end: Int, step: Int => Int): List[Int] = { + val up = step(start) > start + val down = step(start) < start + val b = new ListBuffer[Int] + var i = start + while ((!up || i < end) && (!down || i > end)) { + b += i + val next = step(i) + if (i == next) + throw new IllegalArgumentException("the step function did not make any progress on "+ i) + i = next + } + b.toList + } + + /** Create a list containing several copies of an element. + * + * @param n the length of the resulting list + * @param elem the element composing the resulting list + * @return a list composed of n elements all equal to elem + */ + @deprecated("use `fill' instead") + def make[A](n: Int, elem: A): List[A] = { + val b = new ListBuffer[A] + var i = 0 + while (i < n) { + b += elem + i += 1 + } + b.toList + } + + /** Concatenate all the elements of a given list of lists. + * + * @param xss the list of lists that are to be concatenated + * @return the concatenation of all the lists + */ + @deprecated("use `xss.flatten' instead") + def flatten[A](xss: List[List[A]]): List[A] = { + val b = new ListBuffer[A] + for (xs <- xss) { + var xc = xs + while (!xc.isEmpty) { + b += xc.head + xc = xc.tail + } + } + b.toList + } + + /** Transforms a list of pairs into a pair of lists. + * + * @param xs the list of pairs to unzip + * @return a pair of lists. + */ + @deprecated("use `xs.unzip' instead") + def unzip[A,B](xs: List[(A,B)]): (List[A], List[B]) = { + val b1 = new ListBuffer[A] + val b2 = new ListBuffer[B] + var xc = xs + while (!xc.isEmpty) { + b1 += xc.head._1 + b2 += xc.head._2 + xc = xc.tail + } + (b1.toList, b2.toList) + } + + /** Transforms an iterable of pairs into a pair of lists. + * + * @param xs the iterable of pairs to unzip + * @return a pair of lists. + */ + @deprecated("use `xs.unzip' instead") + 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) + } + + /** + * Returns the <code>Left</code> values in the given <code>Iterable</code> + * of <code>Either</code>s. + */ + @deprecated("use `Either.lefts' instead") + def lefts[A, B](es: Iterable[Either[A, B]]) = + es.foldRight[List[A]](Nil)((e, as) => e match { + case Left(a) => a :: as + case Right(_) => as + }) + + /** + * Returns the <code>Right</code> values in the given<code>Iterable</code> of <code>Either</code>s. + */ + @deprecated("use `Either.rights' instead") + def rights[A, B](es: Iterable[Either[A, B]]) = + es.foldRight[List[B]](Nil)((e, bs) => e match { + case Left(_) => bs + case Right(b) => b :: bs + }) + + /** Transforms an Iterable of Eithers into a pair of lists. + * + * @param xs the iterable of Eithers to separate + * @return a pair of lists. + */ + @deprecated("use `Either.separate' instead") + def separate[A,B](es: Iterable[Either[A,B]]): (List[A], List[B]) = + es.foldRight[(List[A], List[B])]((Nil, Nil)) { + case (Left(a), (lefts, rights)) => (a :: lefts, rights) + case (Right(b), (lefts, rights)) => (lefts, b :: rights) + } + + /** Converts an iterator to a list. + * + * @param it the iterator to convert + * @return a list that contains the elements returned by successive + * calls to <code>it.next</code> + */ + @deprecated("use `it.toList' instead") + def fromIterator[A](it: Iterator[A]): List[A] = it.toList + + /** Converts an array into a list. + * + * @param arr the array to convert + * @return a list that contains the same elements than <code>arr</code> + * in the same order + */ + @deprecated("use `array.toList' instead") + def fromArray[A](arr: Array[A]): List[A] = fromArray(arr, 0, arr.length) + + /** Converts a range of an array into a list. + * + * @param arr the array to convert + * @param start the first index to consider + * @param len the lenght of the range to convert + * @return a list that contains the same elements than <code>arr</code> + * in the same order + */ + @deprecated("use `array.view(start, end).toList' instead") + def fromArray[A](arr: Array[A], start: Int, len: Int): List[A] = { + var res: List[A] = Nil + var i = start + len + while (i > start) { + i -= 1 + res = arr(i) :: res + } + res + } + + /** Parses a string which contains substrings separated by a + * separator character and returns a list of all substrings. + * + * @param str the string to parse + * @param separator the separator character + * @return the list of substrings + */ + @deprecated("use `str.split(separator).toList' instead") + def fromString(str: String, separator: Char): List[String] = { + var words: List[String] = Nil + var pos = str.length() + while (pos > 0) { + val pos1 = str.lastIndexOf(separator, pos - 1) + if (pos1 + 1 < pos) + words = str.substring(pos1 + 1, pos) :: words + pos = pos1 + } + words + } + + /** Returns the given string as a list of characters. + * + * @param str the string to convert. + * @return the string as a list of characters. + */ + @deprecated("use `str.toList' instead") + def fromString(str: String): List[Char] = str.toList + + /** Returns the given list of characters as a string. + * + * @param xs the list to convert. + * @return the list in form of a string. + */ + @deprecated("use `xs.mkString' instead") + def toString(xs: List[Char]): String = { + val sb = new StringBuilder() + var xc = xs + while (!xc.isEmpty) { + sb.append(xc.head) + xc = xc.tail + } + sb.toString() + } + + /** Like xs map f, but returns <code>xs</code> unchanged if function + * <code>f</code> maps all elements to themselves. + */ + @deprecated("use `xs.mapConserve(f)' instead") + def mapConserve[A <: AnyRef](xs: List[A])(f: A => A): List[A] = { + def loop(ys: List[A]): List[A] = + if (ys.isEmpty) xs + else { + val head0 = ys.head + val head1 = f(head0) + if (head1 eq head0) { + loop(ys.tail) + } else { + val ys1 = head1 :: mapConserve(ys.tail)(f) + if (xs eq ys) ys1 + else { + val b = new ListBuffer[A] + var xc = xs + while (xc ne ys) { + b += xc.head + xc = xc.tail + } + b.prependToList(ys1) + } + } + } + loop(xs) + } + + /** Returns the list resulting from applying the given function <code>f</code> + * to corresponding elements of the argument lists. + * @param f function to apply to each pair of elements. + * @return <code>[f(a0,b0), ..., f(an,bn)]</code> if the lists are + * <code>[a0, ..., ak]</code>, <code>[b0, ..., bl]</code> and + * <code>n = min(k,l)</code> + */ + @deprecated("use `(xs, ys).map(f)' instead") + 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 + var yc = ys + while (!xc.isEmpty && !yc.isEmpty) { + b += f(xc.head, yc.head) + xc = xc.tail + yc = yc.tail + } + b.toList + } + + /** Returns the list resulting from applying the given function + * <code>f</code> to corresponding elements of the argument lists. + * + * @param f function to apply to each pair of elements. + * @return <code>[f(a<sub>0</sub>,b<sub>0</sub>,c<sub>0</sub>), + * ..., f(a<sub>n</sub>,b<sub>n</sub>,c<sub>n</sub>)]</code> + * if the lists are <code>[a<sub>0</sub>, ..., a<sub>k</sub>]</code>, + * <code>[b<sub>0</sub>, ..., b<sub>l</sub>]</code>, + * <code>[c<sub>0</sub>, ..., c<sub>m</sub>]</code> and + * <code>n = min(k,l,m)</code> + */ + @deprecated("use `(xs, ys, zs).map(f)' instead") + 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 + var yc = ys + var zc = zs + while (!xc.isEmpty && !yc.isEmpty && !zc.isEmpty) { + b += f(xc.head, yc.head, zc.head) + xc = xc.tail + yc = yc.tail + zc = zc.tail + } + b.toList + } + + /** Tests whether the given predicate <code>p</code> holds + * for all corresponding elements of the argument lists. + * + * @param p function to apply to each pair of elements. + * @return <code>(p(a<sub>0</sub>,b<sub>0</sub>) && + * ... && p(a<sub>n</sub>,b<sub>n</sub>))]</code> + * if the lists are <code>[a<sub>0</sub>, ..., a<sub>k</sub>]</code>; + * <code>[b<sub>0</sub>, ..., b<sub>l</sub>]</code> + * and <code>n = min(k,l)</code> + */ + @deprecated("use `(xs, ys).forall(f)' instead") + def forall2[A,B](xs: List[A], ys: List[B])(f: (A, B) => Boolean): Boolean = { + var xc = xs + var yc = ys + while (!xc.isEmpty && !yc.isEmpty) { + if (!f(xc.head, yc.head)) return false + xc = xc.tail + yc = yc.tail + } + true + } + + /** Tests whether the given predicate <code>p</code> holds + * for some corresponding elements of the argument lists. + * + * @param p function to apply to each pair of elements. + * @return <code>n != 0 && (p(a<sub>0</sub>,b<sub>0</sub>) || + * ... || p(a<sub>n</sub>,b<sub>n</sub>))]</code> if the lists are + * <code>[a<sub>0</sub>, ..., a<sub>k</sub>]</code>, + * <code>[b<sub>0</sub>, ..., b<sub>l</sub>]</code> and + * <code>n = min(k,l)</code> + */ + @deprecated("use `(xs, ys).exists(f)' instead") + def exists2[A,B](xs: List[A], ys: List[B])(f: (A, B) => Boolean): Boolean = { + var xc = xs + var yc = ys + while (!xc.isEmpty && !yc.isEmpty) { + if (f(xc.head, yc.head)) return true + xc = xc.tail + yc = yc.tail + } + false + } + + /** Transposes a list of lists. + * pre: All element lists have the same length. + * + * @param xss the list of lists + * @return the transposed list of lists + */ + @deprecated("use p`xss.transpose' instead") + def transpose[A](xss: List[List[A]]): List[List[A]] = { + val buf = new ListBuffer[List[A]] + var yss = xss + while (!yss.head.isEmpty) { + buf += (yss map (_.head)) + yss = (yss map (_.tail)) + } + buf.toList + } + + /** Lists with ordered elements are ordered + implicit def list2ordered[a <% Ordered[a]](x: List[a]): Ordered[List[a]] = new Ordered[List[a]] { + def compare [b >: List[a] <% Ordered[b]](y: b): Int = y match { + case y1: List[a] => compareLists(x, y1); + case _ => -(y compare x) + } + private def compareLists(xs: List[a], ys: List[a]): Int = { + if (xs.isEmpty && ys.isEmpty) 0 + else if (xs.isEmpty) -1 + else if (ys.isEmpty) 1 + else { + val s = xs.head compare ys.head; + if (s != 0) s + else compareLists(xs.tail, ys.tail) + } + } + } + */ +} + +/** Only used for list serialization */ +@SerialVersionUID(0L - 8476791151975527571L) +private[scala] case object ListSerializeEnd + diff --git a/test/files/pos/spec-annotations.flags b/test/files/pos/spec-annotations.flags new file mode 100644 index 0000000000..973517e1c9 --- /dev/null +++ b/test/files/pos/spec-annotations.flags @@ -0,0 +1 @@ +-Yspecialize diff --git a/test/files/pos/spec-annotations.scala b/test/files/pos/spec-annotations.scala new file mode 100644 index 0000000000..215f00da50 --- /dev/null +++ b/test/files/pos/spec-annotations.scala @@ -0,0 +1,35 @@ +class ann(i: Int) extends Annotation + +// annotations on abstract types +abstract class C1[@serializable @cloneable +T, U, V[_]] +abstract class C2[@deprecated + @ann(1) T <: Number, + V] +abstract class C3 { + @ann(2) type X <: Number +} + +object Test { + + // bug #1028 + val x = 1 + @ann(x) val a = () + @ann({val y = 2; y}) val b = () + + def c: Int @ann(x) = 1 + def d: String @ann({val z = 0; z - 1}) = "2" + def e[@deprecated T, U](x: T) = x + + //bug #1214 + val y = new (Integer @ann(0))(2) + + import scala.reflect.BeanProperty + + // bug #637 + trait S { def getField(): Int } + class O extends S { @BeanProperty val field = 0 } + + // bug #1070 + trait T { @BeanProperty var field = 1 } +} + diff --git a/test/files/pos/spec-arrays.flags b/test/files/pos/spec-arrays.flags new file mode 100644 index 0000000000..973517e1c9 --- /dev/null +++ b/test/files/pos/spec-arrays.flags @@ -0,0 +1 @@ +-Yspecialize diff --git a/test/files/pos/spec-arrays.scala b/test/files/pos/spec-arrays.scala new file mode 100755 index 0000000000..c1f253a39d --- /dev/null +++ b/test/files/pos/spec-arrays.scala @@ -0,0 +1,214 @@ +abstract class AbsArray[T] { + def apply(idx: Int): T + def update(idx: Int, elem: T) + def length: Int + def applyByte(idx: Int): Byte = apply(idx).asInstanceOf[Byte] + def updateByte(idx: Int, elem: Byte) = update(idx, elem.asInstanceOf[T]) + def applyChar(idx: Int): Char = apply(idx).asInstanceOf[Char] + def updateChar(idx: Int, elem: Char) = update(idx, elem.asInstanceOf[T]) + def applyShort(idx: Int): Short = apply(idx).asInstanceOf[Short] + def updateShort(idx: Int, elem: Short) = update(idx, elem.asInstanceOf[T]) + def applyInt(idx: Int): Int = apply(idx).asInstanceOf[Int] + def updateInt(idx: Int, elem: Int) = update(idx, elem.asInstanceOf[T]) + def applyLong(idx: Int): Long = apply(idx).asInstanceOf[Long] + def updateLong(idx: Int, elem: Long) = update(idx, elem.asInstanceOf[T]) + def applyFloat(idx: Int): Float = apply(idx).asInstanceOf[Float] + def updateFloat(idx: Int, elem: Float) = update(idx, elem.asInstanceOf[T]) + def applyDouble(idx: Int): Double = apply(idx).asInstanceOf[Double] + def updateDouble(idx: Int, elem: Double) = update(idx, elem.asInstanceOf[T]) + def applyBoolean(idx: Int): Boolean = apply(idx).asInstanceOf[Boolean] + def updateBoolean(idx: Int, elem: Boolean) = update(idx, elem.asInstanceOf[T]) + def applyObject(idx: Int): Object = apply(idx).asInstanceOf[Object] + def updateObject(idx: Int, elem: Object) = update(idx, elem.asInstanceOf[T]) +} + +final class IntArray(arr: Array[Int]) extends AbsArray[Int] { + def apply(idx: Int): Int = applyInt(idx) + def update(idx: Int, elem: Int) = updateInt(idx, elem) + override def applyInt(idx: Int): Int = arr(idx) + override def updateInt(idx: Int, elem: Int) = arr(idx) = elem + def length: Int = arr.length +} + +final class GenericArray[T](arr: Array[T]) extends AbsArray[T] { + def apply(idx: Int): T = arr(idx) + def update(idx: Int, elem: T) = arr(idx) = elem + def length: Int = arr.length +} + +class SpecArray[@specialized T](arr: Array[T]) extends AbsArray[T] { + def apply(idx: Int): T = arr(idx) + def update(idx: Int, elem: T) = arr(idx) = elem + def length: Int = arr.length +} + +abstract class Test { + def sum(): Int + def modify(i: Int) + def run() { + var s = 0 + for (i <- 1 to 1000000) { + s += sum() + modify(i) + } + println(s) + } +} + +class ScalaSpecTest extends Test { + val arr = new IntArray(new Array[Int](1000)) + + def sum(): Int = { + var acc = 0 + var i = 0 + while (i < arr.length) { acc = acc + arr.applyInt(i); i += 1 } + acc + } + + def modify(j: Int) = { + val base = j * 100 % 1000 + var i = 0 + while (i < 100) { + arr.updateInt(i + base, arr.applyInt(i + base) + 1) + i += 1 + } + } +} + +class ScalaSpec2Test extends Test { + val arr: AbsArray[Int] = new IntArray(new Array[Int](1000)) + + def sum(): Int = { + var acc = 0 + var i = 0 + while (i < arr.length) { acc = acc + arr.applyInt(i); i += 1 } + acc + } + + def modify(j: Int) = { + val base = j * 100 % 1000 + var i = 0 + while (i < 100) { + arr.updateInt(i + base, arr.applyInt(i + base) + 1) + i += 1 + } + } +} + +class ScalaWrapTest extends Test { + val arr: AbsArray[Int] = new GenericArray(new Array[Int](1000)) + + def sum(): Int = { + var acc = 0 + var i = 0 + while (i < arr.length) { acc = acc + arr.applyInt(i); i += 1 } + acc + } + + def modify(j: Int) = { + val base = j * 100 % 1000 + var i = 0 + while (i < 100) { + arr.updateInt(i + base, arr.applyInt(i + base) + 1) + i += 1 + } + } +} + +class ScalaGenTest extends Test { + val arr: AbsArray[Integer] = new GenericArray(new Array[Integer](1000)) + for (i <- 0 until arr.length) arr(i) = new Integer(0) + + def sum(): Int = { + var acc = 0 + var i = 0 + while (i < arr.length) { acc = acc + arr.apply(i).intValue; i += 1 } + acc + } + + def modify(j: Int) = { + val base = j * 100 % 1000 + var i = 0 + while (i < 100) { + arr.update(i + base, new Integer(arr.apply(i + base).intValue + 1)) + i += 1 + } + } +} + +class JavaTest extends Test { + val arr = new Array[Int](1000) + + def sum(): Int = { + var acc = 0 + var i = 0 + while (i < arr.length) { acc = acc + arr(i); i += 1 } + acc + } + + def modify(j: Int) = { + val base = j * 100 % 1000 + var i = 0 + while (i < 100) { + arr(i + base) += 1 + i += 1 + } + } +} + +/** Specialized array test. */ +class ScalaSpec3Test extends Test { + val arr: SpecArray[Int] = new SpecArray(new Array[Int](1000)) + + def sum(): Int = { + var acc = 0 + var i = 0 + while (i < arr.length) { acc = acc + arr(i); i += 1 } + acc + } + + def modify(j: Int) = { + val base = j * 100 % 1000 + var i = 0 + while (i < 100) { + arr(i + base) = arr(i + base) + 1 + i += 1 + } + } +} + +object TestJava extends scala.testing.Benchmark { + def run() { + (new JavaTest).run() + } +} + +object TestSpec extends scala.testing.Benchmark { + def run() { + (new ScalaSpecTest).run() + } +} + +object TestSpec2 extends scala.testing.Benchmark { + def run() { + (new ScalaSpec2Test).run() + } +} + +object TestGen extends scala.testing.Benchmark { + def run() { + (new ScalaGenTest).run() + } +} + +object TestWrap extends scala.testing.Benchmark { + def run() { + (new ScalaWrapTest).run() + } +} + +object TestSpec3 extends scala.testing.Benchmark { + def run() { + (new ScalaSpec3Test).run() + } +} diff --git a/test/files/pos/spec-cyclic.flags b/test/files/pos/spec-cyclic.flags new file mode 100644 index 0000000000..973517e1c9 --- /dev/null +++ b/test/files/pos/spec-cyclic.flags @@ -0,0 +1 @@ +-Yspecialize diff --git a/test/files/pos/spec-cyclic.scala b/test/files/pos/spec-cyclic.scala new file mode 100644 index 0000000000..65da297989 --- /dev/null +++ b/test/files/pos/spec-cyclic.scala @@ -0,0 +1,33 @@ +trait AbsFun[@specialized -A, @specialized +B] { + def apply(x: A): B +} + +trait MyPartialFunction[-A, +B] extends AnyRef with AbsFun[A, B] + +trait ColMap[A, +B] extends MyPartialFunction[A, B] /*with Collection[(A, B)] */ + +trait ColSorted[K,+A] extends ColRanged[K,A] + +trait ColSortedMap[K,+E] extends ColMap[K,E] with ColSorted[K,Tuple2[K,E]] + +trait MutMap[A, B] extends AnyRef + with ColMap[A, B] + +trait ColRanged[K, +A] //extends Iterable[A] + +trait JclRanged[K,A] extends ColRanged[K,A] //with MutableIterable[A] { + +trait JclMap[K,E] extends /*collection.jcl.MutableIterable[Tuple2[K,E]] with*/ MutMap[K,E] + +trait JclSorted[K,A] extends ColSorted[K,A] with JclRanged[K,A] + +trait JclSortedMap[K,E] extends ColSortedMap[K,E] with JclMap[K,E] with JclSorted[K,Tuple2[K,E]] + +class Foo[A, B] extends JclSortedMap[A, B] { + def apply(x: A): B = error("NYI") +} + +class Bar { + val x: Foo[Int, Int] = new Foo[Int, Int] + x.apply(0) +} diff --git a/test/files/pos/spec-example1.flags b/test/files/pos/spec-example1.flags new file mode 100644 index 0000000000..973517e1c9 --- /dev/null +++ b/test/files/pos/spec-example1.flags @@ -0,0 +1 @@ +-Yspecialize diff --git a/test/files/pos/spec-example1.scala b/test/files/pos/spec-example1.scala new file mode 100644 index 0000000000..870c0ed9b9 --- /dev/null +++ b/test/files/pos/spec-example1.scala @@ -0,0 +1,17 @@ +abstract class C[@specialized T](_f: T) { + def m(x: T): T + def n(x: T): T = x + + val f: T = _f +/* + class Inner[@specialized B] { + def foo(x: T): T = x + } + + new Inner +*/ +} + +class D extends C[Int](0) { + def m(x: Int): Int = x * x +} diff --git a/test/files/pos/spec-fields.flags b/test/files/pos/spec-fields.flags new file mode 100644 index 0000000000..973517e1c9 --- /dev/null +++ b/test/files/pos/spec-fields.flags @@ -0,0 +1 @@ +-Yspecialize diff --git a/test/files/pos/spec-fields.scala b/test/files/pos/spec-fields.scala new file mode 100644 index 0000000000..e78c2dead3 --- /dev/null +++ b/test/files/pos/spec-fields.scala @@ -0,0 +1,10 @@ +abstract class Foo[@specialized T, U <: Ordered[U]](x: T, size: Int) { + var y: T + var z: T = x + + def initialSize = 16 + val array = new Array[T](initialSize + size) + + def getZ = z + def setZ(zz: T) = z = zz +} diff --git a/test/files/pos/spec-foo.flags b/test/files/pos/spec-foo.flags new file mode 100644 index 0000000000..973517e1c9 --- /dev/null +++ b/test/files/pos/spec-foo.flags @@ -0,0 +1 @@ +-Yspecialize diff --git a/test/files/pos/spec-foo.scala b/test/files/pos/spec-foo.scala new file mode 100644 index 0000000000..aabe0d51e1 --- /dev/null +++ b/test/files/pos/spec-foo.scala @@ -0,0 +1,4 @@ +class Foo { + val xs = List(1, 2) + 1 :: xs +} diff --git a/test/files/pos/spec-funs.flags b/test/files/pos/spec-funs.flags new file mode 100644 index 0000000000..973517e1c9 --- /dev/null +++ b/test/files/pos/spec-funs.flags @@ -0,0 +1 @@ +-Yspecialize diff --git a/test/files/pos/spec-funs.scala b/test/files/pos/spec-funs.scala new file mode 100644 index 0000000000..5fea5e9560 --- /dev/null +++ b/test/files/pos/spec-funs.scala @@ -0,0 +1,63 @@ +trait AbsFunction1[@specialized -T, @specialized +U] { + def apply(x: T): U +} + +final class IntTest { + + val niters = 10000 + + def transF(xs: Array[Int], f: AbsFunction1[Int, Int]) = { + var i = 0 + var s = 0 + while (i < xs.length) { + xs(i) = f(xs(i)) + 1 + i += 1 + } + } + + def run() { + val xs = new Array[Int](10000) + val f = new AbsFunction1[Int, Int] { + def apply(x: Int): Int = x * x + } + for (j <- 0 until niters) { + transF(xs, f) + } + var acc = 0 + for (i <- 0 until xs.length) acc += xs(i) + println(acc) + } +} + +final class ClosureTest { + + val niters = 10000 + + def transF(xs: Array[Int], f: Int => Int) = { + var i = 0 + var s = 0 + while (i < xs.length) { + xs(i) = f.apply(xs(i)) + 1 + i += 1 + } + } + + def run() { + val xs = new Array[Int](10000) +// val f = (x: Int) => x * x + for (j <- 0 until niters) { + transF(xs, x => x * x) + } + var acc = 0 + for (i <- 0 until xs.length) acc += xs(i) + println(acc) + } +} + +object TestInt extends testing.Benchmark { + def run() = (new IntTest).run() +} + +object TestClosure extends testing.Benchmark { + def run() = (new ClosureTest).run() +} diff --git a/test/files/pos/spec-lists.flags b/test/files/pos/spec-lists.flags new file mode 100644 index 0000000000..973517e1c9 --- /dev/null +++ b/test/files/pos/spec-lists.flags @@ -0,0 +1 @@ +-Yspecialize diff --git a/test/files/pos/spec-lists.scala b/test/files/pos/spec-lists.scala new file mode 100644 index 0000000000..01416da95e --- /dev/null +++ b/test/files/pos/spec-lists.scala @@ -0,0 +1,6 @@ +object Main extends Application { + + val xs = 1 :: 2 :: 3 :: 4 :: 5 :: Nil + + println(xs) +} diff --git a/test/files/pos/spec-localdefs.flags b/test/files/pos/spec-localdefs.flags new file mode 100644 index 0000000000..973517e1c9 --- /dev/null +++ b/test/files/pos/spec-localdefs.flags @@ -0,0 +1 @@ +-Yspecialize diff --git a/test/files/pos/spec-localdefs.scala b/test/files/pos/spec-localdefs.scala new file mode 100644 index 0000000000..2df500e20b --- /dev/null +++ b/test/files/pos/spec-localdefs.scala @@ -0,0 +1,7 @@ +class Foo[@specialized T] { + def foo(x: T) = { + class Bar + x.asInstanceOf[List[Bar]] + x.asInstanceOf[Bar] + } +} diff --git a/test/files/pos/spec-maps.flags b/test/files/pos/spec-maps.flags new file mode 100644 index 0000000000..973517e1c9 --- /dev/null +++ b/test/files/pos/spec-maps.flags @@ -0,0 +1 @@ +-Yspecialize diff --git a/test/files/pos/spec-maps.scala b/test/files/pos/spec-maps.scala new file mode 100644 index 0000000000..fe214c9580 --- /dev/null +++ b/test/files/pos/spec-maps.scala @@ -0,0 +1,10 @@ +trait Fun1[@specialized +R, @specialized -T] { + def apply(x: T): R +} + +object Main { + def mapA[@specialized B](xs: Array[B], f: Fun1[B, B]) { + for (i <- 0 until xs.length) + xs(i) = f(xs(i)) + } +} diff --git a/test/files/pos/spec-params.flags b/test/files/pos/spec-params.flags new file mode 100644 index 0000000000..973517e1c9 --- /dev/null +++ b/test/files/pos/spec-params.flags @@ -0,0 +1 @@ +-Yspecialize diff --git a/test/files/pos/spec-params.scala b/test/files/pos/spec-params.scala new file mode 100644 index 0000000000..231ef8a83e --- /dev/null +++ b/test/files/pos/spec-params.scala @@ -0,0 +1,32 @@ +class Foo[@specialized A] { + + // conflicting in bounds, expect a normalized member calling m + // and bridge + implementation in specialized subclasses + // and overloads here according to specialization on A + def m1[@specialized B <: A](x: B, y: A) = + goal(x) + + // conflicting, unsolvable, expect a warning + def m2[@specialized B <: String](x: B) = x.concat("a") + + // conflicting in bounds, no mention of other spec members + // expect an overload here plus implementation in + // compatible specialized subclasses + def m3[@specialized B >: A](x: B) = () + + // non-conflicting, expect a normalized overload implementation here + def m4[@specialized T, U <: Ordered[T]](x: T, y: U) = () + + // non-conflicting, expect a normalized overload implementation here + def m5[@specialized B](x: B) = x + + // non-conflicting, expect a normalized implementation here + // and specialized implementations for all expansions in specialized subclasses + def m6[@specialized B](x: B, y: A) = + goal(y) + + def goal(x: A) = { + val xs = new Array[A](1) + xs(0) = x + } +} diff --git a/test/files/pos/spec-polymeth.flags b/test/files/pos/spec-polymeth.flags new file mode 100644 index 0000000000..973517e1c9 --- /dev/null +++ b/test/files/pos/spec-polymeth.flags @@ -0,0 +1 @@ +-Yspecialize diff --git a/test/files/pos/spec-polymeth.scala b/test/files/pos/spec-polymeth.scala new file mode 100644 index 0000000000..df2f460fd4 --- /dev/null +++ b/test/files/pos/spec-polymeth.scala @@ -0,0 +1,8 @@ +abstract class AbsFun[@specialized R] { +// def andThen[B](x: B): B + + def compose[A](x: A, y: R): A = { + val y: A = x + x + } +} diff --git a/test/files/pos/spec-sealed.flags b/test/files/pos/spec-sealed.flags new file mode 100644 index 0000000000..973517e1c9 --- /dev/null +++ b/test/files/pos/spec-sealed.flags @@ -0,0 +1 @@ +-Yspecialize diff --git a/test/files/pos/spec-sealed.scala b/test/files/pos/spec-sealed.scala new file mode 100644 index 0000000000..8c06148d3e --- /dev/null +++ b/test/files/pos/spec-sealed.scala @@ -0,0 +1,32 @@ +sealed abstract class MyList[@specialized +A] { + def head: A + def tail: MyList[A] + + def ::[@specialized B >: A](x: B): MyList[B] = + new Cons[B](x, this) +} + +case object MyNil extends MyList[Nothing] { + def head = error("nil") + def tail = error("nil") +} + +case class Cons[@specialized a](private val hd: a, tl: MyList[a]) extends MyList[a] { + def head = hd + def tail = tl +} + +abstract class IntList extends MyList[Int] + +object Main extends Application { + val xs = 1 :: 2 :: 3 :: MyNil + println(xs) +} + +/* +final class ConsI(hd1: Int, tl1: MyList[Int]) extends Cons[Int](hd1, tl1) { + override val hd = hd1 + override val tl = tl1 +} +*/ +//class IntCons(_hd: Int, _tl: MyList[Int]) extends Cons[Int](_hd, _tl) diff --git a/test/files/pos/spec-short.flags b/test/files/pos/spec-short.flags new file mode 100644 index 0000000000..973517e1c9 --- /dev/null +++ b/test/files/pos/spec-short.flags @@ -0,0 +1 @@ +-Yspecialize diff --git a/test/files/pos/spec-short.scala b/test/files/pos/spec-short.scala new file mode 100644 index 0000000000..71e56a485a --- /dev/null +++ b/test/files/pos/spec-short.scala @@ -0,0 +1,26 @@ +abstract class AbsFun[@specialized T, @specialized U] { + // abstract function, fully specialized + def apply(x: T): U + + // abstract function, specialized + def sum(xs: List[T]): Int + + def prod(xs: List[T], mul: (Int, T) => Int): Int = + (1 /: xs)(mul) + + // concrete function, not specialized + def bar(m: String): String = m + + // abstract function, not specialized + def abs(m: Int): Int +} + +class Square extends AbsFun[Int, Int] { + def apply(x: Int): Int = x * x + + def sum(xs: List[Int]): Int = + (0 /: xs) (_ + _) + + def abs(m: Int): Int = + sum(List(1, 2, 3)) +} diff --git a/test/files/pos/spec-simple.flags b/test/files/pos/spec-simple.flags new file mode 100644 index 0000000000..973517e1c9 --- /dev/null +++ b/test/files/pos/spec-simple.flags @@ -0,0 +1 @@ +-Yspecialize diff --git a/test/files/pos/spec-simple.scala b/test/files/pos/spec-simple.scala new file mode 100644 index 0000000000..66a48d155e --- /dev/null +++ b/test/files/pos/spec-simple.scala @@ -0,0 +1,51 @@ +class Foo[@specialized T] { + var v: T = _ + + def foo(x: T): T = x + + println("abc") + + class Bar[@specialized U] { + def bar(x: U): T = v +// def barInt(x: Int): T = bar(x.asInstanceOf[U]) + } +} + +class Test { + def test { + val a = new Foo[Int] + val b = new a.Bar[Int] + a.foo(10) + b.bar(11) + } +} + +/* +abstract class Foo[@specialized T] { + def foo(x: T): T + def foo$Int(x: Int): Int + + abstract class Bar[@specialized U] { + def bar(x: U): T + def bar$Int(x: Int): T + } + abstract class Bar$Int extends Bar[Int] { + def bar(x: Int): T = bar$Int(x) + def bar$Int(x: Int): T + } +} + +abstract class Foo$Int extends Foo[Int] { + def foo(x: Int): Int = foo$Int(x) + def foo$Int(x: Int): Int + + abstract class Bar[@specialized U] { + def bar(x: U): Int + def bar$Int(x: Int): Int + } + abstract class Bar$Int extends Bar[Int] { + def bar(x: Int): Int = bar$Int(x) + def bar$Int(x: Int): Int + } +} +*/ diff --git a/test/files/pos/spec-super.flags b/test/files/pos/spec-super.flags new file mode 100644 index 0000000000..973517e1c9 --- /dev/null +++ b/test/files/pos/spec-super.flags @@ -0,0 +1 @@ +-Yspecialize diff --git a/test/files/pos/spec-super.scala b/test/files/pos/spec-super.scala new file mode 100644 index 0000000000..e06a126aa4 --- /dev/null +++ b/test/files/pos/spec-super.scala @@ -0,0 +1,20 @@ +import scala.collection.immutable._ +import scala.collection.mutable.ListBuffer +import scala.collection.generic._ + +trait Base[+A] extends Traversable[A] { + def add[B >: A, That](that: Traversable[B])(implicit bf: BuilderFactory[B, That, Base[A]]): That = { + val b = bf(this) + b ++= this + b ++= that + b.result + } + +} + +abstract class Derived[@specialized +A] extends Base[A] { + override def add[B >: A, That](that: Traversable[B])(implicit bf: BuilderFactory[B, That, Base[A]]): That = { + val b = bf(this) + super.add[B, That](that) + } +} diff --git a/test/files/pos/spec-tailcall.flags b/test/files/pos/spec-tailcall.flags new file mode 100644 index 0000000000..973517e1c9 --- /dev/null +++ b/test/files/pos/spec-tailcall.flags @@ -0,0 +1 @@ +-Yspecialize diff --git a/test/files/pos/spec-tailcall.scala b/test/files/pos/spec-tailcall.scala new file mode 100644 index 0000000000..703ec011ad --- /dev/null +++ b/test/files/pos/spec-tailcall.scala @@ -0,0 +1,17 @@ +class TailCall[@specialized T] { + final def dropLeft(n: Int, xs: List[T]): List[T] = + if (n == 0) xs + else dropLeft(n - 1, xs.tail) +/* + def filter(pf: PartialFunction[Option[String], Boolean]) = null + + def crash(o: Option[String]) = filter { + case None if { + def dropLeft[T](n: Int, xs: List[T]): List[T] = + if (n == 0) xs + else dropLeft(n - 1, xs.tail) + dropLeft(2, List(1, 2, 3)).isEmpty + } => true + } +*/ +} diff --git a/test/files/pos/spec-thistype.flags b/test/files/pos/spec-thistype.flags new file mode 100644 index 0000000000..973517e1c9 --- /dev/null +++ b/test/files/pos/spec-thistype.flags @@ -0,0 +1 @@ +-Yspecialize diff --git a/test/files/pos/spec-thistype.scala b/test/files/pos/spec-thistype.scala new file mode 100644 index 0000000000..52b2bf34b4 --- /dev/null +++ b/test/files/pos/spec-thistype.scala @@ -0,0 +1,3 @@ +class Foo[@specialized A] { + def bar(xs: List[A]): this.type = this +} |