diff options
-rw-r--r-- | build.xml | 216 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/typechecker/Implicits.scala | 2 | ||||
-rw-r--r-- | src/compiler/scala/tools/reflect/ToolBoxFactory.scala | 5 | ||||
-rw-r--r-- | src/library/scala/Predef.scala | 52 | ||||
-rw-r--r-- | src/library/scala/concurrent/impl/Future.scala | 106 | ||||
-rw-r--r-- | src/library/scala/concurrent/impl/Promise.scala | 25 | ||||
-rw-r--r-- | src/reflect/scala/reflect/internal/Definitions.scala | 2 | ||||
-rw-r--r-- | src/reflect/scala/reflect/runtime/JavaUniverse.scala | 2 | ||||
-rw-r--r-- | test/files/run/t5912.scala | 6 |
9 files changed, 269 insertions, 147 deletions
@@ -55,6 +55,18 @@ END-USER TARGETS </antcall> </target> + + <target name="partialdist" depends="dist.partial" + description="Makes a new distribution without documentation, so just for testing."/> + + <target name="partialdist-opt" + description="Makes a new optimised distribution without testing it or removing partially build elements."> + <antcall target="partialdist"> + <param name="scalac.args.optimise" value="-optimise"/> + </antcall> + </target> + + <target name="fastdist" depends="dist.done" description="Makes a new distribution without testing it or removing partially build elements."/> @@ -123,10 +135,30 @@ END-USER TARGETS <antcall target="palo.done"/> </target> - <target name="fastlocker" + <target name="fastlocker.lib" + description="Buildlocker without extra fuss"> + <property name="fastlocker" value="true"/> + <antcall target="locker.unlock"/> + <antcall target="locker.lib"/> + </target> + + <target name="fastlocker.reflect" + description="Buildlocker without extra fuss"> + <property name="fastlocker" value="true"/> + <antcall target="locker.unlock"/> + <antcall target="locker.reflect"/> + </target> + + <target name="fastlocker.comp" description="Buildlocker without extra fuss"> + <property name="fastlocker" value="true"/> <antcall target="locker.unlock"/> - <antcall target="locker.done"/> + <antcall target="locker.comp"/> + </target> + + <target name="fastlocker" + description="Buildlocker without extra fuss"> + <antcall target="fastlocker.comp"/> </target> <target name="buildlocker" @@ -334,16 +366,31 @@ INITIALISATION <target name="init.version.done" depends="init.version.release, init.version.snapshot"/> <target name="init.testjava6"> - <fail message="This build requires JDK 1.6"> - <condition> - <not> + <condition property="has.java6"> <equals arg1="${ant.java.version}" arg2="1.6"/> - </not> </condition> - </fail> + <condition property="has.java7"> + <equals arg1="${ant.java.version}" arg2="1.7"/> + </condition> + <condition property="has.unsupported.jdk"> + <not><or> + <isset property="has.java7" /> + <isset property="has.java6" /> + </or></not> + </condition> </target> - <target name="init" depends="init.jars, init.maven.jars, init.version.done"> + <target name="init.fail.bad.jdk" depends="init.testjava6"> + <fail if="has.unsupported.jdk" + message="JDK ${ant.java.version} is not supported by this build!"/> + </target> + <target name="init.warn.jdk7" depends="init.testjava6" if="has.java7"> + <echo level="warning"> You are using JDK7 for this build. While this will be able to build most of Scala, it will + not build the Swing project. You will be unable to create a distribution. + </echo> + </target> + + <target name="init" depends="init.jars, init.maven.jars, init.version.done, init.fail.bad.jdk, init.warn.jdk7"> <property name="scalac.args.always" value="" /> <!-- scalac.args.optimise is selectively overridden in certain antcall tasks. --> <property name="scalac.args.optimise" value=""/> @@ -467,7 +514,7 @@ LOCAL DEPENDENCY (Adapted ASM) <!-- =========================================================================== LOCAL DEPENDENCY (FORKJOIN) ============================================================================ --> - <target name="forkjoin.start" depends="init, init.testjava6"> + <target name="forkjoin.start" depends="init"> <uptodate property="forkjoin.available" targetfile="${build-libs.dir}/forkjoin.complete"> <srcfiles dir="${src.dir}/forkjoin"> <include name="**/*.java"/> @@ -477,6 +524,7 @@ LOCAL DEPENDENCY (FORKJOIN) </target> <target name="forkjoin.lib" depends="forkjoin.start" unless="forkjoin.available"> + <stopwatch name="forkjoin.lib.timer"/> <mkdir dir="${build-libs.dir}/classes/forkjoin"/> <javac fork="yes" @@ -490,6 +538,7 @@ LOCAL DEPENDENCY (FORKJOIN) <compilerarg line="${javac.args} -XDignore.symbol.file"/> </javac> <touch file="${build-libs.dir}/forkjoin.complete" verbose="no"/> + <stopwatch name="forkjoin.lib.timer" action="total"/> </target> <target name="forkjoin.pack" depends="forkjoin.lib"> @@ -524,6 +573,7 @@ LOCAL DEPENDENCY (FJBG) </target> <target name="fjbg.lib" depends="fjbg.init" unless="fjbg.available"> + <stopwatch name="fjbg.lib.timer" /> <mkdir dir="${build-libs.dir}/classes/fjbg"/> <javac srcdir="${src.dir}/fjbg" @@ -535,6 +585,7 @@ LOCAL DEPENDENCY (FJBG) <compilerarg line="${javac.args} -XDignore.symbol.file"/> </javac> <touch file="${build-libs.dir}/fjbg.complete" verbose="no"/> + <stopwatch name="fjbg.lib.timer" action="total"/> </target> <target name="fjbg.pack" depends="fjbg.lib"> @@ -677,33 +728,43 @@ LOCAL REFERENCE BUILD (LOCKER) <target name="locker.comp" depends="locker.pre-comp" if="locker.comp.needed"> <stopwatch name="locker.comp.timer"/> <mkdir dir="${build-locker.dir}/classes/compiler"/> - <!-- Compile MSIL inside of locker.... --> - <javac - srcdir="${src.dir}/msil" - destdir="${build-locker.dir}/classes/compiler" - classpath="${build-locker.dir}/classes/compiler" - includes="**/*.java" - excludes="**/tests/**" - debug="true" - target="1.5" source="1.4"> - <compilerarg line="${javac.args}"/> - </javac> - <scalacfork - destdir="${build-locker.dir}/classes/compiler" - compilerpathref="starr.classpath" - params="${scalac.args.all}" - srcdir="${src.dir}/msil" - jvmargs="${scalacfork.jvmargs}"> - <include name="**/*.scala"/> - <compilationpath> - <pathelement location="${build-locker.dir}/classes/library"/> - <pathelement location="${build-locker.dir}/classes/reflect"/> - <pathelement location="${build-locker.dir}/classes/compiler"/> - <path refid="fjbg.classpath"/> - <path refid="aux.libs"/> - <pathelement location="${jline.jar}"/> - </compilationpath> - </scalacfork> + <if> + <equals arg1="${fastlocker}" arg2="true" /> + <then> + <!-- Fastlocker build: don't compile MSIL, use its starr version.... --> + <property name="locker.comp.msil" value="${msil.starr.jar}"/> + </then> + <else> + <!-- Regular build: Compile MSIL inside of locker.... --> + <javac + srcdir="${src.dir}/msil" + destdir="${build-locker.dir}/classes/compiler" + classpath="${build-locker.dir}/classes/compiler" + includes="**/*.java" + excludes="**/tests/**" + debug="true" + target="1.5" source="1.4"> + <compilerarg line="${javac.args}"/> + </javac> + <scalacfork + destdir="${build-locker.dir}/classes/compiler" + compilerpathref="starr.classpath" + params="${scalac.args.all}" + srcdir="${src.dir}/msil" + jvmargs="${scalacfork.jvmargs}"> + <include name="**/*.scala"/> + <compilationpath> + <pathelement location="${build-locker.dir}/classes/library"/> + <pathelement location="${build-locker.dir}/classes/reflect"/> + <pathelement location="${build-locker.dir}/classes/compiler"/> + <path refid="fjbg.classpath"/> + <path refid="aux.libs"/> + <pathelement location="${jline.jar}"/> + </compilationpath> + </scalacfork> + <property name="locker.comp.msil" value="${build-locker.dir}/classes/compiler"/> + </else> + </if> <scalacfork destdir="${build-locker.dir}/classes/compiler" compilerpathref="starr.classpath" @@ -718,6 +779,7 @@ LOCAL REFERENCE BUILD (LOCKER) <path refid="fjbg.classpath"/> <path refid="aux.libs"/> <path refid="asm.classpath"/> + <pathelement location="${locker.comp.msil}" /> <pathelement location="${jline.jar}"/> </compilationpath> </scalacfork> @@ -978,15 +1040,6 @@ QUICK BUILD (QUICK) <include name="**/*.scala"/> <compilationpath refid="quick.compilation.path"/> </scalacfork> - <scalacfork - destdir="${build-quick.dir}/classes/library" - compilerpathref="locker.classpath" - params="${scalac.args.quick}" - srcdir="${src.dir}/swing" - jvmargs="${scalacfork.jvmargs}"> - <include name="**/*.scala"/> - <compilationpath refid="quick.compilation.path"/> - </scalacfork> <propertyfile file="${build-quick.dir}/classes/library/library.properties"> <entry key="version.number" value="${version.number}"/> <entry key="maven.version.number" value="${maven.version.number}"/> @@ -1001,12 +1054,26 @@ QUICK BUILD (QUICK) <include name="**/*.css"/> </fileset> </copy> - <touch file="${build-quick.dir}/library.complete" verbose="no"/> - <stopwatch name="quick.lib.timer" action="total"/> </target> + <target name="quick.swing" depends="quick.lib" if="has.java6" unless="quick.lib.available"> + <scalacfork + destdir="${build-quick.dir}/classes/library" + compilerpathref="locker.classpath" + params="${scalac.args.quick}" + srcdir="${src.dir}/swing" + jvmargs="${scalacfork.jvmargs}"> + <include name="**/*.scala"/> + <compilationpath refid="quick.compilation.path"/> + </scalacfork> + </target> + + <target name="quick.lib.done" depends="quick.swing, quick.lib"> + <stopwatch name="quick.lib.timer" action="total"/> + <touch file="${build-quick.dir}/library.complete" verbose="no"/> + </target> - <target name="quick.pre-reflect" depends="quick.lib"> + <target name="quick.pre-reflect" depends="quick.lib.done"> <uptodate property="quick.reflect.available" targetfile="${build-quick.dir}/reflect.complete"> <srcfiles dir="${src.dir}"> <include name="reflect/**"/> @@ -1412,11 +1479,6 @@ PACKED QUICK BUILD (PACK) </fileset> <fileset dir="${build-libs.dir}/classes/forkjoin"/> </jar> - <jar destfile="${build-pack.dir}/lib/scala-swing.jar"> - <fileset dir="${build-quick.dir}/classes/library"> - <include name="scala/swing/**"/> - </fileset> - </jar> <jar destfile="${build-pack.dir}/lib/scala-actors.jar"> <fileset dir="${build-quick.dir}/classes/library"> <include name="scala/actors/**"/> @@ -1427,7 +1489,15 @@ PACKED QUICK BUILD (PACK) </jar> </target> - <target name="pack.pre-reflect" depends="pack.lib"> + <target name="pack.swing" depends="pack.lib" if="has.java6"> + <jar destfile="${build-pack.dir}/lib/scala-swing.jar"> + <fileset dir="${build-quick.dir}/classes/library"> + <include name="scala/swing/**"/> + </fileset> + </jar> + </target> + + <target name="pack.pre-reflect" depends="pack.lib, pack.swing"> <uptodate property="pack.reflect.available" targetfile="${build-pack.dir}/lib/scala-reflect.jar" @@ -1643,15 +1713,6 @@ BOOTSTRAPPING BUILD (STRAP) <include name="**/*.scala"/> <compilationpath refid="strap.compilation.path"/> </scalacfork> - <scalacfork - destdir="${build-strap.dir}/classes/library" - compilerpathref="pack.classpath" - params="${scalac.args.quick}" - srcdir="${src.dir}/swing" - jvmargs="${scalacfork.jvmargs}"> - <include name="**/*.scala"/> - <compilationpath refid="strap.compilation.path"/> - </scalacfork> <propertyfile file="${build-strap.dir}/classes/library/library.properties"> <entry key="version.number" value="${version.number}"/> <entry key="maven.version.number" value="${maven.version.number}"/> @@ -1666,11 +1727,26 @@ BOOTSTRAPPING BUILD (STRAP) <include name="**/*.css"/> </fileset> </copy> + </target> + + <target name="strap.swing" if="has.java6" unless="strap.lib.available" depends="strap.lib"> + <scalacfork + destdir="${build-strap.dir}/classes/library" + compilerpathref="pack.classpath" + params="${scalac.args.quick}" + srcdir="${src.dir}/swing" + jvmargs="${scalacfork.jvmargs}"> + <include name="**/*.scala"/> + <compilationpath refid="strap.compilation.path"/> + </scalacfork> + </target> + + <target name="strap.lib.done" depends="strap.swing, strap.lib"> <touch file="${build-strap.dir}/library.complete" verbose="no"/> <stopwatch name="strap.lib.timer" action="total"/> </target> - <target name="strap.pre-reflect" depends="strap.lib"> + <target name="strap.pre-reflect" depends="strap.lib.done"> <uptodate property="strap.reflect.available" targetfile="${build-strap.dir}/reflect.complete"> <srcfiles dir="${src.dir}/reflect"/> </uptodate> @@ -2348,7 +2424,7 @@ BOOTRAPING TEST AND TEST SUITE DISTRIBUTION ============================================================================ --> - <target name="dist.start" depends="docs.done, pack.done"> + <target name="dist.start" depends="pack.done"> <property name="dist.name" value="scala-${version.number}"/> <property name="dist.dir" value="${dists.dir}/${dist.name}"/> </target> @@ -2373,7 +2449,7 @@ DISTRIBUTION </copy> </target> - <target name="dist.doc" depends="dist.base"> + <target name="dist.doc" depends="dist.base, docs.done"> <mkdir dir="${dist.dir}/doc/scala-devel-docs"/> <copy file="${docs.dir}/LICENSE" toDir="${dist.dir}/doc"/> <copy file="${docs.dir}/README" toDir="${dist.dir}/doc"/> @@ -2432,11 +2508,11 @@ DISTRIBUTION </jar> </target> - <target name="dist.latest.unix" depends="dist.src" unless="os.win"> + <target name="dist.latest.unix" depends="dist.base" unless="os.win"> <symlink link="${dists.dir}/latest" resource="${dist.name}" overwrite="yes"/> </target> - <target name="dist.latest.win" depends="dist.src" if="os.win"> + <target name="dist.latest.win" depends="dist.base" if="os.win"> <copy todir="${dists.dir}/latest"> <fileset dir="${dist.dir}"/> </copy> @@ -2444,7 +2520,9 @@ DISTRIBUTION <target name="dist.latest" depends="dist.latest.unix,dist.latest.win"/> - <target name="dist.done" depends="dist.latest"/> + <target name="dist.partial" depends="dist.base, dist.latest"/> + + <target name="dist.done" depends="dist.latest, dist.src"/> <target name="dist.clean"> <delete dir="${dists.dir}" includeemptydirs="yes" quiet="yes" failonerror="no"/> diff --git a/src/compiler/scala/tools/nsc/typechecker/Implicits.scala b/src/compiler/scala/tools/nsc/typechecker/Implicits.scala index aa63f3ec31..0ea46f1de4 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Implicits.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Implicits.scala @@ -1319,7 +1319,7 @@ trait Implicits { if (full) { val cm = typed(Ident(ReflectRuntimeCurrentMirror)) gen.mkMethodCall(ReflectRuntimeUniverse, nme.typeTagToManifest, List(tp), List(cm, tagInScope)) - } else gen.mkMethodCall(ReflectRuntimeUniverse, nme.classTagToClassManifest, List(tp), List(tagInScope)) + } else gen.mkMethodCall(ReflectBasis, nme.classTagToClassManifest, List(tp), List(tagInScope)) wrapResult(interop) } } diff --git a/src/compiler/scala/tools/reflect/ToolBoxFactory.scala b/src/compiler/scala/tools/reflect/ToolBoxFactory.scala index 7cf515425d..278f4e3ff7 100644 --- a/src/compiler/scala/tools/reflect/ToolBoxFactory.scala +++ b/src/compiler/scala/tools/reflect/ToolBoxFactory.scala @@ -126,7 +126,10 @@ abstract class ToolBoxFactory[U <: JavaUniverse](val u: U) { factorySelf => wrapper(currentTyper.silent(_.typed(expr, analyzer.EXPRmode, pt)) match { case analyzer.SilentResultValue(result) => trace("success: ")(showAttributed(result, true, true, settings.Yshowsymkinds.value)) - var Block(dummies, unwrapped) = result + var (dummies, unwrapped) = result match { + case Block(dummies, unwrapped) => (dummies, unwrapped) + case unwrapped => (Nil, unwrapped) + } var invertedIndex = freeTerms map (_.swap) // todo. also fixup singleton types unwrapped = new Transformer { diff --git a/src/library/scala/Predef.scala b/src/library/scala/Predef.scala index 65e8549ae1..99bd7f0736 100644 --- a/src/library/scala/Predef.scala +++ b/src/library/scala/Predef.scala @@ -121,16 +121,16 @@ object Predef extends LowPriorityImplicits { // Deprecated - @deprecated("Use sys.error(message) instead", "2.9.0") + @deprecated("Use `sys.error(message)` instead", "2.9.0") def error(message: String): Nothing = sys.error(message) - @deprecated("Use sys.exit() instead", "2.9.0") + @deprecated("Use `sys.exit()` instead", "2.9.0") def exit(): Nothing = sys.exit() - @deprecated("Use sys.exit(status) instead", "2.9.0") + @deprecated("Use `sys.exit(status)` instead", "2.9.0") def exit(status: Int): Nothing = sys.exit(status) - @deprecated("Use formatString.format(args: _*) or arg.formatted(formatString) instead", "2.9.0") + @deprecated("Use `formatString.format(args: _*)` or `arg.formatted(formatString)` instead", "2.9.0") def format(text: String, xs: Any*) = augmentString(text).format(xs: _*) // errors and asserts ------------------------------------------------- @@ -219,7 +219,7 @@ object Predef extends LowPriorityImplicits { final class Ensuring[A](val __resultOfEnsuring: A) extends AnyVal { // `__resultOfEnsuring` must be a public val to allow inlining. // See comments in ArrowAssoc for more. - @deprecated("Use __resultOfEnsuring instead", "2.10.0") + @deprecated("Use `__resultOfEnsuring` instead", "2.10.0") def x = __resultOfEnsuring def ensuring(cond: Boolean): A = { assert(cond); __resultOfEnsuring } @@ -255,7 +255,7 @@ object Predef extends LowPriorityImplicits { // being confused why they get an ambiguous implicit conversion // error. (`foo.x` used to produce this error since both // any2Ensuring and any2ArrowAssoc pimped an `x` onto everything) - @deprecated("Use __leftOfArrow instead", "2.10.0") + @deprecated("Use `__leftOfArrow` instead", "2.10.0") def x = __leftOfArrow @inline def -> [B](y: B): Tuple2[A, B] = Tuple2(__leftOfArrow, y) @@ -320,30 +320,30 @@ object Predef extends LowPriorityImplicits { // Primitive Widenings -------------------------------------------------------------- - @deprecated("Use a method in an AnyVal's companion object", "2.10.0") def byte2short(x: Byte): Short = x.toShort - @deprecated("Use a method in an AnyVal's companion object", "2.10.0") def byte2int(x: Byte): Int = x.toInt - @deprecated("Use a method in an AnyVal's companion object", "2.10.0") def byte2long(x: Byte): Long = x.toLong - @deprecated("Use a method in an AnyVal's companion object", "2.10.0") def byte2float(x: Byte): Float = x.toFloat - @deprecated("Use a method in an AnyVal's companion object", "2.10.0") def byte2double(x: Byte): Double = x.toDouble + @deprecated("Use `.toShort` for explicit conversion and `Byte.byte2short` for implicit conversion", "2.10.0") def byte2short(x: Byte): Short = x.toShort + @deprecated("Use `.toInt` for explicit conversion and `Byte.byte2int` for implicit conversion", "2.10.0") def byte2int(x: Byte): Int = x.toInt + @deprecated("Use `.toLong` for explicit conversion and `Byte.byte2long for implicit conversion", "2.10.0") def byte2long(x: Byte): Long = x.toLong + @deprecated("Use `.toFloat` for explicit conversion and `Byte.byte2float` for implicit conversion", "2.10.0") def byte2float(x: Byte): Float = x.toFloat + @deprecated("Use `.toDouble` for explicit conversion and `Byte.byte2double` for implicit conversion", "2.10.0") def byte2double(x: Byte): Double = x.toDouble - @deprecated("Use a method in an AnyVal's companion object", "2.10.0") def short2int(x: Short): Int = x.toInt - @deprecated("Use a method in an AnyVal's companion object", "2.10.0") def short2long(x: Short): Long = x.toLong - @deprecated("Use a method in an AnyVal's companion object", "2.10.0") def short2float(x: Short): Float = x.toFloat - @deprecated("Use a method in an AnyVal's companion object", "2.10.0") def short2double(x: Short): Double = x.toDouble + @deprecated("Use `.toInt` for explicit conversion and `Short.short2int` for implicit conversion", "2.10.0") def short2int(x: Short): Int = x.toInt + @deprecated("Use `.toLong` for explicit conversion and `Short.short2long` for implicit conversion", "2.10.0") def short2long(x: Short): Long = x.toLong + @deprecated("Use `.toFloat` for explicit conversion and `Short.short2float` for implicit conversion", "2.10.0") def short2float(x: Short): Float = x.toFloat + @deprecated("Use `.toDouble` for explicit conversion and `Short.short2double` for implicit conversion", "2.10.0") def short2double(x: Short): Double = x.toDouble - @deprecated("Use a method in an AnyVal's companion object", "2.10.0") def char2int(x: Char): Int = x.toInt - @deprecated("Use a method in an AnyVal's companion object", "2.10.0") def char2long(x: Char): Long = x.toLong - @deprecated("Use a method in an AnyVal's companion object", "2.10.0") def char2float(x: Char): Float = x.toFloat - @deprecated("Use a method in an AnyVal's companion object", "2.10.0") def char2double(x: Char): Double = x.toDouble + @deprecated("Use `.toInt` for explicit conversion and `Char.char2int` for implicit conversion", "2.10.0") def char2int(x: Char): Int = x.toInt + @deprecated("Use `.toLong` for explicit conversion and `Char.char2long` for implicit conversion", "2.10.0") def char2long(x: Char): Long = x.toLong + @deprecated("Use `.toFloat` for explicit conversion and `Char.char2float` for implicit conversion", "2.10.0") def char2float(x: Char): Float = x.toFloat + @deprecated("Use `.toDouble` for explicit conversion and `Char.char2double` for implicit conversion", "2.10.0") def char2double(x: Char): Double = x.toDouble - @deprecated("Use a method in an AnyVal's companion object", "2.10.0") def int2long(x: Int): Long = x.toLong - @deprecated("Use a method in an AnyVal's companion object", "2.10.0") def int2float(x: Int): Float = x.toFloat - @deprecated("Use a method in an AnyVal's companion object", "2.10.0") def int2double(x: Int): Double = x.toDouble + @deprecated("Use `.toLong` for explicit conversion and `Int.int2long` for implicit conversion", "2.10.0") def int2long(x: Int): Long = x.toLong + @deprecated("Use `.toFloat` for explicit conversion and `Int.int2float` for implicit conversion", "2.10.0") def int2float(x: Int): Float = x.toFloat + @deprecated("Use `.toDouble` for explicit conversion and `Int.int2double` for implicit conversion", "2.10.0") def int2double(x: Int): Double = x.toDouble - @deprecated("Use a method in an AnyVal's companion object", "2.10.0") def long2float(x: Long): Float = x.toFloat - @deprecated("Use a method in an AnyVal's companion object", "2.10.0") def long2double(x: Long): Double = x.toDouble + @deprecated("Use `.toFloat` for explicit conversion and `Long.long2float` for implicit conversion", "2.10.0") def long2float(x: Long): Float = x.toFloat + @deprecated("Use `.toDouble` for explicit conversion and `Long.long2double` for implicit conversion", "2.10.0") def long2double(x: Long): Double = x.toDouble - @deprecated("Use a method in an AnyVal's companion object", "2.10.0") def float2double(x: Float): Double = x.toDouble + @deprecated("Use `.toDouble` for explicit conversion and `Float.float2double` for implicit conversion", "2.10.0") def float2double(x: Float): Double = x.toDouble // "Autoboxing" and "Autounboxing" --------------------------------------------------- @@ -385,7 +385,7 @@ object Predef extends LowPriorityImplicits { implicit def any2stringadd(x: Any) = new runtime.StringAdd(x) implicit def unaugmentString(x: StringOps): String = x.repr - @deprecated("Use StringCanBuildFrom", "2.10.0") + @deprecated("Use `StringCanBuildFrom`", "2.10.0") def stringCanBuildFrom: CanBuildFrom[String, Char, String] = StringCanBuildFrom implicit val StringCanBuildFrom: CanBuildFrom[String, Char, String] = new CanBuildFrom[String, Char, String] { diff --git a/src/library/scala/concurrent/impl/Future.scala b/src/library/scala/concurrent/impl/Future.scala index 47534e398b..6a3487adde 100644 --- a/src/library/scala/concurrent/impl/Future.scala +++ b/src/library/scala/concurrent/impl/Future.scala @@ -44,13 +44,13 @@ private[concurrent] object Future { } def boxedType(c: Class[_]): Class[_] = if (c.isPrimitive) toBoxed(c) else c - - def apply[T](body: =>T)(implicit executor: ExecutionContext): Future[T] = { + + private[impl] class PromiseCompletingTask[T](override val executor: ExecutionContext, body: => T) + extends Task { val promise = new Promise.DefaultPromise[T]() - //TODO: use `dispatchFuture`? - executor.execute(new Runnable { - def run = promise complete { + protected override def task() = { + promise complete { try Right(body) catch { case NonFatal(e) => // Commenting out reporting for now, since it produces too much output in the tests @@ -58,9 +58,14 @@ private[concurrent] object Future { Left(e) } } - }) - - promise.future + } + } + + def apply[T](body: =>T)(implicit executor: ExecutionContext): Future[T] = { + val task = new PromiseCompletingTask(executor, body) + task.dispatch() + + task.promise.future } private[impl] val throwableId: Throwable => Throwable = identity _ @@ -70,38 +75,77 @@ private[concurrent] object Future { // so that it can be stolen from // OR: a push to the local task queue should be so cheap that this is // not even needed, but stealing is still possible - private val _taskStack = new ThreadLocal[Stack[() => Unit]]() + + private[impl] case class TaskStack(stack: Stack[Task], executor: ExecutionContext) + + private val _taskStack = new ThreadLocal[TaskStack]() + + private[impl] trait Task extends Runnable { + def executor: ExecutionContext + + // run the original callback (no dispatch) + protected def task(): Unit + + // we implement Runnable to avoid creating + // an extra object. run() runs ourselves with + // a TaskStack pushed, and then runs any + // other tasks that show up in the stack. + final override def run() = { + try { + val taskStack = TaskStack(Stack[Task](this), executor) + _taskStack set taskStack + while (taskStack.stack.nonEmpty) { + val next = taskStack.stack.pop() + require(next.executor eq executor) + try next.task() catch { case NonFatal(e) => executor reportFailure e } + } + } finally { + _taskStack.remove() + } + } + + // send the task to the running executor.execute() via + // _taskStack, or start a new executor.execute() + def dispatch(force: Boolean = false): Unit = + _taskStack.get match { + case stack if (stack ne null) && (executor eq stack.executor) && !force => stack.stack push this + case _ => executor.execute(this) + } + } + + private[impl] class ReleaseTask(override val executor: ExecutionContext, val elems: List[Task]) + extends Task { + protected override def task() = { + _taskStack.get.stack.elems = elems + } + } private[impl] def releaseStack(executor: ExecutionContext): Unit = _taskStack.get match { - case stack if (stack ne null) && stack.nonEmpty => - val tasks = stack.elems - stack.clear() + case stack if (stack ne null) && stack.stack.nonEmpty => + val tasks = stack.stack.elems + stack.stack.clear() _taskStack.remove() - dispatchFuture(executor, () => _taskStack.get.elems = tasks, true) + val release = new ReleaseTask(executor, tasks) + release.dispatch(force=true) case null => // do nothing - there is no local batching stack anymore case _ => _taskStack.remove() } - private[impl] def dispatchFuture(executor: ExecutionContext, task: () => Unit, force: Boolean = false): Unit = - _taskStack.get match { - case stack if (stack ne null) && !force => stack push task // FIXME we can't mix tasks aimed for different ExecutionContexts see: https://github.com/akka/akka/blob/v2.0.1/akka-actor/src/main/scala/akka/dispatch/Future.scala#L373 - case _ => executor.execute(new Runnable { - def run() { - try { - val taskStack = Stack[() => Unit](task) - _taskStack set taskStack - while (taskStack.nonEmpty) { - val next = taskStack.pop() - try next() catch { case NonFatal(e) => executor reportFailure e } - } - } finally { - _taskStack.remove() - } - } - }) + private[impl] class OnCompleteTask[T](override val executor: ExecutionContext, val onComplete: (Either[Throwable, T]) => Any) + extends Task { + private var value: Either[Throwable, T] = null + + protected override def task() = { + require(value ne null) // dispatch(value) must be called before dispatch() + onComplete(value) } - + + def dispatch(value: Either[Throwable, T]): Unit = { + this.value = value + dispatch() + } + } } diff --git a/src/library/scala/concurrent/impl/Promise.scala b/src/library/scala/concurrent/impl/Promise.scala index 1d573ef818..c5060a2368 100644 --- a/src/library/scala/concurrent/impl/Promise.scala +++ b/src/library/scala/concurrent/impl/Promise.scala @@ -94,10 +94,10 @@ object Promise { val resolved = resolveEither(value) (try { @tailrec - def tryComplete(v: Either[Throwable, T]): List[Either[Throwable, T] => Unit] = { + def tryComplete(v: Either[Throwable, T]): List[Future.OnCompleteTask[T]] = { getState match { case raw: List[_] => - val cur = raw.asInstanceOf[List[Either[Throwable, T] => Unit]] + val cur = raw.asInstanceOf[List[Future.OnCompleteTask[T]]] if (updateState(cur, v)) cur else tryComplete(v) case _ => null } @@ -108,32 +108,21 @@ object Promise { }) match { case null => false case cs if cs.isEmpty => true - // this assumes that f(resolved) will go via dispatchFuture - // and notifyCompleted (see onComplete below) - case cs => cs.foreach(f => f(resolved)); true + case cs => cs.foreach(c => c.dispatch(resolved)); true } } def onComplete[U](func: Either[Throwable, T] => U)(implicit executor: ExecutionContext): Unit = { - val bound: Either[Throwable, T] => Unit = (either: Either[Throwable, T]) => - Future.dispatchFuture(executor, () => notifyCompleted(func, either)) + val bound = new Future.OnCompleteTask[T](executor, func) @tailrec //Tries to add the callback, if already completed, it dispatches the callback to be executed def dispatchOrAddCallback(): Unit = getState match { - case r: Either[_, _] => bound(r.asInstanceOf[Either[Throwable, T]]) + case r: Either[_, _] => bound.dispatch(r.asInstanceOf[Either[Throwable, T]]) case listeners: List[_] => if (updateState(listeners, bound :: listeners)) () else dispatchOrAddCallback() } dispatchOrAddCallback() } - - private final def notifyCompleted(func: Either[Throwable, T] => Any, result: Either[Throwable, T])(implicit executor: ExecutionContext) { - try { - func(result) - } catch { - case NonFatal(e) => executor reportFailure e - } - } } /** An already completed Future is given its result at creation. @@ -149,8 +138,8 @@ object Promise { def tryComplete(value: Either[Throwable, T]): Boolean = false def onComplete[U](func: Either[Throwable, T] => U)(implicit executor: ExecutionContext): Unit = { - val completedAs = value.get // Avoid closing over "this" - Future.dispatchFuture(executor, () => func(completedAs)) + val completedAs = value.get + (new Future.OnCompleteTask(executor, func)).dispatch(completedAs) } def ready(atMost: Duration)(implicit permit: CanAwait): this.type = this diff --git a/src/reflect/scala/reflect/internal/Definitions.scala b/src/reflect/scala/reflect/internal/Definitions.scala index a9d9b06621..320cd3ddae 100644 --- a/src/reflect/scala/reflect/internal/Definitions.scala +++ b/src/reflect/scala/reflect/internal/Definitions.scala @@ -179,7 +179,7 @@ trait Definitions extends api.StandardDefinitions { val EmptyPackage: ModuleSymbol = rootMirror.EmptyPackage @deprecated("Moved to rootMirror.EmptyPackageClass", "2.10.0") - val EmptyPackageClass: ClassSymbol = rootMirror.RootClass + val EmptyPackageClass: ClassSymbol = rootMirror.EmptyPackageClass // It becomes tricky to create dedicated objects for other symbols because // of initialization order issues. diff --git a/src/reflect/scala/reflect/runtime/JavaUniverse.scala b/src/reflect/scala/reflect/runtime/JavaUniverse.scala index d4a83b960d..7ce71166c9 100644 --- a/src/reflect/scala/reflect/runtime/JavaUniverse.scala +++ b/src/reflect/scala/reflect/runtime/JavaUniverse.scala @@ -18,6 +18,8 @@ class JavaUniverse extends internal.SymbolTable with ReflectSetup with runtime.S override val gen = new TreeGen { val global: self.type = self } + override val treeBuild = gen + lazy val settings = new Settings def forInteractive = false def forScaladoc = false diff --git a/test/files/run/t5912.scala b/test/files/run/t5912.scala new file mode 100644 index 0000000000..7710d04396 --- /dev/null +++ b/test/files/run/t5912.scala @@ -0,0 +1,6 @@ +object Test extends App{ + import scala.reflect.runtime.{currentMirror=>cm} + import scala.tools.reflect._ + import scala.reflect.runtime.universe._ + val tree = cm.mkToolBox().typeCheck( Literal(Constant("test")) ) +}
\ No newline at end of file |