diff options
23 files changed, 227 insertions, 54 deletions
diff --git a/src/compiler/scala/reflect/macros/runtime/Aliases.scala b/src/compiler/scala/reflect/macros/runtime/Aliases.scala index 8b742755cd..5e15b61dbd 100644 --- a/src/compiler/scala/reflect/macros/runtime/Aliases.scala +++ b/src/compiler/scala/reflect/macros/runtime/Aliases.scala @@ -21,6 +21,8 @@ trait Aliases { override type TypeTag[T] = universe.TypeTag[T] override val AbsTypeTag = universe.AbsTypeTag override val TypeTag = universe.TypeTag + override def absTypeTag[T](implicit attag: AbsTypeTag[T]) = attag override def typeTag[T](implicit ttag: TypeTag[T]) = ttag + override def absTypeOf[T](implicit attag: AbsTypeTag[T]): Type = attag.tpe override def typeOf[T](implicit ttag: TypeTag[T]): Type = ttag.tpe }
\ No newline at end of file diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala index dfe08c398e..f6baf02c3e 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala @@ -4730,8 +4730,13 @@ trait Typers extends Modes with Adaptations with Tags { if (isInPackageObject(defEntry.sym, pre.typeSymbol)) { defSym = pre.member(defEntry.sym.name) if (defSym ne defEntry.sym) { - log("!!! Overloaded package object member resolved incorrectly.\n Discarded: " + - defEntry.sym.defString + "\n Using: " + defSym.defString) + qual = gen.mkAttributedQualifier(pre) + log(s""" + | !!! Overloaded package object member resolved incorrectly. + | prefix: $pre + | Discarded: ${defEntry.sym.defString} + | Using: ${defSym.defString} + """.stripMargin) } } else diff --git a/src/library/scala/collection/JavaConversions.scala b/src/library/scala/collection/JavaConversions.scala index a978a9a783..8e4fdf537d 100644 --- a/src/library/scala/collection/JavaConversions.scala +++ b/src/library/scala/collection/JavaConversions.scala @@ -22,7 +22,8 @@ import convert._ * scala.collection.mutable.Buffer <=> java.util.List * scala.collection.mutable.Set <=> java.util.Set * scala.collection.mutable.Map <=> java.util.{ Map, Dictionary } - * scala.collection.mutable.ConcurrentMap <=> java.util.concurrent.ConcurrentMap + * scala.collection.mutable.ConcurrentMap (deprecated since 2.10) <=> java.util.concurrent.ConcurrentMap + * scala.collection.concurrent.Map <=> java.util.concurrent.ConcurrentMap *}}} * In all cases, converting from a source type to a target type and back * again will return the original source object, eg. diff --git a/src/library/scala/collection/convert/WrapAsScala.scala b/src/library/scala/collection/convert/WrapAsScala.scala index 49f4d7cd99..c2994a0986 100644 --- a/src/library/scala/collection/convert/WrapAsScala.scala +++ b/src/library/scala/collection/convert/WrapAsScala.scala @@ -13,7 +13,27 @@ import java.{ lang => jl, util => ju }, java.util.{ concurrent => juc } import Wrappers._ import language.implicitConversions -trait WrapAsScala { +trait LowPriorityWrapAsScala { + this: WrapAsScala => + /** + * Implicitly converts a Java ConcurrentMap to a Scala mutable ConcurrentMap. + * The returned Scala ConcurrentMap is backed by the provided Java + * ConcurrentMap and any side-effects of using it via the Scala interface will + * be visible via the Java interface and vice versa. + * + * If the Java ConcurrentMap was previously obtained from an implicit or + * explicit call of `asConcurrentMap(scala.collection.mutable.ConcurrentMap)` + * then the original Scala ConcurrentMap will be returned. + * + * @param m The ConcurrentMap to be converted. + * @return A Scala mutable ConcurrentMap view of the argument. + */ + @deprecated("Use `mapAsScalaConcurrentMap` instead, and use `concurrent.Map` instead of `ConcurrentMap`.", "2.10.0") + implicit def mapAsScalaDeprecatedConcurrentMap[A, B](m: juc.ConcurrentMap[A, B]): mutable.ConcurrentMap[A, B] = + asScalaConcurrentMap(m) +} + +trait WrapAsScala extends LowPriorityWrapAsScala { /** * Implicitly converts a Java `Iterator` to a Scala `Iterator`. * diff --git a/src/library/scala/collection/immutable/Stream.scala b/src/library/scala/collection/immutable/Stream.scala index 1bf1e20694..97707d4f7c 100644 --- a/src/library/scala/collection/immutable/Stream.scala +++ b/src/library/scala/collection/immutable/Stream.scala @@ -479,22 +479,40 @@ self => final class StreamWithFilter(p: A => Boolean) extends WithFilter(p) { override def map[B, That](f: A => B)(implicit bf: CanBuildFrom[Stream[A], B, That]): That = { - def tailMap = asStream[B](tail withFilter p map f) - if (isStreamBuilder(bf)) asThat( - if (isEmpty) Stream.Empty - else if (p(head)) cons(f(head), tailMap) - else tailMap - ) + def tailMap(coll: Stream[A]): Stream[B] = { + var head: A = null.asInstanceOf[A] + var tail: Stream[A] = coll + while (true) { + if (tail.isEmpty) + return Stream.Empty + head = tail.head + tail = tail.tail + if (p(head)) + return cons(f(head), tailMap(tail)) + } + throw new RuntimeException() + } + + if (isStreamBuilder(bf)) asThat(tailMap(Stream.this)) else super.map(f)(bf) } override def flatMap[B, That](f: A => GenTraversableOnce[B])(implicit bf: CanBuildFrom[Stream[A], B, That]): That = { - def tailFlatMap = asStream[B](tail withFilter p flatMap f) - if (isStreamBuilder(bf)) asThat( - if (isEmpty) Stream.Empty - else if (p(head)) f(head).toStream append tailFlatMap - else tailFlatMap - ) + def tailFlatMap(coll: Stream[A]): Stream[B] = { + var head: A = null.asInstanceOf[A] + var tail: Stream[A] = coll + while (true) { + if (tail.isEmpty) + return Stream.Empty + head = tail.head + tail = tail.tail + if (p(head)) + return f(head).toStream append tailFlatMap(tail) + } + throw new RuntimeException() + } + + if (isStreamBuilder(bf)) asThat(tailFlatMap(Stream.this)) else super.flatMap(f)(bf) } diff --git a/src/library/scala/reflect/ClassTag.scala b/src/library/scala/reflect/ClassTag.scala index 7b6df6e31c..5255c44f10 100644 --- a/src/library/scala/reflect/ClassTag.scala +++ b/src/library/scala/reflect/ClassTag.scala @@ -64,6 +64,7 @@ trait ClassTag[T] extends ClassManifestDeprecatedApis[T] with Equals with Serial } object ClassTag { + private val NothingTYPE = classOf[scala.runtime.Nothing$] private val NullTYPE = classOf[scala.runtime.Null$] private val ObjectTYPE = classOf[java.lang.Object] @@ -80,13 +81,7 @@ object ClassTag { val Object : ClassTag[java.lang.Object] = new ClassTag[java.lang.Object]{ def runtimeClass = ObjectTYPE; private def readResolve() = ClassTag.Object } val AnyVal : ClassTag[scala.AnyVal] = ClassTag.Object.asInstanceOf[ClassTag[scala.AnyVal]] val AnyRef : ClassTag[scala.AnyRef] = ClassTag.Object.asInstanceOf[ClassTag[scala.AnyRef]] - val Nothing : ClassTag[scala.Nothing] = new ClassTag[scala.Nothing]{ - def runtimeClass = throw new Exception("Nothing is a bottom type, therefore its erasure does not return a value") - private def readResolve() = ClassTag.Nothing - override def equals(x: Any) = x.isInstanceOf[ClassTag[_]] && (x.asInstanceOf[AnyRef] eq ClassTag.Nothing) - override def hashCode = System.identityHashCode(this) - override def toString = "ClassTag[Nothing]" - } + val Nothing : ClassTag[scala.Nothing] = new ClassTag[scala.Nothing]{ def runtimeClass = NothingTYPE; private def readResolve() = ClassTag.Nothing } val Null : ClassTag[scala.Null] = new ClassTag[scala.Null]{ def runtimeClass = NullTYPE; private def readResolve() = ClassTag.Null } def apply[T](runtimeClass1: jClass[_]): ClassTag[T] = diff --git a/src/library/scala/reflect/base/TypeTags.scala b/src/library/scala/reflect/base/TypeTags.scala index c9d1ccf5bc..b7e0c37a4b 100644 --- a/src/library/scala/reflect/base/TypeTags.scala +++ b/src/library/scala/reflect/base/TypeTags.scala @@ -250,9 +250,11 @@ trait TypeTags { self: Universe => } // incantations + def absTypeTag[T](implicit attag: AbsTypeTag[T]) = attag def typeTag[T](implicit ttag: TypeTag[T]) = ttag // big thanks to Viktor Klang for this brilliant idea! + def absTypeOf[T](implicit attag: AbsTypeTag[T]): Type = attag.tpe def typeOf[T](implicit ttag: TypeTag[T]): Type = ttag.tpe } diff --git a/src/library/scala/util/control/Exception.scala b/src/library/scala/util/control/Exception.scala index 4a5209ecab..1567e06c22 100644 --- a/src/library/scala/util/control/Exception.scala +++ b/src/library/scala/util/control/Exception.scala @@ -145,7 +145,7 @@ object Exception { } final val nothingCatcher: Catcher[Nothing] = mkThrowableCatcher(_ => false, throw _) - final def nonFatalCatcher[T]: Catcher[T] = mkThrowableCatcher({ case NonFatal(_) => false; case _ => true }, throw _) + final def nonFatalCatcher[T]: Catcher[T] = mkThrowableCatcher({ case NonFatal(_) => true; case _ => false }, throw _) final def allCatcher[T]: Catcher[T] = mkThrowableCatcher(_ => true, throw _) /** The empty `Catch` object. */ diff --git a/src/reflect/scala/reflect/api/Symbols.scala b/src/reflect/scala/reflect/api/Symbols.scala index 9e7b3c9712..0c4f143d57 100644 --- a/src/reflect/scala/reflect/api/Symbols.scala +++ b/src/reflect/scala/reflect/api/Symbols.scala @@ -59,6 +59,9 @@ trait Symbols extends base.Symbols { self: Universe => */ def typeSignature: Type + /** Returns all symbols overriden by this symbol. */ + def allOverriddenSymbols: List[Symbol] + /******************* tests *******************/ /** Does this symbol represent a synthetic (i.e. a compiler-generated) entity? diff --git a/src/reflect/scala/reflect/macros/Aliases.scala b/src/reflect/scala/reflect/macros/Aliases.scala index 46b7066902..ad100d7e89 100644 --- a/src/reflect/scala/reflect/macros/Aliases.scala +++ b/src/reflect/scala/reflect/macros/Aliases.scala @@ -21,6 +21,8 @@ trait Aliases { type TypeTag[T] = universe.TypeTag[T] val AbsTypeTag = universe.AbsTypeTag val TypeTag = universe.TypeTag + def absTypeTag[T](implicit attag: AbsTypeTag[T]) = attag def typeTag[T](implicit ttag: TypeTag[T]) = ttag + def absTypeOf[T](implicit attag: AbsTypeTag[T]): Type = attag.tpe def typeOf[T](implicit ttag: TypeTag[T]): Type = ttag.tpe } diff --git a/test/files/neg/javaConversions-2.10-ambiguity.check b/test/files/neg/javaConversions-2.10-ambiguity.check new file mode 100644 index 0000000000..c064a22964 --- /dev/null +++ b/test/files/neg/javaConversions-2.10-ambiguity.check @@ -0,0 +1,6 @@ +javaConversions-2.10-ambiguity.scala:8: error: type mismatch; + found : scala.collection.concurrent.Map[String,String] + required: scala.collection.mutable.ConcurrentMap[String,String] + assertType[mutable.ConcurrentMap[String, String]](a) + ^ +one error found diff --git a/test/files/neg/javaConversions-2.10-ambiguity.scala b/test/files/neg/javaConversions-2.10-ambiguity.scala new file mode 100644 index 0000000000..e856846a29 --- /dev/null +++ b/test/files/neg/javaConversions-2.10-ambiguity.scala @@ -0,0 +1,10 @@ +import collection.{JavaConversions, mutable, concurrent} +import JavaConversions._ +import java.util.concurrent.{ConcurrentHashMap => CHM} + +object Bar { + def assertType[T](t: T) = t + val a = new CHM[String, String]() += (("", "")) + assertType[mutable.ConcurrentMap[String, String]](a) +} +// vim: set et: diff --git a/test/files/pos/javaConversions-2.10-regression.scala b/test/files/pos/javaConversions-2.10-regression.scala new file mode 100644 index 0000000000..e1b81015ba --- /dev/null +++ b/test/files/pos/javaConversions-2.10-regression.scala @@ -0,0 +1,17 @@ +import collection.{JavaConversions, mutable, concurrent} +import JavaConversions._ +import java.util.concurrent.{ConcurrentHashMap => CHM} + +object Foo { + def buildCache2_9_simple[K <: AnyRef, V <: AnyRef]: mutable.ConcurrentMap[K, V] = + asScalaConcurrentMap(new CHM()) + + def buildCache2_9_implicit[K <: AnyRef, V <: AnyRef]: mutable.ConcurrentMap[K, V] = + new CHM[K, V]() +} + +object Bar { + def assertType[T](t: T) = t + val a = new CHM[String, String]() += (("", "")) + assertType[concurrent.Map[String, String]](a) +} diff --git a/test/files/run/classtags_core.check b/test/files/run/classtags_core.check index 2241108ba0..6519db2178 100644 --- a/test/files/run/classtags_core.check +++ b/test/files/run/classtags_core.check @@ -1,30 +1,30 @@ -true -ClassTag[byte] -true -ClassTag[short] -true -ClassTag[char] -true -ClassTag[int] -true -ClassTag[long] -true -ClassTag[float] -true -ClassTag[double] -true -ClassTag[boolean] -true -ClassTag[void] -true -ClassTag[class java.lang.Object] -true -ClassTag[class java.lang.Object] -true -ClassTag[class java.lang.Object] -true -ClassTag[class java.lang.Object] -true -ClassTag[class scala.runtime.Null$] -true -ClassTag[Nothing] +true
+ClassTag[byte]
+true
+ClassTag[short]
+true
+ClassTag[char]
+true
+ClassTag[int]
+true
+ClassTag[long]
+true
+ClassTag[float]
+true
+ClassTag[double]
+true
+ClassTag[boolean]
+true
+ClassTag[void]
+true
+ClassTag[class java.lang.Object]
+true
+ClassTag[class java.lang.Object]
+true
+ClassTag[class java.lang.Object]
+true
+ClassTag[class java.lang.Object]
+true
+ClassTag[class scala.runtime.Null$]
+true
+ClassTag[class scala.runtime.Nothing$]
diff --git a/test/files/run/stream-stack-overflow-filter-map.scala b/test/files/run/stream-stack-overflow-filter-map.scala new file mode 100644 index 0000000000..f3a9dd49cb --- /dev/null +++ b/test/files/run/stream-stack-overflow-filter-map.scala @@ -0,0 +1,44 @@ +import collection.generic.{FilterMonadic, CanBuildFrom} + +object Test extends App { + def mapSucc[Repr, That](s: FilterMonadic[Int, Repr])(implicit cbf: CanBuildFrom[Repr, Int, That]) = s map (_ + 1) + def flatMapId[T, Repr, That](s: FilterMonadic[T, Repr])(implicit cbf: CanBuildFrom[Repr, T, That]) = s flatMap (Seq(_)) + + def testStreamPred(s: Stream[Int])(p: Int => Boolean) { + val res1 = s withFilter p + val res2 = s filter p + + val expected = s.toSeq filter p + + val fMapped1 = flatMapId(res1) + val fMapped2 = flatMapId(res2) + assert(fMapped1 == fMapped2) + assert(fMapped1.toSeq == expected) + + val mapped1 = mapSucc(res1) + val mapped2 = mapSucc(res2) + assert(mapped1 == mapped2) + assert(mapped1.toSeq == (expected map (_ + 1))) + + assert((res1 map identity).toSeq == res2.toSeq) + } + + def testStream(s: Stream[Int]) { + testStreamPred(s)(_ => false) + testStreamPred(s)(_ => true) + testStreamPred(s)(_ % 2 == 0) + testStreamPred(s)(_ % 3 == 0) + } + + //Reduced version of the test case - either invocation used to cause a stack + //overflow before commit 80b3f433e5536d086806fa108ccdfacf10719cc2. + val resFMap = (1 to 10000).toStream withFilter (_ => false) flatMap (Seq(_)) + val resMap = (1 to 10000).toStream withFilter (_ => false) map (_ + 1) + + //Complete test case for withFilter + map/flatMap, as requested by @axel22. + for (j <- (0 to 3) :+ 10000) { + val stream = (1 to j).toStream + assert(stream.toSeq == (1 to j).toSeq) + testStream(stream) + } +} diff --git a/test/files/run/t1987b.check b/test/files/run/t1987b.check new file mode 100644 index 0000000000..68d4b10e12 --- /dev/null +++ b/test/files/run/t1987b.check @@ -0,0 +1 @@ +ok! diff --git a/test/files/run/t1987b/PullIteratees.scala b/test/files/run/t1987b/PullIteratees.scala new file mode 100644 index 0000000000..a5a3e65d8f --- /dev/null +++ b/test/files/run/t1987b/PullIteratees.scala @@ -0,0 +1,17 @@ +package scales.xml + +trait PullType +class QName +trait RetUrn[T] + +/** + * Iteratees related to pull parsing + */ +trait PullIteratees { + /** + * Without the overload it doesn't trigger the CCE, even though its + * not used + */ + def iterate(path: List[QName], xml: String): RetUrn[String] = null + def iterate(path: List[QName], xml: Iterator[PullType]): RetUrn[String] = null +} diff --git a/test/files/run/t1987b/a.scala b/test/files/run/t1987b/a.scala new file mode 100644 index 0000000000..c1be5fe3e0 --- /dev/null +++ b/test/files/run/t1987b/a.scala @@ -0,0 +1,6 @@ +object Test { + def main(args: Array[String]): Unit = { + scales.xml.CCE_Test.main(args) + println("ok!") + } +} diff --git a/test/files/run/t1987b/cce_test.scala b/test/files/run/t1987b/cce_test.scala new file mode 100644 index 0000000000..4f9acf0264 --- /dev/null +++ b/test/files/run/t1987b/cce_test.scala @@ -0,0 +1,15 @@ +package scales.xml +//import scales.xml._ // using another pacakge and importing doesn't CCE + +object CCE_Test { + def main(args: Array[String]): Unit = { + // without the import it doesn't trigger the CCE + import scaley.funny._ + + val pull = null.asInstanceOf[Iterator[PullType]] + val LogEntries = null.asInstanceOf[List[QName]] + // fully qualify with scales.xml. and it won't trigger it + iterate(LogEntries, + pull) + } +} diff --git a/test/files/run/t1987b/pkg1.scala b/test/files/run/t1987b/pkg1.scala new file mode 100644 index 0000000000..6e749fc6b3 --- /dev/null +++ b/test/files/run/t1987b/pkg1.scala @@ -0,0 +1,4 @@ +package scaley + +package object funny { +} diff --git a/test/files/run/t1987b/pkg2.scala b/test/files/run/t1987b/pkg2.scala new file mode 100644 index 0000000000..38056a199e --- /dev/null +++ b/test/files/run/t1987b/pkg2.scala @@ -0,0 +1,3 @@ +package scales + +package object xml extends PullIteratees diff --git a/test/files/run/try-catch-unify.check b/test/files/run/try-catch-unify.check index b1de2bfa74..67a8c64a33 100644 --- a/test/files/run/try-catch-unify.check +++ b/test/files/run/try-catch-unify.check @@ -1,3 +1,4 @@ Failure(java.lang.NumberFormatException: For input string: "Hi") Success(5.0) O NOES +Failure(java.lang.NumberFormatException: For input string: "Hi") diff --git a/test/files/run/try-catch-unify.scala b/test/files/run/try-catch-unify.scala index 0d819ab957..8cb14d060e 100644 --- a/test/files/run/try-catch-unify.scala +++ b/test/files/run/try-catch-unify.scala @@ -11,5 +11,6 @@ object Test { } catch { case t => println(t.getMessage) } + println(nonFatalCatch withTry ("Hi".toDouble)) } } |