summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore25
-rwxr-xr-xbuild.xml13
-rw-r--r--docs/LICENSE56
-rw-r--r--src/compiler/scala/tools/ant/templates/tool-windows.tmpl68
-rw-r--r--src/compiler/scala/tools/nsc/ast/parser/Parsers.scala5
-rw-r--r--src/compiler/scala/tools/nsc/backend/jvm/GenBCode.scala328
-rw-r--r--src/compiler/scala/tools/nsc/backend/opt/DeadCodeElimination.scala2
-rw-r--r--src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala11
-rw-r--r--src/compiler/scala/tools/nsc/symtab/classfile/Pickler.scala7
-rw-r--r--src/compiler/scala/tools/nsc/transform/Erasure.scala4
-rw-r--r--src/compiler/scala/tools/nsc/transform/patmat/Solving.scala9
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Namers.scala8
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala9
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/RefChecks.scala53
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/TypeDiagnostics.scala11
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Typers.scala2
-rw-r--r--src/compiler/scala/tools/nsc/util/ClassPath.scala5
-rw-r--r--src/compiler/scala/tools/nsc/util/StackTracing.scala76
-rw-r--r--src/compiler/scala/tools/nsc/util/package.scala18
-rw-r--r--src/compiler/scala/tools/reflect/ToolBoxFactory.scala5
-rw-r--r--src/compiler/scala/tools/reflect/WrappedProperties.scala8
-rw-r--r--src/interactive/scala/tools/nsc/interactive/Global.scala1
-rw-r--r--src/partest-extras/scala/tools/partest/ReplTest.scala26
-rw-r--r--src/reflect/scala/reflect/internal/ClassfileConstants.scala36
-rw-r--r--src/reflect/scala/reflect/internal/Definitions.scala1
-rw-r--r--src/reflect/scala/reflect/internal/ExistentialsAndSkolems.scala9
-rw-r--r--src/reflect/scala/reflect/internal/Importers.scala5
-rw-r--r--src/reflect/scala/reflect/internal/Names.scala108
-rw-r--r--src/reflect/scala/reflect/internal/Printers.scala2
-rw-r--r--src/reflect/scala/reflect/internal/StdNames.scala1
-rw-r--r--src/reflect/scala/reflect/internal/Types.scala21
-rw-r--r--src/reflect/scala/reflect/internal/annotations/uncheckedBounds.scala13
-rw-r--r--src/reflect/scala/reflect/io/ZipArchive.scala6
-rw-r--r--src/reflect/scala/reflect/runtime/JavaMirrors.scala33
-rw-r--r--src/reflect/scala/reflect/runtime/ReflectionUtils.scala6
-rw-r--r--src/reflect/scala/reflect/runtime/SymbolLoaders.scala11
-rw-r--r--src/reflect/scala/reflect/runtime/SynchronizedOps.scala5
-rw-r--r--src/repl/scala/tools/nsc/interpreter/IMain.scala4
-rw-r--r--test/files/neg/macro-abort.check4
-rw-r--r--test/files/neg/macro-abort/Macros_1.scala9
-rw-r--r--test/files/neg/macro-abort/Test_2.scala3
-rw-r--r--test/files/neg/macro-exception.check7
-rw-r--r--test/files/neg/macro-exception/Macros_1.scala9
-rw-r--r--test/files/neg/macro-exception/Test_2.scala3
-rw-r--r--test/files/neg/macro-invalidusage-presuper.check2
-rw-r--r--test/files/neg/t2796.check5
-rw-r--r--test/files/neg/t2796.flags2
-rw-r--r--test/files/neg/t2796.scala3
-rw-r--r--test/files/neg/t7020.check19
-rw-r--r--test/files/neg/t7020.flags1
-rw-r--r--test/files/neg/t7020.scala30
-rw-r--r--test/files/neg/t7501.check7
-rw-r--r--test/files/neg/t7501/t7501_1.scala12
-rw-r--r--test/files/neg/t7501/t7501_2.scala5
-rw-r--r--test/files/neg/t7694b.check7
-rw-r--r--test/files/neg/t7752.check27
-rw-r--r--test/files/neg/t7752.scala26
-rw-r--r--test/files/pos/t4760.scala34
-rw-r--r--test/files/pos/t7014/ThreadSafety.java9
-rw-r--r--test/files/pos/t7014/ThreadSafetyLevel.java8
-rw-r--r--test/files/pos/t7014/t7014.scala4
-rw-r--r--test/files/pos/t7486-named.scala8
-rw-r--r--test/files/pos/t7486.scala (renamed from test/pending/pos/t7486.scala)0
-rw-r--r--test/files/pos/t7694.scala40
-rw-r--r--test/files/pos/t7716.scala16
-rw-r--r--test/files/pos/t7782.scala25
-rw-r--r--test/files/pos/t7782b.scala25
-rw-r--r--test/files/pos/t7785.scala34
-rw-r--r--test/files/pos/t942/Amount_1.java5
-rw-r--r--test/files/pos/t942/Test_2.scala3
-rw-r--r--test/files/run/WeakHashSetTest.scala174
-rw-r--r--test/files/run/analyzerPlugins.scala6
-rw-r--r--test/files/run/deprecate-early-type-defs.check3
-rw-r--r--test/files/run/deprecate-early-type-defs.flags1
-rw-r--r--test/files/run/deprecate-early-type-defs.scala1
-rw-r--r--test/files/run/macro-auto-duplicate.check1
-rw-r--r--test/files/run/macro-auto-duplicate/Macros_1.scala17
-rw-r--r--test/files/run/macro-auto-duplicate/Test_2.scala3
-rw-r--r--test/files/run/macro-duplicate/Impls_Macros_1.scala2
-rw-r--r--test/files/run/reflection-magicsymbols-invoke.check2
-rw-r--r--test/files/run/repl-trim-stack-trace.scala11
-rw-r--r--test/files/run/t6392b.check2
-rw-r--r--test/files/run/t6989.check24
-rw-r--r--test/files/run/t7407.check1
-rw-r--r--test/files/run/t7407.flags1
-rw-r--r--test/files/run/t7407.scala11
-rw-r--r--test/files/run/t7407b.check2
-rw-r--r--test/files/run/t7407b.flags1
-rw-r--r--test/files/run/t7407b.scala20
-rw-r--r--test/files/run/t7510.check0
-rw-r--r--test/files/run/t7510/Ann_1.java4
-rw-r--r--test/files/run/t7510/Test_2.scala9
-rw-r--r--test/files/run/t7763.scala20
-rw-r--r--test/files/run/t7775.scala17
-rw-r--r--test/files/run/t7779.scala67
-rw-r--r--test/files/run/toolbox_current_run_compiles.check2
-rw-r--r--test/files/run/toolbox_current_run_compiles.scala28
-rw-r--r--test/files/run/typed-annotated.check1
-rw-r--r--test/files/run/typed-annotated/Macros_1.scala17
-rw-r--r--test/files/run/typed-annotated/Test_2.scala3
-rw-r--r--test/junit/scala/reflect/io/ZipArchiveTest.scala37
-rw-r--r--test/junit/scala/tools/nsc/util/StackTraceTest.scala159
-rw-r--r--test/pending/pos/t7778/Foo_1.java6
-rw-r--r--test/pending/pos/t7778/Test_2.scala3
-rw-r--r--test/pending/run/t7733.check1
-rw-r--r--test/pending/run/t7733/Separate_1.scala5
-rw-r--r--test/pending/run/t7733/Test_2.scala9
-rwxr-xr-xtools/binary-repo-lib.sh2
108 files changed, 1803 insertions, 273 deletions
diff --git a/.gitignore b/.gitignore
index e60505f663..f90835d970 100644
--- a/.gitignore
+++ b/.gitignore
@@ -9,10 +9,21 @@
# see also test/files/.gitignore
#
-*.jar
-*~
+#
+# JARs aren't checked in, they are fetched by Ant / pull_binary_libs.sh
+#
+# We could be more concise with /lib/**/*.jar but that assumes
+# a late-model git.
+#
+/lib/ant/*.jar
+/lib/*.jar
+/test/files/codelib/*.jar
+/test/files/lib/*.jar
+/test/files/speclib/instrumented.jar
+/tools/*.jar
-build.properties
+# Developer specific Ant properties
+/build.properties
# target directories for ant build
/build/
@@ -33,11 +44,5 @@ build.properties
/.idea
/.settings
-# bak files produced by ./cleanup-commit
-*.bak
-
# Standard symbolic link to build/quick/bin
-qbin
-
-# Mac specific, but that is common enough a dev platform to warrant inclusion.
-.DS_Store
+/qbin
diff --git a/build.xml b/build.xml
index fa1ca8e699..f8dbf42242 100755
--- a/build.xml
+++ b/build.xml
@@ -462,9 +462,9 @@ TODO:
<property name="sbt.lib.dir" value="${build-sbt.dir}/${sbt.latest.version}/lib"/>
<property name="sbt.interface.jar" value="${sbt.lib.dir}/interface.jar"/>
- <property name="sbt.interface.url" value="http://typesafe.artifactoryonline.com/typesafe/ivy-releases/org.scala-sbt/interface/${sbt.latest.version}/jars/interface.jar"/>
+ <property name="sbt.interface.url" value="http://private-repo.typesafe.com/typesafe/ivy-releases/org.scala-sbt/interface/${sbt.latest.version}/jars/interface.jar"/>
<property name="sbt.interface.src.jar" value="${sbt.src.dir}/compiler-interface-src.jar"/>
- <property name="sbt.interface.src.url" value="http://typesafe.artifactoryonline.com/typesafe/ivy-releases/org.scala-sbt/compiler-interface/${sbt.latest.version}/jars/compiler-interface-src.jar"/>
+ <property name="sbt.interface.src.url" value="http://private-repo.typesafe.com/typesafe/ivy-releases/org.scala-sbt/compiler-interface/${sbt.latest.version}/jars/compiler-interface-src.jar"/>
<!-- Additional command line arguments for scalac. They are added to all build targets -->
@@ -872,7 +872,11 @@ TODO:
<target name="docs.clean"> <clean build="docs"/> <delete dir="${build.dir}/manmaker" includeemptydirs="yes" quiet="yes" failonerror="no"/> </target>
<target name="dist.clean"> <delete dir="${dists.dir}" includeemptydirs="yes" quiet="yes" failonerror="no"/> </target>
- <target name="all.clean" depends="locker.clean, docs.clean"> <clean build="sbt"/> <clean build="osgi"/> </target>
+ <target name="junit.clean"> <clean build="junit"/> </target>
+
+ <target name="all.clean" depends="locker.clean, docs.clean, junit.clean">
+ <clean build="sbt"/> <clean build="osgi"/>
+ </target>
<!-- Used by the scala-installer script -->
<target name="allallclean" depends="all.clean, dist.clean"/>
@@ -1341,9 +1345,11 @@ TODO:
<attribute name="Class-Path" value="scala-reflect.jar scala-library.jar"/>
</manifest>
</pre>
+ <!-- script api is 2.11-only so far
<jar-opts>
<service type="javax.script.ScriptEngineFactory" provider="scala.tools.nsc.interpreter.IMain$Factory"/>
</jar-opts>
+ -->
</staged-pack>
</target>
@@ -1586,6 +1592,7 @@ TODO:
<target name="test.junit" depends="test.junit.comp">
<stopwatch name="test.junit.timer"/>
<mkdir dir="${test.junit.classes}"/>
+ <echo message="Note: details of failed tests will be output to ${build-junit.dir}"/>
<junit fork="yes" haltonfailure="yes" printsummary="on">
<classpath refid="test.junit.compiler.build.path"/>
<batchtest fork="yes" todir="${build-junit.dir}">
diff --git a/docs/LICENSE b/docs/LICENSE
index a9c254ed49..446a1a350b 100644
--- a/docs/LICENSE
+++ b/docs/LICENSE
@@ -1,35 +1,27 @@
-SCALA LICENSE
+Copyright (c) 2002-2013 EPFL
-Copyright (c) 2002-2013 EPFL, Lausanne, unless otherwise specified.
All rights reserved.
-This software was developed by the Programming Methods Laboratory of the
-Swiss Federal Institute of Technology (EPFL), Lausanne, Switzerland.
-
-Permission to use, copy, modify, and distribute this software in source
-or binary form for any purpose with or without fee is hereby granted,
-provided that the following conditions are met:
-
- 1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-
- 2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
- 3. Neither the name of the EPFL nor the names of its contributors
- may be used to endorse or promote products derived from this
- software without specific prior written permission.
-
-
-THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
-FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
-CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-SUCH DAMAGE.
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+ * Neither the name of the EPFL nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/src/compiler/scala/tools/ant/templates/tool-windows.tmpl b/src/compiler/scala/tools/ant/templates/tool-windows.tmpl
index a3a95ffd37..1288eb0b7c 100644
--- a/src/compiler/scala/tools/ant/templates/tool-windows.tmpl
+++ b/src/compiler/scala/tools/ant/templates/tool-windows.tmpl
@@ -22,13 +22,74 @@ if "%~1"=="-toolcp" (
goto another_param
)
-set _LINE_PARAMS=%1
+rem We keep in _JAVA_PARAMS all -J-prefixed and -D-prefixed arguments
+set _JAVA_PARAMS=
+
+if [%1]==[] goto param_afterloop
+set _TEST_PARAM=%~1
+if not "%_TEST_PARAM:~0,1%"=="-" goto param_afterloop
+
+rem ignore -e "scala code"
+if "%_TEST_PARAM:~0,2%"=="-e" (
+ shift
+ shift
+ if [%1]==[] goto param_afterloop
+)
+
+set _TEST_PARAM=%~1
+if "%_TEST_PARAM:~0,2%"=="-J" (
+ set _JAVA_PARAMS=%_TEST_PARAM:~2%
+)
+
+if "%_TEST_PARAM:~0,2%"=="-D" (
+ rem test if this was double-quoted property "-Dprop=42"
+ for /F "delims== tokens=1-2" %%G in ("%_TEST_PARAM%") DO (
+ if not "%%G" == "%_TEST_PARAM%" (
+ rem double quoted: "-Dprop=42" -> -Dprop="42"
+ set _JAVA_PARAMS=%%G="%%H"
+ ) else if [%2] neq [] (
+ rem it was a normal property: -Dprop=42 or -Drop="42"
+ set _JAVA_PARAMS=%_TEST_PARAM%=%2
+ shift
+ )
+ )
+)
+
:param_loop
shift
+
if [%1]==[] goto param_afterloop
-set _LINE_PARAMS=%_LINE_PARAMS% %1
+set _TEST_PARAM=%~1
+if not "%_TEST_PARAM:~0,1%"=="-" goto param_afterloop
+
+rem ignore -e "scala code"
+if "%_TEST_PARAM:~0,2%"=="-e" (
+ shift
+ shift
+ if [%1]==[] goto param_afterloop
+)
+
+set _TEST_PARAM=%~1
+if "%_TEST_PARAM:~0,2%"=="-J" (
+ set _JAVA_PARAMS=%_JAVA_PARAMS% %_TEST_PARAM:~2%
+)
+
+if "%_TEST_PARAM:~0,2%"=="-D" (
+ rem test if this was double-quoted property "-Dprop=42"
+ for /F "delims== tokens=1-2" %%G in ("%_TEST_PARAM%") DO (
+ if not "%%G" == "%_TEST_PARAM%" (
+ rem double quoted: "-Dprop=42" -> -Dprop="42"
+ set _JAVA_PARAMS=%_JAVA_PARAMS% %%G="%%H"
+ ) else if [%2] neq [] (
+ rem it was a normal property: -Dprop=42 or -Drop="42"
+ set _JAVA_PARAMS=%_JAVA_PARAMS% %_TEST_PARAM%=%2
+ shift
+ )
+ )
+)
goto param_loop
:param_afterloop
+
if "%OS%" NEQ "Windows_NT" (
echo "Warning, your version of Windows is not supported. Attempting to start scala anyway."
)
@@ -51,6 +112,9 @@ rem We use the value of the JAVA_OPTS environment variable if defined
set _JAVA_OPTS=%JAVA_OPTS%
if not defined _JAVA_OPTS set _JAVA_OPTS=@javaflags@
+rem We append _JAVA_PARAMS java arguments to JAVA_OPTS if necessary
+if defined _JAVA_PARAMS set _JAVA_OPTS=%_JAVA_OPTS% %_JAVA_PARAMS%
+
set _TOOL_CLASSPATH=@classpath@
if "%_TOOL_CLASSPATH%"=="" (
for %%f in ("!_SCALA_HOME!\lib\*") do call :add_cpath "%%f"
diff --git a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala
index 94270e4cf3..6a09f9f07c 100644
--- a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala
+++ b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala
@@ -2800,9 +2800,10 @@ self =>
case vdef @ ValDef(mods, _, _, _) if !mods.isDeferred =>
List(copyValDef(vdef)(mods = mods | Flags.PRESUPER))
case tdef @ TypeDef(mods, name, tparams, rhs) =>
+ deprecationWarning(tdef.pos.point, "early type members are deprecated. Move them to the regular body: the semantics are the same.")
List(treeCopy.TypeDef(tdef, mods | Flags.PRESUPER, name, tparams, rhs))
case stat if !stat.isEmpty =>
- syntaxError(stat.pos, "only type definitions and concrete field definitions allowed in early object initialization section", skipIt = false)
+ syntaxError(stat.pos, "only concrete field definitions allowed in early object initialization section", skipIt = false)
List()
case _ => List()
}
@@ -3066,7 +3067,7 @@ self =>
while (!isStatSeqEnd && !isCaseDefStart) {
if (in.token == IMPORT) {
stats ++= importClause()
- acceptStatSep()
+ acceptStatSepOpt()
}
else if (isExprIntro) {
stats += statement(InBlock)
diff --git a/src/compiler/scala/tools/nsc/backend/jvm/GenBCode.scala b/src/compiler/scala/tools/nsc/backend/jvm/GenBCode.scala
index e55a3baed0..193100474c 100644
--- a/src/compiler/scala/tools/nsc/backend/jvm/GenBCode.scala
+++ b/src/compiler/scala/tools/nsc/backend/jvm/GenBCode.scala
@@ -17,13 +17,25 @@ import scala.tools.asm
/*
* Prepare in-memory representations of classfiles using the ASM Tree API, and serialize them to disk.
*
- * `BCodePhase.apply(CompilationUnit)` is invoked by some external force and that sets in motion:
- * - visiting each ClassDef contained in that CompilationUnit
- * - lowering the ClassDef into:
+ * Three pipelines are at work, each taking work items from a queue dedicated to that pipeline:
+ *
+ * (There's another pipeline so to speak, the one that populates queue-1 by traversing a CompilationUnit until ClassDefs are found,
+ * but the "interesting" pipelines are the ones described below)
+ *
+ * (1) In the first queue, an item consists of a ClassDef along with its arrival position.
+ * This position is needed at the time classfiles are serialized to disk,
+ * so as to emit classfiles in the same order CleanUp handed them over.
+ * As a result, two runs of the compiler on the same files produce jars that are identical on a byte basis.
+ * See `ant test.stability`
+ *
+ * (2) The second queue contains items where a ClassDef has been lowered into:
* (a) an optional mirror class,
* (b) a plain class, and
* (c) an optional bean class.
- * - each of the ClassNodes above is lowered into a byte-array (ie into a classfile) and serialized.
+ *
+ * (3) The third queue contains items ready for serialization.
+ * It's a priority queue that follows the original arrival order,
+ * so as to emit identical jars on repeated compilation of the same sources.
*
* Plain, mirror, and bean classes are built respectively by PlainClassBuilder, JMirrorBuilder, and JBeanInfoBuilder.
*
@@ -50,75 +62,192 @@ abstract class GenBCode extends BCodeSyncAndTry {
private var mirrorCodeGen : JMirrorBuilder = null
private var beanInfoCodeGen : JBeanInfoBuilder = null
- private var needsOutFolder = false // whether getOutFolder(claszSymbol) should be invoked for each claszSymbol
+ /* ---------------- q1 ---------------- */
+
+ case class Item1(arrivalPos: Int, cd: ClassDef, cunit: CompilationUnit) {
+ def isPoison = { arrivalPos == Int.MaxValue }
+ }
+ private val poison1 = Item1(Int.MaxValue, null, null)
+ private val q1 = new java.util.LinkedList[Item1]
+
+ /* ---------------- q2 ---------------- */
- val caseInsensitively = mutable.Map.empty[String, Symbol]
+ case class Item2(arrivalPos: Int,
+ mirror: asm.tree.ClassNode,
+ plain: asm.tree.ClassNode,
+ bean: asm.tree.ClassNode,
+ outFolder: scala.tools.nsc.io.AbstractFile) {
+ def isPoison = { arrivalPos == Int.MaxValue }
+ }
+
+ private val poison2 = Item2(Int.MaxValue, null, null, null, null)
+ private val q2 = new _root_.java.util.LinkedList[Item2]
+
+ /* ---------------- q3 ---------------- */
/*
- * Checks for duplicate internal names case-insensitively,
- * builds ASM ClassNodes for mirror, plain, and bean classes.
+ * An item of queue-3 (the last queue before serializing to disk) contains three of these
+ * (one for each of mirror, plain, and bean classes).
*
+ * @param jclassName internal name of the class
+ * @param jclassBytes bytecode emitted for the class SubItem3 represents
*/
- def visit(arrivalPos: Int, cd: ClassDef, cunit: CompilationUnit) {
- val claszSymbol = cd.symbol
-
- // GenASM checks this before classfiles are emitted, https://github.com/scala/scala/commit/e4d1d930693ac75d8eb64c2c3c69f2fc22bec739
- val lowercaseJavaClassName = claszSymbol.javaClassName.toLowerCase
- caseInsensitively.get(lowercaseJavaClassName) match {
- case None =>
- caseInsensitively.put(lowercaseJavaClassName, claszSymbol)
- case Some(dupClassSym) =>
- cunit.warning(
- claszSymbol.pos,
- s"Class ${claszSymbol.javaClassName} differs only in case from ${dupClassSym.javaClassName}. " +
- "Such classes will overwrite one another on case-insensitive filesystems."
- )
+ case class SubItem3(
+ jclassName: String,
+ jclassBytes: Array[Byte]
+ )
+
+ case class Item3(arrivalPos: Int,
+ mirror: SubItem3,
+ plain: SubItem3,
+ bean: SubItem3,
+ outFolder: scala.tools.nsc.io.AbstractFile) {
+
+ def isPoison = { arrivalPos == Int.MaxValue }
+ }
+ private val i3comparator = new java.util.Comparator[Item3] {
+ override def compare(a: Item3, b: Item3) = {
+ if (a.arrivalPos < b.arrivalPos) -1
+ else if (a.arrivalPos == b.arrivalPos) 0
+ else 1
}
+ }
+ private val poison3 = Item3(Int.MaxValue, null, null, null, null)
+ private val q3 = new java.util.PriorityQueue[Item3](1000, i3comparator)
+
+ /*
+ * Pipeline that takes ClassDefs from queue-1, lowers them into an intermediate form, placing them on queue-2
+ */
+ class Worker1(needsOutFolder: Boolean) {
+
+ val caseInsensitively = mutable.Map.empty[String, Symbol]
- // -------------- mirror class, if needed --------------
- val mirrorC =
- if (isStaticModule(claszSymbol) && isTopLevelModule(claszSymbol)) {
- if (claszSymbol.companionClass == NoSymbol) {
- mirrorCodeGen.genMirrorClass(claszSymbol, cunit)
- } else {
- log(s"No mirror class for module with linked class: ${claszSymbol.fullName}");
- null
+ def run() {
+ while (true) {
+ val item = q1.poll
+ if (item.isPoison) {
+ q2 add poison2
+ return
}
- } else null
-
- // -------------- "plain" class --------------
- val pcb = new PlainClassBuilder(cunit)
- pcb.genPlainClass(cd)
- val outF = if (needsOutFolder) getOutFolder(claszSymbol, pcb.thisName, cunit) else null;
- val plainC = pcb.cnode
-
- // -------------- bean info class, if needed --------------
- val beanC =
- if (claszSymbol hasAnnotation BeanInfoAttr) {
- beanInfoCodeGen.genBeanInfoClass(
- claszSymbol, cunit,
- fieldSymbols(claszSymbol),
- methodSymbols(cd)
- )
- } else null
-
- // ----------- serialize classfiles to disk
-
- def getByteArray(cn: asm.tree.ClassNode): Array[Byte] = {
- val cw = new CClassWriter(extraProc)
- cn.accept(cw)
- cw.toByteArray
+ else {
+ try { visit(item) }
+ catch {
+ case ex: Throwable =>
+ ex.printStackTrace()
+ error(s"Error while emitting ${item.cunit.source}\n${ex.getMessage}")
+ }
+ }
+ }
}
- if (mirrorC != null) {
- sendToDisk(mirrorC.name, getByteArray(mirrorC), outF)
+ /*
+ * Checks for duplicate internal names case-insensitively,
+ * builds ASM ClassNodes for mirror, plain, and bean classes;
+ * enqueues them in queue-2.
+ *
+ */
+ def visit(item: Item1) {
+ val Item1(arrivalPos, cd, cunit) = item
+ val claszSymbol = cd.symbol
+
+ // GenASM checks this before classfiles are emitted, https://github.com/scala/scala/commit/e4d1d930693ac75d8eb64c2c3c69f2fc22bec739
+ val lowercaseJavaClassName = claszSymbol.javaClassName.toLowerCase
+ caseInsensitively.get(lowercaseJavaClassName) match {
+ case None =>
+ caseInsensitively.put(lowercaseJavaClassName, claszSymbol)
+ case Some(dupClassSym) =>
+ item.cunit.warning(
+ claszSymbol.pos,
+ s"Class ${claszSymbol.javaClassName} differs only in case from ${dupClassSym.javaClassName}. " +
+ "Such classes will overwrite one another on case-insensitive filesystems."
+ )
+ }
+
+ // -------------- mirror class, if needed --------------
+ val mirrorC =
+ if (isStaticModule(claszSymbol) && isTopLevelModule(claszSymbol)) {
+ if (claszSymbol.companionClass == NoSymbol) {
+ mirrorCodeGen.genMirrorClass(claszSymbol, cunit)
+ } else {
+ log(s"No mirror class for module with linked class: ${claszSymbol.fullName}")
+ null
+ }
+ } else null
+
+ // -------------- "plain" class --------------
+ val pcb = new PlainClassBuilder(cunit)
+ pcb.genPlainClass(cd)
+ val outF = if (needsOutFolder) getOutFolder(claszSymbol, pcb.thisName, cunit) else null;
+ val plainC = pcb.cnode
+
+ // -------------- bean info class, if needed --------------
+ val beanC =
+ if (claszSymbol hasAnnotation BeanInfoAttr) {
+ beanInfoCodeGen.genBeanInfoClass(
+ claszSymbol, cunit,
+ fieldSymbols(claszSymbol),
+ methodSymbols(cd)
+ )
+ } else null
+
+ // ----------- hand over to pipeline-2
+
+ val item2 =
+ Item2(arrivalPos,
+ mirrorC, plainC, beanC,
+ outF)
+
+ q2 add item2 // at the very end of this method so that no Worker2 thread starts mutating before we're done.
+
+ } // end of method visit(Item1)
+
+ } // end of class BCodePhase.Worker1
+
+ /*
+ * Pipeline that takes ClassNodes from queue-2. The unit of work depends on the optimization level:
+ *
+ * (a) no optimization involves:
+ * - converting the plain ClassNode to byte array and placing it on queue-3
+ */
+ class Worker2 {
+
+ def run() {
+ while (true) {
+ val item = q2.poll
+ if (item.isPoison) {
+ q3 add poison3
+ return
+ }
+ else {
+ try { addToQ3(item) }
+ catch {
+ case ex: Throwable =>
+ ex.printStackTrace()
+ error(s"Error while emitting ${item.plain.name}\n${ex.getMessage}")
+ }
+ }
+ }
}
- sendToDisk(plainC.name, getByteArray(plainC), outF)
- if (beanC != null) {
- sendToDisk(beanC.name, getByteArray(beanC), outF)
+
+ private def addToQ3(item: Item2) {
+
+ def getByteArray(cn: asm.tree.ClassNode): Array[Byte] = {
+ val cw = new CClassWriter(extraProc)
+ cn.accept(cw)
+ cw.toByteArray
+ }
+
+ val Item2(arrivalPos, mirror, plain, bean, outFolder) = item
+
+ val mirrorC = if (mirror == null) null else SubItem3(mirror.name, getByteArray(mirror))
+ val plainC = SubItem3(plain.name, getByteArray(plain))
+ val beanC = if (bean == null) null else SubItem3(bean.name, getByteArray(bean))
+
+ q3 add Item3(arrivalPos, mirrorC, plainC, beanC, outFolder)
+
}
- } // end of method visit()
+ } // end of class BCodePhase.Worker2
var arrivalPos = 0
@@ -144,15 +273,12 @@ abstract class GenBCode extends BCodeSyncAndTry {
mirrorCodeGen = new JMirrorBuilder
beanInfoCodeGen = new JBeanInfoBuilder
- needsOutFolder = bytecodeWriter.isInstanceOf[ClassBytecodeWriter]
-
- super.run()
+ val needsOutfileForSymbol = bytecodeWriter.isInstanceOf[ClassBytecodeWriter]
+ buildAndSendToDisk(needsOutfileForSymbol)
// closing output files.
bytecodeWriter.close()
- caseInsensitively.clear()
-
/* TODO Bytecode can be verified (now that all classfiles have been written to disk)
*
* (1) asm.util.CheckAdapter.verify()
@@ -170,17 +296,69 @@ abstract class GenBCode extends BCodeSyncAndTry {
clearBCodeTypes()
}
- def sendToDisk(jclassName: String, jclassBytes: Array[Byte], outFolder: _root_.scala.tools.nsc.io.AbstractFile) {
- try {
- val outFile =
- if (outFolder == null) null
- else getFileForClassfile(outFolder, jclassName, ".class")
- bytecodeWriter.writeClass(jclassName, jclassName, jclassBytes, outFile)
+ /*
+ * Sequentially:
+ * (a) place all ClassDefs in queue-1
+ * (b) dequeue one at a time from queue-1, convert it to ASM ClassNode, place in queue-2
+ * (c) dequeue one at a time from queue-2, convert it to byte-array, place in queue-3
+ * (d) serialize to disk by draining queue-3.
+ */
+ private def buildAndSendToDisk(needsOutFolder: Boolean) {
+
+ feedPipeline1()
+ (new Worker1(needsOutFolder)).run()
+ (new Worker2).run()
+ drainQ3()
+
+ }
+
+ /* Feed pipeline-1: place all ClassDefs on q1, recording their arrival position. */
+ private def feedPipeline1() {
+ super.run()
+ q1 add poison1
+ }
+
+ /* Pipeline that writes classfile representations to disk. */
+ private def drainQ3() {
+
+ def sendToDisk(cfr: SubItem3, outFolder: scala.tools.nsc.io.AbstractFile) {
+ if (cfr != null){
+ val SubItem3(jclassName, jclassBytes) = cfr
+ try {
+ val outFile =
+ if (outFolder == null) null
+ else getFileForClassfile(outFolder, jclassName, ".class")
+ bytecodeWriter.writeClass(jclassName, jclassName, jclassBytes, outFile)
+ }
+ catch {
+ case e: FileConflictException =>
+ error(s"error writing $jclassName: ${e.getMessage}")
+ }
+ }
}
- catch {
- case e: FileConflictException =>
- error(s"error writing $jclassName: ${e.getMessage}")
+
+ var moreComing = true
+ // `expected` denotes the arrivalPos whose Item3 should be serialized next
+ var expected = 0
+
+ while (moreComing) {
+ val incoming = q3.poll
+ moreComing = !incoming.isPoison
+ if (moreComing) {
+ val item = incoming
+ val outFolder = item.outFolder
+ sendToDisk(item.mirror, outFolder)
+ sendToDisk(item.plain, outFolder)
+ sendToDisk(item.bean, outFolder)
+ expected += 1
+ }
}
+
+ // we're done
+ assert(q1.isEmpty, s"Some ClassDefs remained in the first queue: $q1")
+ assert(q2.isEmpty, s"Some classfiles remained in the second queue: $q2")
+ assert(q3.isEmpty, s"Some classfiles weren't written to disk: $q3")
+
}
override def apply(cunit: CompilationUnit): Unit = {
@@ -190,7 +368,7 @@ abstract class GenBCode extends BCodeSyncAndTry {
case EmptyTree => ()
case PackageDef(_, stats) => stats foreach gen
case cd: ClassDef =>
- visit(arrivalPos, cd, cunit)
+ q1 add Item1(arrivalPos, cd, cunit)
arrivalPos += 1
}
}
diff --git a/src/compiler/scala/tools/nsc/backend/opt/DeadCodeElimination.scala b/src/compiler/scala/tools/nsc/backend/opt/DeadCodeElimination.scala
index 483bff6467..7511da8b00 100644
--- a/src/compiler/scala/tools/nsc/backend/opt/DeadCodeElimination.scala
+++ b/src/compiler/scala/tools/nsc/backend/opt/DeadCodeElimination.scala
@@ -159,7 +159,7 @@ abstract class DeadCodeElimination extends SubComponent {
case RETURN(_) | JUMP(_) | CJUMP(_, _, _, _) | CZJUMP(_, _, _, _) | STORE_FIELD(_, _) |
THROW(_) | LOAD_ARRAY_ITEM(_) | STORE_ARRAY_ITEM(_) | SCOPE_ENTER(_) | SCOPE_EXIT(_) | STORE_THIS(_) |
- LOAD_EXCEPTION(_) | SWITCH(_, _) | MONITOR_ENTER() | MONITOR_EXIT() =>
+ LOAD_EXCEPTION(_) | SWITCH(_, _) | MONITOR_ENTER() | MONITOR_EXIT() | CHECK_CAST(_) =>
moveToWorkList()
case CALL_METHOD(m1, _) if isSideEffecting(m1) =>
diff --git a/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala b/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala
index 14e3f5b642..2b96961291 100644
--- a/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala
+++ b/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala
@@ -874,9 +874,14 @@ abstract class ClassfileParser {
case ENUM_TAG =>
val t = pool.getType(index)
val n = readName()
- val s = t.typeSymbol.companionModule.info.decls.lookup(n)
- assert(s != NoSymbol, t)
- Some(LiteralAnnotArg(Constant(s)))
+ val module = t.typeSymbol.companionModule
+ val s = module.info.decls.lookup(n)
+ if (s != NoSymbol) Some(LiteralAnnotArg(Constant(s)))
+ else {
+ warning(s"""While parsing annotations in ${in.file}, could not find $n in enum $module.\nThis is likely due to an implementation restriction: an annotation argument cannot refer to a member of the annotated class (SI-7014).""")
+ None
+ }
+
case ARRAY_TAG =>
val arr = new ArrayBuffer[ClassfileAnnotArg]()
var hasError = false
diff --git a/src/compiler/scala/tools/nsc/symtab/classfile/Pickler.scala b/src/compiler/scala/tools/nsc/symtab/classfile/Pickler.scala
index 9bad29097c..9ac1ce1b9c 100644
--- a/src/compiler/scala/tools/nsc/symtab/classfile/Pickler.scala
+++ b/src/compiler/scala/tools/nsc/symtab/classfile/Pickler.scala
@@ -88,12 +88,17 @@ abstract class Pickler extends SubComponent {
/** Returns usually symbol's owner, but picks classfile root instead
* for existentially bound variables that have a non-local owner.
* Question: Should this be done for refinement class symbols as well?
+ *
+ * Note: tree pickling also finds its way here; e.g. in SI-7501 the pickling
+ * of trees in annotation arguments considers the parameter symbol of a method
+ * called in such a tree as "local". The condition `sym.isValueParameter` was
+ * added to fix that bug, but there may be a better way.
*/
private def localizedOwner(sym: Symbol) =
if (isLocal(sym) && !isRootSym(sym) && !isLocal(sym.owner))
// don't use a class as the localized owner for type parameters that are not owned by a class: those are not instantiated by asSeenFrom
// however, they would suddenly be considered by asSeenFrom if their localized owner became a class (causing the crashes of #4079, #2741)
- (if(sym.isTypeParameter && !sym.owner.isClass) nonClassRoot
+ (if ((sym.isTypeParameter || sym.isValueParameter) && !sym.owner.isClass) nonClassRoot
else root)
else sym.owner
diff --git a/src/compiler/scala/tools/nsc/transform/Erasure.scala b/src/compiler/scala/tools/nsc/transform/Erasure.scala
index b8f79ced79..c74fc620ca 100644
--- a/src/compiler/scala/tools/nsc/transform/Erasure.scala
+++ b/src/compiler/scala/tools/nsc/transform/Erasure.scala
@@ -690,7 +690,7 @@ abstract class Erasure extends AddInterfaces
private def adaptMember(tree: Tree): Tree = {
//Console.println("adaptMember: " + tree);
tree match {
- case Apply(TypeApply(sel @ Select(qual, name), List(targ)), List())
+ case Apply(ta @ TypeApply(sel @ Select(qual, name), List(targ)), List())
if tree.symbol == Any_asInstanceOf =>
val qual1 = typedQualifier(qual, NOmode, ObjectTpe) // need to have an expected type, see #3037
@@ -715,7 +715,7 @@ abstract class Erasure extends AddInterfaces
// }
typed(untyped)
}
- } else qual1
+ } else treeCopy.Apply(tree, treeCopy.TypeApply(ta, treeCopy.Select(sel, qual1, name), List(targ)), List())
case Apply(TypeApply(sel @ Select(qual, name), List(targ)), List())
if tree.symbol == Any_isInstanceOf =>
diff --git a/src/compiler/scala/tools/nsc/transform/patmat/Solving.scala b/src/compiler/scala/tools/nsc/transform/patmat/Solving.scala
index 3c7dc79636..114bcba5df 100644
--- a/src/compiler/scala/tools/nsc/transform/patmat/Solving.scala
+++ b/src/compiler/scala/tools/nsc/transform/patmat/Solving.scala
@@ -202,15 +202,16 @@ trait Solving extends Logic {
withLit(findModelFor(dropUnit(f, unitLit)), unitLit)
case _ =>
// partition symbols according to whether they appear in positive and/or negative literals
- val pos = new mutable.HashSet[Sym]()
- val neg = new mutable.HashSet[Sym]()
+ // SI-7020 Linked- for deterministic counter examples.
+ val pos = new mutable.LinkedHashSet[Sym]()
+ val neg = new mutable.LinkedHashSet[Sym]()
f.foreach{_.foreach{ lit =>
if (lit.pos) pos += lit.sym else neg += lit.sym
}}
// appearing in both positive and negative
- val impures = pos intersect neg
+ val impures: mutable.LinkedHashSet[Sym] = pos intersect neg
// appearing only in either positive/negative positions
- val pures = (pos ++ neg) -- impures
+ val pures: mutable.LinkedHashSet[Sym] = (pos ++ neg) -- impures
if (pures nonEmpty) {
val pureSym = pures.head
diff --git a/src/compiler/scala/tools/nsc/typechecker/Namers.scala b/src/compiler/scala/tools/nsc/typechecker/Namers.scala
index 95d6ca52ec..454f913412 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Namers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Namers.scala
@@ -1418,14 +1418,6 @@ trait Namers extends MethodSynthesis {
annCtx.setReportErrors()
// need to be lazy, #1782. beforeTyper to allow inferView in annotation args, SI-5892.
AnnotationInfo lazily {
- if (typer.context ne ctx)
- log(sm"""|The var `typer.context` in ${Namer.this} was mutated before the annotation ${ann} was forced.
- |
- |current value = ${typer.context}
- |original value = $ctx
- |
- |This confirms the hypothesis for the cause of SI-7603. If you see this message, please comment on that ticket.""")
-
enteringTyper(newTyper(annCtx) typedAnnotation ann)
}
}
diff --git a/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala b/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala
index 8e9933f734..dea4c46e79 100644
--- a/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala
@@ -162,7 +162,7 @@ trait NamesDefaults { self: Analyzer =>
// never used for constructor calls, they always have a stable qualifier
def blockWithQualifier(qual: Tree, selected: Name) = {
- val sym = blockTyper.context.owner.newValue(unit.freshTermName("qual$"), qual.pos, newFlags = ARTIFACT) setInfo qual.tpe
+ val sym = blockTyper.context.owner.newValue(unit.freshTermName("qual$"), qual.pos, newFlags = ARTIFACT) setInfo uncheckedBounds(qual.tpe)
blockTyper.context.scope enter sym
val vd = atPos(sym.pos)(ValDef(sym, qual) setType NoType)
// it stays in Vegas: SI-5720, SI-5727
@@ -289,9 +289,10 @@ trait NamesDefaults { self: Analyzer =>
arg.tpe
}
).widen // have to widen or types inferred from literal defaults will be singletons
- val s = context.owner.newValue(unit.freshTermName("x$"), arg.pos, newFlags = ARTIFACT) setInfo (
- if (byName) functionType(Nil, argTpe) else argTpe
- )
+ val s = context.owner.newValue(unit.freshTermName("x$"), arg.pos, newFlags = ARTIFACT) setInfo {
+ val tp = if (byName) functionType(Nil, argTpe) else argTpe
+ uncheckedBounds(tp)
+ }
Some((context.scope.enter(s), byName, repeated))
})
map2(symPs, args) {
diff --git a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala
index 5929cab1d1..32e908e03b 100644
--- a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala
@@ -1414,17 +1414,35 @@ abstract class RefChecks extends InfoTransform with scala.reflect.internal.trans
false
}
- private def checkTypeRef(tp: Type, tree: Tree) = tp match {
+ private def checkTypeRef(tp: Type, tree: Tree, skipBounds: Boolean) = tp match {
case TypeRef(pre, sym, args) =>
checkDeprecated(sym, tree.pos)
if(sym.isJavaDefined)
sym.typeParams foreach (_.cookJavaRawInfo())
- if (!tp.isHigherKinded)
+ if (!tp.isHigherKinded && !skipBounds)
checkBounds(tree, pre, sym.owner, sym.typeParams, args)
case _ =>
}
- private def checkAnnotations(tpes: List[Type], tree: Tree) = tpes foreach (tp => checkTypeRef(tp, tree))
+ private def checkTypeRefBounds(tp: Type, tree: Tree) = {
+ var skipBounds = false
+ tp match {
+ case AnnotatedType(ann :: Nil, underlying, selfSym) if ann.symbol == UncheckedBoundsClass =>
+ skipBounds = true
+ underlying
+ case TypeRef(pre, sym, args) =>
+ if (!tp.isHigherKinded && !skipBounds)
+ checkBounds(tree, pre, sym.owner, sym.typeParams, args)
+ tp
+ case _ =>
+ tp
+ }
+ }
+
+ private def checkAnnotations(tpes: List[Type], tree: Tree) = tpes foreach { tp =>
+ checkTypeRef(tp, tree, skipBounds = false)
+ checkTypeRefBounds(tp, tree)
+ }
private def doTypeTraversal(tree: Tree)(f: Type => Unit) = if (!inPattern) tree.tpe foreach f
private def applyRefchecksToAnnotations(tree: Tree): Unit = {
@@ -1453,8 +1471,9 @@ abstract class RefChecks extends InfoTransform with scala.reflect.internal.trans
}
doTypeTraversal(tree) {
- case AnnotatedType(annots, _, _) => applyChecks(annots)
- case _ =>
+ case tp @ AnnotatedType(annots, _, _) =>
+ applyChecks(annots)
+ case tp =>
}
case _ =>
}
@@ -1639,13 +1658,27 @@ abstract class RefChecks extends InfoTransform with scala.reflect.internal.trans
}
val existentialParams = new ListBuffer[Symbol]
- doTypeTraversal(tree) { // check all bounds, except those that are existential type parameters
- case ExistentialType(tparams, tpe) =>
+ var skipBounds = false
+ // check all bounds, except those that are existential type parameters
+ // or those within typed annotated with @uncheckedBounds
+ doTypeTraversal(tree) {
+ case tp @ ExistentialType(tparams, tpe) =>
existentialParams ++= tparams
- case t: TypeRef =>
- checkTypeRef(deriveTypeWithWildcards(existentialParams.toList)(t), tree)
+ case ann: AnnotatedType if ann.hasAnnotation(UncheckedBoundsClass) =>
+ // SI-7694 Allow code synthetizers to disable checking of bounds for TypeTrees based on inferred LUBs
+ // which might not conform to the constraints.
+ skipBounds = true
+ case tp: TypeRef =>
+ val tpWithWildcards = deriveTypeWithWildcards(existentialParams.toList)(tp)
+ checkTypeRef(tpWithWildcards, tree, skipBounds)
case _ =>
}
+ if (skipBounds) {
+ tree.tpe = tree.tpe.map {
+ _.filterAnnotations(_.symbol != UncheckedBoundsClass)
+ }
+ }
+
tree
case TypeApply(fn, args) =>
@@ -1715,6 +1748,8 @@ abstract class RefChecks extends InfoTransform with scala.reflect.internal.trans
inPattern = false
super.transform(result)
}
+ case ValDef(_, _, _, _) if treeInfo.hasSynthCaseSymbol(result) =>
+ deriveValDef(result)(transform) // SI-7716 Don't refcheck the tpt of the synthetic val that holds the selector.
case _ =>
super.transform(result)
}
diff --git a/src/compiler/scala/tools/nsc/typechecker/TypeDiagnostics.scala b/src/compiler/scala/tools/nsc/typechecker/TypeDiagnostics.scala
index 0c5f798c23..1af176736b 100644
--- a/src/compiler/scala/tools/nsc/typechecker/TypeDiagnostics.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/TypeDiagnostics.scala
@@ -350,11 +350,14 @@ trait TypeDiagnostics {
val strings = mutable.Map[String, Set[TypeDiag]]() withDefaultValue Set()
val names = mutable.Map[Name, Set[TypeDiag]]() withDefaultValue Set()
- def record(t: Type, sym: Symbol) = {
- val diag = TypeDiag(t, sym)
+ val localsSet = locals.toSet
- strings("" + t) += diag
- names(sym.name) += diag
+ def record(t: Type, sym: Symbol) = {
+ if (!localsSet(sym)) {
+ val diag = TypeDiag(t, sym)
+ strings("" + t) += diag
+ names(sym.name) += diag
+ }
}
for (tpe <- types ; t <- tpe) {
t match {
diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
index dd16b5be85..d29d9dbe18 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
@@ -3789,7 +3789,7 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper
// we need symbol-ful originals for reification
// hence we go the extra mile to hand-craft tis guy
val original = arg1 match {
- case tt @ TypeTree() => Annotated(ann, tt.original)
+ case tt @ TypeTree() if tt.original != null => Annotated(ann, tt.original)
// this clause is needed to correctly compile stuff like "new C @D" or "@(inline @getter)"
case _ => Annotated(ann, arg1)
}
diff --git a/src/compiler/scala/tools/nsc/util/ClassPath.scala b/src/compiler/scala/tools/nsc/util/ClassPath.scala
index 7f9b81e1ec..906a575d90 100644
--- a/src/compiler/scala/tools/nsc/util/ClassPath.scala
+++ b/src/compiler/scala/tools/nsc/util/ClassPath.scala
@@ -16,6 +16,7 @@ import File.pathSeparator
import scala.collection.convert.WrapAsScala.enumerationAsScalaIterator
import java.net.MalformedURLException
import java.util.regex.PatternSyntaxException
+import scala.reflect.runtime.ReflectionUtils
/** <p>
* This module provides star expansion of '-classpath' option arguments, behaves the same as
@@ -80,7 +81,7 @@ object ClassPath {
}
/** A useful name filter. */
- def isTraitImplementation(name: String) = name endsWith "$class.class"
+ def isTraitImplementation(name: String) = ReflectionUtils.isTraitImplementation(name)
def specToURL(spec: String): Option[URL] =
try Some(new URL(spec))
@@ -139,7 +140,7 @@ object ClassPath {
}
object DefaultJavaContext extends JavaContext {
- override def isValidName(name: String) = !isTraitImplementation(name)
+ override def isValidName(name: String) = !ReflectionUtils.scalacShouldntLoadClassfile(name)
}
private def endsClass(s: String) = s.length > 6 && s.substring(s.length - 6) == ".class"
diff --git a/src/compiler/scala/tools/nsc/util/StackTracing.scala b/src/compiler/scala/tools/nsc/util/StackTracing.scala
new file mode 100644
index 0000000000..fa4fe29f28
--- /dev/null
+++ b/src/compiler/scala/tools/nsc/util/StackTracing.scala
@@ -0,0 +1,76 @@
+/* NSC -- new Scala compiler
+ * Copyright 2005-2013 LAMP/EPFL
+ */
+
+package scala.tools.nsc.util
+
+private[util] trait StackTracing extends Any {
+
+ /** Format a stack trace, returning the prefix consisting of frames that satisfy
+ * a given predicate.
+ * The format is similar to the typical case described in the JavaDoc
+ * for [[java.lang.Throwable#printStackTrace]].
+ * If a stack trace is truncated, it will be followed by a line of the form
+ * `... 3 elided`, by analogy to the lines `... 3 more` which indicate
+ * shared stack trace segments.
+ * @param e the exception
+ * @param p the predicate to select the prefix
+ */
+ def stackTracePrefixString(e: Throwable)(p: StackTraceElement => Boolean): String = {
+ import collection.mutable.{ ArrayBuffer, ListBuffer }
+ import compat.Platform.EOL
+ import util.Properties.isJavaAtLeast
+
+ val sb = ListBuffer.empty[String]
+
+ type TraceRelation = String
+ val Self = new TraceRelation("")
+ val CausedBy = new TraceRelation("Caused by: ")
+ val Suppressed = new TraceRelation("Suppressed: ")
+
+ val suppressable = isJavaAtLeast("1.7")
+
+ def clazz(e: Throwable) = e.getClass.getName
+ def because(e: Throwable): String = e.getCause match { case null => null ; case c => header(c) }
+ def msg(e: Throwable): String = e.getMessage match { case null => because(e) ; case s => s }
+ def txt(e: Throwable): String = msg(e) match { case null => "" ; case s => s": $s" }
+ def header(e: Throwable): String = s"${clazz(e)}${txt(e)}"
+
+ val indent = "\u0020\u0020"
+
+ val seen = new ArrayBuffer[Throwable](16)
+ def unseen(t: Throwable) = {
+ def inSeen = seen exists (_ eq t)
+ val interesting = (t != null) && !inSeen
+ if (interesting) seen += t
+ interesting
+ }
+
+ def print(e: Throwable, r: TraceRelation, share: Array[StackTraceElement], indents: Int): Unit = if (unseen(e)) {
+ val trace = e.getStackTrace
+ val frames = (
+ if (share.nonEmpty) {
+ val spare = share.reverseIterator
+ val trimmed = trace.reverse dropWhile (spare.hasNext && spare.next == _)
+ trimmed.reverse
+ } else trace
+ )
+ val prefix = frames takeWhile p
+ val margin = indent * indents
+ val indented = margin + indent
+ sb append s"${margin}${r}${header(e)}"
+ prefix foreach (f => sb append s"${indented}at $f")
+ if (frames.size < trace.size) sb append s"$indented... ${trace.size - frames.size} more"
+ if (r == Self && prefix.size < frames.size) sb append s"$indented... ${frames.size - prefix.size} elided"
+ print(e.getCause, CausedBy, trace, indents)
+ if (suppressable) {
+ import scala.language.reflectiveCalls
+ type Suppressing = { def getSuppressed(): Array[Throwable] }
+ for (s <- e.asInstanceOf[Suppressing].getSuppressed) print(s, Suppressed, frames, indents + 1)
+ }
+ }
+ print(e, Self, share = Array.empty, indents = 0)
+
+ sb mkString EOL
+ }
+}
diff --git a/src/compiler/scala/tools/nsc/util/package.scala b/src/compiler/scala/tools/nsc/util/package.scala
index ea3c9d8dde..72a4bbf5c0 100644
--- a/src/compiler/scala/tools/nsc/util/package.scala
+++ b/src/compiler/scala/tools/nsc/util/package.scala
@@ -8,7 +8,6 @@ package tools
package nsc
import java.io.{ OutputStream, PrintStream, ByteArrayOutputStream, PrintWriter, StringWriter }
-import scala.compat.Platform.EOL
package object util {
@@ -79,12 +78,17 @@ package object util {
s"$clazz$msg @ $frame"
}
- def stackTracePrefixString(ex: Throwable)(p: StackTraceElement => Boolean): String = {
- val frames = ex.getStackTrace takeWhile p map (" at " + _)
- val msg = ex.getMessage match { case null => "" ; case s => s": $s" }
- val clazz = ex.getClass.getName
-
- s"$clazz$msg" +: frames mkString EOL
+ implicit class StackTraceOps(val e: Throwable) extends AnyVal with StackTracing {
+ /** Format the stack trace, returning the prefix consisting of frames that satisfy
+ * a given predicate.
+ * The format is similar to the typical case described in the JavaDoc
+ * for [[java.lang.Throwable#printStackTrace]].
+ * If a stack trace is truncated, it will be followed by a line of the form
+ * `... 3 elided`, by analogy to the lines `... 3 more` which indicate
+ * shared stack trace segments.
+ * @param p the predicate to select the prefix
+ */
+ def stackTracePrefixString(p: StackTraceElement => Boolean): String = stackTracePrefixString(e)(p)
}
lazy val trace = new SimpleTracer(System.out)
diff --git a/src/compiler/scala/tools/reflect/ToolBoxFactory.scala b/src/compiler/scala/tools/reflect/ToolBoxFactory.scala
index 8d2f200e99..57ebe1b30d 100644
--- a/src/compiler/scala/tools/reflect/ToolBoxFactory.scala
+++ b/src/compiler/scala/tools/reflect/ToolBoxFactory.scala
@@ -12,6 +12,7 @@ import java.lang.{Class => jClass}
import scala.compat.Platform.EOL
import scala.reflect.NameTransformer
import scala.reflect.api.JavaUniverse
+import scala.reflect.io.NoAbstractFile
abstract class ToolBoxFactory[U <: JavaUniverse](val u: U) { factorySelf =>
@@ -136,7 +137,9 @@ abstract class ToolBoxFactory[U <: JavaUniverse](val u: U) { factorySelf =>
val wrapper2 = if (!withMacrosDisabled) (currentTyper.context.withMacrosEnabled[Tree] _) else (currentTyper.context.withMacrosDisabled[Tree] _)
def wrapper (tree: => Tree) = wrapper1(wrapper2(tree))
- phase = (new Run).typerPhase // need to set a phase to something <= typerPhase, otherwise implicits in typedSelect will be disabled
+ val run = new Run
+ run.symSource(ownerClass) = NoAbstractFile // need to set file to something different from null, so that currentRun.defines works
+ phase = run.typerPhase // need to set a phase to something <= typerPhase, otherwise implicits in typedSelect will be disabled
currentTyper.context.setReportErrors() // need to manually set context mode, otherwise typer.silent will throw exceptions
reporter.reset()
diff --git a/src/compiler/scala/tools/reflect/WrappedProperties.scala b/src/compiler/scala/tools/reflect/WrappedProperties.scala
index 20567719be..523287fc66 100644
--- a/src/compiler/scala/tools/reflect/WrappedProperties.scala
+++ b/src/compiler/scala/tools/reflect/WrappedProperties.scala
@@ -27,9 +27,13 @@ trait WrappedProperties extends PropertiesTrait {
override def envOrNone(name: String) = wrap(super.envOrNone(name)).flatten
override def envOrSome(name: String, alt: Option[String]) = wrap(super.envOrNone(name)).flatten orElse alt
- def systemProperties: Iterator[(String, String)] = {
+ def systemProperties: List[(String, String)] = {
import scala.collection.JavaConverters._
- wrap(System.getProperties.asScala.iterator) getOrElse Iterator.empty
+ wrap {
+ val props = System.getProperties
+ // SI-7269 Be careful to avoid `ConcurrentModificationException` if another thread modifies the properties map
+ props.stringPropertyNames().asScala.toList.map(k => (k, props.get(k).asInstanceOf[String]))
+ } getOrElse Nil
}
}
diff --git a/src/interactive/scala/tools/nsc/interactive/Global.scala b/src/interactive/scala/tools/nsc/interactive/Global.scala
index 492f0f4fb4..721fbf24c7 100644
--- a/src/interactive/scala/tools/nsc/interactive/Global.scala
+++ b/src/interactive/scala/tools/nsc/interactive/Global.scala
@@ -140,6 +140,7 @@ class Global(settings: Settings, _reporter: Reporter, projectName: String = "")
abort("originalOwner is not kept in presentation compiler runs.")
override def forInteractive = true
+ override protected def synchronizeNames = true
override def newAsSeenFromMap(pre: Type, clazz: Symbol): AsSeenFromMap =
new InteractiveAsSeenFromMap(pre, clazz)
diff --git a/src/partest-extras/scala/tools/partest/ReplTest.scala b/src/partest-extras/scala/tools/partest/ReplTest.scala
index 7cc2dd39a9..38662c34b5 100644
--- a/src/partest-extras/scala/tools/partest/ReplTest.scala
+++ b/src/partest-extras/scala/tools/partest/ReplTest.scala
@@ -30,14 +30,30 @@ abstract class ReplTest extends DirectTest {
def show() = eval() foreach println
}
+/** Run a REPL test from a session transcript.
+ * The `session` should be a triple-quoted String starting
+ * with the `Type in expressions` message and ending
+ * after the final `prompt`, including the last space.
+ */
abstract class SessionTest extends ReplTest {
+ /** Session transcript, as a triple-quoted, multiline, marginalized string. */
def session: String
- override final def code = expected filter (_.startsWith(prompt)) map (_.drop(prompt.length)) mkString "\n"
- def expected = session.stripMargin.lines.toList
+
+ /** Expected output, as an iterator. */
+ def expected = session.stripMargin.lines
+
+ /** Code is the command list culled from the session (or the expected session output).
+ * Would be nicer if code were lazy lines.
+ */
+ override final def code = expected filter (_ startsWith prompt) map (_ drop prompt.length) mkString "\n"
+
final def prompt = "scala> "
+
+ /** Default test is to compare expected and actual output and emit the diff on a failed comparison. */
override def show() = {
- val out = eval().toList
- if (out.size != expected.size) Console println s"Expected ${expected.size} lines, got ${out.size}"
- if (out != expected) Console print nest.FileManager.compareContents(expected, out, "expected", "actual")
+ val evaled = eval().toList
+ val wanted = expected.toList
+ if (evaled.size != wanted.size) Console println s"Expected ${wanted.size} lines, got ${evaled.size}"
+ if (evaled != wanted) Console print nest.FileManager.compareContents(wanted, evaled, "expected", "actual")
}
}
diff --git a/src/reflect/scala/reflect/internal/ClassfileConstants.scala b/src/reflect/scala/reflect/internal/ClassfileConstants.scala
index a7ce044780..e0a6757d34 100644
--- a/src/reflect/scala/reflect/internal/ClassfileConstants.scala
+++ b/src/reflect/scala/reflect/internal/ClassfileConstants.scala
@@ -335,13 +335,8 @@ object ClassfileConstants {
abstract class FlagTranslation {
import Flags._
- private var isAnnotation = false
- private var isClass = false
- private def initFields(flags: Int) = {
- isAnnotation = (flags & JAVA_ACC_ANNOTATION) != 0
- isClass = false
- }
- private def translateFlag(jflag: Int): Long = (jflag: @switch) match {
+ private def isAnnotation(flags: Int): Boolean = (flags & JAVA_ACC_ANNOTATION) != 0
+ private def translateFlag(jflag: Int, isAnnotation: Boolean, isClass: Boolean): Long = (jflag: @switch) match {
case JAVA_ACC_PRIVATE => PRIVATE
case JAVA_ACC_PROTECTED => PROTECTED
case JAVA_ACC_FINAL => FINAL
@@ -351,31 +346,28 @@ object ClassfileConstants {
case JAVA_ACC_INTERFACE => if (isAnnotation) 0L else TRAIT | INTERFACE | ABSTRACT
case _ => 0L
}
- private def translateFlags(jflags: Int, baseFlags: Long): Long = {
+ private def translateFlags(jflags: Int, baseFlags: Long, isAnnotation: Boolean, isClass: Boolean): Long = {
+ def translateFlag0(jflags: Int): Long = translateFlag(jflags, isAnnotation, isClass)
var res: Long = JAVA | baseFlags
/* fast, elegant, maintainable, pick any two... */
- res |= translateFlag(jflags & JAVA_ACC_PRIVATE)
- res |= translateFlag(jflags & JAVA_ACC_PROTECTED)
- res |= translateFlag(jflags & JAVA_ACC_FINAL)
- res |= translateFlag(jflags & JAVA_ACC_SYNTHETIC)
- res |= translateFlag(jflags & JAVA_ACC_STATIC)
- res |= translateFlag(jflags & JAVA_ACC_ABSTRACT)
- res |= translateFlag(jflags & JAVA_ACC_INTERFACE)
+ res |= translateFlag0(jflags & JAVA_ACC_PRIVATE)
+ res |= translateFlag0(jflags & JAVA_ACC_PROTECTED)
+ res |= translateFlag0(jflags & JAVA_ACC_FINAL)
+ res |= translateFlag0(jflags & JAVA_ACC_SYNTHETIC)
+ res |= translateFlag0(jflags & JAVA_ACC_STATIC)
+ res |= translateFlag0(jflags & JAVA_ACC_ABSTRACT)
+ res |= translateFlag0(jflags & JAVA_ACC_INTERFACE)
res
}
def classFlags(jflags: Int): Long = {
- initFields(jflags)
- isClass = true
- translateFlags(jflags, 0)
+ translateFlags(jflags, 0, isAnnotation(jflags), isClass = true)
}
def fieldFlags(jflags: Int): Long = {
- initFields(jflags)
- translateFlags(jflags, if ((jflags & JAVA_ACC_FINAL) == 0) MUTABLE else 0)
+ translateFlags(jflags, if ((jflags & JAVA_ACC_FINAL) == 0) MUTABLE else 0 , isAnnotation(jflags), isClass = false)
}
def methodFlags(jflags: Int): Long = {
- initFields(jflags)
- translateFlags(jflags, if ((jflags & JAVA_ACC_BRIDGE) != 0) BRIDGE | ARTIFACT else 0)
+ translateFlags(jflags, if ((jflags & JAVA_ACC_BRIDGE) != 0) BRIDGE | ARTIFACT else 0, isAnnotation(jflags), isClass = false)
}
}
object FlagTranslation extends FlagTranslation { }
diff --git a/src/reflect/scala/reflect/internal/Definitions.scala b/src/reflect/scala/reflect/internal/Definitions.scala
index 92f2a64ce9..90a1ab39d5 100644
--- a/src/reflect/scala/reflect/internal/Definitions.scala
+++ b/src/reflect/scala/reflect/internal/Definitions.scala
@@ -1004,6 +1004,7 @@ trait Definitions extends api.StandardDefinitions {
lazy val ThrowsClass = requiredClass[scala.throws[_]]
lazy val TransientAttr = requiredClass[scala.transient]
lazy val UncheckedClass = requiredClass[scala.unchecked]
+ lazy val UncheckedBoundsClass = getClassIfDefined("scala.reflect.internal.annotations.uncheckedBounds")
lazy val UnspecializedClass = requiredClass[scala.annotation.unspecialized]
lazy val VolatileAttr = requiredClass[scala.volatile]
diff --git a/src/reflect/scala/reflect/internal/ExistentialsAndSkolems.scala b/src/reflect/scala/reflect/internal/ExistentialsAndSkolems.scala
index 073f124630..0eeca4aace 100644
--- a/src/reflect/scala/reflect/internal/ExistentialsAndSkolems.scala
+++ b/src/reflect/scala/reflect/internal/ExistentialsAndSkolems.scala
@@ -19,6 +19,9 @@ trait ExistentialsAndSkolems {
* can be deskolemized to the original type parameter. (A skolem is a
* representation of a bound variable when viewed inside its scope.)
* !!!Adriaan: this does not work for hk types.
+ *
+ * Skolems will be created at level 0, rather than the current value
+ * of `skolemizationLevel`. (See SI-7782)
*/
def deriveFreshSkolems(tparams: List[Symbol]): List[Symbol] = {
class Deskolemizer extends LazyType {
@@ -30,7 +33,11 @@ trait ExistentialsAndSkolems {
sym setInfo sym.deSkolemize.info.substSym(typeParams, typeSkolems)
}
}
- (new Deskolemizer).typeSkolems
+
+ val saved = skolemizationLevel
+ skolemizationLevel = 0
+ try new Deskolemizer().typeSkolems
+ finally skolemizationLevel = saved
}
def isRawParameter(sym: Symbol) = // is it a type parameter leaked by a raw type?
diff --git a/src/reflect/scala/reflect/internal/Importers.scala b/src/reflect/scala/reflect/internal/Importers.scala
index b0828e9c54..9ddf156128 100644
--- a/src/reflect/scala/reflect/internal/Importers.scala
+++ b/src/reflect/scala/reflect/internal/Importers.scala
@@ -411,6 +411,11 @@ trait Importers extends api.Importers { to: SymbolTable =>
if (my != null) {
addFixup(recreatedTreeCompleter(their, my))
tryFixup()
+ // we have to be careful with position import as some shared trees
+ // like EmptyTree, emptyValDef don't support position assignment
+ if (their.pos != NoPosition) {
+ my.setPos(importPosition(their.pos))
+ }
}
my
}
diff --git a/src/reflect/scala/reflect/internal/Names.scala b/src/reflect/scala/reflect/internal/Names.scala
index 0d78e24548..ed248d6e1e 100644
--- a/src/reflect/scala/reflect/internal/Names.scala
+++ b/src/reflect/scala/reflect/internal/Names.scala
@@ -18,6 +18,18 @@ trait Names extends api.Names {
final val nameDebug = false
+ // Ideally we would just synchronize unconditionally and let HotSpot's Biased Locking
+ // kick in in the compiler universe, where access to the lock is single threaded. But,
+ // objects created in the first 4seconds of the JVM startup aren't eligible for biased
+ // locking.
+ //
+ // We might also be able to accept the performance hit, but we don't have tools to
+ // detect performance regressions.
+ //
+ // Discussion: https://groups.google.com/forum/#!search/biased$20scala-internals/scala-internals/0cYB7SkJ-nM/47MLhsgw8jwJ
+ protected def synchronizeNames: Boolean = false
+ private val nameLock: Object = new Object
+
/** Memory to store all names sequentially. */
var chrs: Array[Char] = new Array[Char](NAME_SIZE)
private var nc = 0
@@ -64,61 +76,68 @@ trait Names extends api.Names {
}
/** Create a term name from the characters in cs[offset..offset+len-1]. */
- def newTermName(cs: Array[Char], offset: Int, len: Int): TermName =
+ final def newTermName(cs: Array[Char], offset: Int, len: Int): TermName =
newTermName(cs, offset, len, cachedString = null)
- def newTermName(cs: Array[Char]): TermName = newTermName(cs, 0, cs.length)
- def newTypeName(cs: Array[Char]): TypeName = newTypeName(cs, 0, cs.length)
+ final def newTermName(cs: Array[Char]): TermName = newTermName(cs, 0, cs.length)
+
+ final def newTypeName(cs: Array[Char]): TypeName = newTypeName(cs, 0, cs.length)
/** Create a term name from the characters in cs[offset..offset+len-1].
* TODO - have a mode where name validation is performed at creation time
* (e.g. if a name has the string "$class" in it, then fail if that
* string is not at the very end.)
*/
- protected def newTermName(cs: Array[Char], offset: Int, len: Int, cachedString: String): TermName = {
- val h = hashValue(cs, offset, len) & HASH_MASK
- var n = termHashtable(h)
- while ((n ne null) && (n.length != len || !equals(n.start, cs, offset, len)))
- n = n.next
-
- if (n ne null) n
- else {
- // The logic order here is future-proofing against the possibility
- // that name.toString will become an eager val, in which case the call
- // to enterChars cannot follow the construction of the TermName.
- val ncStart = nc
- enterChars(cs, offset, len)
- if (cachedString ne null) new TermName_S(ncStart, len, h, cachedString)
- else new TermName_R(ncStart, len, h)
+ final def newTermName(cs: Array[Char], offset: Int, len: Int, cachedString: String): TermName = {
+ def body = {
+ val h = hashValue(cs, offset, len) & HASH_MASK
+ var n = termHashtable(h)
+ while ((n ne null) && (n.length != len || !equals(n.start, cs, offset, len)))
+ n = n.next
+
+ if (n ne null) n
+ else {
+ // The logic order here is future-proofing against the possibility
+ // that name.toString will become an eager val, in which case the call
+ // to enterChars cannot follow the construction of the TermName.
+ val ncStart = nc
+ enterChars(cs, offset, len)
+ if (cachedString ne null) new TermName_S(ncStart, len, h, cachedString)
+ else new TermName_R(ncStart, len, h)
+ }
}
+ if (synchronizeNames) nameLock.synchronized(body) else body
}
- protected def newTypeName(cs: Array[Char], offset: Int, len: Int, cachedString: String): TypeName =
+
+ final def newTypeName(cs: Array[Char], offset: Int, len: Int, cachedString: String): TypeName =
newTermName(cs, offset, len, cachedString).toTypeName
/** Create a term name from string. */
+ @deprecatedOverriding("To synchronize, use `override def synchronizeNames = true`", "2.11.0") // overriden in https://github.com/scala-ide/scala-ide/blob/master/org.scala-ide.sdt.core/src/scala/tools/eclipse/ScalaPresentationCompiler.scala
def newTermName(s: String): TermName = newTermName(s.toCharArray(), 0, s.length(), null)
/** Create a type name from string. */
+ @deprecatedOverriding("To synchronize, use `override def synchronizeNames = true`", "2.11.0") // overriden in https://github.com/scala-ide/scala-ide/blob/master/org.scala-ide.sdt.core/src/scala/tools/eclipse/ScalaPresentationCompiler.scala
def newTypeName(s: String): TypeName = newTermName(s).toTypeName
/** Create a term name from the UTF8 encoded bytes in bs[offset..offset+len-1]. */
- def newTermName(bs: Array[Byte], offset: Int, len: Int): TermName = {
+ final def newTermName(bs: Array[Byte], offset: Int, len: Int): TermName = {
val chars = Codec.fromUTF8(bs, offset, len)
newTermName(chars, 0, chars.length)
}
- def newTermNameCached(s: String): TermName =
+ final def newTermNameCached(s: String): TermName =
newTermName(s.toCharArray(), 0, s.length(), cachedString = s)
- def newTypeNameCached(s: String): TypeName =
+ final def newTypeNameCached(s: String): TypeName =
newTypeName(s.toCharArray(), 0, s.length(), cachedString = s)
/** Create a type name from the characters in cs[offset..offset+len-1]. */
- def newTypeName(cs: Array[Char], offset: Int, len: Int): TypeName =
+ final def newTypeName(cs: Array[Char], offset: Int, len: Int): TypeName =
newTermName(cs, offset, len, cachedString = null).toTypeName
/** Create a type name from the UTF8 encoded bytes in bs[offset..offset+len-1]. */
- def newTypeName(bs: Array[Byte], offset: Int, len: Int): TypeName =
+ final def newTypeName(bs: Array[Byte], offset: Int, len: Int): TypeName =
newTermName(bs, offset, len).toTypeName
/**
@@ -128,6 +147,8 @@ trait Names extends api.Names {
* For those of METHOD sort, its descriptor is stored ie has a leading '('
*
* can-multi-thread
+ * TODO SI-6240 !!! JZ Really? the constructors TermName and TypeName publish unconstructed `this` references
+ * into the hash tables; we could observe them here before the subclass constructor completes.
*/
final def lookupTypeName(cs: Array[Char]): TypeName = { lookupTypeNameIfExisting(cs, true) }
@@ -494,23 +515,26 @@ trait Names extends api.Names {
override def toString = new String(chrs, index, len)
}
+ // SYNCNOTE: caller to constructor must synchronize if `synchronizeNames` is enabled
sealed abstract class TermName(index0: Int, len0: Int, hash: Int) extends Name(index0, len0) {
type ThisNameType = TermName
protected[this] def thisName: TermName = this
-
val next: TermName = termHashtable(hash)
termHashtable(hash) = this
def isTermName: Boolean = true
def isTypeName: Boolean = false
def toTermName: TermName = this
def toTypeName: TypeName = {
- val h = hashValue(chrs, index, len) & HASH_MASK
- var n = typeHashtable(h)
- while ((n ne null) && n.start != index)
- n = n.next
-
- if (n ne null) n
- else createCompanionName(h)
+ def body = {
+ val h = hashValue(chrs, index, len) & HASH_MASK
+ var n = typeHashtable(h)
+ while ((n ne null) && n.start != index)
+ n = n.next
+
+ if (n ne null) n
+ else createCompanionName(h)
+ }
+ if (synchronizeNames) nameLock.synchronized(body) else body
}
def newName(str: String): TermName = newTermName(str)
def companionName: TypeName = toTypeName
@@ -518,6 +542,7 @@ trait Names extends api.Names {
newTermName(chrs, start + from, to - from)
def nameKind = "term"
+ /** SYNCNOTE: caller must synchronize if `synchronizeNames` is enabled */
protected def createCompanionName(h: Int): TypeName
}
@@ -534,16 +559,20 @@ trait Names extends api.Names {
val next: TypeName = typeHashtable(hash)
typeHashtable(hash) = this
+
def isTermName: Boolean = false
def isTypeName: Boolean = true
def toTermName: TermName = {
- val h = hashValue(chrs, index, len) & HASH_MASK
- var n = termHashtable(h)
- while ((n ne null) && n.start != index)
- n = n.next
-
- if (n ne null) n
- else createCompanionName(h)
+ def body = {
+ val h = hashValue(chrs, index, len) & HASH_MASK
+ var n = termHashtable(h)
+ while ((n ne null) && n.start != index)
+ n = n.next
+
+ if (n ne null) n
+ else createCompanionName(h)
+ }
+ if (synchronizeNames) nameLock.synchronized(body) else body
}
def toTypeName: TypeName = this
def newName(str: String): TypeName = newTypeName(str)
@@ -553,6 +582,7 @@ trait Names extends api.Names {
def nameKind = "type"
override def decode = if (nameDebug) super.decode + "!" else super.decode
+ /** SYNCNOTE: caller must synchronize if `synchronizeNames` is enabled */
protected def createCompanionName(h: Int): TermName
}
diff --git a/src/reflect/scala/reflect/internal/Printers.scala b/src/reflect/scala/reflect/internal/Printers.scala
index 1603029340..206dff44e2 100644
--- a/src/reflect/scala/reflect/internal/Printers.scala
+++ b/src/reflect/scala/reflect/internal/Printers.scala
@@ -574,6 +574,8 @@ trait Printers extends api.Printers { self: SymbolTable =>
case refTree: RefTree =>
if (tree.symbol.name != refTree.name) print("[", tree.symbol, " aka ", refTree.name, "]")
else print(tree.symbol)
+ case defTree: DefTree =>
+ print(tree.symbol)
case _ =>
print(tree.symbol.name)
}
diff --git a/src/reflect/scala/reflect/internal/StdNames.scala b/src/reflect/scala/reflect/internal/StdNames.scala
index 7a2287664a..13fc7ce0dc 100644
--- a/src/reflect/scala/reflect/internal/StdNames.scala
+++ b/src/reflect/scala/reflect/internal/StdNames.scala
@@ -40,6 +40,7 @@ trait StdNames {
def result: Set[TermName] = try kws finally kws = null
}
+ private[reflect] def compactifyName(orig: String): String = compactify(orig)
private final object compactify extends (String => String) {
val md5 = MessageDigest.getInstance("MD5")
diff --git a/src/reflect/scala/reflect/internal/Types.scala b/src/reflect/scala/reflect/internal/Types.scala
index 49b5dae0ea..9c66dc476f 100644
--- a/src/reflect/scala/reflect/internal/Types.scala
+++ b/src/reflect/scala/reflect/internal/Types.scala
@@ -2842,6 +2842,9 @@ trait Types
// but pattern-matching returned the original constr0 (a bug)
// now, pattern-matching returns the most recent constr
object TypeVar {
+ private val ConstantTrue = ConstantType(Constant(true))
+ private val ConstantFalse = ConstantType(Constant(false))
+
@inline final def trace[T](action: String, msg: => String)(value: T): T = {
if (traceTypeVars) {
val s = msg match {
@@ -3000,6 +3003,7 @@ trait Types
this
else if (newArgs.size == params.size) {
val tv = TypeVar(origin, constr, newArgs, params)
+ tv.linkSuspended(this)
TypeVar.trace("applyArgs", "In " + originLocation + ", apply args " + newArgs.mkString(", ") + " to " + originName)(tv)
}
else
@@ -3061,7 +3065,16 @@ trait Types
// </region>
// ignore subtyping&equality checks while true -- see findMember
- private[Types] var suspended = false
+ // OPT: This could be Either[TypeVar, Boolean], but this encoding was chosen instead to save allocations.
+ private var _suspended: Type = TypeVar.ConstantFalse
+ private[Types] def suspended: Boolean = (_suspended: @unchecked) match {
+ case TypeVar.ConstantFalse => false
+ case TypeVar.ConstantTrue => true
+ case tv: TypeVar => tv.suspended
+ }
+ private[Types] def suspended_=(b: Boolean): Unit = _suspended = if (b) TypeVar.ConstantTrue else TypeVar.ConstantFalse
+ // SI-7785 Link the suspended attribute of a TypeVar created in, say, a TypeMap (e.g. AsSeenFrom) to its originator
+ private[Types] def linkSuspended(origin: TypeVar): Unit = _suspended = origin
/** Called when a TypeVar is involved in a subtyping check. Result is whether
* this TypeVar could plausibly be a [super/sub]type of argument `tp` and if so,
@@ -4539,6 +4552,12 @@ trait Types
else (ps :+ SerializableTpe).toList
)
+ /** Adds the @uncheckedBound annotation if the given `tp` has type arguments */
+ final def uncheckedBounds(tp: Type): Type = {
+ if (tp.typeArgs.isEmpty || UncheckedBoundsClass == NoSymbol) tp // second condition for backwards compatibilty with older scala-reflect.jar
+ else tp.withAnnotation(AnnotationInfo marker UncheckedBoundsClass.tpe)
+ }
+
/** Members of the given class, other than those inherited
* from Any or AnyRef.
*/
diff --git a/src/reflect/scala/reflect/internal/annotations/uncheckedBounds.scala b/src/reflect/scala/reflect/internal/annotations/uncheckedBounds.scala
new file mode 100644
index 0000000000..a44bb54734
--- /dev/null
+++ b/src/reflect/scala/reflect/internal/annotations/uncheckedBounds.scala
@@ -0,0 +1,13 @@
+package scala.reflect
+package internal
+package annotations
+
+/**
+ * An annotation that designates the annotated type should not be checked for violations of
+ * type parameter bounds in the `refchecks` phase of the compiler. This can be used by synthesized
+ * code the uses an inferred type of an expression as the type of an artifict val/def (for example,
+ * a temporary value introduced by an ANF transform). See [[https://issues.scala-lang.org/browse/SI-7694]].
+ *
+ * @since 2.10.3
+ */
+final class uncheckedBounds extends scala.annotation.StaticAnnotation
diff --git a/src/reflect/scala/reflect/io/ZipArchive.scala b/src/reflect/scala/reflect/io/ZipArchive.scala
index eabf1dcbab..8260189459 100644
--- a/src/reflect/scala/reflect/io/ZipArchive.scala
+++ b/src/reflect/scala/reflect/io/ZipArchive.scala
@@ -126,7 +126,11 @@ abstract class ZipArchive(override val file: JFile) extends AbstractFile with Eq
/** ''Note: This library is considered experimental and should not be used unless you know what you are doing.'' */
final class FileZipArchive(file: JFile) extends ZipArchive(file) {
def iterator: Iterator[Entry] = {
- val zipFile = new ZipFile(file)
+ val zipFile = try {
+ new ZipFile(file)
+ } catch {
+ case ioe: IOException => throw new IOException("Error accessing " + file.getPath, ioe)
+ }
val root = new DirEntry("/")
val dirs = mutable.HashMap[String, DirEntry]("/" -> root)
val enum = zipFile.entries()
diff --git a/src/reflect/scala/reflect/runtime/JavaMirrors.scala b/src/reflect/scala/reflect/runtime/JavaMirrors.scala
index 93861b0899..c9a9b74c54 100644
--- a/src/reflect/scala/reflect/runtime/JavaMirrors.scala
+++ b/src/reflect/scala/reflect/runtime/JavaMirrors.scala
@@ -18,7 +18,7 @@ import internal.pickling.ByteCodecs
import internal.pickling.UnPickler
import scala.collection.mutable.{ HashMap, ListBuffer }
import internal.Flags._
-import ReflectionUtils.{staticSingletonInstance, innerSingletonInstance}
+import ReflectionUtils.{staticSingletonInstance, innerSingletonInstance, scalacShouldntLoadClass}
import scala.language.existentials
import scala.runtime.{ScalaRunTime, BoxesRunTime}
@@ -696,8 +696,10 @@ private[reflect] trait JavaMirrors extends internal.SymbolTable with api.JavaUni
val parents = try {
parentsLevel += 1
val jsuperclazz = jclazz.getGenericSuperclass
- val superclazz = if (jsuperclazz == null) AnyTpe else typeToScala(jsuperclazz)
- superclazz :: (jclazz.getGenericInterfaces.toList map typeToScala)
+ val ifaces = jclazz.getGenericInterfaces.toList map typeToScala
+ val isAnnotation = JavaAccFlags(jclazz).isAnnotation
+ if (isAnnotation) AnnotationClass.tpe :: ClassfileAnnotationClass.tpe :: ifaces
+ else (if (jsuperclazz == null) AnyTpe else typeToScala(jsuperclazz)) :: ifaces
} finally {
parentsLevel -= 1
}
@@ -709,14 +711,21 @@ private[reflect] trait JavaMirrors extends internal.SymbolTable with api.JavaUni
def enter(sym: Symbol, mods: JavaAccFlags) =
( if (mods.isStatic) module.moduleClass else clazz ).info.decls enter sym
- for (jinner <- jclazz.getDeclaredClasses)
+ def enterEmptyCtorIfNecessary(): Unit = {
+ if (jclazz.getConstructors.isEmpty)
+ clazz.info.decls.enter(clazz.newClassConstructor(NoPosition))
+ }
+
+ for (jinner <- jclazz.getDeclaredClasses) {
jclassAsScala(jinner) // inner class is entered as a side-effect
// no need to call enter explicitly
+ }
pendingLoadActions ::= { () =>
jclazz.getDeclaredFields foreach (f => enter(jfieldAsScala(f), f.javaFlags))
jclazz.getDeclaredMethods foreach (m => enter(jmethodAsScala(m), m.javaFlags))
jclazz.getConstructors foreach (c => enter(jconstrAsScala(c), c.javaFlags))
+ enterEmptyCtorIfNecessary()
}
if (parentsLevel == 0) {
@@ -949,7 +958,7 @@ private[reflect] trait JavaMirrors extends internal.SymbolTable with api.JavaUni
val cls =
if (jclazz.isMemberClass && !nme.isImplClassName(jname))
lookupClass
- else if (jclazz.isLocalClass0 || isInvalidClassName(jname))
+ else if (jclazz.isLocalClass0 || scalacShouldntLoadClass(jname))
// local classes and implementation classes not preserved by unpickling - treat as Java
//
// upd. but only if they cannot be loaded as top-level classes
@@ -1171,6 +1180,17 @@ private[reflect] trait JavaMirrors extends internal.SymbolTable with api.JavaUni
var fullNameOfJavaClass = ownerClazz.getName
if (childOfClass || childOfTopLevel) fullNameOfJavaClass += "$"
fullNameOfJavaClass += clazz.name
+
+ // compactify (see SI-7779)
+ fullNameOfJavaClass = fullNameOfJavaClass match {
+ case PackageAndClassPattern(pack, clazzName) =>
+ // in a package
+ pack + compactifyName(clazzName)
+ case _ =>
+ // in the empty package
+ compactifyName(fullNameOfJavaClass)
+ }
+
if (clazz.isModuleClass) fullNameOfJavaClass += "$"
// println(s"ownerChildren = ${ownerChildren.toList}")
@@ -1180,6 +1200,8 @@ private[reflect] trait JavaMirrors extends internal.SymbolTable with api.JavaUni
noClass
}
+ private val PackageAndClassPattern = """(.*\.)(.*)$""".r
+
private def expandedName(sym: Symbol): String =
if (sym.isPrivate) nme.expandedName(sym.name.toTermName, sym.owner).toString
else sym.name.toString
@@ -1234,6 +1256,7 @@ private[reflect] trait JavaMirrors extends internal.SymbolTable with api.JavaUni
case TypeRef(_, ArrayClass, List(elemtpe)) => jArrayClass(typeToJavaClass(elemtpe))
case TypeRef(_, sym: ClassSymbol, _) => classToJava(sym.asClass)
case tpe @ TypeRef(_, sym: AliasTypeSymbol, _) => typeToJavaClass(tpe.dealias)
+ case SingleType(_, sym: ModuleSymbol) => classToJava(sym.moduleClass.asClass)
case _ => throw new NoClassDefFoundError("no Java class corresponding to "+tpe+" found")
}
}
diff --git a/src/reflect/scala/reflect/runtime/ReflectionUtils.scala b/src/reflect/scala/reflect/runtime/ReflectionUtils.scala
index 2db9706007..710ec02acd 100644
--- a/src/reflect/scala/reflect/runtime/ReflectionUtils.scala
+++ b/src/reflect/scala/reflect/runtime/ReflectionUtils.scala
@@ -78,4 +78,10 @@ private[scala] object ReflectionUtils {
accessor setAccessible true
accessor invoke outer
}
+
+ def isTraitImplementation(fileName: String) = fileName endsWith "$class.class"
+
+ def scalacShouldntLoadClassfile(fileName: String) = isTraitImplementation(fileName)
+
+ def scalacShouldntLoadClass(name: scala.reflect.internal.SymbolTable#Name) = scalacShouldntLoadClassfile(name + ".class")
}
diff --git a/src/reflect/scala/reflect/runtime/SymbolLoaders.scala b/src/reflect/scala/reflect/runtime/SymbolLoaders.scala
index 815cc0c885..3e01a6df02 100644
--- a/src/reflect/scala/reflect/runtime/SymbolLoaders.scala
+++ b/src/reflect/scala/reflect/runtime/SymbolLoaders.scala
@@ -5,6 +5,7 @@ package runtime
import internal.Flags
import java.lang.{Class => jClass, Package => jPackage}
import scala.collection.mutable
+import scala.reflect.runtime.ReflectionUtils.scalacShouldntLoadClass
private[reflect] trait SymbolLoaders { self: SymbolTable =>
@@ -90,14 +91,6 @@ private[reflect] trait SymbolLoaders { self: SymbolTable =>
}
}
- /** Is the given name valid for a top-level class? We exclude names with embedded $-signs, because
- * these are nested classes or anonymous classes,
- */
- def isInvalidClassName(name: Name) = {
- val dp = name pos '$'
- 0 < dp && dp < (name.length - 1)
- }
-
class PackageScope(pkgClass: Symbol) extends Scope(initFingerPrints = -1L) // disable fingerprinting as we do not know entries beforehand
with SynchronizedScope {
assert(pkgClass.isType)
@@ -107,7 +100,7 @@ private[reflect] trait SymbolLoaders { self: SymbolTable =>
val e = super.lookupEntry(name)
if (e != null)
e
- else if (isInvalidClassName(name) || (negatives contains name))
+ else if (scalacShouldntLoadClass(name) || (negatives contains name))
null
else {
val path =
diff --git a/src/reflect/scala/reflect/runtime/SynchronizedOps.scala b/src/reflect/scala/reflect/runtime/SynchronizedOps.scala
index 132470b2e7..6aa47a0405 100644
--- a/src/reflect/scala/reflect/runtime/SynchronizedOps.scala
+++ b/src/reflect/scala/reflect/runtime/SynchronizedOps.scala
@@ -9,10 +9,7 @@ private[reflect] trait SynchronizedOps extends internal.SymbolTable
// Names
- private lazy val nameLock = new Object
-
- override def newTermName(s: String): TermName = nameLock.synchronized { super.newTermName(s) }
- override def newTypeName(s: String): TypeName = nameLock.synchronized { super.newTypeName(s) }
+ override protected def synchronizeNames = true
// BaseTypeSeqs
diff --git a/src/repl/scala/tools/nsc/interpreter/IMain.scala b/src/repl/scala/tools/nsc/interpreter/IMain.scala
index 3eafa563bc..ee4ff59498 100644
--- a/src/repl/scala/tools/nsc/interpreter/IMain.scala
+++ b/src/repl/scala/tools/nsc/interpreter/IMain.scala
@@ -22,7 +22,7 @@ import scala.reflect.internal.util.{ BatchSourceFile, SourceFile }
import scala.tools.util.PathResolver
import scala.tools.nsc.io.AbstractFile
import scala.tools.nsc.typechecker.{ TypeStrings, StructuredTypeStrings }
-import scala.tools.nsc.util.{ ScalaClassLoader, stringFromWriter, stackTracePrefixString }
+import scala.tools.nsc.util.{ ScalaClassLoader, stringFromWriter, StackTraceOps }
import scala.tools.nsc.util.Exceptional.unwrap
import javax.script.{AbstractScriptEngine, Bindings, ScriptContext, ScriptEngine, ScriptEngineFactory, ScriptException, CompiledScript, Compilable}
@@ -726,7 +726,7 @@ class IMain(@BeanProperty val factory: ScriptEngineFactory, initialSettings: Set
def isWrapperInit(x: StackTraceElement) = cond(x.getClassName) {
case classNameRegex() if x.getMethodName == nme.CONSTRUCTOR.decoded => true
}
- val stackTrace = util.stackTracePrefixString(unwrapped)(!isWrapperInit(_))
+ val stackTrace = unwrapped stackTracePrefixString (!isWrapperInit(_))
withLastExceptionLock[String]({
directBind[Throwable]("lastException", unwrapped)(StdReplTags.tagOfThrowable, classTag[Throwable])
diff --git a/test/files/neg/macro-abort.check b/test/files/neg/macro-abort.check
new file mode 100644
index 0000000000..1e58add533
--- /dev/null
+++ b/test/files/neg/macro-abort.check
@@ -0,0 +1,4 @@
+Test_2.scala:2: error: aborted
+ Macros.abort
+ ^
+one error found
diff --git a/test/files/neg/macro-abort/Macros_1.scala b/test/files/neg/macro-abort/Macros_1.scala
new file mode 100644
index 0000000000..676c112098
--- /dev/null
+++ b/test/files/neg/macro-abort/Macros_1.scala
@@ -0,0 +1,9 @@
+import scala.language.experimental.macros
+import scala.reflect.macros.Context
+
+object Macros {
+ def impl(c: Context) = {
+ c.abort(c.enclosingPosition, "aborted")
+ }
+ def abort = macro impl
+} \ No newline at end of file
diff --git a/test/files/neg/macro-abort/Test_2.scala b/test/files/neg/macro-abort/Test_2.scala
new file mode 100644
index 0000000000..1d0a7a25dc
--- /dev/null
+++ b/test/files/neg/macro-abort/Test_2.scala
@@ -0,0 +1,3 @@
+object Test extends App {
+ Macros.abort
+} \ No newline at end of file
diff --git a/test/files/neg/macro-exception.check b/test/files/neg/macro-exception.check
new file mode 100644
index 0000000000..cee8b32ebd
--- /dev/null
+++ b/test/files/neg/macro-exception.check
@@ -0,0 +1,7 @@
+Test_2.scala:2: error: exception during macro expansion:
+java.lang.Exception
+ at Macros$.impl(Macros_1.scala:6)
+
+ Macros.exception
+ ^
+one error found
diff --git a/test/files/neg/macro-exception/Macros_1.scala b/test/files/neg/macro-exception/Macros_1.scala
new file mode 100644
index 0000000000..60e4020aec
--- /dev/null
+++ b/test/files/neg/macro-exception/Macros_1.scala
@@ -0,0 +1,9 @@
+import scala.language.experimental.macros
+import scala.reflect.macros.Context
+
+object Macros {
+ def impl(c: Context) = {
+ throw new Exception()
+ }
+ def exception = macro impl
+} \ No newline at end of file
diff --git a/test/files/neg/macro-exception/Test_2.scala b/test/files/neg/macro-exception/Test_2.scala
new file mode 100644
index 0000000000..d82b21f2b2
--- /dev/null
+++ b/test/files/neg/macro-exception/Test_2.scala
@@ -0,0 +1,3 @@
+object Test extends App {
+ Macros.exception
+} \ No newline at end of file
diff --git a/test/files/neg/macro-invalidusage-presuper.check b/test/files/neg/macro-invalidusage-presuper.check
index f63a0eef80..c0b1ec0248 100644
--- a/test/files/neg/macro-invalidusage-presuper.check
+++ b/test/files/neg/macro-invalidusage-presuper.check
@@ -1,4 +1,4 @@
-Macros_Test_2.scala:3: error: only type definitions and concrete field definitions allowed in early object initialization section
+Macros_Test_2.scala:3: error: only concrete field definitions allowed in early object initialization section
class D extends { def x = macro impl } with AnyRef
^
one error found
diff --git a/test/files/neg/t2796.check b/test/files/neg/t2796.check
index 4456a7fc19..22ee35a7e6 100644
--- a/test/files/neg/t2796.check
+++ b/test/files/neg/t2796.check
@@ -1,6 +1,9 @@
+t2796.scala:11: warning: early type members are deprecated. Move them to the regular body: the semantics are the same.
+ type X = Int // warn
+ ^
t2796.scala:7: warning: Implementation restriction: early definitions in traits are not initialized before the super class is initialized.
val abstractVal = "T1.abstractVal" // warn
^
error: No warnings can be incurred under -Xfatal-warnings.
-one warning found
+two warnings found
one error found
diff --git a/test/files/neg/t2796.flags b/test/files/neg/t2796.flags
index e8fb65d50c..d1b831ea87 100644
--- a/test/files/neg/t2796.flags
+++ b/test/files/neg/t2796.flags
@@ -1 +1 @@
--Xfatal-warnings \ No newline at end of file
+-deprecation -Xfatal-warnings \ No newline at end of file
diff --git a/test/files/neg/t2796.scala b/test/files/neg/t2796.scala
index 3bcc9df562..fa2f2358b9 100644
--- a/test/files/neg/t2796.scala
+++ b/test/files/neg/t2796.scala
@@ -8,10 +8,9 @@ trait T1 extends {
} with Base
trait T2 extends {
- type X = Int // okay
+ type X = Int // warn
} with Base
-
class C1 extends {
val abstractVal = "C1.abstractVal" // okay
} with Base
diff --git a/test/files/neg/t7020.check b/test/files/neg/t7020.check
new file mode 100644
index 0000000000..f9600ca7fc
--- /dev/null
+++ b/test/files/neg/t7020.check
@@ -0,0 +1,19 @@
+t7020.scala:3: warning: match may not be exhaustive.
+It would fail on the following inputs: List((x: Int forSome x not in (1, 2, 4, 5, 6, 7))), List((x: Int forSome x not in (1, 2, 4, 5, 6, 7)), _), List(1, _), List(2, _), List(4, _), List(5, _), List(6, _), List(7, _), List(??, _), List(_, _)
+ List(5) match {
+ ^
+t7020.scala:10: warning: match may not be exhaustive.
+It would fail on the following inputs: List((x: Int forSome x not in (1, 2, 4, 5, 6, 7))), List((x: Int forSome x not in (1, 2, 4, 5, 6, 7)), _), List(1, _), List(2, _), List(4, _), List(5, _), List(6, _), List(7, _), List(??, _), List(_, _)
+ List(5) match {
+ ^
+t7020.scala:17: warning: match may not be exhaustive.
+It would fail on the following inputs: List((x: Int forSome x not in (1, 2, 4, 5, 6, 7))), List((x: Int forSome x not in (1, 2, 4, 5, 6, 7)), _), List(1, _), List(2, _), List(4, _), List(5, _), List(6, _), List(7, _), List(??, _), List(_, _)
+ List(5) match {
+ ^
+t7020.scala:24: warning: match may not be exhaustive.
+It would fail on the following inputs: List((x: Int forSome x not in (1, 2, 4, 5, 6, 7))), List((x: Int forSome x not in (1, 2, 4, 5, 6, 7)), _), List(1, _), List(2, _), List(4, _), List(5, _), List(6, _), List(7, _), List(??, _), List(_, _)
+ List(5) match {
+ ^
+error: No warnings can be incurred under -Xfatal-warnings.
+four warnings found
+one error found
diff --git a/test/files/neg/t7020.flags b/test/files/neg/t7020.flags
new file mode 100644
index 0000000000..e8fb65d50c
--- /dev/null
+++ b/test/files/neg/t7020.flags
@@ -0,0 +1 @@
+-Xfatal-warnings \ No newline at end of file
diff --git a/test/files/neg/t7020.scala b/test/files/neg/t7020.scala
new file mode 100644
index 0000000000..cc5421bab1
--- /dev/null
+++ b/test/files/neg/t7020.scala
@@ -0,0 +1,30 @@
+object Test {
+ // warning was non-deterministic
+ List(5) match {
+ case 1 :: Nil | 2 :: Nil =>
+ case (x@(4 | 5 | 6)) :: Nil =>
+ case 7 :: Nil =>
+ case Nil =>
+ }
+
+ List(5) match {
+ case 1 :: Nil | 2 :: Nil =>
+ case (x@(4 | 5 | 6)) :: Nil =>
+ case 7 :: Nil =>
+ case Nil =>
+ }
+
+ List(5) match {
+ case 1 :: Nil | 2 :: Nil =>
+ case (x@(4 | 5 | 6)) :: Nil =>
+ case 7 :: Nil =>
+ case Nil =>
+ }
+
+ List(5) match {
+ case 1 :: Nil | 2 :: Nil =>
+ case (x@(4 | 5 | 6)) :: Nil =>
+ case 7 :: Nil =>
+ case Nil =>
+ }
+}
diff --git a/test/files/neg/t7501.check b/test/files/neg/t7501.check
new file mode 100644
index 0000000000..2ded07c7ed
--- /dev/null
+++ b/test/files/neg/t7501.check
@@ -0,0 +1,7 @@
+t7501_2.scala:2: error: value name is not a member of A
+ def foo(a: A) = a.name
+ ^
+t7501_2.scala:4: error: not found: type X
+ type TP = X // already failed before this fix
+ ^
+two errors found
diff --git a/test/files/neg/t7501/t7501_1.scala b/test/files/neg/t7501/t7501_1.scala
new file mode 100644
index 0000000000..323c327623
--- /dev/null
+++ b/test/files/neg/t7501/t7501_1.scala
@@ -0,0 +1,12 @@
+object Test2 {
+ def test[X](name: String) = 12
+}
+class strangeTest(x: Int) extends scala.annotation.StaticAnnotation
+
+trait A {
+ // When picking the type of `test`, the value parameter
+ // `x` was pickled with the owner `trait A`. On unpickling,
+ // it was taken to be a member!
+ @strangeTest(Test2.test("test"))
+ def test(x: String): Unit
+}
diff --git a/test/files/neg/t7501/t7501_2.scala b/test/files/neg/t7501/t7501_2.scala
new file mode 100644
index 0000000000..044caea3c3
--- /dev/null
+++ b/test/files/neg/t7501/t7501_2.scala
@@ -0,0 +1,5 @@
+object Test {
+ def foo(a: A) = a.name
+
+ type TP = X // already failed before this fix
+}
diff --git a/test/files/neg/t7694b.check b/test/files/neg/t7694b.check
new file mode 100644
index 0000000000..ea3d7736f8
--- /dev/null
+++ b/test/files/neg/t7694b.check
@@ -0,0 +1,7 @@
+t7694b.scala:8: error: type arguments [_3,_4] do not conform to trait L's type parameter bounds [A2,B2 <: A2]
+ def d = if (true) (null: L[A, A]) else (null: L[B, B])
+ ^
+t7694b.scala:9: error: type arguments [_1,_2] do not conform to trait L's type parameter bounds [A2,B2 <: A2]
+ val v = if (true) (null: L[A, A]) else (null: L[B, B])
+ ^
+two errors found
diff --git a/test/files/neg/t7752.check b/test/files/neg/t7752.check
new file mode 100644
index 0000000000..0a015d3f37
--- /dev/null
+++ b/test/files/neg/t7752.check
@@ -0,0 +1,27 @@
+t7752.scala:25: error: overloaded method value foo with alternatives:
+ [A](heading: String, rows: A*)(A,) <and>
+ [A, B](heading: (String, String), rows: (A, B)*)(A, B) <and>
+ [A, B, C](heading: (String, String, String), rows: (A, B, C)*)(A, B, C) <and>
+ [A, B, C, D](heading: (String, String, String, String), rows: (A, B, C, D)*)(A, B, C, D) <and>
+ [A, B, C, D, E](heading: (String, String, String, String, String), rows: (A, B, C, D, E)*)(A, B, C, D, E) <and>
+ [A, B, C, D, E, F](heading: (String, String, String, String, String, String), rows: (A, B, C, D, E, F)*)(A, B, C, D, E, F) <and>
+ [A, B, C, D, E, F, G](heading: (String, String, String, String, String, String, String), rows: (A, B, C, D, E, F, G)*)(A, B, C, D, E, F, G) <and>
+ [A, B, C, D, E, F, G, H](heading: (String, String, String, String, String, String, String, String), rows: (A, B, C, D, E, F, G, H)*)(A, B, C, D, E, F, G, H) <and>
+ [A, B, C, D, E, F, G, H, I](heading: (String, String, String, String, String, String, String, String, String), rows: (A, B, C, D, E, F, G, H, I)*)(A, B, C, D, E, F, G, H, I) <and>
+ [A, B, C, D, E, F, G, H, I, J](heading: (String, String, String, String, String, String, String, String, String, String), rows: (A, B, C, D, E, F, G, H, I, J)*)(A, B, C, D, E, F, G, H, I, J) <and>
+ [A, B, C, D, E, F, G, H, I, J, K](heading: (String, String, String, String, String, String, String, String, String, String, String), rows: (A, B, C, D, E, F, G, H, I, J, K)*)(A, B, C, D, E, F, G, H, I, J, K) <and>
+ [A, B, C, D, E, F, G, H, I, J, K, L](heading: (String, String, String, String, String, String, String, String, String, String, String, String), rows: (A, B, C, D, E, F, G, H, I, J, K, L)*)(A, B, C, D, E, F, G, H, I, J, K, L) <and>
+ [A, B, C, D, E, F, G, H, I, J, K, L, M](heading: (String, String, String, String, String, String, String, String, String, String, String, String, String), rows: (A, B, C, D, E, F, G, H, I, J, K, L, M)*)(A, B, C, D, E, F, G, H, I, J, K, L, M) <and>
+ [A, B, C, D, E, F, G, H, I, J, K, L, M, N](heading: (String, String, String, String, String, String, String, String, String, String, String, String, String, String), rows: (A, B, C, D, E, F, G, H, I, J, K, L, M, N)*)(A, B, C, D, E, F, G, H, I, J, K, L, M, N) <and>
+ [A, B, C, D, E, F, G, H, I, J, K, L, M, N, O](heading: (String, String, String, String, String, String, String, String, String, String, String, String, String, String, String), rows: (A, B, C, D, E, F, G, H, I, J, K, L, M, N, O)*)(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O) <and>
+ [A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P](heading: (String, String, String, String, String, String, String, String, String, String, String, String, String, String, String, String), rows: (A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P)*)(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P) <and>
+ [A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q](heading: (String, String, String, String, String, String, String, String, String, String, String, String, String, String, String, String, String), rows: (A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q)*)(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q) <and>
+ [A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R](heading: (String, String, String, String, String, String, String, String, String, String, String, String, String, String, String, String, String, String), rows: (A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R)*)(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R) <and>
+ [A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S](heading: (String, String, String, String, String, String, String, String, String, String, String, String, String, String, String, String, String, String, String), rows: (A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S)*)(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S) <and>
+ [A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T](heading: (String, String, String, String, String, String, String, String, String, String, String, String, String, String, String, String, String, String, String, String), rows: (A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T)*)(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T) <and>
+ [A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U](heading: (String, String, String, String, String, String, String, String, String, String, String, String, String, String, String, String, String, String, String, String, String), rows: (A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U)*)(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U) <and>
+ [A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V](heading: (String, String, String, String, String, String, String, String, String, String, String, String, String, String, String, String, String, String, String, String, String, String), rows: (A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V)*)(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V)
+ cannot be applied to (Int)
+ foo((1))
+ ^
+one error found
diff --git a/test/files/neg/t7752.scala b/test/files/neg/t7752.scala
new file mode 100644
index 0000000000..40ba2103b1
--- /dev/null
+++ b/test/files/neg/t7752.scala
@@ -0,0 +1,26 @@
+object Test {
+ def foo[A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V](heading: (String, String, String, String, String, String, String, String, String, String, String, String, String, String, String, String, String, String, String, String, String, String), rows: (A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V)*): Tuple22[A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V] = null
+ def foo[A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U](heading: (String, String, String, String, String, String, String, String, String, String, String, String, String, String, String, String, String, String, String, String, String), rows: (A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U)*): Tuple21[A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U] = null
+ def foo[A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T](heading: (String, String, String, String, String, String, String, String, String, String, String, String, String, String, String, String, String, String, String, String), rows: (A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T)*): Tuple20[A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T] = null
+ def foo[A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S](heading: (String, String, String, String, String, String, String, String, String, String, String, String, String, String, String, String, String, String, String), rows: (A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S)*): Tuple19[A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S] = null
+ def foo[A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R](heading: (String, String, String, String, String, String, String, String, String, String, String, String, String, String, String, String, String, String), rows: (A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R)*): Tuple18[A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R] = null
+ def foo[A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q](heading: (String, String, String, String, String, String, String, String, String, String, String, String, String, String, String, String, String), rows: (A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q)*): Tuple17[A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q] = null
+ def foo[A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P](heading: (String, String, String, String, String, String, String, String, String, String, String, String, String, String, String, String), rows: (A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P)*): Tuple16[A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P] = null
+ def foo[A, B, C, D, E, F, G, H, I, J, K, L, M, N, O](heading: (String, String, String, String, String, String, String, String, String, String, String, String, String, String, String), rows: (A, B, C, D, E, F, G, H, I, J, K, L, M, N, O)*): Tuple15[A,B,C,D,E,F,G,H,I,J,K,L,M,N,O] = null
+ def foo[A, B, C, D, E, F, G, H, I, J, K, L, M, N](heading: (String, String, String, String, String, String, String, String, String, String, String, String, String, String), rows: (A, B, C, D, E, F, G, H, I, J, K, L, M, N)*): Tuple14[A,B,C,D,E,F,G,H,I,J,K,L,M,N] = null
+ def foo[A, B, C, D, E, F, G, H, I, J, K, L, M](heading: (String, String, String, String, String, String, String, String, String, String, String, String, String), rows: (A, B, C, D, E, F, G, H, I, J, K, L, M)*): Tuple13[A,B,C,D,E,F,G,H,I,J,K,L,M] = null
+ def foo[A, B, C, D, E, F, G, H, I, J, K, L](heading: (String, String, String, String, String, String, String, String, String, String, String, String), rows: (A, B, C, D, E, F, G, H, I, J, K, L)*): Tuple12[A,B,C,D,E,F,G,H,I,J,K,L] = null
+ def foo[A, B, C, D, E, F, G, H, I, J, K](heading: (String, String, String, String, String, String, String, String, String, String, String), rows: (A, B, C, D, E, F, G, H, I, J, K)*): Tuple11[A,B,C,D,E,F,G,H,I,J,K] = null
+ def foo[A, B, C, D, E, F, G, H, I, J](heading: (String, String, String, String, String, String, String, String, String, String), rows: (A, B, C, D, E, F, G, H, I, J)*): Tuple10[A,B,C,D,E,F,G,H,I,J] = null
+ def foo[A, B, C, D, E, F, G, H, I](heading: (String, String, String, String, String, String, String, String, String), rows: (A, B, C, D, E, F, G, H, I)*): Tuple9[A,B,C,D,E,F,G,H,I] = null
+ def foo[A, B, C, D, E, F, G, H](heading: (String, String, String, String, String, String, String, String), rows: (A, B, C, D, E, F, G, H)*): Tuple8[A,B,C,D,E,F,G,H] = null
+ def foo[A, B, C, D, E, F, G](heading: (String, String, String, String, String, String, String), rows: (A, B, C, D, E, F, G)*): Tuple7[A,B,C,D,E,F,G] = null
+ def foo[A, B, C, D, E, F](heading: (String, String, String, String, String, String), rows: (A, B, C, D, E, F)*): Tuple6[A,B,C,D,E,F] = null
+ def foo[A, B, C, D, E](heading: (String, String, String, String, String), rows: (A, B, C, D, E)*): Tuple5[A,B,C,D,E] = null
+ def foo[A, B, C, D](heading: (String, String, String, String), rows: (A, B, C, D)*): Tuple4[A,B,C,D] = null
+ def foo[A, B, C](heading: (String, String, String), rows: (A, B, C)*): Tuple3[A,B,C] = null
+ def foo[A, B](heading: (String, String), rows: (A, B)*): Tuple2[A,B] = null
+ def foo[A](heading: String, rows: A*): Tuple1[A] = null
+
+ foo((1))
+} \ No newline at end of file
diff --git a/test/files/pos/t4760.scala b/test/files/pos/t4760.scala
new file mode 100644
index 0000000000..767e3847f4
--- /dev/null
+++ b/test/files/pos/t4760.scala
@@ -0,0 +1,34 @@
+
+class Test {
+ // parses
+ def f1 = {
+ import scala._;
+ }
+ // b.scala:7: error: ';' expected but '}' found.
+ // }
+ // ^
+ // one error found
+ def f2 = {
+ import scala._
+ }
+ def f2b = {
+ import scala.collection.mutable.{ Map => MMap }
+ }
+ def f(): Unit = {
+ locally {
+ import scala.util.Properties.lineSeparator
+ }
+ }
+
+ // parses
+ def f3 = {
+ import scala._
+ 5
+ }
+ locally { (x: Int) =>
+ import scala.util._
+ }
+ 1 match {
+ case 1 => import scala.concurrent._
+ }
+}
diff --git a/test/files/pos/t7014/ThreadSafety.java b/test/files/pos/t7014/ThreadSafety.java
new file mode 100644
index 0000000000..ed508804e3
--- /dev/null
+++ b/test/files/pos/t7014/ThreadSafety.java
@@ -0,0 +1,9 @@
+package t7014;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+@Retention(RetentionPolicy.RUNTIME) // must be exactly RUNTIME retention (those we parse)
+public @interface ThreadSafety {
+ ThreadSafetyLevel level();
+} \ No newline at end of file
diff --git a/test/files/pos/t7014/ThreadSafetyLevel.java b/test/files/pos/t7014/ThreadSafetyLevel.java
new file mode 100644
index 0000000000..4df1dc787a
--- /dev/null
+++ b/test/files/pos/t7014/ThreadSafetyLevel.java
@@ -0,0 +1,8 @@
+package t7014; // package needed due to other bug in scalac's java parser
+
+// since we parse eagerly, we have not yet parsed the classfile when parsing the annotation,
+// and on doing so, fail to find a symbol for the COMPLETELY_THREADSAFE reference
+// from the annotation's argument to the enum's member
+// for now, let's just not crash -- should implement lazy completing at some point
+@ThreadSafety(level=ThreadSafetyLevel.COMPLETELY_THREADSAFE)
+public enum ThreadSafetyLevel { COMPLETELY_THREADSAFE }
diff --git a/test/files/pos/t7014/t7014.scala b/test/files/pos/t7014/t7014.scala
new file mode 100644
index 0000000000..faec4c7740
--- /dev/null
+++ b/test/files/pos/t7014/t7014.scala
@@ -0,0 +1,4 @@
+package t7014
+
+import ThreadSafetyLevel.COMPLETELY_THREADSAFE // refer to annotation so it gets parsed
+ \ No newline at end of file
diff --git a/test/files/pos/t7486-named.scala b/test/files/pos/t7486-named.scala
new file mode 100644
index 0000000000..253293e5f1
--- /dev/null
+++ b/test/files/pos/t7486-named.scala
@@ -0,0 +1,8 @@
+
+object Test {
+ def fold(empty: Any) = ()
+ implicit val notAnnotatedImplicit = new {
+ fold(empty = 0)
+ def empty[A]: Any = ???
+ }
+}
diff --git a/test/pending/pos/t7486.scala b/test/files/pos/t7486.scala
index 6dd7f4c4ac..6dd7f4c4ac 100644
--- a/test/pending/pos/t7486.scala
+++ b/test/files/pos/t7486.scala
diff --git a/test/files/pos/t7694.scala b/test/files/pos/t7694.scala
new file mode 100644
index 0000000000..9852d5ec79
--- /dev/null
+++ b/test/files/pos/t7694.scala
@@ -0,0 +1,40 @@
+trait A
+trait B
+
+trait L[A2, B2 <: A2] {
+ def bar(a: Any, b: Any) = 0
+}
+
+object Lub {
+ // use named args transforms to include TypeTree(<lub.tpe>) in the AST before refchecks.
+ def foo(a: L[_, _], b: Any) = 0
+
+ foo(b = 0, a = if (true) (null: L[A, A]) else (null: L[B, B]))
+
+ (if (true) (null: L[A, A]) else (null: L[B, B])).bar(b = 0, a = 0)
+}
+
+/*
+The LUB ends up as:
+
+TypeRef(
+ TypeSymbol(
+ abstract trait L#7038[A2#7039, B2#7040 <: A2#7039] extends AnyRef#2197
+
+ )
+ args = List(
+ AbstractTypeRef(
+ AbstractType(
+ type _1#13680 >: A#7036 with B#7037 <: Object#1752
+ )
+ )
+ AbstractTypeRef(
+ AbstractType(
+ type _2#13681 >: A#7036 with B#7037 <: Object#1752
+ )
+ )
+ )
+)
+
+Note that type _2#13681 is *not* bound by _1#13680
+*/
diff --git a/test/files/pos/t7716.scala b/test/files/pos/t7716.scala
new file mode 100644
index 0000000000..40117051ed
--- /dev/null
+++ b/test/files/pos/t7716.scala
@@ -0,0 +1,16 @@
+object Test {
+ def test: Unit = {
+ val e: java.lang.Enum[_] = java.util.concurrent.TimeUnit.SECONDS
+ e match { case x => println(x) }
+
+
+ trait TA[X <: CharSequence]
+ val ta: TA[_] = new TA[String] {}
+
+ ta match {
+ case _ => println("hi")
+ }
+
+ def f(ta: TA[_]) = ta match { case _ => "hi" }
+ }
+}
diff --git a/test/files/pos/t7782.scala b/test/files/pos/t7782.scala
new file mode 100644
index 0000000000..037bdad673
--- /dev/null
+++ b/test/files/pos/t7782.scala
@@ -0,0 +1,25 @@
+package pack
+
+object Test {
+ import O.empty
+ empty // this will trigger completion of `test`
+ // with skolemizationLevel = 1
+}
+
+object O {
+ // order matters (!!!)
+
+ // this order breaks under 2.10.x
+ def empty[E]: C[E] = ???
+ def empty(implicit a: Any): Any = ???
+}
+
+abstract class C[E] {
+ def foo[BB](f: BB)
+ def test[B](f: B): Any = foo(f)
+ // error: no type parameters for method foo: (<param> f: BB)scala.this.Unit exist so that it can be applied to arguments (B&1)
+ // --- because ---
+ // argument expression's type is not compatible with formal parameter type;
+ // found : B&1
+ // required: ?BB
+}
diff --git a/test/files/pos/t7782b.scala b/test/files/pos/t7782b.scala
new file mode 100644
index 0000000000..09da4a5c5b
--- /dev/null
+++ b/test/files/pos/t7782b.scala
@@ -0,0 +1,25 @@
+package pack
+
+object Test {
+ import O.empty
+ empty // this will trigger completion of `test`
+ // with skolemizationLevel = 1
+}
+
+object O {
+ // order matters (!!!)
+
+ // this order breaks under 2.11.x
+ def empty(implicit a: Any): Any = ???
+ def empty[E]: C[E] = ???
+}
+
+abstract class C[E] {
+ def foo[BB](f: BB)
+ def test[B](f: B): Any = foo(f)
+ // error: no type parameters for method foo: (<param> f: BB)scala.this.Unit exist so that it can be applied to arguments (B&1)
+ // --- because ---
+ // argument expression's type is not compatible with formal parameter type;
+ // found : B&1
+ // required: ?BB
+}
diff --git a/test/files/pos/t7785.scala b/test/files/pos/t7785.scala
new file mode 100644
index 0000000000..1de693d137
--- /dev/null
+++ b/test/files/pos/t7785.scala
@@ -0,0 +1,34 @@
+import scala.language._
+
+trait R[+Repr]
+
+trait TraversableOps {
+ implicit val R: R[Nothing] = ???
+
+ // Removing the implicit parameter in both fixes the crash
+ // removing it into one only gives a valid compiler error.
+ trait OpsDup1[Repr] {
+ def force(implicit bf: R[Repr]): Any
+ }
+
+ trait Ops[Repr] extends OpsDup1[Repr] {
+ def force(implicit bf: R[Repr], dummy: DummyImplicit): Any
+ }
+
+ implicit def ct2ops[T, C[+X]](t: C[T]):
+ Ops[C[T]]
+
+ def force[T](t: Option[T]) =
+ // ct2ops(t).force
+ t.force //Fails compilation on 2.10.2.
+
+
+ /* To get a closer look at the crash:
+ :power
+ val foo = typeOf[C].member(TermName("foo"))
+ val pt = analyzer.HasMember(TermName("force"))
+ val instantiated = foo.info.finalResultType.instantiateTypeParams(foo.typeParams, foo.typeParams.map(TypeVar(_)))
+ instantiated <:< pt
+ */
+ def foo[T, C[+X]]: Ops[C[T]]
+}
diff --git a/test/files/pos/t942/Amount_1.java b/test/files/pos/t942/Amount_1.java
new file mode 100644
index 0000000000..d9d37d127b
--- /dev/null
+++ b/test/files/pos/t942/Amount_1.java
@@ -0,0 +1,5 @@
+import java.util.concurrent.Callable;
+
+public abstract class Amount_1<Q> extends Object
+ implements Callable<Amount_1<?>> {
+}
diff --git a/test/files/pos/t942/Test_2.scala b/test/files/pos/t942/Test_2.scala
new file mode 100644
index 0000000000..3cc84dae3c
--- /dev/null
+++ b/test/files/pos/t942/Test_2.scala
@@ -0,0 +1,3 @@
+abstract class Foo {
+ val x: Amount_1[Foo]
+}
diff --git a/test/files/run/WeakHashSetTest.scala b/test/files/run/WeakHashSetTest.scala
new file mode 100644
index 0000000000..3c8f380150
--- /dev/null
+++ b/test/files/run/WeakHashSetTest.scala
@@ -0,0 +1,174 @@
+object Test {
+ def main(args: Array[String]) {
+ val test = scala.reflect.internal.util.WeakHashSetTest
+ test.checkEmpty
+ test.checkPlusEquals
+ test.checkPlusEqualsCollisions
+ test.checkRehashing
+ test.checkRehashCollisions
+ test.checkFindOrUpdate
+ test.checkMinusEquals
+ test.checkMinusEqualsCollisions
+ test.checkClear
+ test.checkIterator
+ test.checkIteratorCollisions
+
+ // This test is commented out because it relies on gc behavior which isn't reliable enough in an automated environment
+ // test.checkRemoveUnreferencedObjects
+ }
+}
+
+// put the main test object in the same package as WeakHashSet because
+// it uses the package private "diagnostics" method
+package scala.reflect.internal.util {
+
+ object WeakHashSetTest {
+ // a class guaranteed to provide hash collisions
+ case class Collider(x : String) extends Comparable[Collider] with Serializable {
+ override def hashCode = 0
+ def compareTo(y : Collider) = this.x compareTo y.x
+ }
+
+ // basic emptiness check
+ def checkEmpty {
+ val hs = new WeakHashSet[String]()
+ assert(hs.size == 0)
+ hs.diagnostics.fullyValidate
+ }
+
+ // make sure += works
+ def checkPlusEquals {
+ val hs = new WeakHashSet[String]()
+ val elements = List("hello", "goodbye")
+ elements foreach (hs += _)
+ assert(hs.size == 2)
+ assert(hs contains "hello")
+ assert(hs contains "goodbye")
+ hs.diagnostics.fullyValidate
+ }
+
+ // make sure += works when there are collisions
+ def checkPlusEqualsCollisions {
+ val hs = new WeakHashSet[Collider]()
+ val elements = List("hello", "goodbye") map Collider
+ elements foreach (hs += _)
+ assert(hs.size == 2)
+ assert(hs contains Collider("hello"))
+ assert(hs contains Collider("goodbye"))
+ hs.diagnostics.fullyValidate
+ }
+
+ // add a large number of elements to force rehashing and then validate
+ def checkRehashing {
+ val size = 200
+ val hs = new WeakHashSet[String]()
+ val elements = (0 until size).toList map ("a" + _)
+ elements foreach (hs += _)
+ elements foreach {i => assert(hs contains i)}
+ hs.diagnostics.fullyValidate
+ }
+
+ // make sure rehashing works properly when the set is rehashed
+ def checkRehashCollisions {
+ val size = 200
+ val hs = new WeakHashSet[Collider]()
+ val elements = (0 until size).toList map {x => Collider("a" + x)}
+ elements foreach (hs += _)
+ elements foreach {i => assert(hs contains i)}
+ hs.diagnostics.fullyValidate
+ }
+
+ // test that unreferenced objects are removed
+ // not run in an automated environment because gc behavior can't be relied on
+ def checkRemoveUnreferencedObjects {
+ val size = 200
+ val hs = new WeakHashSet[Collider]()
+ val elements = (0 until size).toList map {x => Collider("a" + x)}
+ elements foreach (hs += _)
+ // don't throw the following into a retained collection so gc
+ // can remove them
+ for (i <- 0 until size) {
+ hs += Collider("b" + i)
+ }
+ System.gc()
+ Thread.sleep(1000)
+ assert(hs.size == 200)
+ elements foreach {i => assert(hs contains i)}
+ for (i <- 0 until size) {
+ assert(!(hs contains Collider("b" + i)))
+ }
+ hs.diagnostics.fullyValidate
+ }
+
+ // make sure findOrUpdate returns the originally entered element
+ def checkFindOrUpdate {
+ val size = 200
+ val hs = new WeakHashSet[Collider]()
+ val elements = (0 until size).toList map {x => Collider("a" + x)}
+ elements foreach {x => assert(hs findEntryOrUpdate x eq x)}
+ for (i <- 0 until size) {
+ // when we do a lookup the result should be the same reference we
+ // original put in
+ assert(hs findEntryOrUpdate(Collider("a" + i)) eq elements(i))
+ }
+ hs.diagnostics.fullyValidate
+ }
+
+ // check -= functionality
+ def checkMinusEquals {
+ val hs = new WeakHashSet[String]()
+ val elements = List("hello", "goodbye")
+ elements foreach (hs += _)
+ hs -= "goodbye"
+ assert(hs.size == 1)
+ assert(hs contains "hello")
+ assert(!(hs contains "goodbye"))
+ hs.diagnostics.fullyValidate
+ }
+
+ // check -= when there are collisions
+ def checkMinusEqualsCollisions {
+ val hs = new WeakHashSet[Collider]
+ val elements = List(Collider("hello"), Collider("goodbye"))
+ elements foreach (hs += _)
+ hs -= Collider("goodbye")
+ assert(hs.size == 1)
+ assert(hs contains Collider("hello"))
+ assert(!(hs contains Collider("goodbye")))
+ hs -= Collider("hello")
+ assert(hs.size == 0)
+ assert(!(hs contains Collider("hello")))
+ hs.diagnostics.fullyValidate
+ }
+
+ // check that the clear method actually cleans everything
+ def checkClear {
+ val size = 200
+ val hs = new WeakHashSet[String]()
+ val elements = (0 until size).toList map ("a" + _)
+ elements foreach (hs += _)
+ hs.clear()
+ assert(hs.size == 0)
+ elements foreach {i => assert(!(hs contains i))}
+ hs.diagnostics.fullyValidate
+ }
+
+ // check that the iterator covers all the contents
+ def checkIterator {
+ val hs = new WeakHashSet[String]()
+ val elements = (0 until 20).toList map ("a" + _)
+ elements foreach (hs += _)
+ assert(elements.iterator.toList.sorted == elements.sorted)
+ hs.diagnostics.fullyValidate
+ }
+
+ // check that the iterator covers all the contents even when there is a collision
+ def checkIteratorCollisions {
+ val hs = new WeakHashSet[Collider]
+ val elements = (0 until 20).toList map {x => Collider("a" + x)}
+ elements foreach (hs += _)
+ assert(elements.iterator.toList.sorted == elements.sorted)
+ hs.diagnostics.fullyValidate
+ }
+ }
+}
diff --git a/test/files/run/analyzerPlugins.scala b/test/files/run/analyzerPlugins.scala
index b20a734fe6..4b297ff220 100644
--- a/test/files/run/analyzerPlugins.scala
+++ b/test/files/run/analyzerPlugins.scala
@@ -8,7 +8,9 @@ object Test extends DirectTest {
def code = """
class testAnn extends annotation.TypeConstraint
- class A(param: Double) extends { val x: Int = 1; val y = "two"; type T = A } with AnyRef {
+ class A(param: Double) extends { val x: Int = 1; val y = "two" } with AnyRef {
+ type T = A
+
val inferField = ("str": @testAnn)
val annotField: Boolean @testAnn = false
@@ -81,7 +83,7 @@ object Test extends DirectTest {
output += s"pluginsPt($pt, ${treeClass(tree)})"
pt
}
-
+
override def pluginsTyped(tpe: Type, typer: Typer, tree: Tree, mode: Mode, pt: Type): Type = {
output += s"pluginsTyped($tpe, ${treeClass(tree)})"
tpe
diff --git a/test/files/run/deprecate-early-type-defs.check b/test/files/run/deprecate-early-type-defs.check
new file mode 100644
index 0000000000..1ee01df13e
--- /dev/null
+++ b/test/files/run/deprecate-early-type-defs.check
@@ -0,0 +1,3 @@
+deprecate-early-type-defs.scala:1: warning: early type members are deprecated. Move them to the regular body: the semantics are the same.
+object Test extends { type T = Int } with App
+ ^
diff --git a/test/files/run/deprecate-early-type-defs.flags b/test/files/run/deprecate-early-type-defs.flags
new file mode 100644
index 0000000000..c36e713ab8
--- /dev/null
+++ b/test/files/run/deprecate-early-type-defs.flags
@@ -0,0 +1 @@
+-deprecation \ No newline at end of file
diff --git a/test/files/run/deprecate-early-type-defs.scala b/test/files/run/deprecate-early-type-defs.scala
new file mode 100644
index 0000000000..99e42166f2
--- /dev/null
+++ b/test/files/run/deprecate-early-type-defs.scala
@@ -0,0 +1 @@
+object Test extends { type T = Int } with App \ No newline at end of file
diff --git a/test/files/run/macro-auto-duplicate.check b/test/files/run/macro-auto-duplicate.check
new file mode 100644
index 0000000000..d81cc0710e
--- /dev/null
+++ b/test/files/run/macro-auto-duplicate.check
@@ -0,0 +1 @@
+42
diff --git a/test/files/run/macro-auto-duplicate/Macros_1.scala b/test/files/run/macro-auto-duplicate/Macros_1.scala
new file mode 100644
index 0000000000..e3df05ba50
--- /dev/null
+++ b/test/files/run/macro-auto-duplicate/Macros_1.scala
@@ -0,0 +1,17 @@
+import scala.reflect.macros.Context
+import language.experimental.macros
+
+object Macros {
+ def impl(c: Context) = {
+ import c.universe._
+ val x = Ident(newTermName("x"))
+ def defAndUseX(rhs: Tree) = {
+ Block(List(ValDef(NoMods, newTermName("x"), TypeTree(), rhs)), x)
+ }
+ val xi4 = defAndUseX(Literal(Constant(4)))
+ val xs2 = defAndUseX(Literal(Constant("2")))
+ c.Expr[String](Apply(Select(xi4, newTermName("$plus")), List(xs2)))
+ }
+
+ def foo = macro impl
+} \ No newline at end of file
diff --git a/test/files/run/macro-auto-duplicate/Test_2.scala b/test/files/run/macro-auto-duplicate/Test_2.scala
new file mode 100644
index 0000000000..f697da6020
--- /dev/null
+++ b/test/files/run/macro-auto-duplicate/Test_2.scala
@@ -0,0 +1,3 @@
+object Test extends App {
+ println(Macros.foo)
+} \ No newline at end of file
diff --git a/test/files/run/macro-duplicate/Impls_Macros_1.scala b/test/files/run/macro-duplicate/Impls_Macros_1.scala
index af80147a90..85a581585f 100644
--- a/test/files/run/macro-duplicate/Impls_Macros_1.scala
+++ b/test/files/run/macro-duplicate/Impls_Macros_1.scala
@@ -26,4 +26,4 @@ object Macros {
}
def foo = macro impl
-} \ No newline at end of file
+}
diff --git a/test/files/run/reflection-magicsymbols-invoke.check b/test/files/run/reflection-magicsymbols-invoke.check
index f5258efeb7..352aefaf25 100644
--- a/test/files/run/reflection-magicsymbols-invoke.check
+++ b/test/files/run/reflection-magicsymbols-invoke.check
@@ -82,7 +82,7 @@ Array
it's important to print the list of Array's members
if some of them change (possibly, adding and/or removing magic symbols), we must update this test
constructor Array: (_length: Int)Array[T]
-constructor Object: ()java.lang.Object
+constructor Cloneable: ()java.lang.Cloneable
method !=: (x$1: Any)Boolean
method !=: (x$1: AnyRef)Boolean
method ##: ()Int
diff --git a/test/files/run/repl-trim-stack-trace.scala b/test/files/run/repl-trim-stack-trace.scala
index bbf46f2f19..0f4a43bc85 100644
--- a/test/files/run/repl-trim-stack-trace.scala
+++ b/test/files/run/repl-trim-stack-trace.scala
@@ -13,6 +13,7 @@ f: Nothing
scala> f
java.lang.Exception: Uh-oh
at .f(<console>:7)
+ ... 69 elided
scala> def f = throw new Exception("")
f: Nothing
@@ -20,6 +21,7 @@ f: Nothing
scala> f
java.lang.Exception:
at .f(<console>:7)
+ ... 69 elided
scala> def f = throw new Exception
f: Nothing
@@ -27,7 +29,16 @@ f: Nothing
scala> f
java.lang.Exception
at .f(<console>:7)
+ ... 69 elided
scala> """
+ // normalize the "elided" lines because the frame count depends on test context
+ lazy val elided = """(\s+\.{3} )\d+( elided)""".r
+ def normalize(line: String) = line match {
+ case elided(ellipsis, suffix) => s"$ellipsis???$suffix"
+ case s => s
+ }
+ override def eval() = super.eval() map normalize
+ override def expected = super.expected map normalize
}
diff --git a/test/files/run/t6392b.check b/test/files/run/t6392b.check
index 2afc48495f..1ccfced1c6 100644
--- a/test/files/run/t6392b.check
+++ b/test/files/run/t6392b.check
@@ -1 +1 @@
-ModuleDef(Modifiers(), TermName("C"), Template(List(Select(Ident(scala#PK), TypeName("AnyRef")#TPE)), emptyValDef, List(DefDef(Modifiers(), nme.CONSTRUCTOR, List(), List(List()), TypeTree(), Block(List(Apply(Select(Super(This(TypeName("C")), tpnme.EMPTY), nme.CONSTRUCTOR#PCTOR), List())), Literal(Constant(())))))))
+ModuleDef(Modifiers(), TermName("C")#MOD, Template(List(Select(Ident(scala#PK), TypeName("AnyRef")#TPE)), emptyValDef, List(DefDef(Modifiers(), nme.CONSTRUCTOR#PCTOR, List(), List(List()), TypeTree(), Block(List(Apply(Select(Super(This(TypeName("C")), tpnme.EMPTY), nme.CONSTRUCTOR#PCTOR), List())), Literal(Constant(())))))))
diff --git a/test/files/run/t6989.check b/test/files/run/t6989.check
index 8943792115..43d4bbaf02 100644
--- a/test/files/run/t6989.check
+++ b/test/files/run/t6989.check
@@ -101,6 +101,12 @@ isProtected = false
isPublic = false
privateWithin = <none>
============
+sym = constructor $PrivateJavaClass, signature = ()JavaClass_1.this.$PrivateJavaClass, owner = class $PrivateJavaClass
+isPrivate = false
+isProtected = false
+isPublic = true
+privateWithin = <none>
+============
sym = value this$0, signature = foo.JavaClass_1, owner = class $PrivateJavaClass
isPrivate = false
isProtected = false
@@ -119,6 +125,12 @@ isProtected = true
isPublic = false
privateWithin = package foo
============
+sym = constructor $ProtectedJavaClass, signature = ()JavaClass_1.this.$ProtectedJavaClass, owner = class $ProtectedJavaClass
+isPrivate = false
+isProtected = false
+isPublic = true
+privateWithin = <none>
+============
sym = value this$0, signature = foo.JavaClass_1, owner = class $ProtectedJavaClass
isPrivate = false
isProtected = false
@@ -173,6 +185,12 @@ isProtected = false
isPublic = false
privateWithin = <none>
============
+sym = constructor PrivateStaticJavaClass, signature = ()foo.JavaClass_1.PrivateStaticJavaClass, owner = class PrivateStaticJavaClass
+isPrivate = false
+isProtected = false
+isPublic = true
+privateWithin = <none>
+============
sym = object PrivateStaticJavaClass, signature = foo.JavaClass_1.PrivateStaticJavaClass.type, owner = object JavaClass_1
isPrivate = true
isProtected = false
@@ -185,6 +203,12 @@ isProtected = false
isPublic = false
privateWithin = <none>
============
+sym = constructor ProtectedStaticJavaClass, signature = ()foo.JavaClass_1.ProtectedStaticJavaClass, owner = class ProtectedStaticJavaClass
+isPrivate = false
+isProtected = false
+isPublic = true
+privateWithin = <none>
+============
sym = object ProtectedStaticJavaClass, signature = foo.JavaClass_1.ProtectedStaticJavaClass.type, owner = object JavaClass_1
isPrivate = true
isProtected = false
diff --git a/test/files/run/t7407.check b/test/files/run/t7407.check
new file mode 100644
index 0000000000..e965047ad7
--- /dev/null
+++ b/test/files/run/t7407.check
@@ -0,0 +1 @@
+Hello
diff --git a/test/files/run/t7407.flags b/test/files/run/t7407.flags
new file mode 100644
index 0000000000..c8547a27dc
--- /dev/null
+++ b/test/files/run/t7407.flags
@@ -0,0 +1 @@
+-Ynooptimise -Ybackend:GenBCode
diff --git a/test/files/run/t7407.scala b/test/files/run/t7407.scala
new file mode 100644
index 0000000000..cf67602126
--- /dev/null
+++ b/test/files/run/t7407.scala
@@ -0,0 +1,11 @@
+// SI-7407
+object Test {
+
+ def main(args: Array[String]) { println(foo) }
+
+ def foo: String = {
+ try return "Hello" finally 10 match {case x => ()}
+ }
+
+}
+
diff --git a/test/files/run/t7407b.check b/test/files/run/t7407b.check
new file mode 100644
index 0000000000..f30294447b
--- /dev/null
+++ b/test/files/run/t7407b.check
@@ -0,0 +1,2 @@
+Hello
+abc
diff --git a/test/files/run/t7407b.flags b/test/files/run/t7407b.flags
new file mode 100644
index 0000000000..c8547a27dc
--- /dev/null
+++ b/test/files/run/t7407b.flags
@@ -0,0 +1 @@
+-Ynooptimise -Ybackend:GenBCode
diff --git a/test/files/run/t7407b.scala b/test/files/run/t7407b.scala
new file mode 100644
index 0000000000..b0c00878b5
--- /dev/null
+++ b/test/files/run/t7407b.scala
@@ -0,0 +1,20 @@
+object Test {
+
+ def main(args: Array[String]) {
+ println(foo(true))
+ println(foo(false))
+ }
+
+ def foo(b: Boolean): String = {
+ try {
+ if(b)
+ return "Hello"
+ else
+ "abc"
+ } finally {
+ 10 match {case x => ()}
+ }
+ }
+
+}
+
diff --git a/test/files/run/t7510.check b/test/files/run/t7510.check
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/test/files/run/t7510.check
diff --git a/test/files/run/t7510/Ann_1.java b/test/files/run/t7510/Ann_1.java
new file mode 100644
index 0000000000..c8c5b2035f
--- /dev/null
+++ b/test/files/run/t7510/Ann_1.java
@@ -0,0 +1,4 @@
+package foo;
+
+public @interface Ann_1 {
+} \ No newline at end of file
diff --git a/test/files/run/t7510/Test_2.scala b/test/files/run/t7510/Test_2.scala
new file mode 100644
index 0000000000..7d7a95e0f2
--- /dev/null
+++ b/test/files/run/t7510/Test_2.scala
@@ -0,0 +1,9 @@
+import scala.reflect.runtime.universe._
+import scala.reflect.runtime.{currentMirror => cm}
+import scala.tools.reflect.ToolBox
+
+object Test extends App {
+ val tb = cm.mkToolBox()
+ tb.compile(tb.parse("@foo.Ann_1 class C"))
+}
+
diff --git a/test/files/run/t7763.scala b/test/files/run/t7763.scala
new file mode 100644
index 0000000000..638077e64a
--- /dev/null
+++ b/test/files/run/t7763.scala
@@ -0,0 +1,20 @@
+object Test {
+ class A; class B
+ def main(args: Array[String]) {
+ def noExpectedType() {
+ a().asInstanceOf[B] // cast elided!
+ }
+ def withExpectedType(): B = {
+ a().asInstanceOf[B]
+ }
+ def test(a: => Any) = try {
+ a
+ sys.error("no CCE!")
+ } catch {case _: ClassCastException => }
+
+ test(noExpectedType())
+ test(withExpectedType())
+ }
+
+ def a(): Object = new A
+}
diff --git a/test/files/run/t7775.scala b/test/files/run/t7775.scala
new file mode 100644
index 0000000000..5fb0327611
--- /dev/null
+++ b/test/files/run/t7775.scala
@@ -0,0 +1,17 @@
+import scala.concurrent.{duration, future, Await, ExecutionContext}
+import scala.tools.nsc.Settings
+import ExecutionContext.Implicits.global
+
+// Was failing pretty regularly with a ConcurrentModificationException as
+// WrappedProperties#systemProperties iterated directly over the mutable
+// global system properties map.
+object Test {
+ def main(args: Array[String]) {
+ val tries = 1000 // YMMV
+ val compiler = future {
+ for(_ <- 1 to tries) new Settings(_ => {})
+ }
+ for(i <- 1 to tries * 10) System.setProperty(s"foo$i", i.toString)
+ Await.result(compiler, duration.Duration.Inf)
+ }
+}
diff --git a/test/files/run/t7779.scala b/test/files/run/t7779.scala
new file mode 100644
index 0000000000..db32cb751f
--- /dev/null
+++ b/test/files/run/t7779.scala
@@ -0,0 +1,67 @@
+// -Xmax-classfile-length doesn't compress top-level classes.
+// class :::::::::::::::::::::::::::::::::::::::::::::::::
+
+trait Marker
+
+class Short extends Marker
+
+// We just test with member classes
+object O {
+ object ::::::::::::::::::::::::::::::::::::::::::::::::: extends Marker
+}
+class C {
+ class D {
+ class ::::::::::::::::::::::::::::::::::::::::::::::::: extends Marker
+ }
+}
+
+package pack {
+ // abbreviates to: $colon$colon$colon$colon$colon$colon$colon$colon$colon$colon$colon$colon$colon$colon$colon$colon$colon$colon$colon$colon$colon$colon$colon$colon$colon$colon$colon$colon$colon$colon$colon$colon$colon$colon$colon$colon$colon$colon$colon$colon$colon$colon$colon$colon$colon$colon$colon$colon$colon to $read$$iw$$iw$$colon$colon$colon$colon$colon$colon$colon$colon$$$$c39b3f245029fbed9732fc888d44231b$$$$on$colon$colon$colon$colon$colon$colon$colon$colon$colon$colon
+ // class :::::::::::::::::::::::::::::::::::::::::::::::::
+
+ class Short extends Marker
+
+ // We just test with member classes
+ object O {
+ object ::::::::::::::::::::::::::::::::::::::::::::::::: extends Marker
+ }
+ class C {
+ class D {
+ class ::::::::::::::::::::::::::::::::::::::::::::::::: extends Marker
+ }
+ }
+ package p2 {
+ class Short extends Marker
+
+ object O {
+ object ::::::::::::::::::::::::::::::::::::::::::::::::: extends Marker
+ }
+ class C {
+ class D {
+ class ::::::::::::::::::::::::::::::::::::::::::::::::: extends Marker
+ }
+ }
+ }
+}
+
+
+object Test extends App {
+ import reflect.runtime.universe._
+ def test[T: TypeTag] = {
+ val tt = typeTag[T]
+ val clz = tt.mirror.runtimeClass(tt.tpe)
+ assert(classOf[Marker].isAssignableFrom(clz), clz.toString)
+ }
+
+ test[Short]
+ test[O.:::::::::::::::::::::::::::::::::::::::::::::::::.type]
+ test[C#D#`:::::::::::::::::::::::::::::::::::::::::::::::::`]
+
+ test[pack.Short]
+ test[pack.O.:::::::::::::::::::::::::::::::::::::::::::::::::.type]
+ test[pack.C#D#`:::::::::::::::::::::::::::::::::::::::::::::::::`]
+
+ test[pack.p2.Short]
+ test[pack.p2.O.:::::::::::::::::::::::::::::::::::::::::::::::::.type]
+ test[pack.p2.C#D#`:::::::::::::::::::::::::::::::::::::::::::::::::`]
+}
diff --git a/test/files/run/toolbox_current_run_compiles.check b/test/files/run/toolbox_current_run_compiles.check
new file mode 100644
index 0000000000..da29283aaa
--- /dev/null
+++ b/test/files/run/toolbox_current_run_compiles.check
@@ -0,0 +1,2 @@
+true
+false
diff --git a/test/files/run/toolbox_current_run_compiles.scala b/test/files/run/toolbox_current_run_compiles.scala
new file mode 100644
index 0000000000..b48c998e64
--- /dev/null
+++ b/test/files/run/toolbox_current_run_compiles.scala
@@ -0,0 +1,28 @@
+package pkg {
+ import scala.reflect.macros.Context
+ import scala.language.experimental.macros
+
+ object Macros {
+ def impl[T: c.WeakTypeTag](c: Context) = {
+ import c.universe._
+ val sym = c.weakTypeOf[T].typeSymbol
+ val g = c.universe.asInstanceOf[scala.tools.nsc.Global]
+ c.Expr[Boolean](Literal(Constant(g.currentRun.compiles(sym.asInstanceOf[g.Symbol]))))
+ }
+ def compiles[T] = macro impl[T]
+ }
+}
+
+import scala.reflect.runtime.universe._
+import scala.reflect.runtime.{universe => ru}
+import scala.tools.reflect.ToolBox
+
+object Test extends App {
+ val cm = ru.runtimeMirror(getClass.getClassLoader)
+ val toolbox = cm.mkToolBox()
+ toolbox.eval(toolbox.parse("""{
+ class C
+ println(pkg.Macros.compiles[C])
+ println(pkg.Macros.compiles[Object])
+ }"""))
+} \ No newline at end of file
diff --git a/test/files/run/typed-annotated.check b/test/files/run/typed-annotated.check
new file mode 100644
index 0000000000..d81cc0710e
--- /dev/null
+++ b/test/files/run/typed-annotated.check
@@ -0,0 +1 @@
+42
diff --git a/test/files/run/typed-annotated/Macros_1.scala b/test/files/run/typed-annotated/Macros_1.scala
new file mode 100644
index 0000000000..dd18c63d90
--- /dev/null
+++ b/test/files/run/typed-annotated/Macros_1.scala
@@ -0,0 +1,17 @@
+import scala.reflect.macros.Context
+import language.experimental.macros
+
+class ann extends scala.annotation.StaticAnnotation
+
+object Macros {
+ def impl(c: Context) = {
+ import c.universe._
+ // val tpt = Annotated(Apply(Select(New(Ident(newTypeName("ann"))), nme.CONSTRUCTOR), List()), Ident(newTypeName("Int")))
+ val tpt = Annotated(Apply(Select(New(Ident(newTypeName("ann"))), nme.CONSTRUCTOR), List()), TypeTree(weakTypeOf[Int]))
+ c.Expr[Unit](Block(
+ List(ValDef(Modifiers(), newTermName("x"), tpt, Literal(Constant(42)))),
+ Apply(Ident(newTermName("println")), List(Ident(newTermName("x"))))))
+ }
+
+ def foo = macro impl
+} \ No newline at end of file
diff --git a/test/files/run/typed-annotated/Test_2.scala b/test/files/run/typed-annotated/Test_2.scala
new file mode 100644
index 0000000000..acfddae942
--- /dev/null
+++ b/test/files/run/typed-annotated/Test_2.scala
@@ -0,0 +1,3 @@
+object Test extends App {
+ Macros.foo
+} \ No newline at end of file
diff --git a/test/junit/scala/reflect/io/ZipArchiveTest.scala b/test/junit/scala/reflect/io/ZipArchiveTest.scala
new file mode 100644
index 0000000000..1bcd06f5a7
--- /dev/null
+++ b/test/junit/scala/reflect/io/ZipArchiveTest.scala
@@ -0,0 +1,37 @@
+package scala.reflect.io
+
+import java.io.{IOException, File => JFile}
+import org.junit.Assert._
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.JUnit4
+
+@RunWith(classOf[JUnit4])
+class ZipArchiveTest {
+
+ @Test
+ def corruptZip {
+ val f = JFile.createTempFile("test", ".jar")
+ val fza = new FileZipArchive(f)
+ try {
+ fza.iterator
+ } catch {
+ case x: IOException =>
+ assertTrue(x.getMessage, x.getMessage.contains(f.getPath))
+ } finally {
+ f.delete()
+ }
+ }
+
+ @Test
+ def missingFile {
+ val f = new JFile("xxx.does.not.exist")
+ val fza = new FileZipArchive(f)
+ try {
+ fza.iterator
+ } catch {
+ case x: IOException =>
+ assertTrue(x.getMessage, x.getMessage.contains(f.getPath))
+ }
+ }
+}
diff --git a/test/junit/scala/tools/nsc/util/StackTraceTest.scala b/test/junit/scala/tools/nsc/util/StackTraceTest.scala
new file mode 100644
index 0000000000..e7654244c5
--- /dev/null
+++ b/test/junit/scala/tools/nsc/util/StackTraceTest.scala
@@ -0,0 +1,159 @@
+
+package scala.tools.nsc.util
+
+import scala.language.reflectiveCalls
+import scala.util._
+import PartialFunction.cond
+import Properties.isJavaAtLeast
+
+import org.junit.Assert._
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.JUnit4
+
+trait Expecting {
+ /*
+ import org.expecty.Expecty
+ final val expect = new Expecty
+ */
+}
+
+
+@RunWith(classOf[JUnit4])
+class StackTraceTest extends Expecting {
+ // formerly an enum
+ val CausedBy = "Caused by: "
+ val Suppressed = "Suppressed: "
+
+ // throws
+ def sample = throw new RuntimeException("Point of failure")
+ def sampler: String = sample
+
+ // repackage with message
+ def resample: String = try { sample } catch { case e: Throwable => throw new RuntimeException("resample", e) }
+ def resampler: String = resample
+
+ // simple wrapper
+ def wrapper: String = try { sample } catch { case e: Throwable => throw new RuntimeException(e) }
+ // another onion skin
+ def rewrapper: String = try { wrapper } catch { case e: Throwable => throw new RuntimeException(e) }
+ def rewrapperer: String = rewrapper
+
+ // only an insane wretch would do this
+ def insane: String = try { sample } catch {
+ case e: Throwable =>
+ val t = new RuntimeException(e)
+ e initCause t
+ throw t
+ }
+ def insaner: String = insane
+
+ /** Java 7 */
+ val suppressable = isJavaAtLeast("1.7")
+ type Suppressing = { def addSuppressed(t: Throwable): Unit }
+
+ def repressed: String = try { sample } catch {
+ case e: Throwable =>
+ val t = new RuntimeException("My problem")
+ if (suppressable) {
+ t.asInstanceOf[Suppressing] addSuppressed e
+ }
+ throw t
+ }
+ def represser: String = repressed
+
+ // evaluating s should throw, p trims stack trace, t is the test of resulting trace string
+ def probe(s: =>String)(p: StackTraceElement => Boolean)(t: String => Unit): Unit = {
+ Try(s) recover { case e => e stackTracePrefixString p } match {
+ case Success(s) => t(s)
+ case Failure(e) => throw e
+ }
+ }
+
+ @Test def showsAllTrace() {
+ probe(sampler)(_ => true) { s =>
+ val res = s.lines.toList
+ /*
+ expect {
+ res.length > 5 // many lines
+ // these expectations may be framework-specific
+ //s contains "sbt.TestFramework"
+ //res.last contains "java.lang.Thread"
+ }
+ */
+ assert (res.length > 5)
+ }
+ }
+ @Test def showsOnlyPrefix() = probe(sample)(_.getMethodName == "sample") { s =>
+ val res = s.lines.toList
+ /*
+ expect {
+ res.length == 3 // summary + one frame + elision
+ }
+ */
+ assert (res.length == 3)
+ }
+ @Test def showsCause() = probe(resampler)(_.getMethodName != "resampler") { s =>
+ val res = s.lines.toList
+ /*
+ expect {
+ res.length == 6 // summary + one frame + elision, caused by + one frame + elision
+ res exists (_ startsWith CausedBy.toString)
+ }
+ */
+ assert (res.length == 6)
+ assert (res exists (_ startsWith CausedBy.toString))
+ }
+ @Test def showsWrappedExceptions() = probe(rewrapperer)(_.getMethodName != "rewrapperer") { s =>
+ val res = s.lines.toList
+ /*
+ expect {
+ res.length == 9 // summary + one frame + elision times three
+ res exists (_ startsWith CausedBy.toString)
+ (res collect {
+ case s if s startsWith CausedBy.toString => s
+ }).size == 2
+ }
+ */
+ assert (res.length == 9)
+ assert (res exists (_ startsWith CausedBy.toString))
+ assert ((res collect {
+ case s if s startsWith CausedBy.toString => s
+ }).size == 2)
+ }
+ @Test def dontBlowOnCycle() = probe(insaner)(_.getMethodName != "insaner") { s =>
+ val res = s.lines.toList
+ /*
+ expect {
+ res.length == 7 // summary + one frame + elision times two with extra frame
+ res exists (_ startsWith CausedBy.toString)
+ }
+ */
+ assert (res.length == 7)
+ assert (res exists (_ startsWith CausedBy.toString))
+ }
+
+ /** Java 7, but shouldn't bomb on Java 6.
+ *
+java.lang.RuntimeException: My problem
+ at scala.tools.nsc.util.StackTraceTest.repressed(StackTraceTest.scala:56)
+ ... 27 elided
+ Suppressed: java.lang.RuntimeException: Point of failure
+ at scala.tools.nsc.util.StackTraceTest.sample(StackTraceTest.scala:29)
+ at scala.tools.nsc.util.StackTraceTest.repressed(StackTraceTest.scala:54)
+ ... 27 more
+ */
+ @Test def showsSuppressed() = probe(represser)(_.getMethodName != "represser") { s =>
+ val res = s.lines.toList
+ if (suppressable) {
+ assert (res.length == 7)
+ assert (res exists (_.trim startsWith Suppressed.toString))
+ }
+ /*
+ expect {
+ res.length == 7
+ res exists (_ startsWith " " + Suppressed.toString)
+ }
+ */
+ }
+}
diff --git a/test/pending/pos/t7778/Foo_1.java b/test/pending/pos/t7778/Foo_1.java
new file mode 100644
index 0000000000..65431ffd46
--- /dev/null
+++ b/test/pending/pos/t7778/Foo_1.java
@@ -0,0 +1,6 @@
+import java.util.concurrent.Callable;
+
+public abstract class Foo_1<T> implements Callable<Foo_1<Object>.Inner> {
+ public abstract class Inner {
+ }
+}
diff --git a/test/pending/pos/t7778/Test_2.scala b/test/pending/pos/t7778/Test_2.scala
new file mode 100644
index 0000000000..306303a99e
--- /dev/null
+++ b/test/pending/pos/t7778/Test_2.scala
@@ -0,0 +1,3 @@
+class Test {
+ null: Foo_1[_]
+}
diff --git a/test/pending/run/t7733.check b/test/pending/run/t7733.check
new file mode 100644
index 0000000000..19765bd501
--- /dev/null
+++ b/test/pending/run/t7733.check
@@ -0,0 +1 @@
+null
diff --git a/test/pending/run/t7733/Separate_1.scala b/test/pending/run/t7733/Separate_1.scala
new file mode 100644
index 0000000000..a326ecd53e
--- /dev/null
+++ b/test/pending/run/t7733/Separate_1.scala
@@ -0,0 +1,5 @@
+package test
+
+class Separate {
+ for (i <- 1 to 10) println(i)
+} \ No newline at end of file
diff --git a/test/pending/run/t7733/Test_2.scala b/test/pending/run/t7733/Test_2.scala
new file mode 100644
index 0000000000..28358574ec
--- /dev/null
+++ b/test/pending/run/t7733/Test_2.scala
@@ -0,0 +1,9 @@
+import scala.reflect.runtime.universe._
+import scala.reflect.runtime.{currentMirror => cm}
+import scala.tools.reflect.ToolBox
+
+object Test extends App {
+ val tb = cm.mkToolBox()
+ val code = tb.parse("{ val x: test.Separate$$anonfun$1 = null; x }")
+ println(tb.eval(code))
+} \ No newline at end of file
diff --git a/tools/binary-repo-lib.sh b/tools/binary-repo-lib.sh
index 704bf4944d..654ba21547 100755
--- a/tools/binary-repo-lib.sh
+++ b/tools/binary-repo-lib.sh
@@ -4,7 +4,7 @@
remote_urlget="http://repo.typesafe.com/typesafe/scala-sha-bootstrap/org/scala-lang/bootstrap"
-remote_urlpush="http://typesafe.artifactoryonline.com/typesafe/scala-sha-bootstrap/org/scala-lang/bootstrap"
+remote_urlpush="http://private-repo.typesafe.com/typesafe/scala-sha-bootstrap/org/scala-lang/bootstrap"
libraryJar="$(pwd)/lib/scala-library.jar"
desired_ext=".desired.sha1"
push_jar="$(pwd)/tools/push.jar"