diff options
32 files changed, 239 insertions, 372 deletions
diff --git a/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala b/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala index e1ddd260cb..f0c44bb227 100644 --- a/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala +++ b/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala @@ -1410,24 +1410,32 @@ abstract class GenICode extends SubComponent { * When it is statically known that both sides are equal and subtypes of Number of Character, * not using the rich equality is possible (their own equals method will do ok.)*/ def mustUseAnyComparator: Boolean = { + import definitions._ + + /** The various ways a boxed primitive might materialize at runtime. */ + def isJavaBoxed(sym: Symbol) = + (sym == ObjectClass) || + (sym == SerializableClass) || + (sym == ComparableClass) || + (sym isNonBottomSubClass BoxedNumberClass) || + (sym isNonBottomSubClass BoxedCharacterClass) + def isBoxed(sym: Symbol): Boolean = - ((sym isNonBottomSubClass definitions.BoxedNumberClass) || - (!forMSIL && (sym isNonBottomSubClass definitions.BoxedCharacterClass))) - - val lsym = l.tpe.typeSymbol - val rsym = r.tpe.typeSymbol - (lsym == ObjectClass) || - (rsym == ObjectClass) || - (lsym != rsym) && (isBoxed(lsym) || isBoxed(rsym)) + if (forMSIL) (sym isNonBottomSubClass BoxedNumberClass) + else isJavaBoxed(sym) + + isBoxed(l.tpe.typeSymbol) && isBoxed(r.tpe.typeSymbol) } if (mustUseAnyComparator) { - var equalsMethod = BoxesRunTime_equals // when -optimise is on we call the @inline-version of equals, found in ScalaRunTime - if (settings.XO.value) { - equalsMethod = definitions.getMember(definitions.ScalaRunTimeModule, nme.inlinedEquals) - ctx.bb.emit(LOAD_MODULE(definitions.ScalaRunTimeModule)) - } + val equalsMethod = + if (!settings.XO.value) BoxesRunTime_equals + else { + ctx.bb.emit(LOAD_MODULE(definitions.ScalaRunTimeModule)) + definitions.getMember(definitions.ScalaRunTimeModule, nme.inlinedEquals) + } + val ctx1 = genLoad(l, ctx, ANY_REF_CLASS) val ctx2 = genLoad(r, ctx1, ANY_REF_CLASS) ctx2.bb.emit(CALL_METHOD(equalsMethod, if (settings.XO.value) Dynamic else Static(false))) diff --git a/src/compiler/scala/tools/nsc/backend/icode/TypeKinds.scala b/src/compiler/scala/tools/nsc/backend/icode/TypeKinds.scala index a3cc5310ab..8ed2b04045 100644 --- a/src/compiler/scala/tools/nsc/backend/icode/TypeKinds.scala +++ b/src/compiler/scala/tools/nsc/backend/icode/TypeKinds.scala @@ -237,7 +237,7 @@ trait TypeKinds { self: ICodes => // override def maxType(other: TypeKind): TypeKind = other match { // case STRING => STRING; // case _ => - // abort("Uncomparbale type kinds: STRING with " + other); + // abort("Uncomparable type kinds: STRING with " + other); // } // } @@ -263,7 +263,7 @@ trait TypeKinds { self: ICodes => case REFERENCE(_) | ARRAY(_) => REFERENCE(AnyRefClass) case _ => - abort("Uncomparbale type kinds: REFERENCE with " + other) + abort("Uncomparable type kinds: REFERENCE with " + other) } /** Checks subtyping relationship. */ @@ -334,7 +334,7 @@ trait TypeKinds { self: ICodes => if (elem == elem2) ARRAY(elem) else REFERENCE(AnyRefClass) case _ => - abort("Uncomparbale type kinds: ARRAY with " + other) + abort("Uncomparable type kinds: ARRAY with " + other) } /** Array subtyping is covariant, as in Java. Necessary for checking @@ -370,7 +370,7 @@ trait TypeKinds { self: ICodes => case REFERENCE(_) | ARRAY(_) | BOXED(_) => REFERENCE(AnyRefClass) case _ => - abort("Uncomparbale type kinds: ARRAY with " + other) + abort("Uncomparable type kinds: ARRAY with " + other) } /** Checks subtyping relationship. */ @@ -409,7 +409,7 @@ trait TypeKinds { self: ICodes => case REFERENCE(_) => REFERENCE(AnyRefClass) case _ => - abort("Uncomparbale type kinds: ConcatClass with " + other) + abort("Uncomparable type kinds: ConcatClass with " + other) } /** Checks subtyping relationship. */ diff --git a/src/compiler/scala/tools/nsc/symtab/classfile/Pickler.scala b/src/compiler/scala/tools/nsc/symtab/classfile/Pickler.scala index 2d1855dc84..84b08f1258 100644 --- a/src/compiler/scala/tools/nsc/symtab/classfile/Pickler.scala +++ b/src/compiler/scala/tools/nsc/symtab/classfile/Pickler.scala @@ -67,6 +67,7 @@ abstract class Pickler extends SubComponent { private var ep = 0 private val index = new LinkedHashMap[AnyRef, Int] + // collect higher-order type params private var locals: Set[Symbol] = Set() // private var boundSyms: List[Symbol] = Nil @@ -80,16 +81,16 @@ abstract class Pickler extends SubComponent { else sym.owner /** Is root in symbol.owner*, or should it be treated as a local symbol - * anyway? This is the case if symbol is a refinement class or - * an existentially bound variable. + * anyway? This is the case if symbol is a refinement class, + * an existentially bound variable, or a higher-order type parameter. */ private def isLocal(sym: Symbol): Boolean = !sym.isPackageClass && (sym.name.toTermName == rootName && sym.owner == rootOwner || sym != NoSymbol && isLocal(sym.owner) || sym.isRefinementClass || - sym.isAbstractType && sym.hasFlag(EXISTENTIAL) || - (locals contains sym)) + sym.isAbstractType && sym.hasFlag(EXISTENTIAL) || // existential param + (locals contains sym)) // higher-order type param private def staticAnnotations(annots: List[AnnotationInfo]) = annots filter(ann => @@ -191,11 +192,11 @@ abstract class Pickler extends SubComponent { putType(restpe); putSymbols(params) case PolyType(tparams, restpe) => tparams foreach { tparam => - if (!isLocal(tparam)) locals += tparam + if (!isLocal(tparam)) locals += tparam // similar to existential types, these tparams are local } putType(restpe); putSymbols(tparams) case ExistentialType(tparams, restpe) => -// val savedBoundSyms = boundSyms +// val savedBoundSyms = boundSyms // boundSyms are known to be local based on the EXISTENTIAL flag (see isLocal) // boundSyms = tparams ::: boundSyms // try { putType(restpe); diff --git a/src/compiler/scala/tools/nsc/transform/UnCurry.scala b/src/compiler/scala/tools/nsc/transform/UnCurry.scala index eec523a2b8..67c963acf5 100644 --- a/src/compiler/scala/tools/nsc/transform/UnCurry.scala +++ b/src/compiler/scala/tools/nsc/transform/UnCurry.scala @@ -47,9 +47,7 @@ abstract class UnCurry extends InfoTransform with TypingTransformers { // ------ Type transformation -------------------------------------------------------- -//@MAT: uncurry and uncurryType fully expand type aliases in their input and output -// note: don't normalize higher-kined types -- @M TODO: maybe split those uses of normalize? -// OTOH, should be a problem as calls to normalize only occur on types with kind * in principle (in well-typed programs) +// uncurry and uncurryType expand type aliases private def expandAlias(tp: Type): Type = if (!tp.isHigherKinded) tp.normalize else tp private def isUnboundedGeneric(tp: Type) = tp match { @@ -68,9 +66,9 @@ abstract class UnCurry extends InfoTransform with TypingTransformers { tp0 case mt: ImplicitMethodType => apply(MethodType(mt.params, mt.resultType)) - case PolyType(List(), restpe) => + case PolyType(List(), restpe) => // nullary method type apply(MethodType(List(), restpe)) - case PolyType(tparams, restpe) => + case PolyType(tparams, restpe) => // polymorphic nullary method type, since it didn't occur in a higher-kinded position PolyType(tparams, apply(MethodType(List(), restpe))) case TypeRef(pre, ByNameParamClass, List(arg)) => apply(functionType(List(), arg)) @@ -83,6 +81,29 @@ abstract class UnCurry extends InfoTransform with TypingTransformers { expandAlias(mapOver(tp)) } } + +//@M TODO: better fix for the gross hack that conflates polymorphic nullary method types with type functions +// `[tpars] tref` (PolyType(tpars, tref)) could uncurry to either: +// - `[tpars]() tref` (PolyType(tpars, MethodType(List(), tref)) +// a nullary method types uncurry to a method with an empty argument list +// - `[tpars] tref` (PolyType(tpars, tref)) +// a proper type function -- see mapOverArgs: can only occur in args of TypeRef (right?)) +// the issue comes up when a partial type application gets normalised to a polytype, like `[A] Function1[X, A]` +// should not apply the uncurry transform to such a type +// see #2594 for an example + + // decide whether PolyType represents a nullary method type (only if type has kind *) + // for higher-kinded types, leave PolyType intact + override def mapOverArgs(args: List[Type], tparams: List[Symbol]): List[Type] = + map2Conserve(args, tparams) { (arg, tparam) => + arg match { + // is this a higher-kinded position? (TODO: confirm this is the only case) + case PolyType(tparams, restpe) if tparam.typeParams.nonEmpty => // higher-kinded type param + PolyType(tparams, apply(restpe)) // could not be a nullary method type + case _ => + this(arg) + } + } } private val uncurryType = new TypeMap { diff --git a/src/library/scala/Console.scala b/src/library/scala/Console.scala index 8be1e0f8dc..e99a0af8ff 100644 --- a/src/library/scala/Console.scala +++ b/src/library/scala/Console.scala @@ -213,17 +213,6 @@ object Console { */ def printf(text: String, args: Any*) { out.print(text format (args : _*)) } - /** - * @see <a href="#printf(java.lang.String,scala.Any*)" - * target="contentFrame">Console.printf</a>. - */ - @deprecated("For console output, use <code>Console.printf</code>. For <code>String</code>\n"+ - "formatting, <code>StringOps</code>'s <code>format</code> method.") - def format(text: String, args: Any*) { - if (text eq null) out.printf("null") - else out.print(text format (args : _*)) - } - /** Read a full line from the terminal. Returns <code>null</code> if the end of the * input stream has been reached. * @@ -435,26 +424,4 @@ object Console { } res } - - private def textParams(s: Seq[Any]): Array[AnyRef] = { - val res = new Array[AnyRef](s.length) - var i: Int = 0 - val iter = s.iterator - while (iter.hasNext) { - res(i) = iter.next match { - case x: Boolean => java.lang.Boolean.valueOf(x) - case x: Byte => java.lang.Byte.valueOf(x) - case x: Short => java.lang.Short.valueOf(x) - case x: Char => java.lang.Character.valueOf(x) - case x: Int => java.lang.Integer.valueOf(x) - case x: Long => java.lang.Long.valueOf(x) - case x: Float => java.lang.Float.valueOf(x) - case x: Double => java.lang.Double.valueOf(x) - case x: Unit => "()" - case x: AnyRef => x - } - i += 1 - } - res - } } diff --git a/src/library/scala/Option.scala b/src/library/scala/Option.scala index 6f9ba306ad..57539e7139 100644 --- a/src/library/scala/Option.scala +++ b/src/library/scala/Option.scala @@ -50,12 +50,6 @@ sealed abstract class Option[+A] extends Product { */ def get: A - @deprecated("use <code>getOrElse</code> instead") - def get[B >: A](default: B): B = this match { - case None => default - case Some(x) => x - } - /** If the option is nonempty return its value, * otherwise return the result of evaluating a default expression. * diff --git a/src/library/scala/Predef.scala b/src/library/scala/Predef.scala index c44ec72299..892e90d581 100644 --- a/src/library/scala/Predef.scala +++ b/src/library/scala/Predef.scala @@ -20,14 +20,12 @@ import collection.generic.CanBuildFrom * qualification. */ object Predef extends LowPriorityImplicits { - - // classOf dummy ------------------------------------------------------ - - /** Return the runtime representation of a class type. */ + /** Return the runtime representation of a class type. This is a stub method. + * The actual implementation is filled in by the compiler. + */ def classOf[T]: Class[T] = null // aliases ------------------------------------------------------------ - @deprecated("lower-case type aliases will be removed") type byte = scala.Byte @deprecated("lower-case type aliases will be removed") type short = scala.Short @deprecated("lower-case type aliases will be removed") type char = scala.Char @@ -38,44 +36,18 @@ object Predef extends LowPriorityImplicits { @deprecated("lower-case type aliases will be removed") type boolean = scala.Boolean @deprecated("lower-case type aliases will be removed") type unit = scala.Unit - @deprecated("use <code>java.lang.Integer</code> instead") - type Integer = java.lang.Integer - @deprecated("use <code>java.lang.Character</code> instead") - type Character = java.lang.Character - type String = java.lang.String type Class[T] = java.lang.Class[T] - type Runnable = java.lang.Runnable - - type Throwable = java.lang.Throwable - type Exception = java.lang.Exception - type Error = java.lang.Error - - type RuntimeException = java.lang.RuntimeException - type NullPointerException = java.lang.NullPointerException - type ClassCastException = java.lang.ClassCastException - type IndexOutOfBoundsException = java.lang.IndexOutOfBoundsException - type ArrayIndexOutOfBoundsException = java.lang.ArrayIndexOutOfBoundsException - type StringIndexOutOfBoundsException = java.lang.StringIndexOutOfBoundsException - type UnsupportedOperationException = java.lang.UnsupportedOperationException - type IllegalArgumentException = java.lang.IllegalArgumentException - type NoSuchElementException = java.util.NoSuchElementException - type NumberFormatException = java.lang.NumberFormatException - type AbstractMethodError = java.lang.AbstractMethodError // miscelleaneous ----------------------------------------------------- - - private val P = scala.`package` // to force scala package object to be seen. - private val L = scala.collection.immutable.List // to force Nil, :: to be seen. - private val S = scala.collection.mutable.StringBuilder // to force StringBuilder to be seen. - - val $scope = scala.xml.TopScope + scala.`package` // to force scala package object to be seen. + scala.collection.immutable.List // to force Nil, :: to be seen. + scala.collection.mutable.StringBuilder // to force StringBuilder to be seen. type Function[-A, +B] = Function1[A, B] type Map[A, +B] = collection.immutable.Map[A, B] type Set[A] = collection.immutable.Set[A] - val Map = collection.immutable.Map val Set = collection.immutable.Set @@ -85,7 +57,6 @@ object Predef extends LowPriorityImplicits { def manifest[T](implicit m: Manifest[T]) = m def classManifest[T](implicit m: ClassManifest[T]) = m - // will soon stop being a view: subsumed by `conforms` (which is less likely to give rise to ambiguities) // @see `conforms` for the implicit version def identity[A](x: A): A = x @@ -157,6 +128,14 @@ object Predef extends LowPriorityImplicits { throw new IllegalArgumentException("requirement failed: "+ message) } + class Ensuring[A](x: A) { + def ensuring(cond: Boolean): A = { assert(cond); x } + def ensuring(cond: Boolean, msg: Any): A = { assert(cond, msg); x } + def ensuring(cond: A => Boolean): A = { assert(cond(x)); x } + def ensuring(cond: A => Boolean, msg: Any): A = { assert(cond(x), msg); x } + } + implicit def any2Ensuring[A](x: A): Ensuring[A] = new Ensuring(x) + // tupling ------------------------------------------------------------ type Pair[+A, +B] = Tuple2[A, B] @@ -171,14 +150,6 @@ object Predef extends LowPriorityImplicits { def unapply[A, B, C](x: Tuple3[A, B, C]): Option[Tuple3[A, B, C]] = Some(x) } - class Ensuring[A](x: A) { - def ensuring(cond: Boolean): A = { assert(cond); x } - def ensuring(cond: Boolean, msg: Any): A = { assert(cond, msg); x } - def ensuring(cond: A => Boolean): A = { assert(cond(x)); x } - def ensuring(cond: A => Boolean, msg: Any): A = { assert(cond(x), msg); x } - } - implicit def any2Ensuring[A](x: A): Ensuring[A] = new Ensuring(x) - class ArrowAssoc[A](x: A) { def -> [B](y: B): Tuple2[A, B] = Tuple2(x, y) def →[B](y: B): Tuple2[A, B] = ->(y) @@ -227,19 +198,9 @@ object Predef extends LowPriorityImplicits { implicit def longWrapper(x: Long) = new runtime.RichLong(x) implicit def floatWrapper(x: Float) = new runtime.RichFloat(x) implicit def doubleWrapper(x: Double) = new runtime.RichDouble(x) - implicit def booleanWrapper(x: Boolean) = new runtime.RichBoolean(x) - implicit def augmentString(x: String): StringOps = new StringOps(x) - implicit def unaugmentString(x: StringOps): String = x.repr - - implicit def stringCanBuildFrom: CanBuildFrom[String, Char, String] = - new CanBuildFrom[String, Char, String] { - def apply(from: String) = new scala.collection.mutable.StringBuilder - def apply() = new scala.collection.mutable.StringBuilder - } - - implicit def any2stringadd(x: Any) = new runtime.StringAdd(x) + implicit def exceptionWrapper(exc: Throwable) = new runtime.RichException(exc) implicit def genericArrayOps[T](xs: Array[T]): ArrayOps[T] = (xs: AnyRef) match { // !!! drop the AnyRef and get unreachable code errors! case x: Array[AnyRef] => refArrayOps[AnyRef](x).asInstanceOf[ArrayOps[T]] @@ -266,7 +227,7 @@ object Predef extends LowPriorityImplicits { implicit def booleanArrayOps(xs: Array[Boolean]): ArrayOps[Boolean] = new ArrayOps.ofBoolean(xs) implicit def unitArrayOps(xs: Array[Unit]): ArrayOps[Unit] = new ArrayOps.ofUnit(xs) - implicit def exceptionWrapper(exc: Throwable) = new runtime.RichException(exc) + // Primitive Widenings -------------------------------------------------------------- implicit def byte2short(x: Byte): Short = x.toShort implicit def byte2int(x: Byte): Int = x.toInt @@ -293,6 +254,8 @@ object Predef extends LowPriorityImplicits { implicit def float2double(x: Float): Double = x.toDouble + // "Autoboxing" -------------------------------------------------------------- + implicit def byte2Byte(x: Byte) = java.lang.Byte.valueOf(x) implicit def short2Short(x: Short) = java.lang.Short.valueOf(x) implicit def char2Character(x: Char) = java.lang.Character.valueOf(x) @@ -302,10 +265,17 @@ object Predef extends LowPriorityImplicits { implicit def double2Double(x: Double) = java.lang.Double.valueOf(x) implicit def boolean2Boolean(x: Boolean) = java.lang.Boolean.valueOf(x) - /** any array projection can be automatically converted into an array */ - //implicit def forceArrayProjection[A](x: Array.Projection[A]): Array[A] = x.force !!! re-enable? + // Strings and CharSequences -------------------------------------------------------------- + + implicit def any2stringadd(x: Any) = new runtime.StringAdd(x) + implicit def augmentString(x: String): StringOps = new StringOps(x) + implicit def unaugmentString(x: StringOps): String = x.repr - //implicit def lazyStreamToConsable[A](xs: => Stream[A]) = new runtime.StreamCons(xs) + implicit def stringCanBuildFrom: CanBuildFrom[String, Char, String] = + new CanBuildFrom[String, Char, String] { + def apply(from: String) = new scala.collection.mutable.StringBuilder + def apply() = new scala.collection.mutable.StringBuilder + } implicit def seqToCharSequence(xs: collection.IndexedSeq[Char]): CharSequence = new CharSequence { def length: Int = xs.length @@ -321,6 +291,8 @@ object Predef extends LowPriorityImplicits { override def toString: String = xs.mkString("") } + // Type Constraints -------------------------------------------------------------- + // used, for example, in the encoding of generalized constraints // we need a new type constructor `<:<` and evidence `conforms`, as // reusing `Function2` and `identity` leads to ambiguities (any2stringadd is inferred) diff --git a/src/library/scala/collection/Iterator.scala b/src/library/scala/collection/Iterator.scala index 22b8328b1e..ea186c7a7e 100644 --- a/src/library/scala/collection/Iterator.scala +++ b/src/library/scala/collection/Iterator.scala @@ -190,13 +190,6 @@ object Iterator { xs.slice(start, start + length).iterator /** - * @param str the given string - * @return the iterator on <code>str</code> - */ - @deprecated("replaced by <code>str.iterator</code>") - def fromString(str: String): Iterator[Char] = str.iterator - - /** * @param n the product arity * @return the iterator on <code>Product<n></code>. */ diff --git a/src/library/scala/collection/Seq.scala b/src/library/scala/collection/Seq.scala index 8ae857af32..18d37eba82 100644 --- a/src/library/scala/collection/Seq.scala +++ b/src/library/scala/collection/Seq.scala @@ -54,9 +54,5 @@ object Seq extends SeqFactory[Seq] { @deprecated("use Seq(value) instead") def singleton[A](value: A) = Seq(value) - - /** Builds a singleton sequence. */ - @deprecated("use <code>Seq(x)</code> instead.") - def single[A](x: A) = singleton(x) } diff --git a/src/library/scala/collection/SeqLike.scala b/src/library/scala/collection/SeqLike.scala index 749aeacd73..661f7b7a04 100644 --- a/src/library/scala/collection/SeqLike.scala +++ b/src/library/scala/collection/SeqLike.scala @@ -617,15 +617,6 @@ trait SeqLike[+A, +Repr] extends IterableLike[A, Repr] { self => @deprecated("use `lastIndexWhere' instead") def findLastIndexOf(p: A => Boolean): Int = lastIndexWhere(p) - /** A sub-sequence starting at index <code>from</code> - * and extending up to the length of the current sequence - * - * @param from The index of the first element of the slice - * @throws IndexOutOfBoundsException if <code>from < 0</code> - */ - @deprecated("use `drop' instead") - def slice(from: Int): Seq[A] = toCollection(slice(from, length)) - @deprecated("Should be replaced by <code>(s1, s2) forall { case (x, y) => f(x, y) }</code>") def equalsWith[B](that: Seq[B])(f: (A,B) => Boolean): Boolean = { val i = this.iterator diff --git a/src/library/scala/collection/SeqProxyLike.scala b/src/library/scala/collection/SeqProxyLike.scala index df4ea77f56..1ca3bfa155 100644 --- a/src/library/scala/collection/SeqProxyLike.scala +++ b/src/library/scala/collection/SeqProxyLike.scala @@ -57,7 +57,6 @@ trait SeqProxyLike[+A, +This <: SeqLike[A, This] with Seq[A]] extends SeqLike[A, override def view = self.view override def view(from: Int, until: Int) = self.view(from, until) override def findLastIndexOf(p: A => Boolean): Int = self.lastIndexWhere(p) - override def slice(from: Int): Seq[A] = self.drop(from) override def equalsWith[B](that: Seq[B])(f: (A,B) => Boolean): Boolean = (self zip that) forall { case (x,y) => f(x,y) } override def containsSlice[B](that: Seq[B]): Boolean = self.indexOfSeq(that) != -1 } diff --git a/src/library/scala/collection/immutable/List.scala b/src/library/scala/collection/immutable/List.scala index 94732d7ad5..d22865cad4 100644 --- a/src/library/scala/collection/immutable/List.scala +++ b/src/library/scala/collection/immutable/List.scala @@ -656,26 +656,6 @@ object List extends SeqFactory[List] { 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. diff --git a/src/library/scala/collection/immutable/PagedSeq.scala b/src/library/scala/collection/immutable/PagedSeq.scala index 72e09829d4..08979ac347 100644 --- a/src/library/scala/collection/immutable/PagedSeq.scala +++ b/src/library/scala/collection/immutable/PagedSeq.scala @@ -182,7 +182,7 @@ extends scala.collection.IndexedSeq[T] /** the subsequence from index `start' up to the * length of the current sequence. */ - override def slice(start: Int) = slice(start, UndeterminedEnd) + def slice(start: Int): PagedSeq[T] = slice(start, UndeterminedEnd) /** Convert sequence to string */ override def toString = { diff --git a/src/library/scala/concurrent/SyncVar.scala b/src/library/scala/concurrent/SyncVar.scala index d64c2fa51c..d577966f17 100644 --- a/src/library/scala/concurrent/SyncVar.scala +++ b/src/library/scala/concurrent/SyncVar.scala @@ -63,17 +63,6 @@ class SyncVar[A] { notifyAll() } - @deprecated("Will be removed in 2.8. SyncVar should not allow exception by design.") - def setWithCatch(x: => A) = synchronized { - try { - this set x - } catch { - case e => - this setException e - throw e - } - } - def put(x: A) = synchronized { while (isDefined) wait() set(x) diff --git a/src/library/scala/concurrent/jolib.scala b/src/library/scala/concurrent/jolib.scala deleted file mode 100644 index c2cf5d2186..0000000000 --- a/src/library/scala/concurrent/jolib.scala +++ /dev/null @@ -1,82 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ Scala API ** -** / __/ __// _ | / / / _ | (c) 2003-2009, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | | ** -** |/ ** -\* */ - -// $Id$ - - -package scala.concurrent - -import ops._ - -/** - * Library for using join-calculus concurrent primitives in Scala. - * - * @author Vincent Cremet - * @version 1.0, 17/10/2003 - */ -@deprecated("Will be removed.") -object jolib { - - type Pattern = List[Signal] - - type Rule = PartialFunction[List[Any], Unit] - - /////////////////// JOIN DEFINITION ///////////////////////// - - class Join { - - private var ruls: List[(Pattern, Rule)] = null - - def canMatch(p: Pattern) = - p forall { s => !s.queue.isEmpty } - - def values(p: Pattern): List[Any] = - p map { s => s.queue.dequeue: Any } - - def rules(rs: (Pattern, Rule)*) = - ruls = rs.asInstanceOf[List[(Pattern, Rule)]] - - def tryMatch = - ruls find { case (p, _) => canMatch(p) } match { - case None => () => () - case Some((p, r)) => { - val args = values(p) - () => spawn(r(args)) - } - } - - } - - /////////////////// SIGNALS ///////////////////////// - - abstract class Signal(join: Join) { - type C - val queue = new collection.mutable.Queue[C] - def tryReduction(x: C) { - val continuation = join synchronized { - queue.enqueue(x) - join.tryMatch - } - continuation() - } - } - - abstract class Asynchr(join: Join) extends Signal(join) { - def apply(x: C): Unit = tryReduction(x) - } - - abstract class Synchr[A](join: Join) extends Signal(join) { - type C <: SyncVar[A] - def apply(x: C): A = { - tryReduction(x) - x.get - } - } - -} - diff --git a/src/library/scala/math/BigDecimal.scala b/src/library/scala/math/BigDecimal.scala index c379b83abf..d5a57b2c62 100644 --- a/src/library/scala/math/BigDecimal.scala +++ b/src/library/scala/math/BigDecimal.scala @@ -165,17 +165,21 @@ extends ScalaNumber with ScalaNumericConversions * which deems 2 == 2.00, whereas in java these are unequal * with unequal hashCodes. */ - override def hashCode(): Int = doubleValue.hashCode() + override def hashCode(): Int = + if (isWhole) unifiedPrimitiveHashcode + else doubleValue.hashCode() /** Compares this BigDecimal with the specified value for equality. * Will only claim equality with scala.BigDecimal and java.math.BigDecimal. */ override def equals (that: Any): Boolean = that match { - case that: BigDecimal => this equals that - case that: BigDec => this equals BigDecimal(that) - case _ => false + case that: BigDecimal => this equals that + case that: BigInt => this.toBigIntExact exists (that equals _) + case x => unifiedPrimitiveEquals(x) } + override protected def isWhole = (this remainder 1) == BigDecimal(0) + /** Compares this BigDecimal with the specified BigDecimal for equality. */ def equals (that: BigDecimal): Boolean = compare(that) == 0 diff --git a/src/library/scala/math/BigInt.scala b/src/library/scala/math/BigInt.scala index f1e89f4f53..5e4bb569b5 100644 --- a/src/library/scala/math/BigInt.scala +++ b/src/library/scala/math/BigInt.scala @@ -24,6 +24,9 @@ object BigInt { private val maxCached = 1024 private val cache = new Array[BigInt](maxCached - minCached + 1) + val MinLong = BigInt(Long.MinValue) + val MaxLong = BigInt(Long.MaxValue) + /** Constructs a <code>BigInt</code> whose value is equal to that of the * specified integer value. * @@ -112,16 +115,20 @@ object BigInt { class BigInt(val bigInteger: BigInteger) extends ScalaNumber with ScalaNumericConversions { /** Returns the hash code for this BigInt. */ - override def hashCode(): Int = this.bigInteger.hashCode() + override def hashCode(): Int = + if (this >= BigInt.MinLong && this <= BigInt.MaxLong) unifiedPrimitiveHashcode + else bigInteger.hashCode /** Compares this BigInt with the specified value for equality. */ override def equals(that: Any): Boolean = that match { - case that: BigInt => this equals that - case that: BigInteger => this equals new BigInt(that) - case _ => false + case that: BigInt => this equals that + case that: BigDecimal => that.toBigIntExact exists (this equals _) + case x => unifiedPrimitiveEquals(x) } + override protected def isWhole = true + /** Compares this BigInt with the specified BigInt for equality. */ def equals (that: BigInt): Boolean = compare(that) == 0 diff --git a/src/library/scala/math/ScalaNumber.java b/src/library/scala/math/ScalaNumber.java index bb54a5d9c0..4ade1dee14 100644 --- a/src/library/scala/math/ScalaNumber.java +++ b/src/library/scala/math/ScalaNumber.java @@ -17,4 +17,5 @@ package scala.math; * @since 2.8 */ public abstract class ScalaNumber extends java.lang.Number { + protected abstract boolean isWhole(); } diff --git a/src/library/scala/math/ScalaNumericConversions.scala b/src/library/scala/math/ScalaNumericConversions.scala index 53465c7438..cc30d5d756 100644 --- a/src/library/scala/math/ScalaNumericConversions.scala +++ b/src/library/scala/math/ScalaNumericConversions.scala @@ -8,10 +8,12 @@ package scala.math +import java.{ lang => jl } + /** Conversions which present a consistent conversion interface * across all the numeric types. */ -trait ScalaNumericConversions extends java.lang.Number { +trait ScalaNumericConversions extends ScalaNumber { def toChar = intValue.toChar def toByte = byteValue def toShort = shortValue @@ -19,4 +21,27 @@ trait ScalaNumericConversions extends java.lang.Number { def toLong = longValue def toFloat = floatValue def toDouble = doubleValue + + def isValidByte = isWhole && (toByte == toInt) + def isValidShort = isWhole && (toShort == toInt) + def isValidInt = isWhole && (toInt == toLong) + def isValidChar = isWhole && (toInt >= Char.MinValue && toInt <= Char.MaxValue) + + protected def unifiedPrimitiveHashcode() = { + val lv = toLong + if (lv >= Int.MinValue && lv <= Int.MaxValue) lv.toInt + else lv.hashCode + } + + protected def unifiedPrimitiveEquals(x: Any) = x match { + case x: Char => isValidChar && (toInt == x.toInt) + case x: Byte => isValidByte && (toByte == x) + case x: Short => isValidShort && (toShort == x) + case x: Int => isValidInt && (toInt == x) + case x: Long => toLong == x // XXX + case x: Float => toFloat == x // XXX + case x: Double => toDouble == x // XXX + case x: Number => this equals x + case _ => false + } } diff --git a/src/library/scala/package.scala b/src/library/scala/package.scala index e45e5cebe7..7c25757e57 100644 --- a/src/library/scala/package.scala +++ b/src/library/scala/package.scala @@ -10,6 +10,21 @@ package object scala { + type Throwable = java.lang.Throwable + type Exception = java.lang.Exception + type Error = java.lang.Error + + type RuntimeException = java.lang.RuntimeException + type NullPointerException = java.lang.NullPointerException + type ClassCastException = java.lang.ClassCastException + type IndexOutOfBoundsException = java.lang.IndexOutOfBoundsException + type ArrayIndexOutOfBoundsException = java.lang.ArrayIndexOutOfBoundsException + type StringIndexOutOfBoundsException = java.lang.StringIndexOutOfBoundsException + type UnsupportedOperationException = java.lang.UnsupportedOperationException + type IllegalArgumentException = java.lang.IllegalArgumentException + type NoSuchElementException = java.util.NoSuchElementException + type NumberFormatException = java.lang.NumberFormatException + type AbstractMethodError = java.lang.AbstractMethodError type Traversable[+A] = scala.collection.Traversable[A] val Traversable = scala.collection.Traversable @@ -49,6 +64,11 @@ package object scala { type Range = scala.collection.immutable.Range val Range = scala.collection.immutable.Range + // Migrated from Predef + + val $scope = scala.xml.TopScope + def currentThread = java.lang.Thread.currentThread() + // Numeric types which were moved into scala.math.* type BigDecimal = scala.math.BigDecimal @@ -73,6 +93,11 @@ package object scala { type PartialOrdering[T] = scala.math.PartialOrdering[T] type PartiallyOrdered[T] = scala.math.PartiallyOrdered[T] + @deprecated("use <code>java.lang.Integer</code> instead") + type Integer = java.lang.Integer + @deprecated("use <code>java.lang.Character</code> instead") + type Character = java.lang.Character + @deprecated("use Iterable instead") type Collection[+A] = Iterable[A] @deprecated("use Iterable instead") val Collection = Iterable diff --git a/src/library/scala/ref/Reference.scala b/src/library/scala/ref/Reference.scala index 4fa69f77b3..ea25b48bee 100644 --- a/src/library/scala/ref/Reference.scala +++ b/src/library/scala/ref/Reference.scala @@ -15,12 +15,10 @@ package scala.ref * @author Sean McDirmid */ trait Reference[+T <: AnyRef] extends Function0[T] { - @deprecated("Use .get.isDefined instead") - def isValid: Boolean /** return the underlying value */ def apply(): T /** return <code>Some</code> underlying if it hasn't been collected, otherwise <code>None</code> */ - def get : Option[T] + def get: Option[T] override def toString = get.map(_.toString).getOrElse("<deleted>") def clear(): Unit def enqueue(): Boolean diff --git a/src/library/scala/ref/ReferenceWrapper.scala b/src/library/scala/ref/ReferenceWrapper.scala index a562e56c3a..2793876d51 100644 --- a/src/library/scala/ref/ReferenceWrapper.scala +++ b/src/library/scala/ref/ReferenceWrapper.scala @@ -15,7 +15,6 @@ package scala.ref */ trait ReferenceWrapper[+T <: AnyRef] extends Reference[T] with Proxy { val underlying: java.lang.ref.Reference[_ <: T] - @deprecated("Use .get.isDefined instead") def isValid = underlying.get != null override def get = { val ret = underlying.get if (ret eq null) None else Some(ret) diff --git a/src/library/scala/runtime/BoxesRunTime.java b/src/library/scala/runtime/BoxesRunTime.java index 39ea9abcdd..869eb375ac 100644 --- a/src/library/scala/runtime/BoxesRunTime.java +++ b/src/library/scala/runtime/BoxesRunTime.java @@ -140,29 +140,37 @@ public class BoxesRunTime /* COMPARISON ... COMPARISON ... COMPARISON ... COMPARISON ... COMPARISON ... COMPARISON */ - // That's the method we should use from now on. + /** Since all applicable logic has to be present in the equals method of a ScalaNumber + * in any case, we dispatch to it as soon as we spot one on either side. + */ public static boolean equals(Object x, Object y) { if (x instanceof Number) { + if (x instanceof ScalaNumber) + return x.equals(y); + Number xn = (Number)x; if (y instanceof Number) { - Number yn = (Number)y; - if ((y instanceof ScalaNumber) && !(x instanceof ScalaNumber)) { + if (y instanceof ScalaNumber) return y.equals(x); - } + + Number yn = (Number)y; if ((xn instanceof Double) || (yn instanceof Double)) return xn.doubleValue() == yn.doubleValue(); if ((xn instanceof Float) || (yn instanceof Float)) return xn.floatValue() == yn.floatValue(); if ((xn instanceof Long) || (yn instanceof Long)) return xn.longValue() == yn.longValue(); - return xn.intValue() == yn.intValue(); + if (typeCode(x) <= INT && typeCode(y) <= INT) + return xn.intValue() == yn.intValue(); + + return x.equals(y); } if (y instanceof Character) return equalsNumChar(xn, (Character)y); } else if (x instanceof Character) { Character xc = (Character)x; if (y instanceof Character) - return (xc.charValue() == ((Character)y).charValue()); + return xc.equals(y); if (y instanceof Number) return equalsNumChar((Number)y, xc); } else if (x == null) { @@ -181,7 +189,10 @@ public class BoxesRunTime return x.longValue() == ch; if (x instanceof ScalaNumber) return x.equals(y); - return x.intValue() == ch; + if (typeCode(x) <= INT) + return x.intValue() == ch; + + return x.equals(y); } /** Hashcode algorithm is driven by the requirements imposed diff --git a/src/library/scala/runtime/StreamCons.scala b/src/library/scala/runtime/StreamCons.scala deleted file mode 100644 index 96b236f8cf..0000000000 --- a/src/library/scala/runtime/StreamCons.scala +++ /dev/null @@ -1,17 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ Scala API ** -** / __/ __// _ | / / / _ | (c) 2002-2009, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | | ** -** |/ ** -\* */ - -// $Id$ - - -package scala.runtime - -final class StreamCons[T](xs: => Stream[T]) { - def lazy_:: (x: T): Stream[T] = Stream.cons(x, xs) - def lazy_::: (ys: Stream[T]): Stream[T] = ys append xs -} diff --git a/src/library/scala/unsealed.scala b/src/library/scala/unsealed.scala deleted file mode 100644 index 458d971555..0000000000 --- a/src/library/scala/unsealed.scala +++ /dev/null @@ -1,18 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ Scala API ** -** / __/ __// _ | / / / _ | (c) 2002-2009, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | | ** -** |/ ** -\* */ - -// $Id$ - - -package scala - -/** - * @since 2.4 - */ -@deprecated("use `unchecked' instead") -class unsealed extends Annotation diff --git a/src/library/scala/util/parsing/input/CharArrayPosition.scala b/src/library/scala/util/parsing/input/CharArrayPosition.scala deleted file mode 100644 index 54907e037e..0000000000 --- a/src/library/scala/util/parsing/input/CharArrayPosition.scala +++ /dev/null @@ -1,44 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ Scala API ** -** / __/ __// _ | / / / _ | (c) 2006-2009, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | | ** -** |/ ** -\* */ - -// $Id$ - -package scala.util.parsing.input - -/** <code>CharArrayPosition</code> implements the general <code>Position</code> - * class for documents represented by an <code>Array</code> of `char's. - * - * @param source The contents of the document in which this position is contained - * @param line The line number of the position (1-based) - * @param columm The column number of the position (1-based) - * - * @author Martin Odersky, Adriaan Moors - */ -@deprecated("use OffsetPosition instead") -class CharArrayPosition(val source: Array[Char], val line: Int, val column: Int) extends Position { - - // TODO: this could be implemented more high-level: - // return the string representation of the sub-array of source that starts - // after the (lnum-1)'ed '\n' up to (but not including) the (lnum)'ed '\n' - protected def lineContents = { - var i = 0 - var l = 1 - while (i < source.length && l < line) { - while (i < source.length && source(i) != '\n') i += 1 - i += 1 - l += 1 - } - var chars = new StringBuffer - while (i < source.length && source(i) != '\n') { - chars append source(i) - i += 1 - } - chars.toString - } -} - diff --git a/src/library/scala/util/parsing/input/CharArrayReader.scala b/src/library/scala/util/parsing/input/CharArrayReader.scala index 360820608c..713636796b 100644 --- a/src/library/scala/util/parsing/input/CharArrayReader.scala +++ b/src/library/scala/util/parsing/input/CharArrayReader.scala @@ -16,9 +16,6 @@ package scala.util.parsing.input */ object CharArrayReader { final val EofCh = '\032' - - @deprecated("This should probably be LF instead?") - final val CR = '\015' } /** A character array reader reads a stream of characters (keeping track of their positions) diff --git a/src/library/scala/xml/Utility.scala b/src/library/scala/xml/Utility.scala index 0628de8922..2613da6c61 100644 --- a/src/library/scala/xml/Utility.scala +++ b/src/library/scala/xml/Utility.scala @@ -74,9 +74,6 @@ object Utility extends AnyRef with parsing.TokenTests case _ => n } - @deprecated("a string might also be Atom(s) - define your own conversion") - def view(s: String): Text = Text(s) - /** * Escapes the characters < > & and " from string. * diff --git a/src/partest/scala/tools/partest/nest/Worker.scala b/src/partest/scala/tools/partest/nest/Worker.scala index 2e2049ffbe..641950f7b9 100644 --- a/src/partest/scala/tools/partest/nest/Worker.scala +++ b/src/partest/scala/tools/partest/nest/Worker.scala @@ -125,10 +125,9 @@ class Worker(val fileManager: FileManager) extends Actor { val classpath: List[URL] = outDir.toURL :: //List(file.getParentFile.toURL) ::: - List(latestCompFile.toURL, latestLibFile.toURL, - latestActFile.toURL, latestPartestFile.toURL) ::: - (List.fromString(CLASSPATH, File.pathSeparatorChar) map { x => - (new File(x)).toURL }) + List(latestCompFile.toURL, latestLibFile.toURL, latestActFile.toURL, latestPartestFile.toURL) ::: + ((CLASSPATH split File.pathSeparatorChar).toList map (x => new File(x).toURL)) + NestUI.verbose("ObjectRunner classpath: "+classpath) try { @@ -589,7 +588,7 @@ class Worker(val fileManager: FileManager) extends Actor { "-d "+outDir.getCanonicalFile.getAbsolutePath+ " -Xresident"+ " -sourcepath "+sourcepath - val argList = List.fromString(argString, ' ') + val argList = argString split ' ' toList // configure input/output files val logOut = new FileOutputStream(logFile) @@ -610,7 +609,7 @@ class Worker(val fileManager: FileManager) extends Actor { val resCompile = (line: String) => { NestUI.verbose("compiling "+line) - val cmdArgs = List.fromString(line, ' ') map { fs => new File(dir, fs).getAbsolutePath } + val cmdArgs = (line split ' ').toList map (fs => new File(dir, fs).getAbsolutePath) NestUI.verbose("cmdArgs: "+cmdArgs) val sett = new Settings(error) sett.sourcepath.value = sourcepath diff --git a/test/files/run/equality.scala b/test/files/run/equality.scala new file mode 100644 index 0000000000..5b9ad207da --- /dev/null +++ b/test/files/run/equality.scala @@ -0,0 +1,36 @@ +// a quickly assembled test of equality. Needs work. +object Test +{ + def makeFromInt(x: Int) = List( + x.toByte, x.toShort, x.toInt, x.toLong, x.toFloat, x.toDouble, BigInt(x), BigDecimal(x) + ) ::: ( + if (x < 0) Nil else List(x.toChar) + ) + def makeFromDouble(x: Double) = List( + x.toShort, x.toInt, x.toLong, x.toFloat, x.toDouble, BigInt(x.toInt), BigDecimal(x) + ) + + def main(args: Array[String]): Unit = { + var xs = makeFromInt(5) + for (x <- xs ; y <- xs) { + assert(x == y, x + " == " + y) + assert(hash(x) == hash(y), "hash(%s) == hash(%s)".format(x, y)) + } + + xs = makeFromInt(-5) + for (x <- xs ; y <- xs) { + assert(x == y, x + " == " + y) + assert(hash(x) == hash(y), "hash(%s) == hash(%s)".format(x, y)) + } + + xs = makeFromDouble(500.0) + for (x <- xs ; y <- xs) { + assert(x == y, x + " == " + y) + assert(hash(x) == hash(y), "hash(%s) == hash(%s)".format(x, y)) + } + + // negatives + val bigLong = new java.util.concurrent.atomic.AtomicLong(Long.MaxValue) + assert(-1 != bigLong && bigLong != -1) // bigLong.intValue() == -1 + } +} diff --git a/test/files/run/t2594_tcpoly.check b/test/files/run/t2594_tcpoly.check new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/test/files/run/t2594_tcpoly.check diff --git a/test/files/run/t2594_tcpoly.scala b/test/files/run/t2594_tcpoly.scala new file mode 100644 index 0000000000..e759ca8b0f --- /dev/null +++ b/test/files/run/t2594_tcpoly.scala @@ -0,0 +1,18 @@ +trait Monad[M[_]] { + def foo[A](a: M[A]): M[A] +} + +class Bar[A, B] +class Bar1[A] { type And[B] = Bar[A, B] } + +object Test { + // the combination of partial applications and anonymous class is essential to reproduce the bug + // problem: missing bridge method + // --> abstractmethoderror `Main$$anon$1.foo(Ljava/lang/Object;)Ljava/lang/Object;` + // the anonymous class only gets `public Bar foo(Bar a)` + def BarMonad[X] = new Monad[Bar1[X]#And] { + def foo[A](a: Bar[X, A]) = a + } + + def main(as: Array[String]) { BarMonad[Int] foo (new Bar[Int, Int]) } +}
\ No newline at end of file |