summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/compiler/scala/reflect/internal/Trees.scala14
-rw-r--r--src/compiler/scala/reflect/internal/Types.scala17
-rw-r--r--src/compiler/scala/tools/nsc/Global.scala6
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Implicits.scala4
-rw-r--r--src/library/scala/collection/Map.scala2
-rw-r--r--src/library/scala/collection/MapLike.scala4
-rw-r--r--src/library/scala/collection/mutable/Builder.scala2
-rw-r--r--src/library/scala/collection/mutable/HashTable.scala2
-rw-r--r--src/library/scala/collection/mutable/LinkedHashMap.scala8
-rw-r--r--src/library/scala/util/parsing/combinator/Parsers.scala6
-rw-r--r--test/files/buildmanager/t2556_3/t2556_3.check4
-rw-r--r--test/files/neg/logImplicits.check8
-rw-r--r--test/files/neg/t963.check12
-rw-r--r--test/files/neg/t963.scala18
-rw-r--r--test/files/run/nonlocalreturn.check1
-rw-r--r--test/files/run/nonlocalreturn.scala15
-rw-r--r--test/files/run/t5018.scala (renamed from test/pending/run/t5018.scala)5
-rw-r--r--test/files/run/t5514.check19
-rw-r--r--test/files/run/t5514.scala (renamed from test/pending/run/t5514.scala)22
-rw-r--r--test/files/run/t5577.check11
-rw-r--r--test/files/run/t5577.scala27
-rw-r--r--test/files/run/t5590.check4
-rw-r--r--test/files/run/t5590.scala31
-rw-r--r--test/files/run/t5612.check4
-rw-r--r--test/files/run/t5612.scala28
25 files changed, 235 insertions, 39 deletions
diff --git a/src/compiler/scala/reflect/internal/Trees.scala b/src/compiler/scala/reflect/internal/Trees.scala
index 5f1a8f3fbe..c43528b8e9 100644
--- a/src/compiler/scala/reflect/internal/Trees.scala
+++ b/src/compiler/scala/reflect/internal/Trees.scala
@@ -315,11 +315,19 @@ trait Trees extends api.Trees { self: SymbolTable =>
class ChangeOwnerTraverser(val oldowner: Symbol, val newowner: Symbol) extends Traverser {
def changeOwner(tree: Tree) = tree match {
case Return(expr) =>
- if (tree.symbol == oldowner)
- tree.symbol = newowner
+ if (tree.symbol == oldowner) {
+ // SI-5612
+ if (newowner hasTransOwner oldowner)
+ log("NOT changing owner of %s because %s is nested in %s".format(tree, newowner, oldowner))
+ else {
+ log("changing owner of %s: %s => %s".format(tree, oldowner, newowner))
+ tree.symbol = newowner
+ }
+ }
case _: DefTree | _: Function =>
- if (tree.symbol != NoSymbol && tree.symbol.owner == oldowner)
+ if (tree.symbol != NoSymbol && tree.symbol.owner == oldowner) {
tree.symbol.owner = newowner
+ }
case _ =>
}
override def traverse(tree: Tree) {
diff --git a/src/compiler/scala/reflect/internal/Types.scala b/src/compiler/scala/reflect/internal/Types.scala
index 66657c4412..09e7303b90 100644
--- a/src/compiler/scala/reflect/internal/Types.scala
+++ b/src/compiler/scala/reflect/internal/Types.scala
@@ -5719,14 +5719,15 @@ trait Types extends api.Types { self: SymbolTable =>
val info1 = tp1.memberInfo(sym1)
val info2 = tp2.memberInfo(sym2).substThis(tp2.typeSymbol, tp1)
//System.out.println("specializes "+tp1+"."+sym1+":"+info1+sym1.locationString+" AND "+tp2+"."+sym2+":"+info2)//DEBUG
- sym2.isTerm && (info1 <:< info2) /*&& (!sym2.isStable || sym1.isStable) */ ||
- sym2.isAbstractType && {
- val memberTp1 = tp1.memberType(sym1)
- // println("kinds conform? "+(memberTp1, tp1, sym2, kindsConform(List(sym2), List(memberTp1), tp2, sym2.owner)))
- info2.bounds.containsType(memberTp1) &&
- kindsConform(List(sym2), List(memberTp1), tp1, sym1.owner)
- } ||
- sym2.isAliasType && tp2.memberType(sym2).substThis(tp2.typeSymbol, tp1) =:= tp1.memberType(sym1) //@MAT ok
+ ( sym2.isTerm && (info1 <:< info2) && (!sym2.isStable || sym1.isStable)
+ || sym2.isAbstractType && {
+ val memberTp1 = tp1.memberType(sym1)
+ // println("kinds conform? "+(memberTp1, tp1, sym2, kindsConform(List(sym2), List(memberTp1), tp2, sym2.owner)))
+ info2.bounds.containsType(memberTp1) &&
+ kindsConform(List(sym2), List(memberTp1), tp1, sym1.owner)
+ }
+ || sym2.isAliasType && tp2.memberType(sym2).substThis(tp2.typeSymbol, tp1) =:= tp1.memberType(sym1) //@MAT ok
+ )
}
/** A function implementing `tp1` matches `tp2`. */
diff --git a/src/compiler/scala/tools/nsc/Global.scala b/src/compiler/scala/tools/nsc/Global.scala
index e4cfad53c7..dfab703843 100644
--- a/src/compiler/scala/tools/nsc/Global.scala
+++ b/src/compiler/scala/tools/nsc/Global.scala
@@ -464,13 +464,15 @@ class Global(var currentSettings: Settings, var reporter: Reporter) extends Symb
object patmat extends {
val global: Global.this.type = Global.this
val runsAfter = List("typer")
- val runsRightAfter = Some("typer")
+ // patmat doesn't need to be right after typer, as long as we run before supperaccesors
+ // (sbt does need to run right after typer, so don't conflict)
+ val runsRightAfter = None
} with PatternMatching
// phaseName = "superaccessors"
object superAccessors extends {
val global: Global.this.type = Global.this
- val runsAfter = List("typer")
+ val runsAfter = List("patmat")
val runsRightAfter = None
} with SuperAccessors
diff --git a/src/compiler/scala/tools/nsc/typechecker/Implicits.scala b/src/compiler/scala/tools/nsc/typechecker/Implicits.scala
index 0d7ef71193..787d7af136 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Implicits.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Implicits.scala
@@ -214,13 +214,13 @@ trait Implicits {
override def hashCode = 1
}
- /** A constructor for types ?{ name: tp }, used in infer view to member
+ /** A constructor for types ?{ def/type name: tp }, used in infer view to member
* searches.
*/
def memberWildcardType(name: Name, tp: Type) = {
val result = refinedType(List(WildcardType), NoSymbol)
name match {
- case x: TermName => result.typeSymbol.newValue(x) setInfoAndEnter tp
+ case x: TermName => result.typeSymbol.newMethod(x) setInfoAndEnter tp
case x: TypeName => result.typeSymbol.newAbstractType(x) setInfoAndEnter tp
}
result
diff --git a/src/library/scala/collection/Map.scala b/src/library/scala/collection/Map.scala
index a124e60c96..42a56a9c5a 100644
--- a/src/library/scala/collection/Map.scala
+++ b/src/library/scala/collection/Map.scala
@@ -45,7 +45,7 @@ object Map extends MapFactory[Map] {
/** An abstract shell used by { mutable, immutable }.Map but not by collection.Map
* because of variance issues.
*/
- abstract class WithDefault[A, +B](underlying: Map[A, B], d: A => B) extends AbstractMap[A, B] with Map[A, B] {
+ abstract class WithDefault[A, +B](underlying: Map[A, B], d: A => B) extends AbstractMap[A, B] with Map[A, B] with Serializable {
override def size = underlying.size
def get(key: A) = underlying.get(key) // removed in 2.9: orElse Some(default(key))
def iterator = underlying.iterator
diff --git a/src/library/scala/collection/MapLike.scala b/src/library/scala/collection/MapLike.scala
index 034c1a0c0c..b2b687e75a 100644
--- a/src/library/scala/collection/MapLike.scala
+++ b/src/library/scala/collection/MapLike.scala
@@ -165,7 +165,7 @@ self =>
/** The implementation class of the set returned by `keySet`.
*/
- protected class DefaultKeySet extends AbstractSet[A] with Set[A] {
+ protected class DefaultKeySet extends AbstractSet[A] with Set[A] with Serializable {
def contains(key : A) = self.contains(key)
def iterator = keysIterator
def + (elem: A): Set[A] = (Set[A]() ++ this + elem).asInstanceOf[Set[A]] // !!! concrete overrides abstract problem
@@ -200,7 +200,7 @@ self =>
/** The implementation class of the iterable returned by `values`.
*/
- protected class DefaultValuesIterable extends AbstractIterable[B] with Iterable[B] {
+ protected class DefaultValuesIterable extends AbstractIterable[B] with Iterable[B] with Serializable {
def iterator = valuesIterator
override def size = self.size
override def foreach[C](f: B => C) = self.valuesIterator foreach f
diff --git a/src/library/scala/collection/mutable/Builder.scala b/src/library/scala/collection/mutable/Builder.scala
index 44cc1c8582..bbf4f5889d 100644
--- a/src/library/scala/collection/mutable/Builder.scala
+++ b/src/library/scala/collection/mutable/Builder.scala
@@ -100,6 +100,8 @@ trait Builder[-Elem, +To] extends Growable[Elem] {
def +=(x: Elem): this.type = { self += x; this }
def clear() = self.clear()
override def ++=(xs: TraversableOnce[Elem]): this.type = { self ++= xs; this }
+ override def sizeHint(size: Int) = self.sizeHint(size)
+ override def sizeHintBounded(size: Int, boundColl: TraversableLike[_, _]) = self.sizeHintBounded(size, boundColl)
def result: NewTo = f(self.result)
}
}
diff --git a/src/library/scala/collection/mutable/HashTable.scala b/src/library/scala/collection/mutable/HashTable.scala
index 06b7d40bfc..a2f78dbde9 100644
--- a/src/library/scala/collection/mutable/HashTable.scala
+++ b/src/library/scala/collection/mutable/HashTable.scala
@@ -187,7 +187,7 @@ trait HashTable[A, Entry >: Null <: HashEntry[A, Entry]] extends HashTable.HashU
}
/** Avoid iterator for a 2x faster traversal. */
- protected final def foreachEntry[C](f: Entry => C) {
+ protected def foreachEntry[C](f: Entry => C) {
val iterTable = table
var idx = lastPopulatedIndex
var es = iterTable(idx)
diff --git a/src/library/scala/collection/mutable/LinkedHashMap.scala b/src/library/scala/collection/mutable/LinkedHashMap.scala
index cd174523b1..4150cf9eba 100644
--- a/src/library/scala/collection/mutable/LinkedHashMap.scala
+++ b/src/library/scala/collection/mutable/LinkedHashMap.scala
@@ -132,6 +132,14 @@ class LinkedHashMap[A, B] extends AbstractMap[A, B]
}
}
+ protected override def foreachEntry[C](f: Entry => C) {
+ var cur = firstEntry
+ while (cur ne null) {
+ f(cur)
+ cur = cur.later
+ }
+ }
+
override def clear() {
clearTable()
firstEntry = null
diff --git a/src/library/scala/util/parsing/combinator/Parsers.scala b/src/library/scala/util/parsing/combinator/Parsers.scala
index e5458f89af..17e032e7ab 100644
--- a/src/library/scala/util/parsing/combinator/Parsers.scala
+++ b/src/library/scala/util/parsing/combinator/Parsers.scala
@@ -596,7 +596,8 @@ trait Parsers {
* @return A parser for elements satisfying p(e).
*/
def acceptIf(p: Elem => Boolean)(err: Elem => String): Parser[Elem] = Parser { in =>
- if (p(in.first)) Success(in.first, in.rest)
+ if (in.atEnd) Failure("end of input", in)
+ else if (p(in.first)) Success(in.first, in.rest)
else Failure(err(in.first), in)
}
@@ -614,7 +615,8 @@ trait Parsers {
* applying `f` to it to produce the result.
*/
def acceptMatch[U](expected: String, f: PartialFunction[Elem, U]): Parser[U] = Parser{ in =>
- if (f.isDefinedAt(in.first)) Success(f(in.first), in.rest)
+ if (in.atEnd) Failure("end of input", in)
+ else if (f.isDefinedAt(in.first)) Success(f(in.first), in.rest)
else Failure(expected+" expected", in)
}
diff --git a/test/files/buildmanager/t2556_3/t2556_3.check b/test/files/buildmanager/t2556_3/t2556_3.check
index 37808d2b31..34f90f7f9b 100644
--- a/test/files/buildmanager/t2556_3/t2556_3.check
+++ b/test/files/buildmanager/t2556_3/t2556_3.check
@@ -9,10 +9,10 @@ invalidate B.scala because it references invalid (no longer inherited) definitio
compiling Set(B.scala, C.scala)
B.scala:3: error: type mismatch;
found : C
- required: ?{val x: ?}
+ required: ?{def x: ?}
Note that implicit conversions are not applicable because they are ambiguous:
both method any2Ensuring in object Predef of type [A](x: A)Ensuring[A]
and method any2ArrowAssoc in object Predef of type [A](x: A)ArrowAssoc[A]
- are possible conversion functions from C to ?{val x: ?}
+ are possible conversion functions from C to ?{def x: ?}
println( (new C).x )
^
diff --git a/test/files/neg/logImplicits.check b/test/files/neg/logImplicits.check
index d98422dacb..54afc6f86d 100644
--- a/test/files/neg/logImplicits.check
+++ b/test/files/neg/logImplicits.check
@@ -1,16 +1,16 @@
-logImplicits.scala:2: applied implicit conversion from xs.type to ?{val size: ?} = implicit def byteArrayOps(xs: Array[Byte]): scala.collection.mutable.ArrayOps[Byte]
+logImplicits.scala:2: applied implicit conversion from xs.type to ?{def size: ?} = implicit def byteArrayOps(xs: Array[Byte]): scala.collection.mutable.ArrayOps[Byte]
def f(xs: Array[Byte]) = xs.size
^
-logImplicits.scala:7: applied implicit conversion from String("abc") to ?{val map: ?} = implicit def augmentString(x: String): scala.collection.immutable.StringOps
+logImplicits.scala:7: applied implicit conversion from String("abc") to ?{def map: ?} = implicit def augmentString(x: String): scala.collection.immutable.StringOps
def f = "abc" map (_ + 1)
^
logImplicits.scala:15: inferred view from String("abc") to Int = C.this.convert:(p: String("abc"))Int
math.max(122, x: Int)
^
-logImplicits.scala:19: applied implicit conversion from Int(1) to ?{val ->: ?} = implicit def any2ArrowAssoc[A](x: A): ArrowAssoc[A]
+logImplicits.scala:19: applied implicit conversion from Int(1) to ?{def ->: ?} = implicit def any2ArrowAssoc[A](x: A): ArrowAssoc[A]
def f = (1 -> 2) + "c"
^
-logImplicits.scala:19: applied implicit conversion from (Int, Int) to ?{val +: ?} = implicit def any2stringadd(x: Any): scala.runtime.StringAdd
+logImplicits.scala:19: applied implicit conversion from (Int, Int) to ?{def +: ?} = implicit def any2stringadd(x: Any): scala.runtime.StringAdd
def f = (1 -> 2) + "c"
^
logImplicits.scala:22: error: class Un needs to be abstract, since method unimplemented is not defined
diff --git a/test/files/neg/t963.check b/test/files/neg/t963.check
new file mode 100644
index 0000000000..1f2d0687b3
--- /dev/null
+++ b/test/files/neg/t963.check
@@ -0,0 +1,12 @@
+t963.scala:14: error: stable identifier required, but Test.this.y3.x found.
+ val w3 : y3.x.type = y3.x
+ ^
+t963.scala:17: error: stable identifier required, but Test.this.y4.x found.
+ val w4 : y4.x.type = y4.x
+ ^
+t963.scala:10: error: type mismatch;
+ found : Object{def x: Integer}
+ required: AnyRef{val x: Integer}
+ val y2 : { val x : java.lang.Integer } = new { def x = new java.lang.Integer(r.nextInt) }
+ ^
+three errors found
diff --git a/test/files/neg/t963.scala b/test/files/neg/t963.scala
new file mode 100644
index 0000000000..0cc2034299
--- /dev/null
+++ b/test/files/neg/t963.scala
@@ -0,0 +1,18 @@
+import scala.util.Random
+
+// Only y1 (val/val) should actually compile.
+object Test {
+ val r = new Random()
+
+ val y1 : { val x : java.lang.Integer } = new { val x = new java.lang.Integer(r.nextInt) }
+ val w1 : y1.x.type = y1.x
+
+ val y2 : { val x : java.lang.Integer } = new { def x = new java.lang.Integer(r.nextInt) }
+ val w2 : y2.x.type = y2.x
+
+ val y3 : { def x : java.lang.Integer } = new { val x = new java.lang.Integer(r.nextInt) }
+ val w3 : y3.x.type = y3.x
+
+ val y4 : { def x : java.lang.Integer } = new { def x = new java.lang.Integer(r.nextInt) }
+ val w4 : y4.x.type = y4.x
+}
diff --git a/test/files/run/nonlocalreturn.check b/test/files/run/nonlocalreturn.check
new file mode 100644
index 0000000000..aeb2d5e239
--- /dev/null
+++ b/test/files/run/nonlocalreturn.check
@@ -0,0 +1 @@
+Some(1)
diff --git a/test/files/run/nonlocalreturn.scala b/test/files/run/nonlocalreturn.scala
new file mode 100644
index 0000000000..3c1e7420ed
--- /dev/null
+++ b/test/files/run/nonlocalreturn.scala
@@ -0,0 +1,15 @@
+object Test {
+ def wrap[K](body: => K): K = body
+
+ def f(): Option[Int] = {
+ wrap({ return Some(1) ; None })
+ }
+
+ def main(args: Array[String]) {
+ println(f())
+ }
+}
+// java.lang.ClassCastException: scala.Some cannot be cast to scala.None$
+// at Test$$anonfun$f$1.apply(nonlocalreturn.scala:5)
+// at Test$$anonfun$f$1.apply(nonlocalreturn.scala:5)
+// at Test$.wrap(nonlocalreturn.scala:2)
diff --git a/test/pending/run/t5018.scala b/test/files/run/t5018.scala
index 30c0d5ac94..bb67a252e5 100644
--- a/test/pending/run/t5018.scala
+++ b/test/files/run/t5018.scala
@@ -18,7 +18,7 @@ object Test {
def main(args: Array[String]) {
val values = mutable.Map(1 -> 1).values
- assert(serializeDeserialize(values) == values)
+ assert(serializeDeserialize(values).toList == values.toList)
val keyset = mutable.Map(1 -> 1).keySet
assert(serializeDeserialize(keyset) == keyset)
@@ -28,6 +28,9 @@ object Test {
val defaultmap = immutable.Map(1 -> 1).withDefaultValue(1)
assert(serializeDeserialize(defaultmap) == defaultmap)
+
+ val minusmap = mutable.Map(1 -> 1).withDefault(x => -x)
+ assert(serializeDeserialize(minusmap) == minusmap)
}
}
diff --git a/test/files/run/t5514.check b/test/files/run/t5514.check
new file mode 100644
index 0000000000..c68f7c9029
--- /dev/null
+++ b/test/files/run/t5514.check
@@ -0,0 +1,19 @@
+constructed reader: 10
+constructed reader: 9
+constructed reader: 8
+constructed reader: 7
+constructed reader: 6
+constructed reader: 5
+constructed reader: 4
+constructed reader: 3
+constructed reader: 2
+constructed reader: 1
+constructed reader: 0
+[0.0] parsed: List(s10, s9, s8, s7, s6, s5, s4, s3, s2, s1)
+constructed reader: 10
+constructed reader: 9
+constructed reader: 8
+constructed reader: 7
+constructed reader: 6
+constructed reader: 5
+[0.0] parsed: List(s10, s9, s8, s7, s6) \ No newline at end of file
diff --git a/test/pending/run/t5514.scala b/test/files/run/t5514.scala
index eacad21cd8..efd5ba6cb9 100644
--- a/test/pending/run/t5514.scala
+++ b/test/files/run/t5514.scala
@@ -8,28 +8,28 @@ import scala.util.parsing.input.Position
-object DemoApp extends App {
- val parsers = new DemoParsers
- val reader = new DemoReader(10)
- val result = parsers.startsWith("s").*(reader)
- Console println result
-}
-
-
class DemoReader(n: Int) extends Reader[String] {
def atEnd = n == 0
- def first = "s" + n
+ def first = if (n >= 0) "s" + n else throw new IllegalArgumentException("No more input.")
def rest = new DemoReader(n - 1)
def pos = new Position {
def line = 0
def column = 0
def lineContents = first
}
- println("reader: " + n)
+ println("constructed reader: " + n)
}
-class DemoParsers extends Parsers {
+object Test extends App with Parsers {
type Elem = String
def startsWith(prefix: String) = acceptIf(_ startsWith prefix)("Error: " + _)
+
+ val resrep = startsWith("s").*(new DemoReader(10))
+ Console println resrep
+
+ val resrep5 = repN(5, startsWith("s"))(new DemoReader(10))
+ Console println resrep5
}
+
+
diff --git a/test/files/run/t5577.check b/test/files/run/t5577.check
new file mode 100644
index 0000000000..3eca387955
--- /dev/null
+++ b/test/files/run/t5577.check
@@ -0,0 +1,11 @@
+Received a size hint: 10
+0
+1
+2
+3
+4
+5
+6
+7
+8
+9 \ No newline at end of file
diff --git a/test/files/run/t5577.scala b/test/files/run/t5577.scala
new file mode 100644
index 0000000000..b5d6d8c5b6
--- /dev/null
+++ b/test/files/run/t5577.scala
@@ -0,0 +1,27 @@
+
+
+
+import collection._
+
+
+
+object Test {
+
+ class AlarmingBuffer[T] extends mutable.ArrayBuffer[T] {
+ override def sizeHint(x: Int) {
+ println("Received a size hint: " + x)
+ super.sizeHint(x)
+ }
+ }
+
+ def main(args: Array[String]) {
+ val iteratorBuilder = (new AlarmingBuffer[Int]) mapResult {
+ res => res.iterator
+ }
+
+ iteratorBuilder.sizeHint(10)
+ iteratorBuilder ++= (0 until 10)
+ iteratorBuilder.result.foreach(println)
+ }
+
+}
diff --git a/test/files/run/t5590.check b/test/files/run/t5590.check
new file mode 100644
index 0000000000..ad4a2eee64
--- /dev/null
+++ b/test/files/run/t5590.check
@@ -0,0 +1,4 @@
+Map(a -> a, b -> b, c -> c)
+Map(a -> a, b -> b, c -> c)
+Set(a, b, c, d, e)
+Set(a, b, c, d, e) \ No newline at end of file
diff --git a/test/files/run/t5590.scala b/test/files/run/t5590.scala
new file mode 100644
index 0000000000..9c806e0b7d
--- /dev/null
+++ b/test/files/run/t5590.scala
@@ -0,0 +1,31 @@
+
+
+
+import java.io._
+import collection._
+
+
+
+object Test {
+
+ def check(obj: AnyRef) {
+ println(obj)
+
+ val bos = new ByteArrayOutputStream()
+ val out = new ObjectOutputStream(bos)
+ out.writeObject(obj)
+ val arr = bos.toByteArray()
+ val in = new ObjectInputStream(new ByteArrayInputStream(arr))
+ val deser = in.readObject()
+
+ println(deser)
+ }
+
+ def main(args: Array[String]) {
+ val lhm = mutable.LinkedHashMap("a" -> "a", "b" -> "b", "c" -> "c")
+ val lhs = mutable.LinkedHashSet("a", "b", "c", "d", "e")
+ check(lhm)
+ check(lhs)
+ }
+
+}
diff --git a/test/files/run/t5612.check b/test/files/run/t5612.check
new file mode 100644
index 0000000000..9d19cca292
--- /dev/null
+++ b/test/files/run/t5612.check
@@ -0,0 +1,4 @@
+START for List(Two, Two, One, Three)
+TWO
+TWO
+ONE
diff --git a/test/files/run/t5612.scala b/test/files/run/t5612.scala
new file mode 100644
index 0000000000..48b3093548
--- /dev/null
+++ b/test/files/run/t5612.scala
@@ -0,0 +1,28 @@
+object L extends Enumeration {
+ val One, Two, Three = Value
+}
+
+class Foo {
+ def foo(xs: List[L.Value]) {
+ import scala.util.control.Breaks.{break, breakable}
+ println("START for " + xs)
+ breakable {
+ for (x <- xs) {
+ x match {
+ case L.One => println("ONE"); return
+ case L.Two => println("TWO")
+ case L.Three => println("THREE"); break
+ }
+ }
+ }
+ println("FINISH")
+ }
+}
+
+object Test {
+ def main(args: Array[String]) {
+ val f = new Foo()
+ val l = List(L.Two, L.Two, L.One, L.Three)
+ f.foo(l)
+ }
+}