diff options
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) + } +} |