summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/ant/ant-contrib.jar.desired.sha12
-rw-r--r--lib/ant/ant-dotnet-1.0.jar.desired.sha12
-rw-r--r--lib/ant/ant.jar.desired.sha12
-rw-r--r--lib/ant/maven-ant-tasks-2.1.1.jar.desired.sha12
-rw-r--r--lib/ant/vizant.jar.desired.sha12
-rw-r--r--lib/fjbg.jar.desired.sha12
-rw-r--r--lib/forkjoin.jar.desired.sha12
-rw-r--r--lib/jline.jar.desired.sha12
-rw-r--r--lib/msil.jar.desired.sha12
-rw-r--r--lib/scala-compiler-src.jar.desired.sha11
-rw-r--r--lib/scala-compiler.jar.desired.sha12
-rw-r--r--lib/scala-library-src.jar.desired.sha12
-rw-r--r--lib/scala-library.jar.desired.sha12
-rw-r--r--lib/scala-reflect-src.jar.desired.sha11
-rw-r--r--lib/scala-reflect.jar.desired.sha12
-rw-r--r--src/compiler/scala/tools/nsc/Global.scala4
-rw-r--r--src/compiler/scala/tools/nsc/backend/icode/analysis/TypeFlowAnalysis.scala2
-rw-r--r--src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala19
-rw-r--r--src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala3
-rw-r--r--src/compiler/scala/tools/nsc/interactive/tests/InteractiveTest.scala14
-rw-r--r--src/compiler/scala/tools/nsc/interactive/tests/InteractiveTestSettings.scala9
-rw-r--r--src/compiler/scala/tools/nsc/interactive/tests/core/PresentationCompilerInstance.scala9
-rw-r--r--src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala11
-rw-r--r--src/compiler/scala/tools/nsc/symtab/classfile/Pickler.scala4
-rw-r--r--src/compiler/scala/tools/nsc/transform/Erasure.scala80
-rw-r--r--src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala4
-rw-r--r--src/compiler/scala/tools/nsc/transform/PostErasure.scala5
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala4
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Namers.scala73
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala15
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/PatternMatching.scala48
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/SyntheticMethods.scala4
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Typers.scala5
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Unapplies.scala8
-rw-r--r--src/compiler/scala/tools/reflect/FastTrack.scala6
-rw-r--r--src/compiler/scala/tools/reflect/MacroImplementations.scala147
-rw-r--r--src/library/scala/Cloneable.scala14
-rw-r--r--src/library/scala/StringContext.scala38
-rw-r--r--src/library/scala/annotation/cloneable.scala (renamed from src/library/scala/cloneable.scala)5
-rw-r--r--src/library/scala/collection/convert/Wrappers.scala3
-rw-r--r--src/library/scala/collection/immutable/HashMap.scala3
-rw-r--r--src/library/scala/collection/immutable/HashSet.scala3
-rw-r--r--src/library/scala/collection/mutable/ArrayStack.scala2
-rw-r--r--src/library/scala/collection/mutable/Buffer.scala4
-rw-r--r--src/library/scala/collection/mutable/BufferLike.scala2
-rw-r--r--src/library/scala/collection/mutable/Cloneable.scala5
-rw-r--r--src/library/scala/collection/mutable/PriorityQueue.scala2
-rw-r--r--src/library/scala/collection/mutable/Queue.scala1
-rw-r--r--src/library/scala/collection/mutable/Stack.scala1
-rw-r--r--src/library/scala/collection/parallel/ParIterableLike.scala27
-rw-r--r--src/library/scala/collection/parallel/TaskSupport.scala61
-rw-r--r--src/library/scala/package.scala3
-rw-r--r--src/reflect/scala/reflect/internal/Definitions.scala6
-rw-r--r--src/reflect/scala/reflect/internal/Flags.scala93
-rw-r--r--src/reflect/scala/reflect/internal/HasFlags.scala1
-rw-r--r--src/reflect/scala/reflect/internal/StdAttachments.scala17
-rw-r--r--src/reflect/scala/reflect/internal/StdNames.scala1
-rw-r--r--src/reflect/scala/reflect/internal/Symbols.scala23
-rw-r--r--src/reflect/scala/reflect/internal/Trees.scala11
-rw-r--r--src/reflect/scala/reflect/internal/Types.scala143
-rw-r--r--src/reflect/scala/reflect/internal/pickling/UnPickler.scala7
-rw-r--r--src/reflect/scala/reflect/internal/transform/Erasure.scala51
-rw-r--r--src/reflect/scala/reflect/internal/util/Statistics.scala2
-rw-r--r--src/reflect/scala/reflect/makro/Universe.scala24
-rw-r--r--test/files/buildmanager/t2651_3/t2651_3.check2
-rw-r--r--test/files/buildmanager/t2651_4/t2651_4.check4
-rw-r--r--test/files/buildmanager/t2657/t2657.check4
-rw-r--r--test/files/buildmanager/t2789/t2789.check4
-rw-r--r--test/files/codelib/code.jar.desired.sha12
-rw-r--r--test/files/lib/annotations.jar.desired.sha12
-rw-r--r--test/files/lib/enums.jar.desired.sha12
-rw-r--r--test/files/lib/genericNest.jar.desired.sha12
-rw-r--r--test/files/lib/methvsfield.jar.desired.sha12
-rw-r--r--test/files/lib/nest.jar.desired.sha12
-rw-r--r--test/files/lib/scalacheck.jar.desired.sha12
-rw-r--r--test/files/neg/stringinterpolation_macro-neg.check70
-rw-r--r--test/files/neg/stringinterpolation_macro-neg.scala31
-rw-r--r--test/files/neg/t5504.check4
-rw-r--r--test/files/neg/t6042.check4
-rw-r--r--test/files/neg/t6042.scala8
-rw-r--r--test/files/pos/t5504/s_1.scala (renamed from test/files/neg/t5504/s_1.scala)0
-rw-r--r--test/files/pos/t5504/s_2.scala (renamed from test/files/neg/t5504/s_2.scala)0
-rw-r--r--test/files/pos/t5957/T_1.scala6
-rw-r--r--test/files/pos/t5957/Test.java11
-rw-r--r--test/files/pos/t6022.flags1
-rw-r--r--test/files/pos/t6022.scala7
-rw-r--r--test/files/presentation/hyperlinks.flags2
-rw-r--r--test/files/presentation/hyperlinks/Runner.scala4
-rw-r--r--test/files/presentation/ide-bug-1000469/Runner.scala4
-rw-r--r--test/files/presentation/ide-bug-1000531.flags18
-rw-r--r--test/files/presentation/ide-t1000976.check1
-rw-r--r--test/files/presentation/ide-t1000976.flags1
-rw-r--r--test/files/presentation/ide-t1000976/Test.scala30
-rw-r--r--test/files/presentation/ide-t1000976/src/a/A.scala7
-rw-r--r--test/files/presentation/ide-t1000976/src/b/B.scala7
-rw-r--r--test/files/presentation/ide-t1000976/src/c/C.scala3
-rw-r--r--test/files/presentation/ide-t1000976/src/d/D.scala7
-rw-r--r--test/files/presentation/memory-leaks/MemoryLeaksTest.scala5
-rw-r--r--test/files/presentation/t5708/Test.scala4
-rw-r--r--test/files/presentation/visibility/Test.scala4
-rw-r--r--test/files/run/stringinterpolation_macro-run.check62
-rw-r--r--test/files/run/stringinterpolation_macro-run.scala103
-rw-r--r--test/files/run/t5974.check1
-rw-r--r--test/files/run/t5974.scala10
-rw-r--r--test/files/speclib/instrumented.jar.desired.sha12
-rwxr-xr-xtools/new-starr6
106 files changed, 1105 insertions, 401 deletions
diff --git a/lib/ant/ant-contrib.jar.desired.sha1 b/lib/ant/ant-contrib.jar.desired.sha1
index 56745657c5..65bcd122bf 100644
--- a/lib/ant/ant-contrib.jar.desired.sha1
+++ b/lib/ant/ant-contrib.jar.desired.sha1
@@ -1 +1 @@
-943cd5c8802b2a3a64a010efb86ec19bac142e40 ?ant-contrib.jar
+943cd5c8802b2a3a64a010efb86ec19bac142e40 *ant-contrib.jar
diff --git a/lib/ant/ant-dotnet-1.0.jar.desired.sha1 b/lib/ant/ant-dotnet-1.0.jar.desired.sha1
index 1f1dc9b8c1..d8b6a1ca85 100644
--- a/lib/ant/ant-dotnet-1.0.jar.desired.sha1
+++ b/lib/ant/ant-dotnet-1.0.jar.desired.sha1
@@ -1 +1 @@
-3fc1e35ca8c991fc3488548f7a276bd9053c179d ?ant-dotnet-1.0.jar
+3fc1e35ca8c991fc3488548f7a276bd9053c179d *ant-dotnet-1.0.jar
diff --git a/lib/ant/ant.jar.desired.sha1 b/lib/ant/ant.jar.desired.sha1
index 852b3397cb..bcb610d6de 100644
--- a/lib/ant/ant.jar.desired.sha1
+++ b/lib/ant/ant.jar.desired.sha1
@@ -1 +1 @@
-7b456ca6b93900f96e58cc8371f03d90a9c1c8d1 ?ant.jar
+7b456ca6b93900f96e58cc8371f03d90a9c1c8d1 *ant.jar
diff --git a/lib/ant/maven-ant-tasks-2.1.1.jar.desired.sha1 b/lib/ant/maven-ant-tasks-2.1.1.jar.desired.sha1
index 06dcb1e312..53f87c3461 100644
--- a/lib/ant/maven-ant-tasks-2.1.1.jar.desired.sha1
+++ b/lib/ant/maven-ant-tasks-2.1.1.jar.desired.sha1
@@ -1 +1 @@
-7e50e3e227d834695f1e0bf018a7326e06ee4c86 ?maven-ant-tasks-2.1.1.jar
+7e50e3e227d834695f1e0bf018a7326e06ee4c86 *maven-ant-tasks-2.1.1.jar
diff --git a/lib/ant/vizant.jar.desired.sha1 b/lib/ant/vizant.jar.desired.sha1
index 00ff17d159..998da4643a 100644
--- a/lib/ant/vizant.jar.desired.sha1
+++ b/lib/ant/vizant.jar.desired.sha1
@@ -1 +1 @@
-2c61d6e9a912b3253194d5d6d3e1db7e2545ac4b ?vizant.jar
+2c61d6e9a912b3253194d5d6d3e1db7e2545ac4b *vizant.jar
diff --git a/lib/fjbg.jar.desired.sha1 b/lib/fjbg.jar.desired.sha1
index d24a5d01fc..6f3ccc77bd 100644
--- a/lib/fjbg.jar.desired.sha1
+++ b/lib/fjbg.jar.desired.sha1
@@ -1 +1 @@
-c3f9b576c91cb9761932ad936ccc4a71f33d2ef2 ?fjbg.jar
+8acc87f222210b4a5eb2675477602fc1759e7684 *fjbg.jar
diff --git a/lib/forkjoin.jar.desired.sha1 b/lib/forkjoin.jar.desired.sha1
index d31539daf4..8b24962e2c 100644
--- a/lib/forkjoin.jar.desired.sha1
+++ b/lib/forkjoin.jar.desired.sha1
@@ -1 +1 @@
-b5baf94dff8d3ca991d44a59add7bcbf6640379b ?forkjoin.jar
+f93a2525b5616d3a4bee7848fabbb2856b56f653 *forkjoin.jar
diff --git a/lib/jline.jar.desired.sha1 b/lib/jline.jar.desired.sha1
index 8acb0c9b14..b0426130ac 100644
--- a/lib/jline.jar.desired.sha1
+++ b/lib/jline.jar.desired.sha1
@@ -1 +1 @@
-a5261e70728c1847639e2b47d953441d0b217bcb ?jline.jar
+a5261e70728c1847639e2b47d953441d0b217bcb *jline.jar
diff --git a/lib/msil.jar.desired.sha1 b/lib/msil.jar.desired.sha1
index 2c2fe79dda..9396b273ab 100644
--- a/lib/msil.jar.desired.sha1
+++ b/lib/msil.jar.desired.sha1
@@ -1 +1 @@
-d48cb950ceded82a5e0ffae8ef2c68d0923ed00c ?msil.jar
+d48cb950ceded82a5e0ffae8ef2c68d0923ed00c *msil.jar
diff --git a/lib/scala-compiler-src.jar.desired.sha1 b/lib/scala-compiler-src.jar.desired.sha1
new file mode 100644
index 0000000000..48b3d3284e
--- /dev/null
+++ b/lib/scala-compiler-src.jar.desired.sha1
@@ -0,0 +1 @@
+259fd9f0a50ed6003248a01a366a97a5549aa386 ?scala-compiler-src.jar
diff --git a/lib/scala-compiler.jar.desired.sha1 b/lib/scala-compiler.jar.desired.sha1
index 9a47d9f730..a8dbdb0a38 100644
--- a/lib/scala-compiler.jar.desired.sha1
+++ b/lib/scala-compiler.jar.desired.sha1
@@ -1 +1 @@
-554bcc4a543360c8dc48fde91124dc57319d3460 ?scala-compiler.jar
+42f7367cc6ac59022d098e6091e5425390b9c925 ?scala-compiler.jar
diff --git a/lib/scala-library-src.jar.desired.sha1 b/lib/scala-library-src.jar.desired.sha1
index 1ec21bc6ee..3379287733 100644
--- a/lib/scala-library-src.jar.desired.sha1
+++ b/lib/scala-library-src.jar.desired.sha1
@@ -1 +1 @@
-7db4c7523f0e268ce58de2ab4ae6a3dd0e903f43 ?scala-library-src.jar
+e31e38414fd19c10add3e65bf77c2fd7c6c26f7d ?scala-library-src.jar
diff --git a/lib/scala-library.jar.desired.sha1 b/lib/scala-library.jar.desired.sha1
index ec73b5f7b8..bef528ce26 100644
--- a/lib/scala-library.jar.desired.sha1
+++ b/lib/scala-library.jar.desired.sha1
@@ -1 +1 @@
-071d32b24daaeaf961675f248758fedd31a806ed ?scala-library.jar
+2418c95bf7db34f87ebda4a5eaa918fe85047afb ?scala-library.jar
diff --git a/lib/scala-reflect-src.jar.desired.sha1 b/lib/scala-reflect-src.jar.desired.sha1
new file mode 100644
index 0000000000..b3a5f03efe
--- /dev/null
+++ b/lib/scala-reflect-src.jar.desired.sha1
@@ -0,0 +1 @@
+51c64d77ad4c4233a06cea7ea80b0fb77e9867c4 ?scala-reflect-src.jar
diff --git a/lib/scala-reflect.jar.desired.sha1 b/lib/scala-reflect.jar.desired.sha1
index 4be2e84aef..4d913d73ab 100644
--- a/lib/scala-reflect.jar.desired.sha1
+++ b/lib/scala-reflect.jar.desired.sha1
@@ -1 +1 @@
-b6e2bbbc1707104119adcb09aeb666690419c424 ?scala-reflect.jar
+5656bf2f17bb9f22b3ba61a83393a9794eaa5429 ?scala-reflect.jar
diff --git a/src/compiler/scala/tools/nsc/Global.scala b/src/compiler/scala/tools/nsc/Global.scala
index 327a864e3b..e378d71944 100644
--- a/src/compiler/scala/tools/nsc/Global.scala
+++ b/src/compiler/scala/tools/nsc/Global.scala
@@ -319,7 +319,7 @@ class Global(var currentSettings: Settings, var reporter: Reporter)
def ccon = Class.forName(name).getConstructor(classOf[CharsetDecoder], classOf[Reporter])
try Some(ccon.newInstance(charset.newDecoder(), reporter).asInstanceOf[SourceReader])
- catch { case x: Exception =>
+ catch { case ex: Throwable =>
globalError("exception while trying to instantiate source reader '" + name + "'")
None
}
@@ -1546,7 +1546,7 @@ class Global(var currentSettings: Settings, var reporter: Reporter)
def compileUnits(units: List[CompilationUnit], fromPhase: Phase) {
try compileUnitsInternal(units, fromPhase)
- catch { case ex =>
+ catch { case ex: Throwable =>
val shown = if (settings.verbose.value) {
val pw = new java.io.PrintWriter(new java.io.StringWriter)
ex.printStackTrace(pw)
diff --git a/src/compiler/scala/tools/nsc/backend/icode/analysis/TypeFlowAnalysis.scala b/src/compiler/scala/tools/nsc/backend/icode/analysis/TypeFlowAnalysis.scala
index c3fbf31cc6..7a5615ac26 100644
--- a/src/compiler/scala/tools/nsc/backend/icode/analysis/TypeFlowAnalysis.scala
+++ b/src/compiler/scala/tools/nsc/backend/icode/analysis/TypeFlowAnalysis.scala
@@ -516,7 +516,7 @@ abstract class TypeFlowAnalysis {
* but the effect on method size could be explored. */
putOnRadar(m.linearizedBlocks(linearizer))
populatePerimeter()
- assert(relevantBBs.isEmpty || relevantBBs.contains(m.startBlock), "you gave me dead code")
+ // usually but not always true (counterexample in SI-6015) `(relevantBBs.isEmpty || relevantBBs.contains(m.startBlock))`
}
def conclusives(b: BasicBlock): List[opcodes.CALL_METHOD] = {
diff --git a/src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala b/src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala
index ac2780f53e..8d243a1dd0 100644
--- a/src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala
+++ b/src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala
@@ -295,6 +295,7 @@ abstract class GenASM extends SubComponent with BytecodeWriters {
if (finalFlag && !sym.hasAbstractFlag) ACC_FINAL else 0,
if (sym.isStaticMember) ACC_STATIC else 0,
if (sym.isBridge) ACC_BRIDGE | ACC_SYNTHETIC else 0,
+ if (sym.isHidden) ACC_SYNTHETIC else 0,
if (sym.isClass && !sym.isInterface) ACC_SUPER else 0,
if (sym.isVarargsMethod) ACC_VARARGS else 0,
if (sym.hasFlag(Flags.SYNCHRONIZED)) ACC_SYNCHRONIZED else 0
@@ -849,7 +850,7 @@ abstract class GenASM extends SubComponent with BytecodeWriters {
// without it. This is particularly bad because the availability of
// generic information could disappear as a consequence of a seemingly
// unrelated change.
- sym.isSynthetic
+ sym.isHidden
|| sym.isLiftedMethod
|| sym.isBridge
|| (sym.ownerChain exists (_.isImplClass))
@@ -1322,7 +1323,7 @@ abstract class GenASM extends SubComponent with BytecodeWriters {
// Additional interface parents based on annotations and other cues
def newParentForAttr(attr: Symbol): Option[Symbol] = attr match {
case SerializableAttr => Some(SerializableClass)
- case CloneableAttr => Some(JavaCloneableClass)
+ case CloneableAttr => Some(CloneableClass)
case RemoteAttr => Some(RemoteInterfaceClass)
case _ => None
}
@@ -2191,9 +2192,15 @@ abstract class GenASM extends SubComponent with BytecodeWriters {
val st = pending.getOrElseUpdate(lv, mutable.Stack.empty[Label])
st.push(start)
}
- def popScope(lv: Local, end: Label) {
- val start = pending(lv).pop()
- seen ::= LocVarEntry(lv, start, end)
+ def popScope(lv: Local, end: Label, iPos: Position) {
+ pending.get(lv) match {
+ case Some(st) if st.nonEmpty =>
+ val start = st.pop()
+ seen ::= LocVarEntry(lv, start, end)
+ case _ =>
+ // TODO SI-6049
+ getCurrentCUnit().warning(iPos, "Visited SCOPE_EXIT before visiting corresponding SCOPE_ENTER. SI-6049")
+ }
}
def getMerged(): collection.Map[Local, List[Interval]] = {
@@ -2406,7 +2413,7 @@ abstract class GenASM extends SubComponent with BytecodeWriters {
// similarly, these labels aren't tracked in the `labels` map.
val end = new asm.Label
jmethod.visitLabel(end)
- scoping.popScope(lv, end)
+ scoping.popScope(lv, end, instr.pos)
}
}
diff --git a/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala b/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala
index 21260d399c..9661ae6b3e 100644
--- a/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala
+++ b/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala
@@ -727,7 +727,7 @@ abstract class GenJVM extends SubComponent with GenJVMUtil with GenAndroid with
// without it. This is particularly bad because the availability of
// generic information could disappear as a consequence of a seemingly
// unrelated change.
- sym.isSynthetic
+ sym.isHidden
|| sym.isLiftedMethod
|| sym.isBridge
|| (sym.ownerChain exists (_.isImplClass))
@@ -1972,6 +1972,7 @@ abstract class GenJVM extends SubComponent with GenJVMUtil with GenAndroid with
if (finalFlag && !sym.hasAbstractFlag) ACC_FINAL else 0,
if (sym.isStaticMember) ACC_STATIC else 0,
if (sym.isBridge) ACC_BRIDGE | ACC_SYNTHETIC else 0,
+ if (sym.isHidden) ACC_SYNTHETIC else 0,
if (sym.isClass && !sym.isInterface) ACC_SUPER else 0,
if (sym.isVarargsMethod) ACC_VARARGS else 0,
if (sym.hasFlag(Flags.SYNCHRONIZED)) JAVA_ACC_SYNCHRONIZED else 0
diff --git a/src/compiler/scala/tools/nsc/interactive/tests/InteractiveTest.scala b/src/compiler/scala/tools/nsc/interactive/tests/InteractiveTest.scala
index f622f11ffd..afb8985700 100644
--- a/src/compiler/scala/tools/nsc/interactive/tests/InteractiveTest.scala
+++ b/src/compiler/scala/tools/nsc/interactive/tests/InteractiveTest.scala
@@ -82,13 +82,17 @@ abstract class InteractiveTest
/** Test's entry point */
def main(args: Array[String]) {
+ try execute()
+ finally shutdown()
+ }
+
+ protected def execute(): Unit = {
loadSources()
- runTests()
- shutdown()
+ runDefaultTests()
}
/** Load all sources before executing the test. */
- private def loadSources() {
+ protected def loadSources() {
// ask the presentation compiler to track all sources. We do
// not wait for the file to be entirely typed because we do want
// to exercise the presentation compiler on scoped type requests.
@@ -100,7 +104,7 @@ abstract class InteractiveTest
}
/** Run all defined `PresentationCompilerTestDef` */
- protected def runTests() {
+ protected def runDefaultTests() {
//TODO: integrate random tests!, i.e.: if (runRandomTests) randomTests(20, sourceFiles)
testActions.foreach(_.runTest())
}
@@ -109,7 +113,7 @@ abstract class InteractiveTest
private def randomTests(n: Int, files: Array[SourceFile]) {
val tester = new Tester(n, files, settings) {
override val compiler = self.compiler
- override val reporter = compilerReporter
+ override val reporter = new reporters.StoreReporter
}
tester.run()
}
diff --git a/src/compiler/scala/tools/nsc/interactive/tests/InteractiveTestSettings.scala b/src/compiler/scala/tools/nsc/interactive/tests/InteractiveTestSettings.scala
index 36671555d1..4d85ab9d88 100644
--- a/src/compiler/scala/tools/nsc/interactive/tests/InteractiveTestSettings.scala
+++ b/src/compiler/scala/tools/nsc/interactive/tests/InteractiveTestSettings.scala
@@ -4,10 +4,8 @@ package tests
import java.io.File.pathSeparatorChar
import java.io.File.separatorChar
-
import scala.tools.nsc.interactive.tests.core.PresentationCompilerInstance
-import scala.tools.nsc.io.File
-
+import scala.tools.nsc.io.{File,Path}
import core.Reporter
import core.TestSettings
@@ -46,6 +44,11 @@ trait InteractiveTestSettings extends TestSettings with PresentationCompilerInst
println("error processing arguments (unprocessed: %s)".format(rest))
case _ => ()
}
+
+ // Make the --sourcepath path provided in the .flags file (if any) relative to the test's base directory
+ if(settings.sourcepath.isSetByUser)
+ settings.sourcepath.value = (baseDir / Path(settings.sourcepath.value)).path
+
adjustPaths(settings.bootclasspath, settings.classpath, settings.javabootclasspath, settings.sourcepath)
}
diff --git a/src/compiler/scala/tools/nsc/interactive/tests/core/PresentationCompilerInstance.scala b/src/compiler/scala/tools/nsc/interactive/tests/core/PresentationCompilerInstance.scala
index 8ccb5aa075..5c1837b3bf 100644
--- a/src/compiler/scala/tools/nsc/interactive/tests/core/PresentationCompilerInstance.scala
+++ b/src/compiler/scala/tools/nsc/interactive/tests/core/PresentationCompilerInstance.scala
@@ -2,12 +2,15 @@ package scala.tools.nsc
package interactive
package tests.core
-import reporters.StoreReporter
+import reporters.{Reporter => CompilerReporter}
+import scala.reflect.internal.util.Position
/** Trait encapsulating the creation of a presentation compiler's instance.*/
-private[tests] trait PresentationCompilerInstance {
+private[tests] trait PresentationCompilerInstance extends TestSettings {
protected val settings = new Settings
- protected val compilerReporter = new StoreReporter
+ protected val compilerReporter: CompilerReporter = new InteractiveReporter {
+ override def compiler = PresentationCompilerInstance.this.compiler
+ }
protected lazy val compiler: Global = {
prepareSettings(settings)
diff --git a/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala b/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala
index 65b0ff1e6d..60e11291c1 100644
--- a/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala
+++ b/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala
@@ -645,7 +645,14 @@ abstract class ClassfileParser {
// if this is a non-static inner class, remove the explicit outer parameter
val newParams = innerClasses.get(currentClass) match {
case Some(entry) if !isScalaRaw && !isStatic(entry.jflags) =>
- assert(params.head.tpe.typeSymbol == clazz.owner, params.head.tpe.typeSymbol + ": " + clazz.owner)
+ /* About `clazz.owner.isPackage` below: SI-5957
+ * For every nested java class A$B, there are two symbols in the scala compiler.
+ * 1. created by SymbolLoader, because of the existence of the A$B.class file, owner: package
+ * 2. created by ClassfileParser of A when reading the inner classes, owner: A
+ * If symbol 1 gets completed (e.g. because the compiled source mentions `A$B`, not `A#B`), the
+ * ClassfileParser for 1 executes, and clazz.owner is the package.
+ */
+ assert(params.head.tpe.typeSymbol == clazz.owner || clazz.owner.isPackage, params.head.tpe.typeSymbol + ": " + clazz.owner)
params.tail
case _ =>
params
@@ -862,7 +869,7 @@ abstract class ClassfileParser {
}
else in.skip(attrLen)
case tpnme.SyntheticATTR =>
- sym.setFlag(SYNTHETIC)
+ sym.setFlag(SYNTHETIC | HIDDEN)
in.skip(attrLen)
case tpnme.BridgeATTR =>
sym.setFlag(BRIDGE)
diff --git a/src/compiler/scala/tools/nsc/symtab/classfile/Pickler.scala b/src/compiler/scala/tools/nsc/symtab/classfile/Pickler.scala
index 192cc94b90..cc5ed0f129 100644
--- a/src/compiler/scala/tools/nsc/symtab/classfile/Pickler.scala
+++ b/src/compiler/scala/tools/nsc/symtab/classfile/Pickler.scala
@@ -503,7 +503,7 @@ abstract class Pickler extends SubComponent {
private def writeSymInfo(sym: Symbol) {
writeRef(sym.name)
writeRef(localizedOwner(sym))
- writeLongNat((rawFlagsToPickled(sym.flags & PickledFlags)))
+ writeLongNat((rawToPickledFlags(sym.flags & PickledFlags)))
if (sym.hasAccessBoundary) writeRef(sym.privateWithin)
writeRef(sym.info)
}
@@ -966,7 +966,7 @@ abstract class Pickler extends SubComponent {
TREE
case Modifiers(flags, privateWithin, _) =>
- val pflags = rawFlagsToPickled(flags)
+ val pflags = rawToPickledFlags(flags)
writeNat((pflags >> 32).toInt)
writeNat((pflags & 0xFFFFFFFF).toInt)
writeRef(privateWithin)
diff --git a/src/compiler/scala/tools/nsc/transform/Erasure.scala b/src/compiler/scala/tools/nsc/transform/Erasure.scala
index 1276d62995..5115c49c87 100644
--- a/src/compiler/scala/tools/nsc/transform/Erasure.scala
+++ b/src/compiler/scala/tools/nsc/transform/Erasure.scala
@@ -351,7 +351,7 @@ abstract class Erasure extends AddInterfaces
List())
if cast.symbol == Object_asInstanceOf &&
tpt.tpe.typeSymbol.isDerivedValueClass &&
- sel.symbol == tpt.tpe.typeSymbol.firstParamAccessor =>
+ sel.symbol == tpt.tpe.typeSymbol.derivedValueClassUnbox =>
Some(arg)
case _ =>
None
@@ -498,7 +498,8 @@ abstract class Erasure extends AddInterfaces
ldef setType ldef.rhs.tpe
case _ =>
val tree1 = tree.tpe match {
- case ErasedValueType(clazz) =>
+ case ErasedValueType(tref) =>
+ val clazz = tref.sym
tree match {
case Unboxed(arg) if arg.tpe.typeSymbol == clazz =>
log("shortcircuiting unbox -> box "+arg); arg
@@ -554,25 +555,26 @@ abstract class Erasure extends AddInterfaces
ldef setType ldef.rhs.tpe
case _ =>
val tree1 = pt match {
- case ErasedValueType(clazz) =>
+ case ErasedValueType(tref) =>
tree match {
case Boxed(arg) if arg.tpe.isInstanceOf[ErasedValueType] =>
log("shortcircuiting box -> unbox "+arg)
arg
case _ =>
+ val clazz = tref.sym
log("not boxed: "+tree)
val tree0 = adaptToType(tree, clazz.tpe)
- cast(Apply(Select(tree0, clazz.firstParamAccessor), List()), pt)
+ cast(Apply(Select(tree0, clazz.derivedValueClassUnbox), List()), pt)
}
case _ =>
pt.typeSymbol match {
- case UnitClass =>
- if (treeInfo isExprSafeToInline tree) UNIT
- else BLOCK(tree, UNIT)
- case x =>
- assert(x != ArrayClass)
- // don't `setType pt` the Apply tree, as the Apply's fun won't be typechecked if the Apply tree already has a type
- Apply(unboxMethod(pt.typeSymbol), tree)
+ case UnitClass =>
+ if (treeInfo isExprSafeToInline tree) UNIT
+ else BLOCK(tree, UNIT)
+ case x =>
+ assert(x != ArrayClass)
+ // don't `setType pt` the Apply tree, as the Apply's fun won't be typechecked if the Apply tree already has a type
+ Apply(unboxMethod(pt.typeSymbol), tree)
}
}
typedPos(tree.pos)(tree1)
@@ -601,7 +603,7 @@ abstract class Erasure extends AddInterfaces
* @return the adapted tree
*/
private def adaptToType(tree: Tree, pt: Type): Tree = {
- if (settings.debug.value && pt != WildcardType)
+ //if (settings.debug.value && pt != WildcardType)
log("adapting " + tree + ":" + tree.tpe + " : " + tree.tpe.parents + " to " + pt)//debug
if (tree.tpe <:< pt)
tree
@@ -629,7 +631,7 @@ abstract class Erasure extends AddInterfaces
* - `x != y` for != in class Any becomes `!(x equals y)` with equals in class Object.
* - x.asInstanceOf[T] becomes x.$asInstanceOf[T]
* - x.isInstanceOf[T] becomes x.$isInstanceOf[T]
- * - x.isInstanceOf[ErasedValueType(clazz)] becomes x.isInstanceOf[clazz.tpe]
+ * - x.isInstanceOf[ErasedValueType(tref)] becomes x.isInstanceOf[tref.sym.tpe]
* - x.m where m is some other member of Any becomes x.m where m is a member of class Object.
* - x.m where x has unboxed value type T and m is not a directly translated member of T becomes T.box(x).m
* - x.m where x is a reference type and m is a directly translated member of value type T becomes x.TValue().m
@@ -651,12 +653,33 @@ abstract class Erasure extends AddInterfaces
atPos(tree.pos)(Apply(Select(qual1, "to" + targClass.name), List()))
else
*/
- if (isPrimitiveValueType(targ.tpe) || isErasedValueType(targ.tpe)) unbox(qual1, targ.tpe)
- else tree
+ if (isPrimitiveValueType(targ.tpe) || isErasedValueType(targ.tpe)) {
+ val noNullCheckNeeded = targ.tpe match {
+ case ErasedValueType(tref) =>
+ atPhase(currentRun.erasurePhase) {
+ isPrimitiveValueClass(erasedValueClassArg(tref).typeSymbol)
+ }
+ case _ =>
+ true
+ }
+ if (noNullCheckNeeded) unbox(qual1, targ.tpe)
+ else {
+ def nullConst = Literal(Constant(null)) setType NullClass.tpe
+ val untyped =
+// util.trace("new asinstanceof test") {
+ gen.evalOnce(qual1, context.owner, context.unit) { qual =>
+ If(Apply(Select(qual(), nme.eq), List(Literal(Constant(null)) setType NullClass.tpe)),
+ Literal(Constant(null)) setType targ.tpe,
+ unbox(qual(), targ.tpe))
+ }
+// }
+ typed(untyped)
+ }
+ } else tree
case Apply(TypeApply(sel @ Select(qual, name), List(targ)), List())
if tree.symbol == Any_isInstanceOf =>
targ.tpe match {
- case ErasedValueType(clazz) => targ.setType(clazz.tpe)
+ case ErasedValueType(tref) => targ.setType(tref.sym.tpe)
case _ =>
}
tree
@@ -711,17 +734,22 @@ abstract class Erasure extends AddInterfaces
val tree1 = try {
tree match {
case InjectDerivedValue(arg) =>
- val clazz = tree.symbol
- val result = typed1(arg, mode, underlyingOfValueClass(clazz)) setType ErasedValueType(clazz)
- log("transforming inject "+arg+":"+underlyingOfValueClass(clazz)+"/"+ErasedValueType(clazz)+" = "+result)
- return result
+ (tree.attachments.get[TypeRefAttachment]: @unchecked) match {
+ case Some(itype) =>
+ val tref = itype.tpe
+ val argPt = atPhase(currentRun.erasurePhase)(erasedValueClassArg(tref))
+ log(s"transforming inject $arg -> $tref/$argPt")
+ val result = typed(arg, mode, argPt)
+ log(s"transformed inject $arg -> $tref/$argPt = $result:${result.tpe}")
+ return result setType ErasedValueType(tref)
+ }
case _ =>
- super.typed1(adaptMember(tree), mode, pt)
+ super.typed1(adaptMember(tree), mode, pt)
}
} catch {
case er: TypeError =>
- Console.println("exception when typing " + tree)
+ Console.println("exception when typing " + tree+"/"+tree.getClass)
Console.println(er.msg + " in file " + context.owner.sourceFile)
er.printStackTrace
abort("unrecoverable error")
@@ -731,6 +759,7 @@ abstract class Erasure extends AddInterfaces
finally throw ex
throw ex
}
+
def adaptCase(cdef: CaseDef): CaseDef = {
val newCdef = deriveCaseDef(cdef)(adaptToType(_, tree1.tpe))
newCdef setType newCdef.body.tpe
@@ -970,8 +999,11 @@ abstract class Erasure extends AddInterfaces
else
tree
+
case Apply(Select(New(tpt), nme.CONSTRUCTOR), List(arg)) if (tpt.tpe.typeSymbol.isDerivedValueClass) =>
- InjectDerivedValue(arg) setSymbol tpt.tpe.typeSymbol
+// println("inject derived: "+arg+" "+tpt.tpe)
+ InjectDerivedValue(arg) addAttachment //@@@ setSymbol tpt.tpe.typeSymbol
+ new TypeRefAttachment(tree.tpe.asInstanceOf[TypeRef])
case Apply(fn, args) =>
def qualifier = fn match {
case Select(qual, _) => qual
@@ -1125,4 +1157,6 @@ abstract class Erasure extends AddInterfaces
}
}
}
+
+ private class TypeRefAttachment(val tpe: TypeRef)
}
diff --git a/src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala b/src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala
index 1b8513373d..ab7bbc591b 100644
--- a/src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala
+++ b/src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala
@@ -92,7 +92,7 @@ abstract class ExplicitOuter extends InfoTransform
else findOrElse(clazz.info.decls)(_.outerSource == clazz)(NoSymbol)
}
def newOuterAccessor(clazz: Symbol) = {
- val accFlags = SYNTHETIC | METHOD | STABLE | ( if (clazz.isTrait) DEFERRED else 0 )
+ val accFlags = SYNTHETIC | HIDDEN | METHOD | STABLE | ( if (clazz.isTrait) DEFERRED else 0 )
val sym = clazz.newMethod(nme.OUTER, clazz.pos, accFlags)
val restpe = if (clazz.isTrait) clazz.outerClass.tpe else clazz.outerClass.thisType
@@ -101,7 +101,7 @@ abstract class ExplicitOuter extends InfoTransform
sym setInfo MethodType(Nil, restpe)
}
def newOuterField(clazz: Symbol) = {
- val accFlags = SYNTHETIC | PARAMACCESSOR | ( if (clazz.isEffectivelyFinal) PrivateLocal else PROTECTED )
+ val accFlags = SYNTHETIC | HIDDEN | PARAMACCESSOR | ( if (clazz.isEffectivelyFinal) PrivateLocal else PROTECTED )
val sym = clazz.newValue(nme.OUTER_LOCAL, clazz.pos, accFlags)
sym setInfo clazz.outerClass.thisType
diff --git a/src/compiler/scala/tools/nsc/transform/PostErasure.scala b/src/compiler/scala/tools/nsc/transform/PostErasure.scala
index ef158a71f6..999d00520d 100644
--- a/src/compiler/scala/tools/nsc/transform/PostErasure.scala
+++ b/src/compiler/scala/tools/nsc/transform/PostErasure.scala
@@ -21,7 +21,8 @@ trait PostErasure extends InfoTransform with TypingTransformers {
object elimErasedValueType extends TypeMap {
def apply(tp: Type) = tp match {
- case ErasedValueType(clazz) => erasure.underlyingOfValueClass(clazz)
+ case ErasedValueType(tref) =>
+ atPhase(currentRun.erasurePhase)(erasure.erasedValueClassArg(tref))
case _ => mapOver(tp)
}
}
@@ -38,7 +39,7 @@ trait PostErasure extends InfoTransform with TypingTransformers {
acc), List())
if atPhase(currentRun.erasurePhase) {
tpt.tpe.typeSymbol.isDerivedValueClass &&
- sel.symbol == tpt.tpe.typeSymbol.firstParamAccessor
+ sel.symbol == tpt.tpe.typeSymbol.derivedValueClassUnbox
} =>
if (settings.debug.value) log("Removing "+tree+" -> "+arg)
arg
diff --git a/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala b/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala
index 49f5fca19d..ba6c43f9d3 100644
--- a/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala
@@ -562,7 +562,9 @@ trait ContextErrors {
// SelectFromTypeTree
def TypeSelectionFromVolatileTypeError(tree: Tree, qual: Tree) = {
- issueNormalTypeError(tree, "illegal type selection from volatile type "+qual.tpe)
+ val hiBound = qual.tpe.bounds.hi
+ val addendum = if (hiBound =:= qual.tpe) "" else s" (with upper bound ${hiBound})"
+ issueNormalTypeError(tree, s"illegal type selection from volatile type ${qual.tpe}${addendum}")
setError(tree)
}
diff --git a/src/compiler/scala/tools/nsc/typechecker/Namers.scala b/src/compiler/scala/tools/nsc/typechecker/Namers.scala
index 6428173577..9580cd5676 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Namers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Namers.scala
@@ -52,27 +52,6 @@ trait Namers extends MethodSynthesis {
def newNamerFor(context: Context, tree: Tree): Namer =
newNamer(context.makeNewScope(tree, tree.symbol))
- // In the typeCompleter (templateSig) of a case class (resp it's module),
- // synthetic `copy` (reps `apply`, `unapply`) methods are added. To compute
- // their signatures, the corresponding ClassDef is needed.
- // During naming, for each case class module symbol, the corresponding ClassDef
- // is stored in this map. The map is cleared lazily, i.e. when the new symbol
- // is created with the same name, the old one (if present) is wiped out, or the
- // entry is deleted when it is used and no longer needed.
- private val classOfModuleClass = perRunCaches.newWeakMap[Symbol, WeakReference[ClassDef]]()
-
- // Default getters of constructors are added to the companion object in the
- // typeCompleter of the constructor (methodSig). To compute the signature,
- // we need the ClassDef. To create and enter the symbols into the companion
- // object, we need the templateNamer of that module class.
- // This map is extended during naming of classes, the Namer is added in when
- // it's available, i.e. in the type completer (templateSig) of the module class.
- private[typechecker] val classAndNamerOfModule = perRunCaches.newMap[Symbol, (ClassDef, Namer)]()
-
- def resetNamer() {
- classAndNamerOfModule.clear()
- }
-
abstract class Namer(val context: Context) extends MethodSynth with NamerContextErrors { thisNamer =>
import NamerErrorGen._
@@ -618,7 +597,7 @@ trait Namers extends MethodSynthesis {
MaxParametersCaseClassError(tree)
val m = ensureCompanionObject(tree, caseModuleDef)
- classOfModuleClass(m.moduleClass) = new WeakReference(tree)
+ m.moduleClass.addAttachment(new ClassForCaseCompanionAttachment(tree))
}
val hasDefault = impl.body exists {
case DefDef(_, nme.CONSTRUCTOR, _, vparamss, _, _) => mexists(vparamss)(_.mods.hasDefault)
@@ -626,7 +605,7 @@ trait Namers extends MethodSynthesis {
}
if (hasDefault) {
val m = ensureCompanionObject(tree)
- classAndNamerOfModule(m) = (tree, null)
+ m.addAttachment(new ConstructorDefaultsAttachment(tree, null))
}
val owner = tree.symbol.owner
if (settings.lint.value && owner.isPackageObjectClass && !mods.isImplicit) {
@@ -657,7 +636,8 @@ trait Namers extends MethodSynthesis {
if (sym.isLazy)
sym.lazyAccessor andAlso enterIfNotThere
- defaultParametersOfMethod(sym) foreach { symRef => enterIfNotThere(symRef()) }
+ for (defAtt <- sym.attachments.get[DefaultsOfLocalMethodAttachment])
+ defAtt.defaultGetters foreach enterIfNotThere
}
this.context
}
@@ -846,23 +826,20 @@ trait Namers extends MethodSynthesis {
// add apply and unapply methods to companion objects of case classes,
// unless they exist already; here, "clazz" is the module class
if (clazz.isModuleClass) {
- Namers.this.classOfModuleClass get clazz foreach { cdefRef =>
- val cdef = cdefRef()
- if (cdef.mods.isCase) addApplyUnapply(cdef, templateNamer)
- classOfModuleClass -= clazz
+ clazz.attachments.get[ClassForCaseCompanionAttachment] foreach { cma =>
+ val cdef = cma.caseClass
+ assert(cdef.mods.isCase, "expected case class: "+ cdef)
+ addApplyUnapply(cdef, templateNamer)
}
}
// add the copy method to case classes; this needs to be done here, not in SyntheticMethods, because
// the namer phase must traverse this copy method to create default getters for its parameters.
// here, clazz is the ClassSymbol of the case class (not the module).
- // @check: this seems to work only if the type completer of the class runs before the one of the
- // module class: the one from the module class removes the entry from classOfModuleClass (see above).
if (clazz.isClass && !clazz.hasModuleFlag) {
val modClass = companionSymbolOf(clazz, context).moduleClass
- Namers.this.classOfModuleClass get modClass map { cdefRef =>
- val cdef = cdefRef()
-
+ modClass.attachments.get[ClassForCaseCompanionAttachment] foreach { cma =>
+ val cdef = cma.caseClass
def hasCopy(decls: Scope) = (decls lookup nme.copy) != NoSymbol
if (cdef.mods.isCase && !hasCopy(decls) &&
!parents.exists(p => hasCopy(p.typeSymbol.info.decls)) &&
@@ -874,9 +851,8 @@ trait Namers extends MethodSynthesis {
// if default getters (for constructor defaults) need to be added to that module, here's the namer
// to use. clazz is the ModuleClass. sourceModule works also for classes defined in methods.
val module = clazz.sourceModule
- classAndNamerOfModule get module foreach {
- case (cdef, _) =>
- classAndNamerOfModule(module) = (cdef, templateNamer)
+ for (cda <- module.attachments.get[ConstructorDefaultsAttachment]) {
+ cda.companionModuleClassNamer = templateNamer
}
ClassInfoType(parents, decls, clazz)
}
@@ -1097,13 +1073,15 @@ trait Namers extends MethodSynthesis {
val module = companionSymbolOf(clazz, context)
module.initialize // call type completer (typedTemplate), adds the
// module's templateNamer to classAndNamerOfModule
- classAndNamerOfModule get module match {
- case s @ Some((cdef, nmr)) if nmr != null =>
- moduleNamer = s
- (cdef, nmr)
+ module.attachments.get[ConstructorDefaultsAttachment] match {
+ // by martin: the null case can happen in IDE; this is really an ugly hack on top of an ugly hack but it seems to work
+ // later by lukas: disabled when fixing SI-5975, i think it cannot happen anymore
+ case Some(cda) /*if cma.companionModuleClassNamer == null*/ =>
+ val p = (cda.classWithDefault, cda.companionModuleClassNamer)
+ moduleNamer = Some(p)
+ p
case _ =>
return // fix #3649 (prevent crash in erroneous source code)
- // nmr == null can happen in IDE; this is really an ugly hack on top[ of an ugly hack but it seems to work
}
}
deftParams = cdef.tparams map copyUntypedInvariant
@@ -1141,11 +1119,14 @@ trait Namers extends MethodSynthesis {
clazz.resetFlag(INTERFACE) // there's a concrete member now
val default = parentNamer.enterSyntheticSym(defaultTree)
if (forInteractive && default.owner.isTerm) {
- // enter into map from method symbols to default arguments.
- // if compiling the same local block several times (which can happen in interactive mode)
- // we might otherwise not find the default symbol, because the second time it the
- // method symbol will be re-entered in the scope but the default parameter will not.
- defaultParametersOfMethod(meth) += new WeakReference(default)
+ // save the default getters as attachments in the method symbol. if compiling the
+ // same local block several times (which can happen in interactive mode) we might
+ // otherwise not find the default symbol, because the second time it the method
+ // symbol will be re-entered in the scope but the default parameter will not.
+ val att = meth.attachments.get[DefaultsOfLocalMethodAttachment] match {
+ case Some(att) => att.defaultGetters += default
+ case None => meth.addAttachment(new DefaultsOfLocalMethodAttachment(default))
+ }
}
} else if (baseHasDefault) {
// the parameter does not have a default itself, but the
diff --git a/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala b/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala
index 61443faba0..a0c1342026 100644
--- a/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala
@@ -21,8 +21,19 @@ trait NamesDefaults { self: Analyzer =>
import definitions._
import NamesDefaultsErrorsGen._
- val defaultParametersOfMethod =
- perRunCaches.newWeakMap[Symbol, Set[WeakReference[Symbol]]]() withDefaultValue Set()
+ // Default getters of constructors are added to the companion object in the
+ // typeCompleter of the constructor (methodSig). To compute the signature,
+ // we need the ClassDef. To create and enter the symbols into the companion
+ // object, we need the templateNamer of that module class. These two are stored
+ // as an attachment in the companion module symbol
+ class ConstructorDefaultsAttachment(val classWithDefault: ClassDef, var companionModuleClassNamer: Namer)
+
+ // To attach the default getters of local (term-owned) methods to the method symbol.
+ // Used in Namer.enterExistingSym: it needs to re-enter the method symbol and also
+ // default getters, which could not be found otherwise.
+ class DefaultsOfLocalMethodAttachment(val defaultGetters: mutable.Set[Symbol]) {
+ def this(default: Symbol) = this(mutable.Set(default))
+ }
case class NamedApplyInfo(
qual: Option[Tree],
diff --git a/src/compiler/scala/tools/nsc/typechecker/PatternMatching.scala b/src/compiler/scala/tools/nsc/typechecker/PatternMatching.scala
index 53c2d16928..b1e68e2757 100644
--- a/src/compiler/scala/tools/nsc/typechecker/PatternMatching.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/PatternMatching.scala
@@ -8,7 +8,7 @@ package scala.tools.nsc
package typechecker
import symtab._
-import Flags.{MUTABLE, METHOD, LABEL, SYNTHETIC}
+import Flags.{MUTABLE, METHOD, LABEL, SYNTHETIC, HIDDEN}
import language.postfixOps
import scala.tools.nsc.transform.TypingTransformers
import scala.tools.nsc.transform.Transform
@@ -949,7 +949,7 @@ trait PatternMatching extends Transform with TypingTransformers with ast.TreeDSL
// ExplicitOuter replaces `Select(q, outerSym) OBJ_EQ expectedPrefix` by `Select(q, outerAccessor(outerSym.owner)) OBJ_EQ expectedPrefix`
// if there's an outer accessor, otherwise the condition becomes `true` -- TODO: can we improve needsOuterTest so there's always an outerAccessor?
- val outer = expectedTp.typeSymbol.newMethod(vpmName.outer) setInfo expectedTp.prefix setFlag SYNTHETIC
+ val outer = expectedTp.typeSymbol.newMethod(vpmName.outer) setInfo expectedTp.prefix setFlag SYNTHETIC | HIDDEN
(Select(codegen._asInstanceOf(testedBinder, expectedTp), outer)) OBJ_EQ expectedOuter
}
@@ -1616,7 +1616,16 @@ trait PatternMatching extends Transform with TypingTransformers with ast.TreeDSL
type Const <: AbsConst
trait AbsConst {
+ // when we know V = C, which other equalities must hold
+ // in general, equality to some type implies equality to its supertypes
+ // (this multi-valued kind of equality is necessary for unreachability)
+ // note that we use subtyping as a model for implication between instanceof tests
+ // i.e., when S <:< T we assume x.isInstanceOf[S] implies x.isInstanceOf[T]
+ // unfortunately this is not true in general (see e.g. SI-6022)
def implies(other: Const): Boolean
+
+ // does V = C preclude V having value `other`? V = null is an exclusive assignment,
+ // but V = 1 does not preclude V = Int, or V = Any
def excludes(other: Const): Boolean
}
@@ -2164,11 +2173,30 @@ trait PatternMatching extends Transform with TypingTransformers with ast.TreeDSL
def isAny = wideTp.typeSymbol == AnyClass
+ // we use subtyping as a model for implication between instanceof tests
+ // i.e., when S <:< T we assume x.isInstanceOf[S] implies x.isInstanceOf[T]
+ // unfortunately this is not true in general:
+ // SI-6022 expects instanceOfTpImplies(ProductClass.tpe, AnyRefClass.tpe)
+ private def instanceOfTpImplies(tp: Type, tpImplied: Type) = {
+ val tpValue = tp.typeSymbol.isPrimitiveValueClass
+
+ // pretend we're comparing to Any when we're actually comparing to AnyVal or AnyRef
+ // (and the subtype is respectively a value type or not a value type)
+ // this allows us to reuse subtyping as a model for implication between instanceOf tests
+ // the latter don't see a difference between AnyRef, Object or Any when comparing non-value types -- SI-6022
+ val tpImpliedNormalizedToAny =
+ if ((tpValue && tpImplied =:= AnyValClass.tpe) ||
+ (!tpValue && tpImplied =:= AnyRefClass.tpe)) AnyClass.tpe
+ else tpImplied
+
+ tp <:< tpImpliedNormalizedToAny
+ }
+
final def implies(other: Const): Boolean = {
val r = (this, other) match {
case (_: ValueConst, _: ValueConst) => this == other // hashconsed
- case (_: ValueConst, _: TypeConst) => tp <:< other.tp
- case (_: TypeConst, _) => tp <:< other.tp
+ case (_: ValueConst, _: TypeConst) => instanceOfTpImplies(tp, other.tp)
+ case (_: TypeConst, _) => instanceOfTpImplies(tp, other.tp)
case _ => false
}
// if(r) patmatDebug("implies : "+(this, other))
@@ -2185,12 +2213,12 @@ trait PatternMatching extends Transform with TypingTransformers with ast.TreeDSL
// this causes false negative for unreachability, but that's ok:
// example: val X = 1; val Y = 1; (2: Int) match { case X => case Y => /* considered reachable */ }
case (_: ValueConst, _: ValueConst) => this != other
- case (_: ValueConst, _: TypeConst) => !((tp <:< other.tp) || (other.tp <:< wideTp))
- case (_: TypeConst, _: ValueConst) => !((other.tp <:< tp) || (tp <:< other.wideTp))
- case (_: TypeConst, _: TypeConst) => !((tp <:< other.tp) || (other.tp <:< tp))
+ case (_: ValueConst, _: TypeConst) => !(instanceOfTpImplies(tp, other.tp) || instanceOfTpImplies(other.tp, wideTp))
+ case (_: TypeConst, _: ValueConst) => !(instanceOfTpImplies(other.tp, tp) || instanceOfTpImplies(tp, other.wideTp))
+ case (_: TypeConst, _: TypeConst) => !(instanceOfTpImplies(tp, other.tp) || instanceOfTpImplies(other.tp, tp))
case _ => false
}
- // if(r) patmatDebug("excludes : "+(this, this.tp, other, other.tp, (tp <:< other.tp), (tp <:< other.wideTp), (other.tp <:< tp), (other.tp <:< wideTp)))
+ // if(r) patmatDebug("excludes : "+(this, this.tp, other, other.tp))
// else patmatDebug("NOT excludes: "+(this, other))
r
}
@@ -2752,7 +2780,7 @@ trait PatternMatching extends Transform with TypingTransformers with ast.TreeDSL
def simplify(c: Cond): Set[Cond] = c match {
case AndCond(a, b) => simplify(a) ++ simplify(b)
case OrCond(_, _) => Set(FalseCond) // TODO: make more precise
- case NonNullCond(_) => Set(TrueCond) // not worth remembering
+ case NonNullCond(_) => Set(TrueCond) // not worth remembering
case _ => Set(c)
}
val conds = simplify(cond)
@@ -2768,7 +2796,7 @@ trait PatternMatching extends Transform with TypingTransformers with ast.TreeDSL
case (priorTest, deps) =>
((simplify(priorTest.cond) == nonTrivial) || // our conditions are implied by priorTest if it checks the same thing directly
(nonTrivial subsetOf deps) // or if it depends on a superset of our conditions
- ) && (deps subsetOf tested) // the conditions we've tested when we are here in the match satisfy the prior test, and hence what it tested
+ ) && (deps subsetOf tested) // the conditions we've tested when we are here in the match satisfy the prior test, and hence what it tested
} foreach {
case (priorTest, _) =>
// if so, note the dependency in both tests
diff --git a/src/compiler/scala/tools/nsc/typechecker/SyntheticMethods.scala b/src/compiler/scala/tools/nsc/typechecker/SyntheticMethods.scala
index f01e095856..5465a3b47f 100644
--- a/src/compiler/scala/tools/nsc/typechecker/SyntheticMethods.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/SyntheticMethods.scala
@@ -196,14 +196,14 @@ trait SyntheticMethods extends ast.TreeDSL {
* (this.underlying == that.underlying
*/
def equalsDerivedValueClassMethod: Tree = createMethod(nme.equals_, List(AnyClass.tpe), BooleanClass.tpe) { m =>
- equalsCore(m, List(clazz.firstParamAccessor))
+ equalsCore(m, List(clazz.derivedValueClassUnbox))
}
/** The hashcode method for value classes
* def hashCode(): Int = this.underlying.hashCode
*/
def hashCodeDerivedValueClassMethod: Tree = createMethod(nme.hashCode_, Nil, IntClass.tpe) { m =>
- Select(mkThisSelect(clazz.firstParamAccessor), nme.hashCode_)
+ Select(mkThisSelect(clazz.derivedValueClassUnbox), nme.hashCode_)
}
/** The _1, _2, etc. methods to implement ProductN.
diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
index 6aa93f9cec..5241974793 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
@@ -47,7 +47,6 @@ trait Typers extends Modes with Adaptations with Tags {
def resetTyper() {
//println("resetTyper called")
resetContexts()
- resetNamer()
resetImplicits()
transformed.clear()
}
@@ -1380,7 +1379,7 @@ trait Typers extends Modes with Adaptations with Tags {
for (stat <- body)
if (!treeInfo.isAllowedInUniversalTrait(stat) && !isUnderlyingAcc(stat.symbol))
unit.error(stat.pos,
- if (stat.symbol hasFlag PARAMACCESSOR) "illegal parameter for value class"
+ if (stat.symbol != null && (stat.symbol hasFlag PARAMACCESSOR)) "illegal parameter for value class"
else "this statement is not allowed in value class: " + stat)
case x =>
unit.error(clazz.pos, "value class needs to have exactly one public val parameter")
@@ -5114,7 +5113,7 @@ trait Typers extends Modes with Adaptations with Tags {
case SelectFromTypeTree(qual, selector) =>
val qual1 = typedType(qual, mode)
- if (qual1.tpe.isVolatile) TypeSelectionFromVolatileTypeError(tree, qual)
+ if (qual1.tpe.isVolatile) TypeSelectionFromVolatileTypeError(tree, qual1)
else typedSelect(qual1, selector)
case CompoundTypeTree(templ) =>
diff --git a/src/compiler/scala/tools/nsc/typechecker/Unapplies.scala b/src/compiler/scala/tools/nsc/typechecker/Unapplies.scala
index 1b89f3db44..ad936ac39d 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Unapplies.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Unapplies.scala
@@ -23,6 +23,14 @@ trait Unapplies extends ast.TreeDSL
private val unapplyParamName = nme.x_0
+
+ // In the typeCompleter (templateSig) of a case class (resp it's module),
+ // synthetic `copy` (reps `apply`, `unapply`) methods are added. To compute
+ // their signatures, the corresponding ClassDef is needed. During naming (in
+ // `enterClassDef`), the case class ClassDef is added as an attachment to the
+ // moduleClass symbol of the companion module.
+ class ClassForCaseCompanionAttachment(val caseClass: ClassDef)
+
/** returns type list for return type of the extraction */
def unapplyTypeList(ufn: Symbol, ufntpe: Type) = {
assert(ufn.isMethod, ufn)
diff --git a/src/compiler/scala/tools/reflect/FastTrack.scala b/src/compiler/scala/tools/reflect/FastTrack.scala
index 59160f87d0..8ea66979bc 100644
--- a/src/compiler/scala/tools/reflect/FastTrack.scala
+++ b/src/compiler/scala/tools/reflect/FastTrack.scala
@@ -15,8 +15,9 @@ trait FastTrack {
import definitions._
import language.implicitConversions
- private implicit def context2taggers(c0: MacroContext) : Taggers { val c: c0.type } = new { val c: c0.type = c0 } with Taggers
- private implicit def context2contextreifiers(c0: MacroContext) : ContextReifiers { val c: c0.type } = new { val c: c0.type = c0 } with ContextReifiers
+ private implicit def context2taggers(c0: MacroContext): Taggers { val c: c0.type } = new { val c: c0.type = c0 } with Taggers
+ private implicit def context2contextreifiers(c0: MacroContext): ContextReifiers { val c: c0.type } = new { val c: c0.type = c0 } with ContextReifiers
+ private implicit def context2macroimplementations(c0: MacroContext): MacroImplementations { val c: c0.type } = new { val c: c0.type = c0 } with MacroImplementations
implicit def fastTrackEntry2MacroRuntime(entry: FastTrackEntry): MacroRuntime = args => entry.run(args)
type FastTrackExpander = PartialFunction[(MacroContext, Tree), Tree]
@@ -42,6 +43,7 @@ trait FastTrack {
ApiUniverseReify bindTo { case (c, Apply(TypeApply(_, List(tt)), List(expr))) => c.materializeExpr(c.prefix.tree, EmptyTree, expr) }
MacroContextReify bindTo { case (c, Apply(TypeApply(_, List(tt)), List(expr))) => c.materializeExprForMacroContext(c.prefix.tree, expr) }
ReflectRuntimeCurrentMirror bindTo { case (c, _) => scala.reflect.runtime.Macros.currentMirror(c).tree }
+ StringContext_f bindTo { case (c, Apply(Select(Apply(_, parts), _), args)) => c.macro_StringInterpolation_f(parts, args) }
registry
}
} \ No newline at end of file
diff --git a/src/compiler/scala/tools/reflect/MacroImplementations.scala b/src/compiler/scala/tools/reflect/MacroImplementations.scala
new file mode 100644
index 0000000000..a5f7928f55
--- /dev/null
+++ b/src/compiler/scala/tools/reflect/MacroImplementations.scala
@@ -0,0 +1,147 @@
+package scala.tools.reflect
+
+import scala.reflect.makro.{ReificationError, UnexpectedReificationError}
+import scala.reflect.makro.runtime.Context
+import scala.collection.mutable.ListBuffer
+import scala.collection.mutable.Stack
+
+abstract class MacroImplementations {
+ val c: Context
+
+ import c.universe._
+
+ def macro_StringInterpolation_f(parts: List[Tree], args: List[Tree]): Tree = {
+ // the parts all have the same position information (as the expression is generated by the compiler)
+ // the args have correct position information
+
+ // the following conditions can only be violated if invoked directly
+ if (parts.length != args.length + 1) {
+ if(parts.length == 0)
+ c.abort(c.prefix.tree.pos, "too few parts")
+ else if(args.length + 1 < parts.length)
+ c.abort(if(args.length==0) c.enclosingPosition else args.last.pos,
+ "too few arguments for interpolated string")
+ else
+ c.abort(args(parts.length-1).pos,
+ "too many arguments for interpolated string")
+ }
+
+ val stringParts = parts map {
+ case Literal(Constant(s: String)) => s;
+ case _ => throw new IllegalArgumentException("argument parts must be a list of string literals")
+ }
+
+ val pi = stringParts.iterator
+ val bldr = new java.lang.StringBuilder
+ val evals = ListBuffer[ValDef]()
+ val ids = ListBuffer[Ident]()
+ val argsStack = Stack(args : _*)
+
+ def defval(value: Tree, tpe: Type): Unit = {
+ val freshName = newTermName(c.fresh("arg$"))
+ evals += ValDef(Modifiers(), freshName, TypeTree(tpe), value)
+ ids += Ident(freshName)
+ }
+
+ def isFlag(ch: Char): Boolean = {
+ ch match {
+ case '-' | '#' | '+' | ' ' | '0' | ',' | '(' => true
+ case _ => false
+ }
+ }
+
+ def checkType(arg: Tree, variants: Type*): Option[Type] = {
+ variants.find(arg.tpe <:< _).orElse(
+ variants.find(c.inferImplicitView(arg, arg.tpe, _) != EmptyTree).orElse(
+ Some(variants(0))
+ )
+ )
+ }
+
+ def conversionType(ch: Char, arg: Tree): Option[Type] = {
+ ch match {
+ case 'b' | 'B' =>
+ if(arg.tpe <:< NullTpe) Some(NullTpe) else Some(BooleanTpe)
+ case 'h' | 'H' =>
+ Some(AnyTpe)
+ case 's' | 'S' =>
+ Some(AnyTpe)
+ case 'c' | 'C' =>
+ checkType(arg, CharTpe, ByteTpe, ShortTpe, IntTpe)
+ case 'd' | 'o' | 'x' | 'X' =>
+ checkType(arg, IntTpe, LongTpe, ByteTpe, ShortTpe, typeOf[BigInt])
+ case 'e' | 'E' | 'g' | 'G' | 'f' | 'a' | 'A' =>
+ checkType(arg, DoubleTpe, FloatTpe, typeOf[BigDecimal])
+ case 't' | 'T' =>
+ checkType(arg, LongTpe, typeOf[java.util.Calendar], typeOf[java.util.Date])
+ case _ => None
+ }
+ }
+
+ def copyString(first: Boolean): Unit = {
+ val str = StringContext.treatEscapes(pi.next())
+ val strLen = str.length
+ val strIsEmpty = strLen == 0
+ var start = 0
+ var idx = 0
+
+ if (!first) {
+ val arg = argsStack.pop
+ if (strIsEmpty || (str charAt 0) != '%') {
+ bldr append "%s"
+ defval(arg, AnyTpe)
+ } else {
+ // PRE str is not empty and str(0) == '%'
+ // argument index parameter is not allowed, thus parse
+ // [flags][width][.precision]conversion
+ var pos = 1
+ while(pos < strLen && isFlag(str charAt pos)) pos += 1
+ while(pos < strLen && Character.isDigit(str charAt pos)) pos += 1
+ if(pos < strLen && str.charAt(pos) == '.') { pos += 1
+ while(pos < strLen && Character.isDigit(str charAt pos)) pos += 1
+ }
+ if(pos < strLen) {
+ conversionType(str charAt pos, arg) match {
+ case Some(tpe) => defval(arg, tpe)
+ case None => c.error(arg.pos, "illegal conversion character")
+ }
+ } else {
+ // TODO: place error message on conversion string
+ c.error(arg.pos, "wrong conversion string")
+ }
+ }
+ idx = 1
+ }
+ if (!strIsEmpty) {
+ val len = str.length
+ while (idx < len) {
+ if (str(idx) == '%') {
+ bldr append (str substring (start, idx)) append "%%"
+ start = idx + 1
+ }
+ idx += 1
+ }
+ bldr append (str substring (start, idx))
+ }
+ }
+
+ copyString(first = true)
+ while (pi.hasNext) {
+ copyString(first = false)
+ }
+
+ val fstring = bldr.toString
+// val expr = c.reify(fstring.format((ids.map(id => Expr(id).eval)) : _*))
+// https://issues.scala-lang.org/browse/SI-5824, therefore
+ val expr =
+ Apply(
+ Select(
+ Literal(Constant(fstring)),
+ newTermName("format")),
+ List(ids: _* )
+ );
+
+ Block(evals.toList, expr)
+ }
+
+} \ No newline at end of file
diff --git a/src/library/scala/Cloneable.scala b/src/library/scala/Cloneable.scala
new file mode 100644
index 0000000000..5ba76ddde5
--- /dev/null
+++ b/src/library/scala/Cloneable.scala
@@ -0,0 +1,14 @@
+/* __ *\
+** ________ ___ / / ___ Scala API **
+** / __/ __// _ | / / / _ | (c) 2002-2011, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
+** /____/\___/_/ |_/____/_/ | | **
+** |/ **
+\* */
+
+package scala
+
+/**
+ * Classes extending this trait are cloneable across platforms (Java, .NET).
+ */
+trait Cloneable extends java.lang.Cloneable
diff --git a/src/library/scala/StringContext.scala b/src/library/scala/StringContext.scala
index f400f18dab..f11dfb72ae 100644
--- a/src/library/scala/StringContext.scala
+++ b/src/library/scala/StringContext.scala
@@ -8,7 +8,7 @@
package scala
-import collection.mutable.ArrayBuffer
+import language.experimental.macros
/** A class to support string interpolation.
* This class supports string interpolation as outlined in Scala SIP-11.
@@ -42,7 +42,7 @@ case class StringContext(parts: String*) {
* @throws A `StringContext.InvalidEscapeException` if if a `parts` string contains a backslash (`\`) character
* that does not start a valid escape sequence.
*/
- def s(args: Any*) = {
+ def s(args: Any*): String = {
checkLengths(args: _*)
val pi = parts.iterator
val ai = args.iterator
@@ -82,38 +82,8 @@ case class StringContext(parts: String*) {
* string literally. This is achieved by replacing each such occurrence by the
* format specifier `%%`.
*/
- def f(args: Any*) = {
- checkLengths(args: _*)
- val pi = parts.iterator
- val bldr = new java.lang.StringBuilder
- def copyString(first: Boolean): Unit = {
- val str = treatEscapes(pi.next())
- val strIsEmpty = str.length == 0
- var start = 0
- var idx = 0
- if (!first) {
- if (strIsEmpty || (str charAt 0) != '%')
- bldr append "%s"
- idx = 1
- }
- if (!strIsEmpty) {
- val len = str.length
- while (idx < len) {
- if (str(idx) == '%') {
- bldr append (str substring (start, idx)) append "%%"
- start = idx + 1
- }
- idx += 1
- }
- bldr append (str substring (start, idx))
- }
- }
- copyString(first = true)
- while (pi.hasNext) {
- copyString(first = false)
- }
- bldr.toString format (args: _*)
- }
+ // The implementation is magically hardwired into `scala.tools.reflect.MacroImplementations.macro_StringInterpolation_f`
+ def f(args: Any*): String = macro ???
}
object StringContext {
diff --git a/src/library/scala/cloneable.scala b/src/library/scala/annotation/cloneable.scala
index 32a1ea640d..aa45e8325f 100644
--- a/src/library/scala/cloneable.scala
+++ b/src/library/scala/annotation/cloneable.scala
@@ -6,11 +6,10 @@
** |/ **
\* */
-
-
-package scala
+package scala.annotation
/**
* An annotation that designates the class to which it is applied as cloneable
*/
+@deprecated("instead of `@cloneable class C`, use `class C extends Cloneable`", "2.10.0")
class cloneable extends annotation.StaticAnnotation
diff --git a/src/library/scala/collection/convert/Wrappers.scala b/src/library/scala/collection/convert/Wrappers.scala
index 8c603dc91b..75707b69b0 100644
--- a/src/library/scala/collection/convert/Wrappers.scala
+++ b/src/library/scala/collection/convert/Wrappers.scala
@@ -467,4 +467,5 @@ private[collection] trait Wrappers {
}
}
-object Wrappers extends Wrappers
+@SerialVersionUID(0 - 5857859809262781311L)
+object Wrappers extends Wrappers with Serializable
diff --git a/src/library/scala/collection/immutable/HashMap.scala b/src/library/scala/collection/immutable/HashMap.scala
index 05529761d3..2cf9985523 100644
--- a/src/library/scala/collection/immutable/HashMap.scala
+++ b/src/library/scala/collection/immutable/HashMap.scala
@@ -15,8 +15,7 @@ import parallel.immutable.ParHashMap
/** This class implements immutable maps using a hash trie.
*
- * '''Note:''' the builder of a hash map returns specialized representations EmptyMap,Map1,..., Map4
- * for maps of size <= 4.
+ * '''Note:''' The builder of this hash map may return specialized representations for small maps.
*
* @tparam A the type of the keys contained in this hash map.
* @tparam B the type of the values associated with the keys.
diff --git a/src/library/scala/collection/immutable/HashSet.scala b/src/library/scala/collection/immutable/HashSet.scala
index b956a4d838..c60fdc3bf1 100644
--- a/src/library/scala/collection/immutable/HashSet.scala
+++ b/src/library/scala/collection/immutable/HashSet.scala
@@ -17,8 +17,7 @@ import collection.parallel.immutable.ParHashSet
/** This class implements immutable sets using a hash trie.
*
- * '''Note:''' the builder of a hash set returns specialized representations `EmptySet`,`Set1`,..., `Set4`
- * for sets of `size <= 4`.
+ * '''Note:''' The builder of this hash set may return specialized representations for small sets.
*
* @tparam A the type of the elements contained in this hash set.
*
diff --git a/src/library/scala/collection/mutable/ArrayStack.scala b/src/library/scala/collection/mutable/ArrayStack.scala
index 040a0e2aa7..8f834d265b 100644
--- a/src/library/scala/collection/mutable/ArrayStack.scala
+++ b/src/library/scala/collection/mutable/ArrayStack.scala
@@ -59,7 +59,7 @@ object ArrayStack extends SeqFactory[ArrayStack] {
* @define mayNotTerminateInf
* @define willNotTerminateInf
*/
-@cloneable @SerialVersionUID(8565219180626620510L)
+@SerialVersionUID(8565219180626620510L)
class ArrayStack[T] private(private var table : Array[AnyRef],
private var index : Int)
extends AbstractSeq[T]
diff --git a/src/library/scala/collection/mutable/Buffer.scala b/src/library/scala/collection/mutable/Buffer.scala
index dd225cfab9..fd5dc66292 100644
--- a/src/library/scala/collection/mutable/Buffer.scala
+++ b/src/library/scala/collection/mutable/Buffer.scala
@@ -28,10 +28,10 @@ import generic._
* @define Coll `Buffer`
* @define coll buffer
*/
-@cloneable
trait Buffer[A] extends Seq[A]
with GenericTraversableTemplate[A, Buffer]
- with BufferLike[A, Buffer[A]] {
+ with BufferLike[A, Buffer[A]]
+ with scala.Cloneable {
override def companion: GenericCompanion[Buffer] = Buffer
}
diff --git a/src/library/scala/collection/mutable/BufferLike.scala b/src/library/scala/collection/mutable/BufferLike.scala
index f82a596b32..3274fe6194 100644
--- a/src/library/scala/collection/mutable/BufferLike.scala
+++ b/src/library/scala/collection/mutable/BufferLike.scala
@@ -58,13 +58,13 @@ import annotation.{migration, bridge}
* mutates the collection in place, unlike similar but
* undeprecated methods throughout the collections hierarchy.
*/
-@cloneable
trait BufferLike[A, +This <: BufferLike[A, This] with Buffer[A]]
extends Growable[A]
with Shrinkable[A]
with Scriptable[A]
with Subtractable[A, This]
with SeqLike[A, This]
+ with scala.Cloneable
{ self : This =>
// Abstract methods from Seq:
diff --git a/src/library/scala/collection/mutable/Cloneable.scala b/src/library/scala/collection/mutable/Cloneable.scala
index e6fbce415a..6daac3094a 100644
--- a/src/library/scala/collection/mutable/Cloneable.scala
+++ b/src/library/scala/collection/mutable/Cloneable.scala
@@ -17,9 +17,6 @@ package mutable
*
* @tparam A Type of the elements contained in the collection, covariant and with reference types as upperbound.
*/
-@cloneable
-trait Cloneable[+A <: AnyRef] {
- // !!! why doesn't this extend java.lang.Cloneable?
- // because neither did @serializable, then we changed it to Serializable
+trait Cloneable[+A <: AnyRef] extends scala.Cloneable {
override def clone: A = super.clone().asInstanceOf[A]
}
diff --git a/src/library/scala/collection/mutable/PriorityQueue.scala b/src/library/scala/collection/mutable/PriorityQueue.scala
index af55a01ed6..e37cbdc712 100644
--- a/src/library/scala/collection/mutable/PriorityQueue.scala
+++ b/src/library/scala/collection/mutable/PriorityQueue.scala
@@ -31,7 +31,6 @@ import generic._
* @define mayNotTerminateInf
* @define willNotTerminateInf
*/
-@cloneable
class PriorityQueue[A](implicit val ord: Ordering[A])
extends AbstractIterable[A]
with Iterable[A]
@@ -40,6 +39,7 @@ class PriorityQueue[A](implicit val ord: Ordering[A])
with Growable[A]
with Builder[A, PriorityQueue[A]]
with Serializable
+ with scala.Cloneable
{
import ord._
diff --git a/src/library/scala/collection/mutable/Queue.scala b/src/library/scala/collection/mutable/Queue.scala
index 605d37aec6..2aa19d6cb0 100644
--- a/src/library/scala/collection/mutable/Queue.scala
+++ b/src/library/scala/collection/mutable/Queue.scala
@@ -30,7 +30,6 @@ import generic._
* @define mayNotTerminateInf
* @define willNotTerminateInf
*/
-@cloneable
class Queue[A]
extends MutableList[A]
with GenericTraversableTemplate[A, Queue]
diff --git a/src/library/scala/collection/mutable/Stack.scala b/src/library/scala/collection/mutable/Stack.scala
index 042eac517a..db9e48d1cf 100644
--- a/src/library/scala/collection/mutable/Stack.scala
+++ b/src/library/scala/collection/mutable/Stack.scala
@@ -53,7 +53,6 @@ object Stack extends SeqFactory[Stack] {
* @define mayNotTerminateInf
* @define willNotTerminateInf
*/
-@cloneable
class Stack[A] private (var elems: List[A])
extends AbstractSeq[A]
with Seq[A]
diff --git a/src/library/scala/collection/parallel/ParIterableLike.scala b/src/library/scala/collection/parallel/ParIterableLike.scala
index 82498f9b63..d4f1c2f39f 100644
--- a/src/library/scala/collection/parallel/ParIterableLike.scala
+++ b/src/library/scala/collection/parallel/ParIterableLike.scala
@@ -72,6 +72,10 @@ import language.implicitConversions
* very fast operation which simply creates wrappers around the receiver collection.
* This can be repeated recursively.
*
+ * Tasks are scheduled for execution through a
+ * [[scala.collection.parallel.TaskSupport]] object, which can be changed
+ * through the `tasksupport` setter of the collection.
+ *
* Method `newCombiner` produces a new combiner. Combiners are an extension of builders.
* They provide a method `combine` which combines two combiners and returns a combiner
* containing elements of both combiners.
@@ -165,6 +169,11 @@ self: ParIterableLike[T, Repr, Sequential] =>
_tasksupport = defaultTaskSupport
}
+ /** The task support object which is responsible for scheduling and
+ * load-balancing tasks to processors.
+ *
+ * @see [[scala.collection.parallel.TaskSupport]]
+ */
def tasksupport = {
val ts = _tasksupport
if (ts eq null) {
@@ -173,6 +182,24 @@ self: ParIterableLike[T, Repr, Sequential] =>
} else ts
}
+ /** Changes the task support object which is responsible for scheduling and
+ * load-balancing tasks to processors.
+ *
+ * A task support object can be changed in a parallel collection after it
+ * has been created, but only during a quiescent period, i.e. while there
+ * are no concurrent invocations to parallel collection methods.
+ *
+ * Here is a way to change the task support of a parallel collection:
+ *
+ * {{{
+ * import scala.collection.parallel._
+ * val pc = mutable.ParArray(1, 2, 3)
+ * pc.tasksupport = new ForkJoinTaskSupport(
+ * new scala.concurrent.forkjoin.ForkJoinPool(2))
+ * }}}
+ *
+ * @see [[scala.collection.parallel.TaskSupport]]
+ */
def tasksupport_=(ts: TaskSupport) = _tasksupport = ts
def seq: Sequential
diff --git a/src/library/scala/collection/parallel/TaskSupport.scala b/src/library/scala/collection/parallel/TaskSupport.scala
index 3d27f619bb..b2ff5c9e44 100644
--- a/src/library/scala/collection/parallel/TaskSupport.scala
+++ b/src/library/scala/collection/parallel/TaskSupport.scala
@@ -19,34 +19,71 @@ import scala.concurrent.ExecutionContext
/** A trait implementing the scheduling of
* a parallel collection operation.
+ *
+ * Parallel collections are modular in the way operations are scheduled. Each
+ * parallel collection is parametrized with a task support object which is
+ * responsible for scheduling and load-balancing tasks to processors.
*
- * Task support objects handle how a task is split and
- * distributed across processors. A task support object can be
- * changed in a parallel collection after it has been created,
- * but only during a quiescent period, i.e. while there are no
+ * A task support object can be changed in a parallel collection after it has
+ * been created, but only during a quiescent period, i.e. while there are no
* concurrent invocations to parallel collection methods.
+ *
+ * There are currently a few task support implementations available for
+ * parallel collections. The [[scala.collection.parallel.ForkJoinTaskSupport]]
+ * uses a fork-join pool
+ * internally and is used by default on JVM 1.6 or greater. The less efficient
+ * [[scala.collection.parallel.ThreadPoolTaskSupport]] is a fallback for JVM
+ * 1.5 and JVMs that do not support the fork join pools. The
+ * [[scala.collection.parallel.ExecutionContextTaskSupport]] uses the
+ * default execution context implementation found in scala.concurrent, and it
+ * reuses the thread pool used in scala.concurrent (this is either a fork join
+ * pool or a thread pool executor, depending on the JVM version). The
+ * execution context task support is set to each parallel collection by
+ * default, so parallel collections reuse the same fork-join pool as the
+ * future API.
+ *
+ * Here is a way to change the task support of a parallel collection:
+ *
+ * {{{
+ * import scala.collection.parallel._
+ * val pc = mutable.ParArray(1, 2, 3)
+ * pc.tasksupport = new ForkJoinTaskSupport(
+ * new scala.concurrent.forkjoin.ForkJoinPool(2))
+ * }}}
+ *
+ * @see [[http://docs.scala-lang.org/overviews/parallel-collections/configuration.html Configuring Parallel Collections]] section
+ * on the parallel collection's guide for more information.
*/
trait TaskSupport extends Tasks
-/** A task support that uses a fork join pool to schedule tasks */
+/** A task support that uses a fork join pool to schedule tasks.
+ *
+ * @see [[scala.collection.parallel.TaskSupport]] for more information.
+ */
class ForkJoinTaskSupport(val environment: ForkJoinPool = ForkJoinTasks.defaultForkJoinPool)
extends TaskSupport with AdaptiveWorkStealingForkJoinTasks
-
-/** A task support that uses a thread pool executor to schedule tasks */
+/** A task support that uses a thread pool executor to schedule tasks.
+ *
+ * @see [[scala.collection.parallel.TaskSupport]] for more information.
+ */
class ThreadPoolTaskSupport(val environment: ThreadPoolExecutor = ThreadPoolTasks.defaultThreadPool)
extends TaskSupport with AdaptiveWorkStealingThreadPoolTasks
/** A task support that uses an execution context to schedule tasks.
*
- * It can be used with the default execution context implementation in the `scala.concurrent` package.
- * It internally forwards the call to either a forkjoin based task support or a thread pool executor one,
- * depending on what the execution context uses.
+ * It can be used with the default execution context implementation in the
+ * `scala.concurrent` package. It internally forwards the call to either a
+ * forkjoin based task support or a thread pool executor one, depending on
+ * what the execution context uses.
*
- * By default, parallel collections are parametrized with this task support object, so parallel collections
- * share the same execution context backend as the rest of the `scala.concurrent` package.
+ * By default, parallel collections are parametrized with this task support
+ * object, so parallel collections share the same execution context backend
+ * as the rest of the `scala.concurrent` package.
+ *
+ * @see [[scala.collection.parallel.TaskSupport]] for more information.
*/
class ExecutionContextTaskSupport(val environment: ExecutionContext = scala.concurrent.ExecutionContext.global)
extends TaskSupport with ExecutionContextTasks
diff --git a/src/library/scala/package.scala b/src/library/scala/package.scala
index 5f90c32e22..a41cdedfa9 100644
--- a/src/library/scala/package.scala
+++ b/src/library/scala/package.scala
@@ -37,6 +37,9 @@ package object scala {
@deprecated("instead of `@serializable class C`, use `class C extends Serializable`", "2.9.0")
type serializable = annotation.serializable
+ @deprecated("instead of `@cloneable class C`, use `class C extends Cloneable`", "2.10.0")
+ type cloneable = annotation.cloneable
+
type TraversableOnce[+A] = scala.collection.TraversableOnce[A]
type Traversable[+A] = scala.collection.Traversable[A]
diff --git a/src/reflect/scala/reflect/internal/Definitions.scala b/src/reflect/scala/reflect/internal/Definitions.scala
index 0b592be454..cd243b9df0 100644
--- a/src/reflect/scala/reflect/internal/Definitions.scala
+++ b/src/reflect/scala/reflect/internal/Definitions.scala
@@ -368,6 +368,7 @@ trait Definitions extends api.StandardDefinitions {
lazy val SerializableClass = requiredClass[scala.Serializable]
lazy val JavaSerializableClass = requiredClass[java.io.Serializable] modifyInfo fixupAsAnyTrait
lazy val ComparableClass = requiredClass[java.lang.Comparable[_]] modifyInfo fixupAsAnyTrait
+ lazy val CloneableClass = requiredClass[scala.Cloneable]
lazy val JavaCloneableClass = requiredClass[java.lang.Cloneable]
lazy val JavaNumberClass = requiredClass[java.lang.Number]
lazy val RemoteInterfaceClass = requiredClass[java.rmi.Remote]
@@ -496,6 +497,9 @@ trait Definitions extends api.StandardDefinitions {
def MacroInternal_materializeAbsTypeTag = getMemberMethod(MacroInternalPackage, nme.materializeAbsTypeTag)
def MacroInternal_materializeTypeTag = getMemberMethod(MacroInternalPackage, nme.materializeTypeTag)
+ lazy val StringContextClass = requiredClass[scala.StringContext]
+ def StringContext_f = getMemberMethod(StringContextClass, nme.f)
+
lazy val ScalaSignatureAnnotation = requiredClass[scala.reflect.ScalaSignature]
lazy val ScalaLongSignatureAnnotation = requiredClass[scala.reflect.ScalaLongSignature]
@@ -900,7 +904,7 @@ trait Definitions extends api.StandardDefinitions {
lazy val BeanPropertyAttr = requiredClass[scala.beans.BeanProperty]
lazy val BooleanBeanPropertyAttr = requiredClass[scala.beans.BooleanBeanProperty]
- lazy val CloneableAttr = requiredClass[scala.cloneable]
+ lazy val CloneableAttr = requiredClass[scala.annotation.cloneable]
lazy val DeprecatedAttr = requiredClass[scala.deprecated]
lazy val DeprecatedNameAttr = requiredClass[scala.deprecatedName]
lazy val NativeAttr = requiredClass[scala.native]
diff --git a/src/reflect/scala/reflect/internal/Flags.scala b/src/reflect/scala/reflect/internal/Flags.scala
index 37e5a23819..55fa00dd4d 100644
--- a/src/reflect/scala/reflect/internal/Flags.scala
+++ b/src/reflect/scala/reflect/internal/Flags.scala
@@ -135,7 +135,7 @@ class Flags extends ModifierFlags {
final val CAPTURED = 1 << 16 // variable is accessed from nested function. Set by LambdaLift.
final val LABEL = 1 << 17 // method symbol is a label. Set by TailCall
final val INCONSTRUCTOR = 1 << 17 // class symbol is defined in this/superclass constructor.
- final val SYNTHETIC = 1 << 21 // symbol is compiler-generated
+ final val SYNTHETIC = 1 << 21 // symbol is compiler-generated (compare with HIDDEN)
final val STABLE = 1 << 22 // functions that are assumed to be stable
// (typically, access methods for valdefs)
// or classes that do not contain abstract types.
@@ -165,6 +165,8 @@ class Flags extends ModifierFlags {
// A Java method's type is ``cooked'' by transforming raw types to existentials
final val SYNCHRONIZED = 1L << 45 // symbol is a method which should be marked ACC_SYNCHRONIZED
+ final val HIDDEN = 1L << 46 // symbol should be ignored when typechecking; will be marked ACC_SYNTHETIC in bytecode
+
// ------- shift definitions -------------------------------------------------------
final val InitialFlags = 0x0001FFFFFFFFFFFFL // flags that are enabled from phase 1.
@@ -174,6 +176,11 @@ class Flags extends ModifierFlags {
final val AntiShift = 56L
// Flags which sketchily share the same slot
+ // 16: BYNAMEPARAM/M CAPTURED COVARIANT/M
+ // 17: CONTRAVARIANT/M INCONSTRUCTOR LABEL
+ // 25: DEFAULTPARAM/M TRAIT/M
+ // 35: EXISTENTIAL MIXEDIN
+ // 37: IMPLCLASS PRESUPER/M
val OverloadedFlagsMask = 0L | BYNAMEPARAM | CONTRAVARIANT | DEFAULTPARAM | EXISTENTIAL | IMPLCLASS
// ------- late flags (set by a transformer phase) ---------------------------------
@@ -211,7 +218,7 @@ class Flags extends ModifierFlags {
/** To be a little clearer to people who aren't habitual bit twiddlers.
*/
final val AllFlags = -1L
-
+
/** These flags can be set when class or module symbol is first created.
* They are the only flags to survive a call to resetFlags().
*/
@@ -279,6 +286,16 @@ class Flags extends ModifierFlags {
/** Module flags inherited by their module-class */
final val ModuleToClassFlags = AccessFlags | TopLevelCreationFlags | CASE | SYNTHETIC
+ /** These flags are not pickled */
+ final val FlagsNotPickled = IS_ERROR | OVERLOADED | LIFTED | TRANS_FLAG | LOCKED | TRIEDCOOKING
+
+ // A precaution against future additions to FlagsNotPickled turning out
+ // to be overloaded flags thus not-pickling more than intended.
+ assert((OverloadedFlagsMask & FlagsNotPickled) == 0, flagsToString(OverloadedFlagsMask & FlagsNotPickled))
+
+ /** These flags are pickled */
+ final val PickledFlags = InitialFlags & ~FlagsNotPickled
+
def getterFlags(fieldFlags: Long): Long = ACCESSOR + (
if ((fieldFlags & MUTABLE) != 0) fieldFlags & ~MUTABLE & ~PRESUPER
else fieldFlags & ~PRESUPER | STABLE
@@ -307,47 +324,45 @@ class Flags extends ModifierFlags {
private final val PKL_MASK = 0x00000FFF
- final val PickledFlags = 0xFFFFFFFFL
-
- private def rawPickledCorrespondence = Array(
- (IMPLICIT, IMPLICIT_PKL),
- (FINAL, FINAL_PKL),
+ /** Pickler correspondence, ordered roughly by frequency of occurrence */
+ private def rawPickledCorrespondence = Array[(Long, Long)](
+ (METHOD, METHOD_PKL),
(PRIVATE, PRIVATE_PKL),
+ (FINAL, FINAL_PKL),
(PROTECTED, PROTECTED_PKL),
- (SEALED, SEALED_PKL),
- (OVERRIDE, OVERRIDE_PKL),
(CASE, CASE_PKL),
- (ABSTRACT, ABSTRACT_PKL),
(DEFERRED, DEFERRED_PKL),
- (METHOD, METHOD_PKL),
(MODULE, MODULE_PKL),
- (INTERFACE, INTERFACE_PKL)
+ (OVERRIDE, OVERRIDE_PKL),
+ (INTERFACE, INTERFACE_PKL),
+ (IMPLICIT, IMPLICIT_PKL),
+ (SEALED, SEALED_PKL),
+ (ABSTRACT, ABSTRACT_PKL)
)
- private val rawFlags: Array[Int] = rawPickledCorrespondence map (_._1)
- private val pickledFlags: Array[Int] = rawPickledCorrespondence map (_._2)
-
- private def r2p(flags: Int): Int = {
- var result = 0
- var i = 0
- while (i < rawFlags.length) {
- if ((flags & rawFlags(i)) != 0)
- result |= pickledFlags(i)
-
- i += 1
- }
- result
- }
- private def p2r(flags: Int): Int = {
- var result = 0
- var i = 0
- while (i < rawFlags.length) {
- if ((flags & pickledFlags(i)) != 0)
- result |= rawFlags(i)
-
- i += 1
+
+ private val mappedRawFlags = rawPickledCorrespondence map (_._1)
+ private val mappedPickledFlags = rawPickledCorrespondence map (_._2)
+
+ private class MapFlags(from: Array[Long], to: Array[Long]) extends (Long => Long) {
+ val fromSet = (0L /: from) (_ | _)
+
+ def apply(flags: Long): Long = {
+ var result = flags & ~fromSet
+ var tobeMapped = flags & fromSet
+ var i = 0
+ while (tobeMapped != 0) {
+ if ((tobeMapped & from(i)) != 0) {
+ result |= to(i)
+ tobeMapped &= ~from(i)
+ }
+ i += 1
+ }
+ result
}
- result
}
+
+ val rawToPickledFlags: Long => Long = new MapFlags(mappedRawFlags, mappedPickledFlags)
+ val pickledToRawFlags: Long => Long = new MapFlags(mappedPickledFlags, mappedRawFlags)
// ------ displaying flags --------------------------------------------------------
@@ -462,18 +477,12 @@ class Flags extends ModifierFlags {
}
}
- def rawFlagsToPickled(flags: Long): Long =
- (flags & ~PKL_MASK) | r2p(flags.toInt & PKL_MASK)
-
- def pickledToRawFlags(pflags: Long): Long =
- (pflags & ~PKL_MASK) | p2r(pflags.toInt & PKL_MASK)
-
// List of the raw flags, in pickled order
final val MaxBitPosition = 62
final val pickledListOrder: List[Long] = {
val all = 0 to MaxBitPosition map (1L << _)
- val front = rawFlags map (_.toLong)
+ val front = mappedRawFlags map (_.toLong)
front.toList ++ (all filterNot (front contains _))
}
diff --git a/src/reflect/scala/reflect/internal/HasFlags.scala b/src/reflect/scala/reflect/internal/HasFlags.scala
index c7c0882209..7ead9d6a1b 100644
--- a/src/reflect/scala/reflect/internal/HasFlags.scala
+++ b/src/reflect/scala/reflect/internal/HasFlags.scala
@@ -92,6 +92,7 @@ trait HasFlags {
def isCaseAccessor = hasFlag(CASEACCESSOR)
def isDeferred = hasFlag(DEFERRED)
def isFinal = hasFlag(FINAL)
+ def isHidden = hasFlag(HIDDEN)
def isImplicit = hasFlag(IMPLICIT)
def isInterface = hasFlag(INTERFACE)
def isJavaDefined = hasFlag(JAVA)
diff --git a/src/reflect/scala/reflect/internal/StdAttachments.scala b/src/reflect/scala/reflect/internal/StdAttachments.scala
index 4ea9b27da9..60b3a6f436 100644
--- a/src/reflect/scala/reflect/internal/StdAttachments.scala
+++ b/src/reflect/scala/reflect/internal/StdAttachments.scala
@@ -4,9 +4,24 @@ package internal
trait StdAttachments {
self: SymbolTable =>
+ /**
+ * Common code between reflect-internal Symbol and Tree related to Attachments.
+ */
+ trait Attachable {
+ protected var rawatt: base.Attachments { type Pos = Position } = NoPosition
+ def attachments = rawatt
+ def addAttachment(attachment: Any): this.type = { rawatt = rawatt.add(attachment); this }
+ def removeAttachment[T: ClassTag]: this.type = { rawatt = rawatt.remove[T]; this }
+
+ // cannot be final due to SynchronizedSymbols
+ def pos: Position = rawatt.pos
+ def pos_=(pos: Position): Unit = rawatt = (rawatt withPos pos)
+ def setPos(newpos: Position): this.type = { pos = newpos; this }
+ }
+
case object BackquotedIdentifierAttachment
case class CompoundTypeTreeOriginalAttachment(parents: List[Tree], stats: List[Tree])
case class MacroExpansionAttachment(original: Tree)
-} \ No newline at end of file
+}
diff --git a/src/reflect/scala/reflect/internal/StdNames.scala b/src/reflect/scala/reflect/internal/StdNames.scala
index 72a99589d5..22b0908cab 100644
--- a/src/reflect/scala/reflect/internal/StdNames.scala
+++ b/src/reflect/scala/reflect/internal/StdNames.scala
@@ -662,6 +662,7 @@ trait StdNames {
val eval: NameType = "eval"
val ex: NameType = "ex"
val experimental: NameType = "experimental"
+ val f: NameType = "f"
val false_ : NameType = "false"
val filter: NameType = "filter"
val finalize_ : NameType = if (forMSIL) "Finalize" else "finalize"
diff --git a/src/reflect/scala/reflect/internal/Symbols.scala b/src/reflect/scala/reflect/internal/Symbols.scala
index 3cb9f6ff37..04fa01c6f3 100644
--- a/src/reflect/scala/reflect/internal/Symbols.scala
+++ b/src/reflect/scala/reflect/internal/Symbols.scala
@@ -10,6 +10,7 @@ import scala.collection.{ mutable, immutable }
import scala.collection.mutable.ListBuffer
import util.Statistics
import Flags._
+import base.Attachments
trait Symbols extends api.Symbols { self: SymbolTable =>
import definitions._
@@ -363,7 +364,8 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
abstract class Symbol protected[Symbols] (initOwner: Symbol, initPos: Position, initName: Name)
extends SymbolContextApiImpl
with HasFlags
- with Annotatable[Symbol] {
+ with Annotatable[Symbol]
+ with Attachable {
type AccessBoundaryType = Symbol
type AnnotationType = AnnotationInfo
@@ -385,7 +387,7 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
def rawowner = _rawowner
def rawflags = _rawflags
- private var rawpos = initPos
+ rawatt = initPos
val id = nextId() // identity displayed when -uniqid
//assert(id != 3390, initName)
@@ -398,8 +400,6 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
def validTo = _validTo
def validTo_=(x: Period) { _validTo = x}
- def pos = rawpos
- def setPos(pos: Position): this.type = { this.rawpos = pos; this }
def setName(name: Name): this.type = { this.name = asNameType(name) ; this }
// Update the surrounding scopes
@@ -957,13 +957,13 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
/** Is this symbol an accessor method for outer? */
final def isOuterAccessor = {
- hasFlag(STABLE | SYNTHETIC) &&
+ hasFlag(STABLE | HIDDEN) &&
originalName == nme.OUTER
}
/** Is this symbol an accessor method for outer? */
final def isOuterField = {
- hasFlag(SYNTHETIC) &&
+ hasFlag(HIDDEN) &&
originalName == nme.OUTER_LOCAL
}
@@ -1821,6 +1821,7 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
setInfo (this.info cloneInfo clone)
setAnnotations this.annotations
)
+ this.attachments.all.foreach(clone.addAttachment)
if (clone.thisSym != clone)
clone.typeOfThis = (clone.typeOfThis cloneInfo clone)
@@ -2238,10 +2239,10 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
base.info.decl(sname) filter (_.hasAccessorFlag)
}
- /** Return the accessor method of the first parameter of this class.
+ /** If this is a derived value class, return its unbox method
* or NoSymbol if it does not exist.
*/
- def firstParamAccessor: Symbol = NoSymbol
+ def derivedValueClassUnbox: Symbol = NoSymbol
/** The case module corresponding to this case class
* @pre case class is a member of some other class or package
@@ -3145,8 +3146,10 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
clone
}
- override def firstParamAccessor =
- info.decls.find(_ hasAllFlags PARAMACCESSOR | METHOD) getOrElse NoSymbol
+ override def derivedValueClassUnbox =
+ (info.decl(nme.unbox)) orElse
+ (info.decls.find(_ hasAllFlags PARAMACCESSOR | METHOD) getOrElse
+ NoSymbol)
private[this] var childSet: Set[Symbol] = Set()
override def children = childSet
diff --git a/src/reflect/scala/reflect/internal/Trees.scala b/src/reflect/scala/reflect/internal/Trees.scala
index dd13dd4c4c..e92d644f4a 100644
--- a/src/reflect/scala/reflect/internal/Trees.scala
+++ b/src/reflect/scala/reflect/internal/Trees.scala
@@ -15,20 +15,13 @@ trait Trees extends api.Trees { self: SymbolTable =>
private[scala] var nodeCount = 0
- abstract class Tree extends TreeContextApiImpl with Product {
+ abstract class Tree extends TreeContextApiImpl with Attachable with Product {
val id = nodeCount // TODO: add to attachment?
nodeCount += 1
Statistics.incCounter(TreesStats.nodeByType, getClass)
- @inline final def pos: Position = rawatt.pos
- def pos_=(pos: Position): Unit = rawatt = (rawatt withPos pos)
- def setPos(newpos: Position): this.type = { pos = newpos; this }
-
- private var rawatt: Attachments { type Pos = Position } = NoPosition
- def attachments = rawatt
- def addAttachment(attachment: Any): this.type = { rawatt = rawatt.add(attachment); this }
- def removeAttachment[T: ClassTag]: this.type = { rawatt = rawatt.remove[T]; this }
+ @inline final override def pos: Position = rawatt.pos
private[this] var rawtpe: Type = _
@inline final def tpe = rawtpe
diff --git a/src/reflect/scala/reflect/internal/Types.scala b/src/reflect/scala/reflect/internal/Types.scala
index 56cc265e48..f3dd1f03ad 100644
--- a/src/reflect/scala/reflect/internal/Types.scala
+++ b/src/reflect/scala/reflect/internal/Types.scala
@@ -66,7 +66,7 @@ import util.Statistics
// inst is the instantiation and constr is a list of bounds.
case DeBruijnIndex(level, index)
// for dependent method types: a type referring to a method parameter.
- case ErasedValueType(tp)
+ case ErasedValueType(clazz, underlying)
// only used during erasure of derived value classes.
*/
@@ -693,20 +693,21 @@ trait Types extends api.Types { self: SymbolTable =>
* = Int
*/
def asSeenFrom(pre: Type, clazz: Symbol): Type = {
- if (isTrivial || phase.erasedTypes && pre.typeSymbol != ArrayClass) this
- else {
-// scala.tools.nsc.util.trace.when(pre.isInstanceOf[ExistentialType])("X "+this+".asSeenfrom("+pre+","+clazz+" = ") {
- Statistics.incCounter(asSeenFromCount)
- val start = Statistics.pushTimer(typeOpsStack, asSeenFromNanos)
- val m = new AsSeenFromMap(pre.normalize, clazz)
- val tp = m apply this
- val tp1 = existentialAbstraction(m.capturedParams, tp)
- val result: Type =
+ TypesStats.timedTypeOp(asSeenFromNanos) {
+ val trivial = (
+ this.isTrivial
+ || phase.erasedTypes && pre.typeSymbol != ArrayClass
+ || pre.normalize.isTrivial && !isPossiblePrefix(clazz)
+ )
+ if (trivial) this
+ else {
+ val m = new AsSeenFromMap(pre.normalize, clazz)
+ val tp = m(this)
+ val tp1 = existentialAbstraction(m.capturedParams, tp)
+
if (m.capturedSkolems.isEmpty) tp1
else deriveType(m.capturedSkolems, _.cloneSymbol setFlag CAPTURED)(tp1)
-
- Statistics.popTimer(typeOpsStack, start)
- result
+ }
}
}
@@ -1289,7 +1290,7 @@ trait Types extends api.Types { self: SymbolTable =>
/** A class for this-types of the form <sym>.this.type
*/
abstract case class ThisType(sym: Symbol) extends SingletonType with ThisTypeApi {
- assert(sym.isClass)
+ assert(sym.isClass, sym)
//assert(sym.isClass && !sym.isModuleClass || sym.isRoot, sym)
override def isTrivial: Boolean = sym.isPackageClass
override def isNotNull = true
@@ -2207,6 +2208,8 @@ trait Types extends api.Types { self: SymbolTable =>
* @M: a higher-kinded type is represented as a TypeRef with sym.typeParams.nonEmpty, but args.isEmpty
*/
abstract case class TypeRef(pre: Type, sym: Symbol, args: List[Type]) extends Type with TypeRefApi {
+ override val isTrivial: Boolean = !sym.isTypeParameter && pre.isTrivial && args.forall(_.isTrivial)
+
private[reflect] var parentsCache: List[Type] = _
private[reflect] var parentsPeriod = NoPeriod
private[reflect] var baseTypeSeqCache: BaseTypeSeq = _
@@ -2269,9 +2272,6 @@ trait Types extends api.Types { self: SymbolTable =>
override def typeSymbol = sym
override def typeSymbolDirect = sym
- override lazy val isTrivial: Boolean =
- !sym.isTypeParameter && pre.isTrivial && args.forall(_.isTrivial)
-
override def isNotNull =
sym.isModuleClass || sym == NothingClass || (sym isNonBottomSubClass NotNullClass) || super.isNotNull
@@ -2435,11 +2435,15 @@ trait Types extends api.Types { self: SymbolTable =>
*/
case class MethodType(override val params: List[Symbol],
override val resultType: Type) extends Type with MethodTypeApi {
- override def isTrivial: Boolean = isTrivial0 && (resultType eq resultType.withoutAnnotations)
- private lazy val isTrivial0 =
- resultType.isTrivial && params.forall{p => p.tpe.isTrivial && (
- !(params.exists(_.tpe.contains(p)) || resultType.contains(p)))
- }
+
+ override lazy val isTrivial: Boolean =
+ isTrivialResult && (params forall isTrivialParam)
+
+ private def isTrivialResult =
+ resultType.isTrivial && (resultType eq resultType.withoutAnnotations)
+
+ private def isTrivialParam(p: Symbol) =
+ p.tpe.isTrivial && !(params.exists(_.tpe contains p) || (resultType contains p))
def isImplicit = params.nonEmpty && params.head.isImplicit
def isJava = false // can we do something like for implicits? I.e. do Java methods without parameters need to be recognized?
@@ -3211,8 +3215,7 @@ trait Types extends api.Types { self: SymbolTable =>
override protected def rewrap(tp: Type) = copy(underlying = tp)
- override def isTrivial: Boolean = isTrivial0
- private lazy val isTrivial0 = underlying.isTrivial && annotations.forall(_.isTrivial)
+ override def isTrivial: Boolean = underlying.isTrivial && annotations.forall(_.isTrivial)
override def safeToString = annotations.mkString(underlying + " @", " @", "")
@@ -3305,16 +3308,21 @@ trait Types extends api.Types { self: SymbolTable =>
}
}
- abstract case class ErasedValueType(sym: Symbol) extends Type {
- override def safeToString = sym.name+"$unboxed"
+ /** A temporary type representing the reasure of a user-defined value type.
+ * Created during phase reasure, elimintaed again in posterasure.
+ * @param sym The value class symbol
+ * @param underlying The underlying type before erasure
+ */
+ abstract case class ErasedValueType(original: TypeRef) extends Type {
+ override def safeToString = "ErasedValueType("+original+")"
}
- final class UniqueErasedValueType(sym: Symbol) extends ErasedValueType(sym) with UniqueType
+ final class UniqueErasedValueType(original: TypeRef) extends ErasedValueType(original) with UniqueType
object ErasedValueType {
- def apply(sym: Symbol): Type = {
- assert(sym ne NoSymbol, "ErasedValueType cannot be NoSymbol")
- unique(new UniqueErasedValueType(sym))
+ def apply(original: TypeRef): Type = {
+ assert(original.sym ne NoSymbol, "ErasedValueType over NoSymbol")
+ unique(new UniqueErasedValueType(original))
}
}
@@ -4250,55 +4258,58 @@ trait Types extends api.Types { self: SymbolTable =>
def singletonBounds(hi: Type) = TypeBounds.upper(intersectionType(List(hi, SingletonClass.tpe)))
+ /** Might the given symbol be important when calculating the prefix
+ * of a type? When tp.asSeenFrom(pre, clazz) is called on `tp`,
+ * the result will be `tp` unchanged if `pre` is trivial and `clazz`
+ * is a symbol such that isPossiblePrefix(clazz) == false.
+ */
+ def isPossiblePrefix(clazz: Symbol) = clazz.isClass && !clazz.isPackageClass
+
/** A map to compute the asSeenFrom method */
class AsSeenFromMap(pre: Type, clazz: Symbol) extends TypeMap with KeepOnlyTypeConstraints {
var capturedSkolems: List[Symbol] = List()
var capturedParams: List[Symbol] = List()
- var capturedPre = emptySymMap
+ @inline private def skipPrefixOf(pre: Type, clazz: Symbol) = (
+ (pre eq NoType) || (pre eq NoPrefix) || !isPossiblePrefix(clazz)
+ )
override def mapOver(tree: Tree, giveup: ()=>Nothing): Tree = {
object annotationArgRewriter extends TypeMapTransformer {
+ private def canRewriteThis(sym: Symbol) = (
+ (sym isNonBottomSubClass clazz)
+ && (pre.widen.typeSymbol isNonBottomSubClass sym)
+ && (pre.isStable || giveup())
+ )
+ // what symbol should really be used?
+ private def newTermSym() = {
+ val p = pre.typeSymbol
+ p.owner.newValue(p.name.toTermName, p.pos) setInfo pre
+ }
/** Rewrite `This` trees in annotation argument trees */
- def rewriteThis(tree: Tree): Tree =
- tree match {
- case This(_)
- if (tree.symbol isNonBottomSubClass clazz) &&
- (pre.widen.typeSymbol isNonBottomSubClass tree.symbol) =>
- if (pre.isStable) { // XXX why is this in this method? pull it out and guard the call `annotationArgRewriter.transform(tree)`?
- val termSym = (
- pre.typeSymbol.owner.newValue(pre.typeSymbol.name.toTermName, pre.typeSymbol.pos) // what symbol should really be used?
- setInfo pre
- )
- gen.mkAttributedQualifier(pre, termSym)
- } else
- giveup()
-
- case tree => tree
- }
-
- override def transform(tree: Tree): Tree = {
- val tree1 = rewriteThis(super.transform(tree))
- tree1
+ override def transform(tree: Tree): Tree = super.transform(tree) match {
+ case This(_) if canRewriteThis(tree.symbol) => gen.mkAttributedQualifier(pre, newTermSym())
+ case tree => tree
}
}
-
annotationArgRewriter.transform(tree)
}
- def stabilize(pre: Type, clazz: Symbol): Type =
- capturedPre.getOrElse(clazz, {
- val qvar = clazz freshExistential ".type" setInfo singletonBounds(pre)
- capturedPre += (clazz -> qvar)
- capturedParams = qvar :: capturedParams
- qvar
- }).tpe
+ def stabilize(pre: Type, clazz: Symbol): Type = {
+ capturedParams find (_.owner == clazz) match {
+ case Some(qvar) => qvar.tpe
+ case _ =>
+ val qvar = clazz freshExistential nme.SINGLETON_SUFFIX setInfo singletonBounds(pre)
+ capturedParams ::= qvar
+ qvar.tpe
+ }
+ }
def apply(tp: Type): Type =
- if ((pre eq NoType) || (pre eq NoPrefix) || !clazz.isClass) tp
+ if (skipPrefixOf(pre, clazz)) tp
else tp match {
case ThisType(sym) =>
def toPrefix(pre: Type, clazz: Symbol): Type =
- if ((pre eq NoType) || (pre eq NoPrefix) || !clazz.isClass) tp
+ if (skipPrefixOf(pre, clazz)) tp
else if ((sym isNonBottomSubClass clazz) &&
(pre.widen.typeSymbol isNonBottomSubClass sym)) {
val pre1 = pre match {
@@ -4334,7 +4345,7 @@ trait Types extends api.Types { self: SymbolTable =>
// (skolems also aren't affected: they are ruled out by the isTypeParameter check)
case TypeRef(prefix, sym, args) if (sym.isTypeParameter && sym.owner.isClass) =>
def toInstance(pre: Type, clazz: Symbol): Type =
- if ((pre eq NoType) || (pre eq NoPrefix) || !clazz.isClass) mapOver(tp)
+ if (skipPrefixOf(pre, clazz)) mapOver(tp)
//@M! see test pos/tcpoly_return_overriding.scala why mapOver is necessary
else {
def throwError = abort("" + tp + sym.locationString + " cannot be instantiated from " + pre.widen)
@@ -4604,7 +4615,7 @@ trait Types extends api.Types { self: SymbolTable =>
if (existentials(pid) eq null) {
val param = params(pid)
existentials(pid) = (
- param.owner.newExistential(newTypeName(param.name + ".type"), param.pos, param.flags)
+ param.owner.newExistential(param.name.toTypeName append nme.SINGLETON_SUFFIX, param.pos, param.flags)
setInfo singletonBounds(actuals(pid))
)
}
@@ -6910,4 +6921,10 @@ object TypesStats {
val typerefBaseTypeSeqCount = Statistics.newSubCounter(" of which for typerefs", baseTypeSeqCount)
val singletonBaseTypeSeqCount = Statistics.newSubCounter(" of which for singletons", baseTypeSeqCount)
val typeOpsStack = Statistics.newTimerStack()
+
+ @inline final def timedTypeOp[T](c: Statistics.StackableTimer)(op: => T): T = {
+ val start = Statistics.pushTimer(typeOpsStack, c)
+ try op
+ finally Statistics.popTimer(typeOpsStack, start)
+ }
}
diff --git a/src/reflect/scala/reflect/internal/pickling/UnPickler.scala b/src/reflect/scala/reflect/internal/pickling/UnPickler.scala
index 4d8e932862..4411b79b97 100644
--- a/src/reflect/scala/reflect/internal/pickling/UnPickler.scala
+++ b/src/reflect/scala/reflect/internal/pickling/UnPickler.scala
@@ -373,12 +373,7 @@ abstract class UnPickler /*extends reflect.generic.UnPickler*/ {
NullaryMethodType(restpe)
case EXISTENTIALtpe =>
val restpe = readTypeRef()
- // @PP: Where is the flag setting supposed to happen? I infer
- // from the lack of flag setting in the rest of the unpickler
- // that it isn't right here. See #4757 for the immediate
- // motivation to fix it.
- val tparams = until(end, readSymbolRef) map (_ setFlag EXISTENTIAL)
- newExistentialType(tparams, restpe)
+ newExistentialType(until(end, readSymbolRef), restpe)
case ANNOTATEDtpe =>
var typeRef = readNat()
diff --git a/src/reflect/scala/reflect/internal/transform/Erasure.scala b/src/reflect/scala/reflect/internal/transform/Erasure.scala
index 5beec70d62..368d55a59c 100644
--- a/src/reflect/scala/reflect/internal/transform/Erasure.scala
+++ b/src/reflect/scala/reflect/internal/transform/Erasure.scala
@@ -2,7 +2,7 @@ package scala.reflect
package internal
package transform
-import Flags.PARAMACCESSOR
+import Flags.{PARAMACCESSOR, METHOD}
trait Erasure {
@@ -72,8 +72,37 @@ trait Erasure {
if (cls.owner.isClass) cls.owner.tpe else pre // why not cls.isNestedClass?
}
+ def unboxDerivedValueClassMethod(clazz: Symbol): Symbol =
+ (clazz.info.decl(nme.unbox)) orElse
+ (clazz.info.decls.find(_ hasAllFlags PARAMACCESSOR | METHOD) getOrElse
+ NoSymbol)
+
def underlyingOfValueClass(clazz: Symbol): Type =
- clazz.firstParamAccessor.tpe.resultType
+ clazz.derivedValueClassUnbox.tpe.resultType
+
+ /** The type of the argument of a value class reference after erasure
+ * This method needs to be called at a phase no later than erasurephase
+ */
+ def erasedValueClassArg(tref: TypeRef): Type = {
+ assert(!phase.erasedTypes)
+ val clazz = tref.sym
+ if (valueClassIsParametric(clazz)) {
+ val underlying = tref.memberType(clazz.derivedValueClassUnbox).resultType
+ boxingErasure(underlying)
+ } else {
+ scalaErasure(underlyingOfValueClass(clazz))
+ }
+ }
+
+ /** Does this vakue class have an underlying type that's a type parameter of
+ * the class itself?
+ * This method needs to be called at a phase no later than erasurephase
+ */
+ def valueClassIsParametric(clazz: Symbol): Boolean = {
+ assert(!phase.erasedTypes)
+ clazz.typeParams contains
+ clazz.derivedValueClassUnbox.tpe.resultType.normalize.typeSymbol
+ }
abstract class ErasureMap extends TypeMap {
private lazy val ObjectArray = arrayType(ObjectClass.tpe)
@@ -84,15 +113,14 @@ trait Erasure {
def eraseNormalClassRef(pre: Type, clazz: Symbol): Type =
typeRef(apply(rebindInnerClass(pre, clazz)), clazz, List()) // #2585
- protected def eraseDerivedValueClassRef(clazz: Symbol): Type =
- scalaErasure(underlyingOfValueClass(clazz))
+ protected def eraseDerivedValueClassRef(tref: TypeRef): Type = erasedValueClassArg(tref)
def apply(tp: Type): Type = tp match {
case ConstantType(_) =>
tp
case st: SubType =>
apply(st.supertype)
- case TypeRef(pre, sym, args) =>
+ case tref @ TypeRef(pre, sym, args) =>
if (sym == ArrayClass)
if (unboundedGenericArrayLevel(tp) == 1) ObjectClass.tpe
else if (args.head.typeSymbol.isBottomClass) ObjectArray
@@ -100,7 +128,7 @@ trait Erasure {
else if (sym == AnyClass || sym == AnyValClass || sym == SingletonClass || sym == NotNullClass) ErasedObject
else if (sym == UnitClass) erasedTypeRef(BoxedUnitClass)
else if (sym.isRefinementClass) apply(mergeParents(tp.parents))
- else if (sym.isDerivedValueClass) eraseDerivedValueClassRef(sym)
+ else if (sym.isDerivedValueClass) eraseDerivedValueClassRef(tref)
else if (sym.isClass) eraseNormalClassRef(pre, sym)
else apply(sym.info) // alias type or abstract type
case PolyType(tparams, restpe) =>
@@ -236,7 +264,8 @@ trait Erasure {
* are then later converted to the underlying parameter type in phase posterasure.
*/
object specialScalaErasure extends ScalaErasureMap {
- override def eraseDerivedValueClassRef(clazz: Symbol): Type = ErasedValueType(clazz)
+ override def eraseDerivedValueClassRef(tref: TypeRef): Type =
+ ErasedValueType(tref)
}
object javaErasure extends JavaErasureMap
@@ -251,6 +280,14 @@ trait Erasure {
}
}
+ object boxingErasure extends ScalaErasureMap {
+ override def eraseNormalClassRef(pre: Type, clazz: Symbol) =
+ if (isPrimitiveValueClass(clazz)) boxedClass(clazz).tpe
+ else super.eraseNormalClassRef(pre, clazz)
+ override def eraseDerivedValueClassRef(tref: TypeRef) =
+ super.eraseNormalClassRef(tref.pre, tref.sym)
+ }
+
/** The intersection dominator (SLS 3.7) of a list of types is computed as follows.
*
* - If the list contains one or more occurrences of scala.Array with
diff --git a/src/reflect/scala/reflect/internal/util/Statistics.scala b/src/reflect/scala/reflect/internal/util/Statistics.scala
index 3a31c2858b..e503d812e6 100644
--- a/src/reflect/scala/reflect/internal/util/Statistics.scala
+++ b/src/reflect/scala/reflect/internal/util/Statistics.scala
@@ -169,7 +169,7 @@ quant)
nanos = nanos0 + System.nanoTime() - start
timings += 1
}
- protected def show(ns: Long) = s"${ns/1000}ms"
+ protected def show(ns: Long) = s"${ns/1000000}ms"
override def toString = s"$timings spans, ${show(nanos)}"
}
diff --git a/src/reflect/scala/reflect/makro/Universe.scala b/src/reflect/scala/reflect/makro/Universe.scala
index 98046be555..a676f7f1de 100644
--- a/src/reflect/scala/reflect/makro/Universe.scala
+++ b/src/reflect/scala/reflect/makro/Universe.scala
@@ -5,13 +5,24 @@ abstract class Universe extends scala.reflect.api.Universe {
val treeBuild: TreeBuilder { val global: Universe.this.type }
+ trait AttachableApi {
+ /** ... */
+ def attachments: base.Attachments { type Pos = Position }
+
+ /** ... */
+ def addAttachment(attachment: Any): AttachableApi.this.type
+
+ /** ... */
+ def removeAttachment[T: ClassTag]: AttachableApi.this.type
+ }
+
// Symbol extensions ---------------------------------------------------------------
override type Symbol >: Null <: SymbolContextApi
/** The extended API of symbols that's supported in macro context universes
*/
- trait SymbolContextApi extends SymbolApi { this: Symbol =>
+ trait SymbolContextApi extends SymbolApi with AttachableApi { this: Symbol =>
// [Eugene++ to Martin] should we also add mutability methods here (similarly to what's done below for trees)?
// I'm talking about `setAnnotations` and friends
@@ -23,7 +34,7 @@ abstract class Universe extends scala.reflect.api.Universe {
/** The extended API of trees that's supported in macro context universes
*/
- trait TreeContextApi extends TreeApi { this: Tree =>
+ trait TreeContextApi extends TreeApi with AttachableApi { this: Tree =>
/** ... */
def pos_=(pos: Position): Unit
@@ -62,15 +73,6 @@ abstract class Universe extends scala.reflect.api.Universe {
/** ... */
def setSymbol(sym: Symbol): this.type
-
- /** ... */
- def attachments: base.Attachments { type Pos = Position }
-
- /** ... */
- def addAttachment(attachment: Any): this.type
-
- /** ... */
- def removeAttachment[T: ClassTag]: this.type
}
override type SymTree >: Null <: Tree with SymTreeContextApi
diff --git a/test/files/buildmanager/t2651_3/t2651_3.check b/test/files/buildmanager/t2651_3/t2651_3.check
index d4bac196e9..2a60e3d806 100644
--- a/test/files/buildmanager/t2651_3/t2651_3.check
+++ b/test/files/buildmanager/t2651_3/t2651_3.check
@@ -3,4 +3,4 @@ compiling Set(A.scala)
Changes: Map()
builder > A.scala
compiling Set(A.scala)
-Changes: Map(trait A -> List(Changed(Definition(A.x))[method x changed from ()T to ()S flags: <deferred> <method>]))
+Changes: Map(trait A -> List(Changed(Definition(A.x))[method x changed from ()T to ()S flags: <method> <deferred>]))
diff --git a/test/files/buildmanager/t2651_4/t2651_4.check b/test/files/buildmanager/t2651_4/t2651_4.check
index b182f31c09..74e5d8f99b 100644
--- a/test/files/buildmanager/t2651_4/t2651_4.check
+++ b/test/files/buildmanager/t2651_4/t2651_4.check
@@ -3,8 +3,8 @@ compiling Set(A.scala, B.scala)
Changes: Map()
builder > A.scala
compiling Set(A.scala)
-Changes: Map(trait A -> List(Changed(Definition(A.x))[method x changed from ()T to ()T flags: <deferred> <method> <triedcooking>], Changed(Definition(A.y))[method y changed from (a: T)Unit to (a: T)Unit flags: <deferred> <method>], Changed(Definition(A.z))[method z changed from [B <: T]()Unit to [B <: T]()Unit flags: <deferred> <method>]))
-invalidate B.scala because inherited method changed [Changed(Definition(A.x))[method x changed from ()T to ()T flags: <deferred> <method> <triedcooking>]]
+Changes: Map(trait A -> List(Changed(Definition(A.x))[method x changed from ()T to ()T flags: <method> <deferred> <triedcooking>], Changed(Definition(A.y))[method y changed from (a: T)Unit to (a: T)Unit flags: <method> <deferred>], Changed(Definition(A.z))[method z changed from [B <: T]()Unit to [B <: T]()Unit flags: <method> <deferred>]))
+invalidate B.scala because inherited method changed [Changed(Definition(A.x))[method x changed from ()T to ()T flags: <method> <deferred> <triedcooking>]]
compiling Set(B.scala)
B.scala:2: error: type mismatch;
found : Int(3)
diff --git a/test/files/buildmanager/t2657/t2657.check b/test/files/buildmanager/t2657/t2657.check
index cd0357599c..0d6709e58b 100644
--- a/test/files/buildmanager/t2657/t2657.check
+++ b/test/files/buildmanager/t2657/t2657.check
@@ -4,8 +4,8 @@ warning: there were 1 feature warnings; re-run with -feature for details
Changes: Map()
builder > A.scala
compiling Set(A.scala)
-Changes: Map(class A -> List(Changed(Definition(A.y))[method y changed from (i: Int)String to (i: Int)String flags: implicit <method> <triedcooking>]))
-invalidate B.scala because inherited method changed [Changed(Definition(A.y))[method y changed from (i: Int)String to (i: Int)String flags: implicit <method> <triedcooking>]]
+Changes: Map(class A -> List(Changed(Definition(A.y))[method y changed from (i: Int)String to (i: Int)String flags: <method> implicit <triedcooking>]))
+invalidate B.scala because inherited method changed [Changed(Definition(A.y))[method y changed from (i: Int)String to (i: Int)String flags: <method> implicit <triedcooking>]]
compiling Set(B.scala)
B.scala:2: error: type mismatch;
found : Int(3)
diff --git a/test/files/buildmanager/t2789/t2789.check b/test/files/buildmanager/t2789/t2789.check
index a7c767cc45..066561ac44 100644
--- a/test/files/buildmanager/t2789/t2789.check
+++ b/test/files/buildmanager/t2789/t2789.check
@@ -3,8 +3,8 @@ compiling Set(A.scala, B.scala)
Changes: Map()
builder > A.scala
compiling Set(A.scala)
-Changes: Map(class A -> List(Changed(Definition(A.e))[method e changed from ()E to ()E flags: implicit <method> <triedcooking>]), class E -> List())
-invalidate B.scala because inherited method changed [Changed(Definition(A.e))[method e changed from ()E to ()E flags: implicit <method> <triedcooking>]]
+Changes: Map(class A -> List(Changed(Definition(A.e))[method e changed from ()E to ()E flags: <method> implicit <triedcooking>]), class E -> List())
+invalidate B.scala because inherited method changed [Changed(Definition(A.e))[method e changed from ()E to ()E flags: <method> implicit <triedcooking>]]
compiling Set(B.scala)
B.scala:2: error: could not find implicit value for parameter y: E
val y = x(3)
diff --git a/test/files/codelib/code.jar.desired.sha1 b/test/files/codelib/code.jar.desired.sha1
index d2b8d9add9..c4cc74c244 100644
--- a/test/files/codelib/code.jar.desired.sha1
+++ b/test/files/codelib/code.jar.desired.sha1
@@ -1 +1 @@
-e737b123d31eede5594ceda07caafed1673ec472 ?code.jar
+e737b123d31eede5594ceda07caafed1673ec472 *code.jar
diff --git a/test/files/lib/annotations.jar.desired.sha1 b/test/files/lib/annotations.jar.desired.sha1
index 2b4292d796..ff7bc9425e 100644
--- a/test/files/lib/annotations.jar.desired.sha1
+++ b/test/files/lib/annotations.jar.desired.sha1
@@ -1 +1 @@
-02fe2ed93766323a13f22c7a7e2ecdcd84259b6c ?annotations.jar
+02fe2ed93766323a13f22c7a7e2ecdcd84259b6c *annotations.jar
diff --git a/test/files/lib/enums.jar.desired.sha1 b/test/files/lib/enums.jar.desired.sha1
index 46cd8e92cf..040dff4487 100644
--- a/test/files/lib/enums.jar.desired.sha1
+++ b/test/files/lib/enums.jar.desired.sha1
@@ -1 +1 @@
-981392dbd1f727b152cd1c908c5fce60ad9d07f7 ?enums.jar
+981392dbd1f727b152cd1c908c5fce60ad9d07f7 *enums.jar
diff --git a/test/files/lib/genericNest.jar.desired.sha1 b/test/files/lib/genericNest.jar.desired.sha1
index e9321262f2..77e4fec408 100644
--- a/test/files/lib/genericNest.jar.desired.sha1
+++ b/test/files/lib/genericNest.jar.desired.sha1
@@ -1 +1 @@
-b1ec8a095cec4902b3609d74d274c04365c59c04 ?genericNest.jar
+b1ec8a095cec4902b3609d74d274c04365c59c04 *genericNest.jar
diff --git a/test/files/lib/methvsfield.jar.desired.sha1 b/test/files/lib/methvsfield.jar.desired.sha1
index 8c01532b88..6655f45ddb 100644
--- a/test/files/lib/methvsfield.jar.desired.sha1
+++ b/test/files/lib/methvsfield.jar.desired.sha1
@@ -1 +1 @@
-be8454d5e7751b063ade201c225dcedefd252775 ?methvsfield.jar
+be8454d5e7751b063ade201c225dcedefd252775 *methvsfield.jar
diff --git a/test/files/lib/nest.jar.desired.sha1 b/test/files/lib/nest.jar.desired.sha1
index 674ca79a5b..056e7ada90 100644
--- a/test/files/lib/nest.jar.desired.sha1
+++ b/test/files/lib/nest.jar.desired.sha1
@@ -1 +1 @@
-cd33e0a0ea249eb42363a2f8ba531186345ff68c ?nest.jar
+cd33e0a0ea249eb42363a2f8ba531186345ff68c *nest.jar
diff --git a/test/files/lib/scalacheck.jar.desired.sha1 b/test/files/lib/scalacheck.jar.desired.sha1
index e6ed543d73..2f15402d18 100644
--- a/test/files/lib/scalacheck.jar.desired.sha1
+++ b/test/files/lib/scalacheck.jar.desired.sha1
@@ -1 +1 @@
-b6f4dbb29f0c2ec1eba682414f60d52fea84f703 ?scalacheck.jar
+b6f4dbb29f0c2ec1eba682414f60d52fea84f703 *scalacheck.jar
diff --git a/test/files/neg/stringinterpolation_macro-neg.check b/test/files/neg/stringinterpolation_macro-neg.check
new file mode 100644
index 0000000000..8986b899a3
--- /dev/null
+++ b/test/files/neg/stringinterpolation_macro-neg.check
@@ -0,0 +1,70 @@
+stringinterpolation_macro-neg.scala:8: error: too few parts
+ new StringContext().f()
+ ^
+stringinterpolation_macro-neg.scala:9: error: too few arguments for interpolated string
+ new StringContext("", " is ", "%2d years old").f(s)
+ ^
+stringinterpolation_macro-neg.scala:10: error: too many arguments for interpolated string
+ new StringContext("", " is ", "%2d years old").f(s, d, d)
+ ^
+stringinterpolation_macro-neg.scala:11: error: too few arguments for interpolated string
+ new StringContext("", "").f()
+ ^
+stringinterpolation_macro-neg.scala:14: error: type mismatch;
+ found : String
+ required: Boolean
+ f"$s%b"
+ ^
+stringinterpolation_macro-neg.scala:15: error: type mismatch;
+ found : String
+ required: Char
+ f"$s%c"
+ ^
+stringinterpolation_macro-neg.scala:16: error: type mismatch;
+ found : Double
+ required: Char
+ f"$f%c"
+ ^
+stringinterpolation_macro-neg.scala:17: error: type mismatch;
+ found : String
+ required: Int
+ f"$s%x"
+ ^
+stringinterpolation_macro-neg.scala:18: error: type mismatch;
+ found : Boolean
+ required: Int
+ f"$b%d"
+ ^
+stringinterpolation_macro-neg.scala:19: error: type mismatch;
+ found : String
+ required: Int
+ f"$s%d"
+ ^
+stringinterpolation_macro-neg.scala:20: error: type mismatch;
+ found : Double
+ required: Int
+ f"$f%o"
+ ^
+stringinterpolation_macro-neg.scala:21: error: type mismatch;
+ found : String
+ required: Double
+ f"$s%e"
+ ^
+stringinterpolation_macro-neg.scala:22: error: type mismatch;
+ found : Boolean
+ required: Double
+ f"$b%f"
+ ^
+stringinterpolation_macro-neg.scala:27: error: type mismatch;
+ found : String
+ required: Int
+Note that implicit conversions are not applicable because they are ambiguous:
+ both value strToInt2 of type String => Int
+ and value strToInt1 of type String => Int
+ are possible conversion functions from String to Int
+ f"$s%d"
+ ^
+stringinterpolation_macro-neg.scala:30: error: illegal conversion character
+ f"$s%i"
+ ^
+15 errors found
diff --git a/test/files/neg/stringinterpolation_macro-neg.scala b/test/files/neg/stringinterpolation_macro-neg.scala
new file mode 100644
index 0000000000..ac9d97d678
--- /dev/null
+++ b/test/files/neg/stringinterpolation_macro-neg.scala
@@ -0,0 +1,31 @@
+object Test extends App {
+ val s = "Scala"
+ val d = 8
+ val b = false
+ val f = 3.14159
+
+ // 1) number of arguments
+ new StringContext().f()
+ new StringContext("", " is ", "%2d years old").f(s)
+ new StringContext("", " is ", "%2d years old").f(s, d, d)
+ new StringContext("", "").f()
+
+ // 2) Interpolation mismatches
+ f"$s%b"
+ f"$s%c"
+ f"$f%c"
+ f"$s%x"
+ f"$b%d"
+ f"$s%d"
+ f"$f%o"
+ f"$s%e"
+ f"$b%f"
+
+ {
+ implicit val strToInt1 = (s: String) => 1
+ implicit val strToInt2 = (s: String) => 2
+ f"$s%d"
+ }
+
+ f"$s%i"
+}
diff --git a/test/files/neg/t5504.check b/test/files/neg/t5504.check
deleted file mode 100644
index 2827c02d10..0000000000
--- a/test/files/neg/t5504.check
+++ /dev/null
@@ -1,4 +0,0 @@
-error: type _$1 is defined twice
- conflicting symbols both originated in file 't5504/s_1.scala'
- Note: this may be due to a bug in the compiler involving wildcards in package objects
-one error found
diff --git a/test/files/neg/t6042.check b/test/files/neg/t6042.check
new file mode 100644
index 0000000000..221f06e2c5
--- /dev/null
+++ b/test/files/neg/t6042.check
@@ -0,0 +1,4 @@
+t6042.scala:7: error: illegal type selection from volatile type a.OpSemExp (with upper bound LazyExp[a.OpSemExp] with _$1)
+ def foo[AA <: LazyExp[_]](a: AA): a.OpSemExp#Val = ??? // a.OpSemExp is volatile, because of `with This`
+ ^
+one error found
diff --git a/test/files/neg/t6042.scala b/test/files/neg/t6042.scala
new file mode 100644
index 0000000000..5a123d17ca
--- /dev/null
+++ b/test/files/neg/t6042.scala
@@ -0,0 +1,8 @@
+trait LazyExp[+This <: LazyExp[This]] { this: This =>
+ type OpSemExp <: LazyExp[OpSemExp] with This
+ type Val
+}
+
+object Test {
+ def foo[AA <: LazyExp[_]](a: AA): a.OpSemExp#Val = ??? // a.OpSemExp is volatile, because of `with This`
+}
diff --git a/test/files/neg/t5504/s_1.scala b/test/files/pos/t5504/s_1.scala
index 35cb2c8bae..35cb2c8bae 100644
--- a/test/files/neg/t5504/s_1.scala
+++ b/test/files/pos/t5504/s_1.scala
diff --git a/test/files/neg/t5504/s_2.scala b/test/files/pos/t5504/s_2.scala
index 03eecf6e19..03eecf6e19 100644
--- a/test/files/neg/t5504/s_2.scala
+++ b/test/files/pos/t5504/s_2.scala
diff --git a/test/files/pos/t5957/T_1.scala b/test/files/pos/t5957/T_1.scala
new file mode 100644
index 0000000000..1db5a3891f
--- /dev/null
+++ b/test/files/pos/t5957/T_1.scala
@@ -0,0 +1,6 @@
+abstract class T {
+ def t1: Test$Bar
+ def t2: Test#Bar
+ def t3: Test$Baz
+ def t4: Test.Baz
+}
diff --git a/test/files/pos/t5957/Test.java b/test/files/pos/t5957/Test.java
new file mode 100644
index 0000000000..4fbd257d95
--- /dev/null
+++ b/test/files/pos/t5957/Test.java
@@ -0,0 +1,11 @@
+public class Test {
+ public class Bar {
+ public Bar(int i) {
+ }
+ }
+
+ public static class Baz {
+ public Baz(int i) {
+ }
+ }
+}
diff --git a/test/files/pos/t6022.flags b/test/files/pos/t6022.flags
new file mode 100644
index 0000000000..e8fb65d50c
--- /dev/null
+++ b/test/files/pos/t6022.flags
@@ -0,0 +1 @@
+-Xfatal-warnings \ No newline at end of file
diff --git a/test/files/pos/t6022.scala b/test/files/pos/t6022.scala
new file mode 100644
index 0000000000..522c3352c7
--- /dev/null
+++ b/test/files/pos/t6022.scala
@@ -0,0 +1,7 @@
+class Test {
+ (null: Any) match {
+ case x: AnyRef if false =>
+ case list: Option[_] =>
+ case product: Product => // change Product to String and it's all good
+ }
+} \ No newline at end of file
diff --git a/test/files/presentation/hyperlinks.flags b/test/files/presentation/hyperlinks.flags
deleted file mode 100644
index dc13682c5e..0000000000
--- a/test/files/presentation/hyperlinks.flags
+++ /dev/null
@@ -1,2 +0,0 @@
-# This test will fail in the new pattern matcher because
-# it generates trees whose positions are not transparent
diff --git a/test/files/presentation/hyperlinks/Runner.scala b/test/files/presentation/hyperlinks/Runner.scala
index 3d19f2d948..61da49a3d7 100644
--- a/test/files/presentation/hyperlinks/Runner.scala
+++ b/test/files/presentation/hyperlinks/Runner.scala
@@ -1,11 +1,11 @@
import scala.tools.nsc.interactive.tests.InteractiveTest
object Test extends InteractiveTest {
- override def runTests() {
+ override def runDefaultTests() {
// make sure typer is done.. the virtual pattern matcher might translate
// some trees and mess up positions. But we'll catch it red handed!
sourceFiles foreach (src => askLoadedTyped(src).get)
- super.runTests()
+ super.runDefaultTests()
}
} \ No newline at end of file
diff --git a/test/files/presentation/ide-bug-1000469/Runner.scala b/test/files/presentation/ide-bug-1000469/Runner.scala
index c53533fddd..1ef3cf9025 100644
--- a/test/files/presentation/ide-bug-1000469/Runner.scala
+++ b/test/files/presentation/ide-bug-1000469/Runner.scala
@@ -1,5 +1,3 @@
import scala.tools.nsc.interactive.tests._
-object Test extends InteractiveTest {
- override val runRandomTests = false
-}
+object Test extends InteractiveTest \ No newline at end of file
diff --git a/test/files/presentation/ide-bug-1000531.flags b/test/files/presentation/ide-bug-1000531.flags
deleted file mode 100644
index 56d026a62d..0000000000
--- a/test/files/presentation/ide-bug-1000531.flags
+++ /dev/null
@@ -1,18 +0,0 @@
-# This file contains command line options that are passed to the presentation compiler
-# Lines starting with # are stripped, and you can split arguments on several lines.
-
-# The -bootclasspath option is treated specially by the test framework: if it's not specified
-# in this file, the presentation compiler will pick up the scala-library/compiler that's on the
-# java classpath used to run this test (usually build/pack)
-
-# Any option can be passed this way, like presentation debug
-# -Ypresentation-debug -Ypresentation-verbose
-
-# the classpath is relative to the current working directory. That means it depends where you're
-# running partest from. Run it from the root scala checkout for these files to resolve correctly
-# (by default when running 'ant test', or 'test/partest'). Paths use Unix separators, the test
-# framework translates them to the platform dependent representation.
-# -bootclasspath lib/scala-compiler.jar:lib/scala-library.jar:lib/fjbg.jar
-
-# the following line would test using the quick compiler
-# -bootclasspath build/quick/classes/compiler:build/quick/classes/library:lib/fjbg.jar
diff --git a/test/files/presentation/ide-t1000976.check b/test/files/presentation/ide-t1000976.check
new file mode 100644
index 0000000000..d58f86d6c6
--- /dev/null
+++ b/test/files/presentation/ide-t1000976.check
@@ -0,0 +1 @@
+Test OK \ No newline at end of file
diff --git a/test/files/presentation/ide-t1000976.flags b/test/files/presentation/ide-t1000976.flags
new file mode 100644
index 0000000000..9a1a05a4f6
--- /dev/null
+++ b/test/files/presentation/ide-t1000976.flags
@@ -0,0 +1 @@
+-sourcepath src \ No newline at end of file
diff --git a/test/files/presentation/ide-t1000976/Test.scala b/test/files/presentation/ide-t1000976/Test.scala
new file mode 100644
index 0000000000..722259d3a1
--- /dev/null
+++ b/test/files/presentation/ide-t1000976/Test.scala
@@ -0,0 +1,30 @@
+import scala.tools.nsc.interactive.tests.InteractiveTest
+import scala.reflect.internal.util.SourceFile
+import scala.tools.nsc.interactive.Response
+
+object Test extends InteractiveTest {
+ override def execute(): Unit = {
+ loadSourceAndWaitUntilTypechecked("A.scala")
+ val sourceB = loadSourceAndWaitUntilTypechecked("B.scala")
+ checkErrors(sourceB)
+ }
+
+ private def loadSourceAndWaitUntilTypechecked(sourceName: String): SourceFile = {
+ val sourceFile = sourceFiles.find(_.file.name == sourceName).head
+ compiler.askToDoFirst(sourceFile)
+ val res = new Response[Unit]
+ compiler.askReload(List(sourceFile), res)
+ res.get
+ askLoadedTyped(sourceFile).get
+ sourceFile
+ }
+
+ private def checkErrors(source: SourceFile): Unit = compiler.getUnitOf(source) match {
+ case Some(unit) =>
+ val problems = unit.problems.toList
+ if(problems.isEmpty) reporter.println("Test OK")
+ else problems.foreach(problem => reporter.println(problem.msg))
+
+ case None => reporter.println("No compilation unit found for " + source.file.name)
+ }
+}
diff --git a/test/files/presentation/ide-t1000976/src/a/A.scala b/test/files/presentation/ide-t1000976/src/a/A.scala
new file mode 100644
index 0000000000..fcfef8b525
--- /dev/null
+++ b/test/files/presentation/ide-t1000976/src/a/A.scala
@@ -0,0 +1,7 @@
+package a
+
+import d.D._
+
+object A {
+ Seq.empty[Byte].toArray.toSeq
+}
diff --git a/test/files/presentation/ide-t1000976/src/b/B.scala b/test/files/presentation/ide-t1000976/src/b/B.scala
new file mode 100644
index 0000000000..628348cac1
--- /dev/null
+++ b/test/files/presentation/ide-t1000976/src/b/B.scala
@@ -0,0 +1,7 @@
+package b
+
+import c.C
+
+class B {
+ new C("")
+}
diff --git a/test/files/presentation/ide-t1000976/src/c/C.scala b/test/files/presentation/ide-t1000976/src/c/C.scala
new file mode 100644
index 0000000000..cc23e3eef1
--- /dev/null
+++ b/test/files/presentation/ide-t1000976/src/c/C.scala
@@ -0,0 +1,3 @@
+package c
+
+class C(key: String = "", componentStates: String = "")
diff --git a/test/files/presentation/ide-t1000976/src/d/D.scala b/test/files/presentation/ide-t1000976/src/d/D.scala
new file mode 100644
index 0000000000..d7a48f98d5
--- /dev/null
+++ b/test/files/presentation/ide-t1000976/src/d/D.scala
@@ -0,0 +1,7 @@
+package d
+
+import c.C
+
+object D {
+ implicit def c2s(c: C): String = ""
+}
diff --git a/test/files/presentation/memory-leaks/MemoryLeaksTest.scala b/test/files/presentation/memory-leaks/MemoryLeaksTest.scala
index 857beac7df..a5533a623a 100644
--- a/test/files/presentation/memory-leaks/MemoryLeaksTest.scala
+++ b/test/files/presentation/memory-leaks/MemoryLeaksTest.scala
@@ -24,10 +24,7 @@ import scala.tools.nsc.io._
object Test extends InteractiveTest {
final val mega = 1024 * 1024
- override def main(args: Array[String]) {
- memoryConsumptionTest()
- compiler.askShutdown()
- }
+ override def execute(): Unit = memoryConsumptionTest()
def batchSource(name: String) =
new BatchSourceFile(AbstractFile.getFile(name))
diff --git a/test/files/presentation/t5708/Test.scala b/test/files/presentation/t5708/Test.scala
index 96e758d974..bec1131c4c 100644
--- a/test/files/presentation/t5708/Test.scala
+++ b/test/files/presentation/t5708/Test.scala
@@ -1,5 +1,3 @@
import scala.tools.nsc.interactive.tests.InteractiveTest
-object Test extends InteractiveTest {
-
-} \ No newline at end of file
+object Test extends InteractiveTest \ No newline at end of file
diff --git a/test/files/presentation/visibility/Test.scala b/test/files/presentation/visibility/Test.scala
index 96e758d974..bec1131c4c 100644
--- a/test/files/presentation/visibility/Test.scala
+++ b/test/files/presentation/visibility/Test.scala
@@ -1,5 +1,3 @@
import scala.tools.nsc.interactive.tests.InteractiveTest
-object Test extends InteractiveTest {
-
-} \ No newline at end of file
+object Test extends InteractiveTest \ No newline at end of file
diff --git a/test/files/run/stringinterpolation_macro-run.check b/test/files/run/stringinterpolation_macro-run.check
new file mode 100644
index 0000000000..be62c5780b
--- /dev/null
+++ b/test/files/run/stringinterpolation_macro-run.check
@@ -0,0 +1,62 @@
+false
+false
+true
+false
+true
+FALSE
+FALSE
+TRUE
+FALSE
+TRUE
+true
+false
+null
+0
+80000000
+4c01926
+NULL
+4C01926
+null
+NULL
+Scala
+SCALA
+5
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+S
+120
+120
+120
+120
+120
+120
+120
+120
+120
+120
+120
+120
+120
+42
+3.400000e+00
+3.400000e+00
+3.400000e+00
+3.400000e+00
+3.400000e+00
+3.400000e+00
+3.000000e+00
+3.000000e+00
+05/26/12
+05/26/12
+05/26/12
+05/26/12
diff --git a/test/files/run/stringinterpolation_macro-run.scala b/test/files/run/stringinterpolation_macro-run.scala
new file mode 100644
index 0000000000..9c59c334f8
--- /dev/null
+++ b/test/files/run/stringinterpolation_macro-run.scala
@@ -0,0 +1,103 @@
+object Test extends App {
+
+// 'b' / 'B' (category: general)
+// -----------------------------
+println(f"${null}%b")
+println(f"${false}%b")
+println(f"${true}%b")
+println(f"${new java.lang.Boolean(false)}%b")
+println(f"${new java.lang.Boolean(true)}%b")
+
+println(f"${null}%B")
+println(f"${false}%B")
+println(f"${true}%B")
+println(f"${new java.lang.Boolean(false)}%B")
+println(f"${new java.lang.Boolean(true)}%B")
+
+implicit val stringToBoolean = java.lang.Boolean.parseBoolean(_: String)
+println(f"${"true"}%b")
+println(f"${"false"}%b")
+
+// 'h' | 'H' (category: general)
+// -----------------------------
+println(f"${null}%h")
+println(f"${0.0}%h")
+println(f"${-0.0}%h")
+println(f"${"Scala"}%h")
+
+println(f"${null}%H")
+println(f"${"Scala"}%H")
+
+// 's' | 'S' (category: general)
+// -----------------------------
+println(f"${null}%s")
+println(f"${null}%S")
+println(f"${"Scala"}%s")
+println(f"${"Scala"}%S")
+println(f"${5}")
+
+// 'c' | 'C' (category: character)
+// -------------------------------
+println(f"${120:Char}%c")
+println(f"${120:Byte}%c")
+println(f"${120:Short}%c")
+println(f"${120:Int}%c")
+println(f"${new java.lang.Character('x')}%c")
+println(f"${new java.lang.Byte(120:Byte)}%c")
+println(f"${new java.lang.Short(120:Short)}%c")
+println(f"${new java.lang.Integer(120)}%c")
+
+println(f"${'x' : java.lang.Character}%c")
+println(f"${(120:Byte) : java.lang.Byte}%c")
+println(f"${(120:Short) : java.lang.Short}%c")
+println(f"${120 : java.lang.Integer}%c")
+
+implicit val stringToChar = (x: String) => x(0)
+println(f"${"Scala"}%c")
+
+// 'd' | 'o' | 'x' | 'X' (category: integral)
+// ------------------------------------------
+println(f"${120:Byte}%d")
+println(f"${120:Short}%d")
+println(f"${120:Int}%d")
+println(f"${120:Long}%d")
+println(f"${new java.lang.Byte(120:Byte)}%d")
+println(f"${new java.lang.Short(120:Short)}%d")
+println(f"${new java.lang.Integer(120)}%d")
+println(f"${new java.lang.Long(120)}%d")
+println(f"${120 : java.lang.Integer}%d")
+println(f"${120 : java.lang.Long}%d")
+println(f"${BigInt(120)}%d")
+println(f"${new java.math.BigInteger("120")}%d")
+
+{
+ implicit val strToShort = (s: String) => java.lang.Short.parseShort(s)
+ println(f"${"120"}%d")
+ implicit val strToInt = (s: String) => 42
+ println(f"${"120"}%d")
+}
+
+// 'e' | 'E' | 'g' | 'G' | 'f' | 'a' | 'A' (category: floating point)
+// ------------------------------------------------------------------
+println(f"${3.4f}%e")
+println(f"${3.4}%e")
+println(f"${3.4f : java.lang.Float}%e")
+println(f"${3.4 : java.lang.Double}%e")
+println(f"${BigDecimal(3.4)}%e")
+println(f"${new java.math.BigDecimal(3.4)}%e")
+println(f"${3}%e")
+println(f"${3L}%e")
+
+// 't' | 'T' (category: date/time)
+// -------------------------------
+import java.util.Calendar
+import java.util.Locale
+val c = Calendar.getInstance(Locale.US)
+c.set(2012, Calendar.MAY, 26)
+println(f"${c}%TD")
+println(f"${c.getTime}%TD")
+println(f"${c.getTime.getTime}%TD")
+
+implicit val strToDate = (x: String) => c
+println(f"""${"1234"}%TD""")
+}
diff --git a/test/files/run/t5974.check b/test/files/run/t5974.check
new file mode 100644
index 0000000000..9766475a41
--- /dev/null
+++ b/test/files/run/t5974.check
@@ -0,0 +1 @@
+ok
diff --git a/test/files/run/t5974.scala b/test/files/run/t5974.scala
new file mode 100644
index 0000000000..5b99e9f721
--- /dev/null
+++ b/test/files/run/t5974.scala
@@ -0,0 +1,10 @@
+object Test extends App {
+ import scala.collection.JavaConverters._
+
+ def ser(a: AnyRef) =
+ (new java.io.ObjectOutputStream(new java.io.ByteArrayOutputStream())).writeObject(a)
+
+ val l = java.util.Arrays.asList("pigdog").asScala
+ ser(l)
+ println("ok")
+}
diff --git a/test/files/speclib/instrumented.jar.desired.sha1 b/test/files/speclib/instrumented.jar.desired.sha1
index 24856fe19a..0b8ee593da 100644
--- a/test/files/speclib/instrumented.jar.desired.sha1
+++ b/test/files/speclib/instrumented.jar.desired.sha1
@@ -1 +1 @@
-474d8c20ab31438d5d4a2ba6bc07ebdcdb530b50 ?instrumented.jar
+474d8c20ab31438d5d4a2ba6bc07ebdcdb530b50 *instrumented.jar
diff --git a/tools/new-starr b/tools/new-starr
new file mode 100755
index 0000000000..5f00cc758e
--- /dev/null
+++ b/tools/new-starr
@@ -0,0 +1,6 @@
+#!/bin/bash
+
+ant -Dscalac.args.optimise="-optimise" locker.done
+cp -R src/starr/* src/
+ant build-opt
+ant starr.done