summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGrzegorz Kossakowski <grzegorz.kossakowski@gmail.com>2012-10-03 09:37:08 -0700
committerGrzegorz Kossakowski <grzegorz.kossakowski@gmail.com>2012-10-03 09:37:08 -0700
commit5132659241e25b7695b3203fe0bc5c81c17b65d3 (patch)
treea271163aa9d6a9c79b1d5f03297bc9296b101fb8 /src
parentd85224b3a1b0884172ee6985b643a2dda49094d6 (diff)
parent9b2154e43a8a138e561a004ccab85660d3c0b4dd (diff)
downloadscala-5132659241e25b7695b3203fe0bc5c81c17b65d3.tar.gz
scala-5132659241e25b7695b3203fe0bc5c81c17b65d3.tar.bz2
scala-5132659241e25b7695b3203fe0bc5c81c17b65d3.zip
Merge pull request #1452 from gkossakowski/master
Merge remote-tracking branch 'scala/2.10.x' into master
Diffstat (limited to 'src')
-rw-r--r--src/actors-migration/scala/actors/migration/ActorDSL.scala56
-rw-r--r--src/actors-migration/scala/actors/migration/MigrationSystem.scala37
-rw-r--r--src/actors-migration/scala/actors/migration/StashingActor.scala12
-rw-r--r--src/actors/scala/actors/ActorRef.scala2
-rw-r--r--src/compiler/scala/reflect/reify/utils/Extractors.scala13
-rw-r--r--src/compiler/scala/tools/nsc/Global.scala4
-rw-r--r--src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala11
-rw-r--r--src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala5
-rw-r--r--src/compiler/scala/tools/nsc/doc/html/HtmlPage.scala2
-rw-r--r--src/compiler/scala/tools/nsc/doc/model/ModelFactory.scala2
-rw-r--r--src/compiler/scala/tools/nsc/doc/model/comment/CommentFactory.scala2
-rw-r--r--src/compiler/scala/tools/nsc/interactive/CompilerControl.scala6
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Infer.scala15
-rw-r--r--src/library/rootdoc.txt21
-rw-r--r--src/library/scala/StringContext.scala15
-rw-r--r--src/library/scala/annotation/migration.scala2
-rw-r--r--src/library/scala/collection/TraversableOnce.scala4
-rw-r--r--src/library/scala/collection/immutable/BitSet.scala4
-rw-r--r--src/library/scala/collection/immutable/RedBlack.scala2
-rw-r--r--src/library/scala/collection/immutable/TreeMap.scala2
-rw-r--r--src/library/scala/collection/immutable/TreeSet.scala2
-rw-r--r--src/library/scala/language.scala79
-rw-r--r--src/library/scala/testing/Show.scala2
-rw-r--r--src/library/scala/throws.scala6
-rw-r--r--src/library/scala/util/Either.scala2
-rwxr-xr-xsrc/library/scala/xml/Elem.scala2
-rwxr-xr-xsrc/library/scala/xml/Utility.scala2
-rw-r--r--src/reflect/scala/reflect/internal/AnnotationInfos.scala21
-rw-r--r--src/reflect/scala/reflect/internal/Definitions.scala2
-rw-r--r--src/reflect/scala/reflect/internal/Printers.scala3
-rw-r--r--src/reflect/scala/reflect/internal/Symbols.scala6
-rw-r--r--src/reflect/scala/reflect/internal/Types.scala111
32 files changed, 324 insertions, 131 deletions
diff --git a/src/actors-migration/scala/actors/migration/ActorDSL.scala b/src/actors-migration/scala/actors/migration/ActorDSL.scala
new file mode 100644
index 0000000000..b8cb8ec998
--- /dev/null
+++ b/src/actors-migration/scala/actors/migration/ActorDSL.scala
@@ -0,0 +1,56 @@
+/* __ *\
+** ________ ___ / / ___ Scala API **
+** / __/ __// _ | / / / _ | (c) 2005-2011, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
+** /____/\___/_/ |_/____/_/ | | **
+** |/ **
+\* */
+
+package scala.actors
+package migration
+
+import scala.actors.{ Actor, ActorRef, InternalActorRef }
+import scala.collection.immutable
+import scala.reflect.ClassTag
+
+object ActorDSL {
+
+ private[migration] val contextStack = new ThreadLocal[immutable.Stack[Boolean]] {
+ override def initialValue() = immutable.Stack[Boolean]()
+ }
+
+ private[this] def withCleanContext(block: => ActorRef): ActorRef = {
+ // push clean marker
+ val old = contextStack.get
+ contextStack.set(old.push(true))
+ try {
+ val instance = block
+
+ if (instance eq null)
+ throw new Exception("ActorRef can't be 'null'")
+
+ instance
+ } finally {
+ val stackAfter = contextStack.get
+ if (stackAfter.nonEmpty)
+ contextStack.set(if (!stackAfter.head) stackAfter.pop.pop else stackAfter.pop)
+ }
+ }
+
+ /**
+ * Create an actor from the given thunk which must produce an [[scala.actors.Actor]].
+ *
+ * @param ctor is a by-name argument which captures an [[scala.actors.Actor]]
+ * factory; <b>do not make the generated object accessible to code
+ * outside and do not return the same object upon subsequent invocations.</b>
+ */
+ def actor[T <: InternalActor: ClassTag](ctor: ⇒ T): ActorRef = {
+ withCleanContext {
+ val newActor = ctor
+ val newRef = new InternalActorRef(newActor)
+ newActor.start()
+ newRef
+ }
+ }
+
+}
diff --git a/src/actors-migration/scala/actors/migration/MigrationSystem.scala b/src/actors-migration/scala/actors/migration/MigrationSystem.scala
deleted file mode 100644
index 3dcb38e634..0000000000
--- a/src/actors-migration/scala/actors/migration/MigrationSystem.scala
+++ /dev/null
@@ -1,37 +0,0 @@
-package scala.actors.migration
-
-import scala.actors._
-import scala.collection._
-
-object MigrationSystem {
-
- private[migration] val contextStack = new ThreadLocal[immutable.Stack[Boolean]] {
- override def initialValue() = immutable.Stack[Boolean]()
- }
-
- private[this] def withCleanContext(block: => ActorRef): ActorRef = {
- // push clean marker
- val old = contextStack.get
- contextStack.set(old.push(true))
- try {
- val instance = block
-
- if (instance eq null)
- throw new Exception("Actor instance passed to actorOf can't be 'null'")
-
- instance
- } finally {
- val stackAfter = contextStack.get
- if (stackAfter.nonEmpty)
- contextStack.set(if (!stackAfter.head) stackAfter.pop.pop else stackAfter.pop)
- }
- }
-
- def actorOf(props: Props): ActorRef = withCleanContext {
- val creator = props.creator()
- val r = new InternalActorRef(creator)
- creator.start()
- r
- }
-
-} \ No newline at end of file
diff --git a/src/actors-migration/scala/actors/migration/StashingActor.scala b/src/actors-migration/scala/actors/migration/StashingActor.scala
index d0a1432e72..12bad2ed1c 100644
--- a/src/actors-migration/scala/actors/migration/StashingActor.scala
+++ b/src/actors-migration/scala/actors/migration/StashingActor.scala
@@ -13,7 +13,7 @@ object StashingActor extends Combinators {
}
}
-@deprecated("Scala Actors are being removed from the standard library. Please refer to the migration guide.", "2.10")
+@deprecated("Scala Actors are being removed from the standard library. Please refer to the migration guide.", "2.10.0")
trait StashingActor extends InternalActor {
type Receive = PartialFunction[Any, Unit]
@@ -110,18 +110,18 @@ trait StashingActor extends InternalActor {
private[actors] var behaviorStack = immutable.Stack[PartialFunction[Any, Unit]]()
/*
- * Checks that StashingActor can be created only by MigrationSystem.actorOf method.
+ * Checks that StashingActor instances can only be created using the ActorDSL.
*/
private[this] def creationCheck(): Unit = {
// creation check (see ActorRef)
- val context = MigrationSystem.contextStack.get
+ val context = ActorDSL.contextStack.get
if (context.isEmpty)
- throw new RuntimeException("In order to create StashingActor one must use actorOf.")
+ throw new RuntimeException("In order to create a StashingActor one must use the ActorDSL object")
else {
if (!context.head)
- throw new RuntimeException("Only one actor can be created per actorOf call.")
+ throw new RuntimeException("Cannot create more than one actor")
else
- MigrationSystem.contextStack.set(context.push(false))
+ ActorDSL.contextStack.set(context.push(false))
}
}
diff --git a/src/actors/scala/actors/ActorRef.scala b/src/actors/scala/actors/ActorRef.scala
index 5e0ca1554a..cca78b0832 100644
--- a/src/actors/scala/actors/ActorRef.scala
+++ b/src/actors/scala/actors/ActorRef.scala
@@ -8,7 +8,7 @@ import scala.concurrent.ExecutionContext.Implicits.global
/**
* Trait used for migration of Scala actors to Akka.
*/
-@deprecated("ActorRef ought to be used only with the Actor Migration Kit.")
+@deprecated("ActorRef ought to be used only with the Actor Migration Kit.", "2.10.0")
trait ActorRef {
/**
diff --git a/src/compiler/scala/reflect/reify/utils/Extractors.scala b/src/compiler/scala/reflect/reify/utils/Extractors.scala
index b7206eda0e..b60d15c1d4 100644
--- a/src/compiler/scala/reflect/reify/utils/Extractors.scala
+++ b/src/compiler/scala/reflect/reify/utils/Extractors.scala
@@ -92,11 +92,18 @@ trait Extractors {
Block(List(universeAlias, mirrorAlias), wrappee)
}
+ // if we're reifying a MethodType, we can't use it as a type argument for TypeTag ctor
+ // http://groups.google.com/group/scala-internals/browse_thread/thread/2d7bb85bfcdb2e2
+ private def mkTarg(tpe: Type): Tree = (
+ if ((tpe eq null) || !isUseableAsTypeArg(tpe)) TypeTree(AnyTpe)
+ else TypeTree(tpe)
+ )
+
object ReifiedTree {
def apply(universe: Tree, mirror: Tree, symtab: SymbolTable, rtree: Tree, tpe: Type, rtpe: Tree, concrete: Boolean): Tree = {
val tagFactory = if (concrete) nme.TypeTag else nme.WeakTypeTag
- val tagCtor = TypeApply(Select(Select(Ident(nme.UNIVERSE_SHORT), tagFactory), nme.apply), List(TypeTree(tpe)))
- val exprCtor = TypeApply(Select(Select(Ident(nme.UNIVERSE_SHORT), nme.Expr), nme.apply), List(TypeTree(tpe)))
+ val tagCtor = TypeApply(Select(Select(Ident(nme.UNIVERSE_SHORT), tagFactory), nme.apply), List(mkTarg(tpe)))
+ val exprCtor = TypeApply(Select(Select(Ident(nme.UNIVERSE_SHORT), nme.Expr), nme.apply), List(mkTarg(tpe)))
val tagArgs = List(Ident(nme.MIRROR_SHORT), mkCreator(tpnme.REIFY_TYPECREATOR_PREFIX, symtab, rtpe))
val unwrapped = Apply(Apply(exprCtor, List(Ident(nme.MIRROR_SHORT), mkCreator(tpnme.REIFY_TREECREATOR_PREFIX, symtab, rtree))), List(Apply(tagCtor, tagArgs)))
mkWrapper(universe, mirror, unwrapped)
@@ -123,7 +130,7 @@ trait Extractors {
object ReifiedType {
def apply(universe: Tree, mirror: Tree, symtab: SymbolTable, tpe: Type, rtpe: Tree, concrete: Boolean) = {
val tagFactory = if (concrete) nme.TypeTag else nme.WeakTypeTag
- val ctor = TypeApply(Select(Select(Ident(nme.UNIVERSE_SHORT), tagFactory), nme.apply), List(TypeTree(tpe)))
+ val ctor = TypeApply(Select(Select(Ident(nme.UNIVERSE_SHORT), tagFactory), nme.apply), List(mkTarg(tpe)))
val args = List(Ident(nme.MIRROR_SHORT), mkCreator(tpnme.REIFY_TYPECREATOR_PREFIX, symtab, rtpe))
val unwrapped = Apply(ctor, args)
mkWrapper(universe, mirror, unwrapped)
diff --git a/src/compiler/scala/tools/nsc/Global.scala b/src/compiler/scala/tools/nsc/Global.scala
index 0252f9677c..cb5e2ad555 100644
--- a/src/compiler/scala/tools/nsc/Global.scala
+++ b/src/compiler/scala/tools/nsc/Global.scala
@@ -1001,7 +1001,7 @@ class Global(var currentSettings: Settings, var reporter: Reporter)
*
* @param sym A class symbol, object symbol, package, or package class.
*/
- @deprecated("use invalidateClassPathEntries instead")
+ @deprecated("use invalidateClassPathEntries instead", "2.10.0")
def clearOnNextRun(sym: Symbol) = false
/* To try out clearOnNext run on the scala.tools.nsc project itself
* replace `false` above with the following code
@@ -1259,7 +1259,7 @@ class Global(var currentSettings: Settings, var reporter: Reporter)
/** Reset all classes contained in current project, as determined by
* the clearOnNextRun hook
*/
- @deprecated("use invalidateClassPathEntries instead")
+ @deprecated("use invalidateClassPathEntries instead", "2.10.0")
def resetProjectClasses(root: Symbol): Unit = try {
def unlink(sym: Symbol) =
if (sym != NoSymbol) root.info.decls.unlink(sym)
diff --git a/src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala b/src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala
index 85ad5a6884..5b87e5427c 100644
--- a/src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala
+++ b/src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala
@@ -839,15 +839,10 @@ abstract class GenASM extends SubComponent with BytecodeWriters {
*
* The contents of that attribute are determined by the `String[] exceptions` argument to ASM's ClassVisitor.visitMethod()
* This method returns such list of internal names.
- *
*/
- def getExceptions(excs: List[AnnotationInfo]): List[String] = {
- for (AnnotationInfo(tp, List(exc), _) <- excs.distinct if tp.typeSymbol == ThrowsClass)
- yield {
- val Literal(const) = exc
- javaName(const.typeValue.typeSymbol)
- }
- }
+ def getExceptions(excs: List[AnnotationInfo]): List[String] =
+ for (ThrownException(exc) <- excs.distinct)
+ yield javaName(exc)
/** Whether an annotation should be emitted as a Java annotation
* .initialize: if 'annot' is read from pickle, atp might be un-initialized
diff --git a/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala b/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala
index 660e88b173..e11704d694 100644
--- a/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala
+++ b/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala
@@ -606,11 +606,10 @@ abstract class GenJVM extends SubComponent with GenJVMUtil with GenAndroid with
// put some random value; the actual number is determined at the end
buf putShort 0xbaba.toShort
- for (AnnotationInfo(tp, List(exc), _) <- excs.distinct if tp.typeSymbol == ThrowsClass) {
- val Literal(const) = exc
+ for (ThrownException(exc) <- excs.distinct) {
buf.putShort(
cpool.addClass(
- javaName(const.typeValue.typeSymbol)).shortValue)
+ javaName(exc)).shortValue)
nattr += 1
}
diff --git a/src/compiler/scala/tools/nsc/doc/html/HtmlPage.scala b/src/compiler/scala/tools/nsc/doc/html/HtmlPage.scala
index 2c719e5d70..b47e9f5784 100644
--- a/src/compiler/scala/tools/nsc/doc/html/HtmlPage.scala
+++ b/src/compiler/scala/tools/nsc/doc/html/HtmlPage.scala
@@ -117,7 +117,7 @@ abstract class HtmlPage extends Page { thisPage =>
case Underline(in) => <u>{ inlineToHtml(in) }</u>
case Superscript(in) => <sup>{ inlineToHtml(in) }</sup>
case Subscript(in) => <sub>{ inlineToHtml(in) }</sub>
- case Link(raw, title) => <a href={ raw }>{ inlineToHtml(title) }</a>
+ case Link(raw, title) => <a href={ raw } target="_blank">{ inlineToHtml(title) }</a>
case Monospace(in) => <code>{ inlineToHtml(in) }</code>
case Text(text) => scala.xml.Text(text)
case Summary(in) => inlineToHtml(in)
diff --git a/src/compiler/scala/tools/nsc/doc/model/ModelFactory.scala b/src/compiler/scala/tools/nsc/doc/model/ModelFactory.scala
index 15189bdcac..906c17faa0 100644
--- a/src/compiler/scala/tools/nsc/doc/model/ModelFactory.scala
+++ b/src/compiler/scala/tools/nsc/doc/model/ModelFactory.scala
@@ -845,7 +845,7 @@ class ModelFactory(val global: Global, val settings: doc.Settings) {
inTpl.members.find(_.sym == aSym)
}
- @deprecated("2.10", "Use findLinkTarget instead!")
+ @deprecated("Use `findLinkTarget` instead.", "2.10.0")
def findTemplate(query: String): Option[DocTemplateImpl] = {
assert(modelFinished)
docTemplatesCache.values find { (tpl: DocTemplateImpl) => tpl.qualifiedName == query && !packageDropped(tpl) && !tpl.isObject }
diff --git a/src/compiler/scala/tools/nsc/doc/model/comment/CommentFactory.scala b/src/compiler/scala/tools/nsc/doc/model/comment/CommentFactory.scala
index 1baa7f9831..924ebb8a3b 100644
--- a/src/compiler/scala/tools/nsc/doc/model/comment/CommentFactory.scala
+++ b/src/compiler/scala/tools/nsc/doc/model/comment/CommentFactory.scala
@@ -147,7 +147,7 @@ trait CommentFactory { thisFactory: ModelFactory with CommentFactory with Member
case (group, body) =>
try {
body match {
- case Body(List(Paragraph(Chain(List(Summary(Text(prio))))))) => List(group -> prio.toInt)
+ case Body(List(Paragraph(Chain(List(Summary(Text(prio))))))) => List(group -> prio.trim.toInt)
case _ => List()
}
} catch {
diff --git a/src/compiler/scala/tools/nsc/interactive/CompilerControl.scala b/src/compiler/scala/tools/nsc/interactive/CompilerControl.scala
index 3de2359ce3..ae38a082ca 100644
--- a/src/compiler/scala/tools/nsc/interactive/CompilerControl.scala
+++ b/src/compiler/scala/tools/nsc/interactive/CompilerControl.scala
@@ -69,11 +69,11 @@ trait CompilerControl { self: Global =>
* if it does not yet exist create a new one atomically
* Note: We want to get roid of this operation as it messes compiler invariants.
*/
- @deprecated("use getUnitOf(s) or onUnitOf(s) instead")
+ @deprecated("use getUnitOf(s) or onUnitOf(s) instead", "2.10.0")
def unitOf(s: SourceFile): RichCompilationUnit = getOrCreateUnitOf(s)
/** The compilation unit corresponding to a position */
- @deprecated("use getUnitOf(pos.source) or onUnitOf(pos.source) instead")
+ @deprecated("use getUnitOf(pos.source) or onUnitOf(pos.source) instead", "2.10.0")
def unitOf(pos: Position): RichCompilationUnit = getOrCreateUnitOf(pos.source)
/** Removes the CompilationUnit corresponding to the given SourceFile
@@ -232,7 +232,7 @@ trait CompilerControl { self: Global =>
/** Tells the compile server to shutdown, and not to restart again */
def askShutdown() = scheduler raise ShutdownReq
- @deprecated("use parseTree(source) instead") // deleted 2nd parameter, as this has to run on 2.8 also.
+ @deprecated("use parseTree(source) instead", "2.10.0") // deleted 2nd parameter, as this has to run on 2.8 also.
def askParse(source: SourceFile, response: Response[Tree]) = respond(response) {
parseTree(source)
}
diff --git a/src/compiler/scala/tools/nsc/typechecker/Infer.scala b/src/compiler/scala/tools/nsc/typechecker/Infer.scala
index 6558379c51..d9f0c150ce 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Infer.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Infer.scala
@@ -516,7 +516,7 @@ trait Infer extends Checkable {
val tvars = tparams map freshVar
if (isConservativelyCompatible(restpe.instantiateTypeParams(tparams, tvars), pt))
map2(tparams, tvars)((tparam, tvar) =>
- instantiateToBound(tvar, inferVariance(formals, restpe)(tparam)))
+ instantiateToBound(tvar, varianceInTypes(formals)(tparam)))
else
tvars map (tvar => WildcardType)
}
@@ -646,9 +646,8 @@ trait Infer extends Checkable {
"argument expression's type is not compatible with formal parameter type" + foundReqMsg(tp1, pt1))
}
}
-
val targs = solvedTypes(
- tvars, tparams, tparams map inferVariance(formals, restpe),
+ tvars, tparams, tparams map varianceInTypes(formals),
false, lubDepth(formals) max lubDepth(argtpes)
)
// Can warn about inferring Any/AnyVal as long as they don't appear
@@ -673,16 +672,6 @@ trait Infer extends Checkable {
adjustTypeArgs(tparams, tvars, targs, restpe)
}
- /** Determine which variance to assume for the type paraneter. We first chose the variance
- * that minimizes any formal parameters. If that is still undetermined, because the type parameter
- * does not appear as a formal parameter type, then we pick the variance so that it minimizes the
- * method's result type instead.
- */
- private def inferVariance(formals: List[Type], restpe: Type)(tparam: Symbol): Int = {
- val v = varianceInTypes(formals)(tparam)
- if (v != VarianceFlags) v else varianceInType(restpe)(tparam)
- }
-
private[typechecker] def followApply(tp: Type): Type = tp match {
case NullaryMethodType(restp) =>
val restp1 = followApply(restp)
diff --git a/src/library/rootdoc.txt b/src/library/rootdoc.txt
index da27a0084b..0722d808bf 100644
--- a/src/library/rootdoc.txt
+++ b/src/library/rootdoc.txt
@@ -4,24 +4,25 @@ This is the documentation for the Scala standard library.
The [[scala]] package contains core types.
-scala.[[scala.collection]] and its subpackages contain a collections framework with higher-order functions for manipulation. Both [[scala.collection.immutable]] and [[scala.collection.mutable]] data structures are available, with immutable as the default. The [[scala.collection.parallel]] collections provide automatic parallel operation.
+[[scala.collection `scala.collection`]] and its subpackages contain a collections framework with higher-order functions for manipulation. Both [[scala.collection.immutable `scala.collection.immutable`]] and [[scala.collection.mutable `scala.collection.mutable`]] data structures are available, with immutable as the default. The [[scala.collection.parallel `scala.collection.parallel`]] collections provide automatic parallel operation.
Other important packages include:
- - scala.[[scala.actors]] - Concurrency framework inspired by Erlang.
- - scala.[[scala.io]] - Input and output.
- - scala.[[scala.math]] - Basic math functions and additional numeric types.
- - scala.[[scala.sys]] - Interaction with other processes and the operating system.
- - scala.util.[[scala.util.matching]] - Pattern matching in text using regular expressions.
- - scala.util.parsing.[[scala.util.parsing.combinator]] - Composable combinators for parsing.
- - scala.[[scala.xml]] - XML parsing, manipulation, and serialization.
+ - [[scala.actors `scala.actors`]] - Concurrency framework inspired by Erlang.
+ - [[scala.io `scala.io`]] - Input and output.
+ - [[scala.math `scala.math`]] - Basic math functions and additional numeric types.
+ - [[scala.sys `scala.sys`]] - Interaction with other processes and the operating system.
+ - [[scala.util.matching `scala.util.matching`]] - Pattern matching in text using regular expressions.
+ - [[scala.util.parsing.combinator `scala.util.parsing.combinator`]] - Composable combinators for parsing.
+ - [[scala.xml `scala.xml`]] - XML parsing, manipulation, and serialization.
Many other packages exist. See the complete list on the left.
== Automatic imports ==
-Identifiers in the scala package and the [[scala.Predef]] object are always in scope by default.
+Identifiers in the scala package and the [[scala.Predef `scala.Predef`]] object are always in scope by default.
-Some of these identifiers are type aliases provided as shortcuts to commonly used classes. For example, `List` is an alias for scala.collection.immutable.[[scala.collection.immutable.List]].
+Some of these identifiers are type aliases provided as shortcuts to commonly used classes. For example, `List` is an alias for
+[[scala.collection.immutable.List `scala.collection.immutable.List`]].
Other aliases refer to classes provided by the underlying platform. For example, on the JVM, `String` is an alias for `java.lang.String`.
diff --git a/src/library/scala/StringContext.scala b/src/library/scala/StringContext.scala
index e381c09398..4078168bb3 100644
--- a/src/library/scala/StringContext.scala
+++ b/src/library/scala/StringContext.scala
@@ -8,7 +8,7 @@
package scala
-/** This class provides the basic mechanism to do String Interpolation.
+/** This class provides the basic mechanism to do String Interpolation.
* String Interpolation allows users
* to embed variable references directly in *processed* string literals.
* Here's an example:
@@ -26,7 +26,7 @@ package scala
* is rewritten to be:
*
* {{{
- * new StringContext("Hello, ", "").s(name)
+ * StringContext("Hello, ", "").s(name)
* }}}
*
* By default, this class provides the `raw`, `s` and `f` methods as
@@ -36,7 +36,7 @@ package scala
* which adds a method to `StringContext`. Here's an example:
* {{{
* implicit class JsonHelper(val sc: StringContext) extends AnyVal {
- * def json(args: Any*): JSONObject = ...
+ * def json(args: Any*): JSONObject = ...
* }
* val x: JSONObject = json"{ a: $a }"
* }}}
@@ -72,7 +72,7 @@ case class StringContext(parts: String*) {
* println(s"Hello, $name") // Hello, James
* }}}
* In this example, the expression $name is replaced with the `toString` of the
- * variable `name`.
+ * variable `name`.
* The `s` interpolator can take the `toString` of any arbitrary expression within
* a `${}` block, for example:
* {{{
@@ -97,6 +97,13 @@ case class StringContext(parts: String*) {
*
* For example, the raw processed string `raw"a\nb"` is equal to the scala string `"a\\nb"`.
*
+ * ''Note:'' Even when using the raw interpolator, Scala will preprocess unicode escapes.
+ * For example:
+ * {{{
+ * scala> raw"\u0123"
+ * res0: String = ģ
+ * }}}
+ *
* @param `args` The arguments to be inserted into the resulting string.
* @throws An `IllegalArgumentException`
* if the number of `parts` in the enclosing `StringContext` does not exceed
diff --git a/src/library/scala/annotation/migration.scala b/src/library/scala/annotation/migration.scala
index f60c827620..a55c7006a1 100644
--- a/src/library/scala/annotation/migration.scala
+++ b/src/library/scala/annotation/migration.scala
@@ -25,6 +25,6 @@ package scala.annotation
* @since 2.8
*/
private[scala] final class migration(message: String, changedIn: String) extends scala.annotation.StaticAnnotation {
- @deprecated("Use the constructor taking two Strings instead.", "2.10")
+ @deprecated("Use the constructor taking two Strings instead.", "2.10.0")
def this(majorVersion: Int, minorVersion: Int, message: String) = this(message, majorVersion + "." + minorVersion)
}
diff --git a/src/library/scala/collection/TraversableOnce.scala b/src/library/scala/collection/TraversableOnce.scala
index d77d278fca..f912304680 100644
--- a/src/library/scala/collection/TraversableOnce.scala
+++ b/src/library/scala/collection/TraversableOnce.scala
@@ -366,9 +366,9 @@ trait TraversableOnce[+A] extends Any with GenTraversableOnce[A] {
object TraversableOnce {
- @deprecated("use OnceCanBuildFrom instead")
+ @deprecated("use OnceCanBuildFrom instead", "2.10.0")
def traversableOnceCanBuildFrom[T] = new OnceCanBuildFrom[T]
- @deprecated("use MonadOps instead")
+ @deprecated("use MonadOps instead", "2.10.0")
def wrapTraversableOnce[A](trav: TraversableOnce[A]) = new MonadOps(trav)
implicit def alternateImplicit[A](trav: TraversableOnce[A]) = new ForceImplicitAmbiguity
diff --git a/src/library/scala/collection/immutable/BitSet.scala b/src/library/scala/collection/immutable/BitSet.scala
index 1b676e2d2f..d79e2adbda 100644
--- a/src/library/scala/collection/immutable/BitSet.scala
+++ b/src/library/scala/collection/immutable/BitSet.scala
@@ -31,7 +31,7 @@ abstract class BitSet extends scala.collection.AbstractSet[Int]
with Serializable {
override def empty = BitSet.empty
- @deprecated("Use BitSet.fromBitMask[NoCopy] instead of fromArray", "2.10")
+ @deprecated("Use BitSet.fromBitMask[NoCopy] instead of fromArray", "2.10.0")
def fromArray(elems: Array[Long]): BitSet = fromBitMaskNoCopy(elems)
protected def fromBitMaskNoCopy(elems: Array[Long]): BitSet = BitSet.fromBitMaskNoCopy(elems)
@@ -82,7 +82,7 @@ object BitSet extends BitSetFactory[BitSet] {
implicit def canBuildFrom: CanBuildFrom[BitSet, Int, BitSet] = bitsetCanBuildFrom
/** A bitset containing all the bits in an array */
- @deprecated("Use fromBitMask[NoCopy] instead of fromArray", "2.10")
+ @deprecated("Use fromBitMask[NoCopy] instead of fromArray", "2.10.0")
def fromArray(elems: Array[Long]): BitSet = fromBitMaskNoCopy(elems)
/** A bitset containing all the bits in an array */
diff --git a/src/library/scala/collection/immutable/RedBlack.scala b/src/library/scala/collection/immutable/RedBlack.scala
index a3ab27f814..77e5a87e73 100644
--- a/src/library/scala/collection/immutable/RedBlack.scala
+++ b/src/library/scala/collection/immutable/RedBlack.scala
@@ -18,7 +18,7 @@ package immutable
*
* @since 2.3
*/
-@deprecated("use `TreeMap` or `TreeSet` instead", "2.10")
+@deprecated("use `TreeMap` or `TreeSet` instead", "2.10.0")
@SerialVersionUID(8691885935445612921L)
abstract class RedBlack[A] extends Serializable {
diff --git a/src/library/scala/collection/immutable/TreeMap.scala b/src/library/scala/collection/immutable/TreeMap.scala
index 51bc76efc3..f7a24f3d66 100644
--- a/src/library/scala/collection/immutable/TreeMap.scala
+++ b/src/library/scala/collection/immutable/TreeMap.scala
@@ -51,7 +51,7 @@ class TreeMap[A, +B] private (tree: RB.Tree[A, B])(implicit val ordering: Orderi
with MapLike[A, B, TreeMap[A, B]]
with Serializable {
- @deprecated("use `ordering.lt` instead", "2.10")
+ @deprecated("use `ordering.lt` instead", "2.10.0")
def isSmaller(x: A, y: A) = ordering.lt(x, y)
override protected[this] def newBuilder : Builder[(A, B), TreeMap[A, B]] =
diff --git a/src/library/scala/collection/immutable/TreeSet.scala b/src/library/scala/collection/immutable/TreeSet.scala
index 697da2bc4b..0fdb16c23b 100644
--- a/src/library/scala/collection/immutable/TreeSet.scala
+++ b/src/library/scala/collection/immutable/TreeSet.scala
@@ -96,7 +96,7 @@ class TreeSet[A] private (tree: RB.Tree[A, Unit])(implicit val ordering: Orderin
override def takeWhile(p: A => Boolean) = take(countWhile(p))
override def span(p: A => Boolean) = splitAt(countWhile(p))
- @deprecated("use `ordering.lt` instead", "2.10")
+ @deprecated("use `ordering.lt` instead", "2.10.0")
def isSmaller(x: A, y: A) = compare(x,y) < 0
def this()(implicit ordering: Ordering[A]) = this(null)(ordering)
diff --git a/src/library/scala/language.scala b/src/library/scala/language.scala
index 297f344f65..c638f531bb 100644
--- a/src/library/scala/language.scala
+++ b/src/library/scala/language.scala
@@ -1,5 +1,28 @@
package scala
+/**
+ * The `scala.language` object controls the language features available to the programmer, as proposed in the
+ * [[https://docs.google.com/document/d/1nlkvpoIRkx7at1qJEZafJwthZ3GeIklTFhqmXMvTX9Q/edit '''SIP-18 document''']].
+ *
+ * Each of these features has to be explicitly imported into the current scope to become available:
+ * {{{
+ * import language.postfixOps // or language._
+ * List(1, 2, 3) reverse
+ * }}}
+ *
+ * The language features are:
+ * - [[dynamics `dynamics`]] enables defining calls rewriting using the [[scala.Dynamic `Dynamic`]] trait
+ * - [[postfixOps `postfixOps`]] enables postfix operators
+ * - [[reflectiveCalls `reflectiveCalls`]] enables using structural types
+ * - [[implicitConversions `implicitConversions`]] enables defining implicit methods and members
+ * - [[higherKinds `higherKinds`]] enables writing higher-kinded types
+ * - [[existentials `existentials`]] enables writing existential types
+ * - [[experimental `experimental`]] contains newer features that have not yet been tested in production
+ *
+ * @groupname production Language Features
+ * @groupname experimental Experimental Language Features
+ * @groupprio experimental 10
+ */
object language {
import languageFeature._
@@ -10,21 +33,25 @@ object language {
* selection of existing subclasses of trait Dynamic are unaffected;
* they can be used anywhere.
*
- * _Why introduce the feature?_ To enable flexible DSLs and convenient interfacing
+ * '''Why introduce the feature?''' To enable flexible DSLs and convenient interfacing
* with dynamic languages.
*
- * _Why control it?_ Dynamic member selection can undermine static checkability
+ * '''Why control it?''' Dynamic member selection can undermine static checkability
* of programs. Furthermore, dynamic member selection often relies on reflection,
* which is not available on all platforms.
+ *
+ * @group production
*/
implicit lazy val dynamics: dynamics = languageFeature.dynamics
/** Only where enabled, postfix operator notation `(expr op)` will be allowed.
*
- * _Why keep the feature?_ Several DSLs written in Scala need the notation.
+ * '''Why keep the feature?''' Several DSLs written in Scala need the notation.
*
- * _Why control it?_ Postfix operators interact poorly with semicolon inference.
+ * '''Why control it?''' Postfix operators interact poorly with semicolon inference.
* Most programmers avoid them for this reason.
+ *
+ * @group production
*/
implicit lazy val postfixOps: postfixOps = languageFeature.postfixOps
@@ -34,13 +61,15 @@ object language {
* not override any member in `Parents`. To access one of these members, a
* reflective call is needed.
*
- * _Why keep the feature?_ Structural types provide great flexibility because
+ * '''Why keep the feature?''' Structural types provide great flexibility because
* they avoid the need to define inheritance hierarchies a priori. Besides,
* their definition falls out quite naturally from Scala’s concept of type refinement.
*
- * _Why control it?+ Reflection is not available on all platforms. Popular tools
+ * '''Why control it?''' Reflection is not available on all platforms. Popular tools
* such as ProGuard have problems dealing with it. Even where reflection is available,
* reflective dispatch can lead to surprising performance degradations.
+ *
+ * @group production
*/
implicit lazy val reflectiveCalls: reflectiveCalls = languageFeature.reflectiveCalls
@@ -49,32 +78,36 @@ object language {
* or an implicit method that has in its first parameter section a single,
* non-implicit parameter. Examples:
*
+ * {{{
* implicit def stringToInt(s: String): Int = s.length
* implicit val conv = (s: String) => s.length
- * implicit def listToX(xs: List[T])(implicit f: T => X): X = …
+ * implicit def listToX(xs: List[T])(implicit f: T => X): X = ...
+ * }}}
*
* implicit values of other types are not affected, and neither are implicit
* classes.
*
- * _Why keep the feature?_ Implicit conversions are central to many aspects
+ * '''Why keep the feature?''' Implicit conversions are central to many aspects
* of Scala’s core libraries.
*
- * _Why control it?_ Implicit conversions are known to cause many pitfalls
+ * '''Why control it?''' Implicit conversions are known to cause many pitfalls
* if over-used. And there is a tendency to over-use them because they look
* very powerful and their effects seem to be easy to understand. Also, in
* most situations using implicit parameters leads to a better design than
* implicit conversions.
+ *
+ * @group production
*/
implicit lazy val implicitConversions: implicitConversions = languageFeature.implicitConversions
/** Only where this flag is enabled, higher-kinded types can be written.
*
- * _Why keep the feature?_ Higher-kinded types enable the definition of very general
+ * '''Why keep the feature?''' Higher-kinded types enable the definition of very general
* abstractions such as functor, monad, or arrow. A significant set of advanced
* libraries relies on them. Higher-kinded types are also at the core of the
* scala-virtualized effort to produce high-performance parallel DSLs through staging.
*
- * _Why control it?_ Higher kinded types in Scala lead to a Turing-complete
+ * '''Why control it?''' Higher kinded types in Scala lead to a Turing-complete
* type system, where compiler termination is no longer guaranteed. They tend
* to be useful mostly for type-level computation and for highly generic design
* patterns. The level of abstraction implied by these design patterns is often
@@ -85,6 +118,8 @@ object language {
* higher-kinded types will change in future versions of Scala. So an explicit
* enabling also serves as a warning that code involving higher-kinded types
* might have to be slightly revised in the future.
+ *
+ * @group production
*/
implicit lazy val higherKinds: higherKinds = languageFeature.higherKinds
@@ -93,17 +128,31 @@ object language {
* types of methods. Existential types with wildcard type syntax such as `List[_]`,
* or `Map[String, _]` are not affected.
*
- * _Why keep the feature?_ Existential types are needed to make sense of Java’s wildcard
+ * '''Why keep the feature?''' Existential types are needed to make sense of Java’s wildcard
* types and raw types and the erased types of run-time values.
*
- * Why control it? Having complex existential types in a code base usually makes
+ * '''Why control it?''' Having complex existential types in a code base usually makes
* application code very brittle, with a tendency to produce type errors with
* obscure error messages. Therefore, going overboard with existential types
* is generally perceived not to be a good idea. Also, complicated existential types
* might be no longer supported in a future simplification of the language.
+ *
+ * @group production
*/
implicit lazy val existentials: existentials = languageFeature.existentials
+ /** The experimental object contains features that have been recently added but have not
+ * been thoroughly tested in production yet.
+ *
+ * Experimental features '''may undergo API changes''' in future releases, so production
+ * code should not rely on them.
+ *
+ * Programmers are encouraged to try out experimental features and
+ * [[http://issues.scala-lang.org report any bugs or API inconsistencies]]
+ * they encounter so they can be improved in future releases.
+ *
+ * @group experimental
+ */
object experimental {
import languageFeature.experimental._
@@ -111,12 +160,12 @@ object language {
/** Where enabled, macro definitions are allowed. Macro implementations and
* macro applications are unaffected; they can be used anywhere.
*
- * _Why introduce the feature?_ Macros promise to make the language more regular,
+ * '''Why introduce the feature?''' Macros promise to make the language more regular,
* replacing ad-hoc language constructs with a general powerful abstraction
* capability that can express them. Macros are also a more disciplined and
* powerful replacement for compiler plugins.
*
- * _Why control it?_ For their very power, macros can lead to code that is hard
+ * '''Why control it?''' For their very power, macros can lead to code that is hard
* to debug and understand.
*/
implicit lazy val macros: macros = languageFeature.experimental.macros
diff --git a/src/library/scala/testing/Show.scala b/src/library/scala/testing/Show.scala
index da1868c7f6..c6c58f5da2 100644
--- a/src/library/scala/testing/Show.scala
+++ b/src/library/scala/testing/Show.scala
@@ -37,7 +37,7 @@ trait Show {
}
}
- @deprecated("use SymApply instead", "2.10")
+ @deprecated("use SymApply instead", "2.10.0")
def symApply(sym: Symbol): SymApply = new SymApply(sym)
/** Apply method with name of given symbol `f` to given arguments and return
diff --git a/src/library/scala/throws.scala b/src/library/scala/throws.scala
index 0aa0d31c9f..02dffb00b0 100644
--- a/src/library/scala/throws.scala
+++ b/src/library/scala/throws.scala
@@ -14,7 +14,7 @@ package scala
* {{{
* class Reader(fname: String) {
* private val in = new BufferedReader(new FileReader(fname))
- * @throws(classOf[IOException])
+ * @throws[IOException]("if the file doesn't exist")
* def read() = in.read()
* }
* }}}
@@ -23,4 +23,6 @@ package scala
* @version 1.0, 19/05/2006
* @since 2.1
*/
-class throws(clazz: Class[_]) extends scala.annotation.StaticAnnotation
+class throws[T <: Throwable](cause: String = "") extends scala.annotation.StaticAnnotation {
+ def this(clazz: Class[T]) = this()
+}
diff --git a/src/library/scala/util/Either.scala b/src/library/scala/util/Either.scala
index f0253eee07..51342eda78 100644
--- a/src/library/scala/util/Either.scala
+++ b/src/library/scala/util/Either.scala
@@ -221,7 +221,7 @@ object Either {
case Right(a) => a
}
}
- @deprecated("use MergeableEither instead", "2.10")
+ @deprecated("use MergeableEither instead", "2.10.0")
def either2mergeable[A](x: Either[A, A]): MergeableEither[A] = new MergeableEither(x)
/**
diff --git a/src/library/scala/xml/Elem.scala b/src/library/scala/xml/Elem.scala
index 2ca1dbfcd0..a92d7859c3 100755
--- a/src/library/scala/xml/Elem.scala
+++ b/src/library/scala/xml/Elem.scala
@@ -59,7 +59,7 @@ class Elem(
val child: Node*)
extends Node with Serializable
{
- @deprecated("This constructor is retained for backward compatibility. Please use the primary constructor, which lets you specify your own preference for `minimizeEmpty`.", "2.10")
+ @deprecated("This constructor is retained for backward compatibility. Please use the primary constructor, which lets you specify your own preference for `minimizeEmpty`.", "2.10.0")
def this(prefix: String, label: String, attributes: MetaData, scope: NamespaceBinding, child: Node*) = {
this(prefix, label, attributes, scope, child.isEmpty, child: _*)
}
diff --git a/src/library/scala/xml/Utility.scala b/src/library/scala/xml/Utility.scala
index 50a284d7cd..b390235d59 100755
--- a/src/library/scala/xml/Utility.scala
+++ b/src/library/scala/xml/Utility.scala
@@ -175,7 +175,7 @@ object Utility extends AnyRef with parsing.TokenTests {
* Note that calling this source-compatible method will result in the same old, arguably almost universally unwanted,
* behaviour.
*/
- @deprecated("Please use `serialize` instead and specify a `minimizeTags` parameter", "2.10")
+ @deprecated("Please use `serialize` instead and specify a `minimizeTags` parameter", "2.10.0")
def toXML(
x: Node,
pscope: NamespaceBinding = TopScope,
diff --git a/src/reflect/scala/reflect/internal/AnnotationInfos.scala b/src/reflect/scala/reflect/internal/AnnotationInfos.scala
index 3bd7f4f4fa..46e4329b2e 100644
--- a/src/reflect/scala/reflect/internal/AnnotationInfos.scala
+++ b/src/reflect/scala/reflect/internal/AnnotationInfos.scala
@@ -30,7 +30,7 @@ trait AnnotationInfos extends api.Annotations { self: SymbolTable =>
/** Symbols of any @throws annotations on this symbol.
*/
def throwsAnnotations(): List[Symbol] = annotations collect {
- case AnnotationInfo(tp, Literal(Constant(tpe: Type)) :: Nil, _) if tp.typeSymbol == ThrowsClass => tpe.typeSymbol
+ case ThrownException(exc) => exc
}
/** Tests for, get, or remove an annotation */
@@ -325,4 +325,23 @@ trait AnnotationInfos extends api.Annotations { self: SymbolTable =>
implicit val AnnotationTag = ClassTag[AnnotationInfo](classOf[AnnotationInfo])
object UnmappableAnnotation extends CompleteAnnotationInfo(NoType, Nil, Nil)
+
+ /** Extracts symbol of thrown exception from AnnotationInfo.
+ *
+ * Supports both “old-style” `@throws(classOf[Exception])`
+ * as well as “new-stye” `@throws[Exception]("cause")` annotations.
+ */
+ object ThrownException {
+ def unapply(ann: AnnotationInfo): Option[Symbol] =
+ ann match {
+ case AnnotationInfo(tpe, _, _) if tpe.typeSymbol != ThrowsClass =>
+ None
+ // old-style: @throws(classOf[Exception]) (which is throws[T](classOf[Exception]))
+ case AnnotationInfo(_, List(Literal(Constant(tpe: Type))), _) =>
+ Some(tpe.typeSymbol)
+ // new-style: @throws[Exception], @throws[Exception]("cause")
+ case AnnotationInfo(TypeRef(_, _, args), _, _) =>
+ Some(args.head.typeSymbol)
+ }
+ }
}
diff --git a/src/reflect/scala/reflect/internal/Definitions.scala b/src/reflect/scala/reflect/internal/Definitions.scala
index abf11020fa..8865c762c4 100644
--- a/src/reflect/scala/reflect/internal/Definitions.scala
+++ b/src/reflect/scala/reflect/internal/Definitions.scala
@@ -957,7 +957,7 @@ trait Definitions extends api.StandardDefinitions {
lazy val ScalaNoInlineClass = requiredClass[scala.noinline]
lazy val SerialVersionUIDAttr = requiredClass[scala.SerialVersionUID]
lazy val SpecializedClass = requiredClass[scala.specialized]
- lazy val ThrowsClass = requiredClass[scala.throws]
+ lazy val ThrowsClass = requiredClass[scala.throws[_]]
lazy val TransientAttr = requiredClass[scala.transient]
lazy val UncheckedClass = requiredClass[scala.unchecked]
lazy val UnspecializedClass = requiredClass[scala.annotation.unspecialized]
diff --git a/src/reflect/scala/reflect/internal/Printers.scala b/src/reflect/scala/reflect/internal/Printers.scala
index cb8dc4b197..fb165ab50f 100644
--- a/src/reflect/scala/reflect/internal/Printers.scala
+++ b/src/reflect/scala/reflect/internal/Printers.scala
@@ -576,7 +576,8 @@ trait Printers extends api.Printers { self: SymbolTable =>
case _ => // do nothing
})
case sym: Symbol =>
- if (sym.isStatic && (sym.isClass || sym.isModule)) print(sym.fullName)
+ if (sym == NoSymbol) print("NoSymbol")
+ else if (sym.isStatic && (sym.isClass || sym.isModule)) print(sym.fullName)
else print(sym.name)
if (printIds) print("#", sym.id)
if (printKinds) print("#", sym.abbreviatedKindString)
diff --git a/src/reflect/scala/reflect/internal/Symbols.scala b/src/reflect/scala/reflect/internal/Symbols.scala
index 3adcd86c73..d7962eb62b 100644
--- a/src/reflect/scala/reflect/internal/Symbols.scala
+++ b/src/reflect/scala/reflect/internal/Symbols.scala
@@ -91,8 +91,8 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
def module = sourceModule
def thisPrefix: Type = thisType
def selfType: Type = typeOfThis
- def typeSignature: Type = info
- def typeSignatureIn(site: Type): Type = site memberInfo this
+ def typeSignature: Type = { fullyInitializeSymbol(this); info }
+ def typeSignatureIn(site: Type): Type = { fullyInitializeSymbol(this); site memberInfo this }
def toType: Type = tpe
def toTypeIn(site: Type): Type = site.memberType(this)
@@ -2973,7 +2973,7 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
}
override def derivedValueClassUnbox =
- (info.decl(nme.unbox)) orElse
+ // (info.decl(nme.unbox)) orElse uncomment once we accept unbox methods
(info.decls.find(_ hasAllFlags PARAMACCESSOR | METHOD) getOrElse
NoSymbol)
diff --git a/src/reflect/scala/reflect/internal/Types.scala b/src/reflect/scala/reflect/internal/Types.scala
index 876ae53da0..52efab3e48 100644
--- a/src/reflect/scala/reflect/internal/Types.scala
+++ b/src/reflect/scala/reflect/internal/Types.scala
@@ -3599,9 +3599,20 @@ trait Types extends api.Types { self: SymbolTable =>
*/
/** A creator for type applications */
- def appliedType(tycon: Type, args: List[Type]): Type =
- if (args.isEmpty) tycon //@M! `if (args.isEmpty) tycon' is crucial (otherwise we create new types in phases after typer and then they don't get adapted (??))
- else tycon match {
+ def appliedType(tycon: Type, args: List[Type]): Type = {
+ if (args.isEmpty)
+ return tycon //@M! `if (args.isEmpty) tycon' is crucial (otherwise we create new types in phases after typer and then they don't get adapted (??))
+
+ /** Disabled - causes cycles in tcpoly tests. */
+ if (false && isDefinitionsInitialized) {
+ assert(isUseableAsTypeArgs(args), {
+ val tapp_s = s"""$tycon[${args mkString ", "}]"""
+ val arg_s = args filterNot isUseableAsTypeArg map (t => t + "/" + t.getClass) mkString ", "
+ s"$tapp_s includes illegal type argument $arg_s"
+ })
+ }
+
+ tycon match {
case TypeRef(pre, sym @ (NothingClass|AnyClass), _) => copyTypeRef(tycon, pre, sym, Nil) //@M drop type args to Any/Nothing
case TypeRef(pre, sym, _) => copyTypeRef(tycon, pre, sym, args)
case PolyType(tparams, restpe) => restpe.instantiateTypeParams(tparams, args)
@@ -3615,6 +3626,7 @@ trait Types extends api.Types { self: SymbolTable =>
case WildcardType => tycon // needed for neg/t0226
case _ => abort(debugString(tycon))
}
+ }
/** Very convenient. */
def appliedType(tyconSym: Symbol, args: Type*): Type =
@@ -5673,6 +5685,99 @@ trait Types extends api.Types { self: SymbolTable =>
case _ => false
}
+ /** This is defined and named as it is because the goal is to exclude source
+ * level types which are not value types (e.g. MethodType) without excluding
+ * necessary internal types such as WildcardType. There are also non-value
+ * types which can be used as type arguments (e.g. type constructors.)
+ */
+ def isUseableAsTypeArg(tp: Type) = (
+ isInternalTypeUsedAsTypeArg(tp) // the subset of internal types which can be type args
+ || isHKTypeRef(tp) // not a value type, but ok as a type arg
+ || isValueElseNonValue(tp) // otherwise only value types
+ )
+
+ private def isHKTypeRef(tp: Type) = tp match {
+ case TypeRef(_, sym, Nil) => tp.isHigherKinded
+ case _ => false
+ }
+ @tailrec final def isUseableAsTypeArgs(tps: List[Type]): Boolean = tps match {
+ case Nil => true
+ case x :: xs => isUseableAsTypeArg(x) && isUseableAsTypeArgs(xs)
+ }
+
+ /** The "third way", types which are neither value types nor
+ * non-value types as defined in the SLS, further divided into
+ * types which are used internally in type applications and
+ * types which are not.
+ */
+ private def isInternalTypeNotUsedAsTypeArg(tp: Type): Boolean = tp match {
+ case AntiPolyType(pre, targs) => true
+ case ClassInfoType(parents, defs, clazz) => true
+ case ErasedValueType(tref) => true
+ case NoPrefix => true
+ case NoType => true
+ case SuperType(thistpe, supertpe) => true
+ case TypeBounds(lo, hi) => true
+ case _ => false
+ }
+ private def isInternalTypeUsedAsTypeArg(tp: Type): Boolean = tp match {
+ case WildcardType => true
+ case BoundedWildcardType(_) => true
+ case ErrorType => true
+ case _: TypeVar => true
+ case _ => false
+ }
+ private def isAlwaysValueType(tp: Type) = tp match {
+ case RefinedType(_, _) => true
+ case ExistentialType(_, _) => true
+ case ConstantType(_) => true
+ case _ => false
+ }
+ private def isAlwaysNonValueType(tp: Type) = tp match {
+ case OverloadedType(_, _) => true
+ case NullaryMethodType(_) => true
+ case MethodType(_, _) => true
+ case PolyType(_, MethodType(_, _)) => true
+ case _ => false
+ }
+ /** Should be called only with types for which a clear true/false answer
+ * can be given: true == value type, false == non-value type. Otherwise,
+ * an exception is thrown.
+ */
+ private def isValueElseNonValue(tp: Type): Boolean = tp match {
+ case tp if isAlwaysValueType(tp) => true
+ case tp if isAlwaysNonValueType(tp) => false
+ case AnnotatedType(_, underlying, _) => isValueElseNonValue(underlying)
+ case SingleType(_, sym) => sym.isValue // excludes packages and statics
+ case TypeRef(_, _, _) if tp.isHigherKinded => false // excludes type constructors
+ case ThisType(sym) => !sym.isPackageClass // excludes packages
+ case TypeRef(_, sym, _) => !sym.isPackageClass // excludes packages
+ case PolyType(_, _) => true // poly-methods excluded earlier
+ case tp => sys.error("isValueElseNonValue called with third-way type " + tp)
+ }
+
+ /** SLS 3.2, Value Types
+ * Is the given type definitely a value type? A true result means
+ * it verifiably is, but a false result does not mean it is not,
+ * only that it cannot be assured. To avoid false positives, this
+ * defaults to false, but since Type is not sealed, one should take
+ * a false answer with a grain of salt. This method may be primarily
+ * useful as documentation; it is likely that !isNonValueType(tp)
+ * will serve better than isValueType(tp).
+ */
+ def isValueType(tp: Type) = isValueElseNonValue(tp)
+
+ /** SLS 3.3, Non-Value Types
+ * Is the given type definitely a non-value type, as defined in SLS 3.3?
+ * The specification-enumerated non-value types are method types, polymorphic
+ * method types, and type constructors. Supplements to the specified set of
+ * non-value types include: types which wrap non-value symbols (packages
+ * abd statics), overloaded types. Varargs and by-name types T* and (=>T) are
+ * not designated non-value types because there is code which depends on using
+ * them as type arguments, but their precise status is unclear.
+ */
+ def isNonValueType(tp: Type) = !isValueElseNonValue(tp)
+
def isNonRefinementClassType(tpe: Type) = tpe match {
case SingleType(_, sym) => sym.isModuleClass
case TypeRef(_, sym, _) => sym.isClass && !sym.isRefinementClass