summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.travis.yml2
-rw-r--r--Gemfile2
-rwxr-xr-xbuild.xml1
-rw-r--r--src/compiler/scala/reflect/quasiquotes/Holes.scala4
-rw-r--r--src/compiler/scala/reflect/quasiquotes/Reifiers.scala2
-rw-r--r--src/compiler/scala/reflect/reify/codegen/GenSymbols.scala2
-rw-r--r--src/compiler/scala/reflect/reify/codegen/GenTrees.scala4
-rw-r--r--src/compiler/scala/reflect/reify/codegen/GenUtils.scala8
-rw-r--r--src/compiler/scala/tools/ant/FastScalac.scala2
-rw-r--r--src/compiler/scala/tools/ant/sabbus/Compiler.scala2
-rw-r--r--src/compiler/scala/tools/ant/sabbus/ScalacFork.scala2
-rw-r--r--src/compiler/scala/tools/nsc/EvalLoop.scala3
-rw-r--r--src/compiler/scala/tools/nsc/GenericRunnerCommand.scala3
-rw-r--r--src/compiler/scala/tools/nsc/ObjectRunner.scala2
-rw-r--r--src/compiler/scala/tools/nsc/Reporting.scala2
-rw-r--r--src/compiler/scala/tools/nsc/ast/NodePrinters.scala1
-rw-r--r--src/compiler/scala/tools/nsc/ast/Trees.scala2
-rw-r--r--src/compiler/scala/tools/nsc/ast/parser/Parsers.scala4
-rwxr-xr-xsrc/compiler/scala/tools/nsc/ast/parser/SymbolicXMLBuilder.scala1
-rw-r--r--src/compiler/scala/tools/nsc/backend/icode/GenICode.scala21
-rw-r--r--src/compiler/scala/tools/nsc/backend/jvm/BCodeHelpers.scala4
-rw-r--r--src/compiler/scala/tools/nsc/backend/jvm/BTypes.scala28
-rw-r--r--src/compiler/scala/tools/nsc/backend/jvm/BTypesFromSymbols.scala23
-rw-r--r--src/compiler/scala/tools/nsc/backend/jvm/BackendReporting.scala56
-rw-r--r--src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala14
-rw-r--r--src/compiler/scala/tools/nsc/backend/jvm/GenBCode.scala8
-rw-r--r--src/compiler/scala/tools/nsc/backend/jvm/opt/BytecodeUtils.scala28
-rw-r--r--src/compiler/scala/tools/nsc/backend/jvm/opt/CallGraph.scala14
-rw-r--r--src/compiler/scala/tools/nsc/backend/jvm/opt/Inliner.scala63
-rw-r--r--src/compiler/scala/tools/nsc/backend/jvm/opt/LocalOpt.scala72
-rw-r--r--src/compiler/scala/tools/nsc/javac/JavaParsers.scala3
-rw-r--r--src/compiler/scala/tools/nsc/plugins/Plugin.scala4
-rw-r--r--src/compiler/scala/tools/nsc/settings/ScalaSettings.scala25
-rw-r--r--src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala30
-rw-r--r--src/compiler/scala/tools/nsc/symtab/classfile/ICodeReader.scala2
-rw-r--r--src/compiler/scala/tools/nsc/transform/AddInterfaces.scala2
-rw-r--r--src/compiler/scala/tools/nsc/transform/Constructors.scala1
-rw-r--r--src/compiler/scala/tools/nsc/transform/Erasure.scala2
-rw-r--r--src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala2
-rw-r--r--src/compiler/scala/tools/nsc/transform/Mixin.scala18
-rw-r--r--src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala8
-rw-r--r--src/compiler/scala/tools/nsc/transform/UnCurry.scala3
-rw-r--r--src/compiler/scala/tools/nsc/transform/patmat/Logic.scala24
-rw-r--r--src/compiler/scala/tools/nsc/transform/patmat/MatchAnalysis.scala109
-rw-r--r--src/compiler/scala/tools/nsc/transform/patmat/MatchTreeMaking.scala2
-rw-r--r--src/compiler/scala/tools/nsc/transform/patmat/Solving.scala74
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Implicits.scala4
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Infer.scala5
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Macros.scala3
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/MethodSynthesis.scala5
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Namers.scala9
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/PatternTypers.scala2
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/RefChecks.scala6
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala2
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/SyntheticMethods.scala2
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/TreeCheckers.scala6
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/TypeDiagnostics.scala6
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Typers.scala34
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Unapplies.scala1
-rw-r--r--src/compiler/scala/tools/reflect/ToolBoxFactory.scala2
-rw-r--r--src/library/scala/annotation/switch.scala3
-rw-r--r--src/library/scala/collection/GenTraversableOnce.scala4
-rw-r--r--src/library/scala/collection/TraversableLike.scala2
-rw-r--r--src/library/scala/collection/TraversableOnce.scala17
-rw-r--r--src/library/scala/runtime/BoxesRunTime.java6
-rw-r--r--src/reflect/scala/reflect/api/Names.scala8
-rw-r--r--src/reflect/scala/reflect/api/StandardLiftables.scala2
-rw-r--r--src/reflect/scala/reflect/api/Trees.scala4
-rw-r--r--src/reflect/scala/reflect/api/Types.scala2
-rw-r--r--src/reflect/scala/reflect/internal/Definitions.scala12
-rw-r--r--src/reflect/scala/reflect/internal/Importers.scala2
-rw-r--r--src/reflect/scala/reflect/internal/Printers.scala4
-rw-r--r--src/reflect/scala/reflect/internal/Symbols.scala28
-rw-r--r--src/reflect/scala/reflect/internal/TreeGen.scala4
-rw-r--r--src/reflect/scala/reflect/internal/Trees.scala2
-rw-r--r--src/reflect/scala/reflect/internal/Types.scala4
-rw-r--r--src/reflect/scala/reflect/runtime/JavaMirrors.scala14
-rw-r--r--src/reflect/scala/reflect/runtime/SymbolLoaders.scala3
-rw-r--r--src/reflect/scala/reflect/runtime/package.scala6
-rw-r--r--src/repl/scala/tools/nsc/interpreter/IMain.scala6
-rwxr-xr-xsrc/scaladoc/scala/tools/nsc/doc/base/CommentFactoryBase.scala33
-rw-r--r--src/scaladoc/scala/tools/nsc/doc/html/HtmlPage.scala47
-rw-r--r--src/scaladoc/scala/tools/nsc/doc/html/SyntaxHigh.scala34
-rw-r--r--src/scaladoc/scala/tools/nsc/doc/html/page/Template.scala6
-rw-r--r--src/scaladoc/scala/tools/nsc/doc/html/resource/lib/template.css2
-rw-r--r--src/scaladoc/scala/tools/nsc/doc/html/resource/lib/template.js2
-rw-r--r--test/files/jvm/t8689.scala9
-rw-r--r--test/files/neg/case-collision2.flags2
-rw-r--r--test/files/neg/inlineMaxSize.check9
-rw-r--r--test/files/neg/inlineMaxSize.flags1
-rw-r--r--test/files/neg/inlineMaxSize.scala8
-rw-r--r--test/files/neg/macro-invalidusage-badargs.check3
-rw-r--r--test/files/neg/reflection-names-neg.check13
-rw-r--r--test/files/neg/reflection-names-neg.scala6
-rw-r--r--test/files/neg/t0899.check6
-rw-r--r--test/files/neg/t562.check2
-rw-r--r--test/files/neg/t7157.check36
-rw-r--r--test/files/neg/t7848-interp-warn.check5
-rw-r--r--test/files/neg/t7848-interp-warn.scala2
-rw-r--r--test/files/neg/t8731.check5
-rw-r--r--test/files/neg/t9127.check12
-rw-r--r--test/files/neg/t9127.flags1
-rw-r--r--test/files/neg/t9127.scala7
-rw-r--r--test/files/pos/t6942.flags2
-rw-r--r--test/files/pos/t8861.flags1
-rw-r--r--test/files/pos/t8861.scala11
-rw-r--r--test/files/pos/t9181.flags1
-rw-r--r--test/files/pos/t9181.scala806
-rw-r--r--test/files/run/t7407.flags2
-rw-r--r--test/files/run/t7407b.flags2
-rw-r--r--test/files/run/t7741a/GroovyInterface$1Dump.java222
-rw-r--r--test/files/run/t7741a/GroovyInterfaceDump.java51
-rw-r--r--test/files/run/t7741a/Test.scala47
-rw-r--r--test/files/run/t7741b.check3
-rw-r--r--test/files/run/t7741b/HasInner.java3
-rw-r--r--test/files/run/t7741b/Test.scala29
-rw-r--r--test/files/run/t8845.flags2
-rw-r--r--test/files/run/t8925.flags2
-rw-r--r--test/files/run/t9182.check3
-rw-r--r--test/files/run/t9182.scala12
-rw-r--r--test/files/run/t9252.check1
-rw-r--r--test/files/run/t9252.scala5
-rw-r--r--test/junit/scala/tools/nsc/backend/jvm/CodeGenTools.scala7
-rw-r--r--test/junit/scala/tools/nsc/backend/jvm/opt/EmptyExceptionHandlersTest.scala4
-rw-r--r--test/junit/scala/tools/nsc/backend/jvm/opt/EmptyLabelsAndLineNumbersTest.scala6
-rw-r--r--test/junit/scala/tools/nsc/backend/jvm/opt/InlineWarningTest.scala48
-rw-r--r--test/junit/scala/tools/nsc/backend/jvm/opt/InlinerTest.scala27
-rw-r--r--test/junit/scala/tools/nsc/backend/jvm/opt/SimplifyJumpsTest.scala24
-rw-r--r--test/junit/scala/tools/nsc/backend/jvm/opt/UnreachableCodeTest.scala2
-rw-r--r--test/junit/scala/tools/nsc/doc/html/HtmlDocletTest.scala22
-rw-r--r--test/junit/scala/tools/nsc/symtab/SymbolTableTest.scala4
-rw-r--r--test/junit/scala/tools/nsc/transform/patmat/SolvingTest.scala3
-rw-r--r--test/scaladoc/run/t5795.check4
-rw-r--r--test/scaladoc/run/t5795.scala63
-rw-r--r--test/scaladoc/scalacheck/CommentFactoryTest.scala20
-rw-r--r--test/scaladoc/scalacheck/HtmlFactoryTest.scala4
-rw-r--r--versions.properties2
137 files changed, 2115 insertions, 490 deletions
diff --git a/.travis.yml b/.travis.yml
index e90fc35267..6a7ac45e3d 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -2,7 +2,7 @@
# based on http://www.paperplanes.de/2013/8/13/deploying-your-jekyll-blog-to-s3-with-travis-ci.html
language: ruby
rvm:
- - 1.9.3
+ - 2.2
script: bundle exec jekyll build -s spec/ -d build/spec
install: bundle install
diff --git a/Gemfile b/Gemfile
index 53924a4381..6921f792c3 100644
--- a/Gemfile
+++ b/Gemfile
@@ -1,7 +1,7 @@
# To build the spec on Travis CI
source "https://rubygems.org"
-gem "jekyll", "2.0.0.alpha.2"
+gem "jekyll", "2.5.3"
gem "rouge"
# gem 's3_website'
# gem 'redcarpet'
diff --git a/build.xml b/build.xml
index ee6a045bda..4b79b68a02 100755
--- a/build.xml
+++ b/build.xml
@@ -978,6 +978,7 @@ TODO:
<pathelement location="${test.junit.classes}"/>
<path refid="quick.compiler.build.path"/>
<path refid="quick.repl.build.path"/>
+ <path refid="quick.scaladoc.build.path"/>
<path refid="quick.partest-extras.build.path"/>
<path refid="junit.classpath"/>
</path>
diff --git a/src/compiler/scala/reflect/quasiquotes/Holes.scala b/src/compiler/scala/reflect/quasiquotes/Holes.scala
index 38b05f9d4b..6fa6b9b37a 100644
--- a/src/compiler/scala/reflect/quasiquotes/Holes.scala
+++ b/src/compiler/scala/reflect/quasiquotes/Holes.scala
@@ -132,7 +132,7 @@ trait Holes { self: Quasiquotes =>
private def mapF(tree: Tree, f: Tree => Tree): Tree =
if (f(Ident(TermName("x"))) equalsStructure Ident(TermName("x"))) tree
else {
- val x: TermName = c.freshName()
+ val x = TermName(c.freshName())
// q"$tree.map { $x => ${f(Ident(x))} }"
Apply(Select(tree, nme.map),
Function(ValDef(Modifiers(PARAM), x, TypeTree(), EmptyTree) :: Nil,
@@ -187,7 +187,7 @@ trait Holes { self: Quasiquotes =>
lazy val tree =
tptopt.map { tpt =>
val TypeDef(_, _, _, typedTpt) =
- try c.typeCheck(TypeDef(NoMods, TypeName("T"), Nil, tpt))
+ try c.typecheck(TypeDef(NoMods, TypeName("T"), Nil, tpt))
catch { case TypecheckException(pos, msg) => c.abort(pos.asInstanceOf[c.Position], msg) }
val tpe = typedTpt.tpe
val (iterableRank, _) = stripIterable(tpe)
diff --git a/src/compiler/scala/reflect/quasiquotes/Reifiers.scala b/src/compiler/scala/reflect/quasiquotes/Reifiers.scala
index cc98717c4e..7c0e7dfbb8 100644
--- a/src/compiler/scala/reflect/quasiquotes/Reifiers.scala
+++ b/src/compiler/scala/reflect/quasiquotes/Reifiers.scala
@@ -247,7 +247,7 @@ trait Reifiers { self: Quasiquotes =>
hole.tree
case Placeholder(hole: UnapplyHole) => hole.treeNoUnlift
case FreshName(prefix) if prefix != nme.QUASIQUOTE_NAME_PREFIX =>
- def fresh() = c.freshName[TermName](nme.QUASIQUOTE_NAME_PREFIX)
+ def fresh() = c.freshName(TermName(nme.QUASIQUOTE_NAME_PREFIX))
def introduceName() = { val n = fresh(); nameMap(name) += n; n}
def result(n: Name) = if (isReifyingExpressions) Ident(n) else Bind(n, Ident(nme.WILDCARD))
if (isReifyingPatterns) result(introduceName())
diff --git a/src/compiler/scala/reflect/reify/codegen/GenSymbols.scala b/src/compiler/scala/reflect/reify/codegen/GenSymbols.scala
index 52ddcb154b..e41fbf042a 100644
--- a/src/compiler/scala/reflect/reify/codegen/GenSymbols.scala
+++ b/src/compiler/scala/reflect/reify/codegen/GenSymbols.scala
@@ -39,7 +39,7 @@ trait GenSymbols {
else if (sym.isModuleClass)
if (sym.sourceModule.isLocatable) Select(Select(reify(sym.sourceModule), nme.asModule), nme.moduleClass)
else reifySymDef(sym)
- else if (sym.isPackage)
+ else if (sym.hasPackageFlag)
mirrorMirrorCall(nme.staticPackage, reify(sym.fullName))
else if (sym.isLocatable) {
/* This is a fancy conundrum that stems from the fact that Scala allows
diff --git a/src/compiler/scala/reflect/reify/codegen/GenTrees.scala b/src/compiler/scala/reflect/reify/codegen/GenTrees.scala
index 743fe131c4..f34d75140b 100644
--- a/src/compiler/scala/reflect/reify/codegen/GenTrees.scala
+++ b/src/compiler/scala/reflect/reify/codegen/GenTrees.scala
@@ -153,7 +153,7 @@ trait GenTrees {
else mirrorCall(nme.Ident, reify(name))
case Select(qual, name) =>
- if (qual.symbol != null && qual.symbol.isPackage) {
+ if (qual.symbol != null && qual.symbol.hasPackageFlag) {
mirrorBuildCall(nme.mkIdent, reify(sym))
} else {
val effectiveName = if (sym != null && sym != NoSymbol) sym.name else name
@@ -199,7 +199,7 @@ trait GenTrees {
}
}
else tree match {
- case Select(qual, name) if !qual.symbol.isPackage =>
+ case Select(qual, name) if !qual.symbol.hasPackageFlag =>
if (reifyDebug) println(s"reifying Select($qual, $name)")
mirrorCall(nme.Select, reify(qual), reify(name))
case SelectFromTypeTree(qual, name) =>
diff --git a/src/compiler/scala/reflect/reify/codegen/GenUtils.scala b/src/compiler/scala/reflect/reify/codegen/GenUtils.scala
index de9fec0df5..b5b0f93750 100644
--- a/src/compiler/scala/reflect/reify/codegen/GenUtils.scala
+++ b/src/compiler/scala/reflect/reify/codegen/GenUtils.scala
@@ -15,7 +15,7 @@ trait GenUtils {
def reifyProduct(prefix: String, elements: List[Any]): Tree = {
// reflection would be more robust, but, hey, this is a hot path
if (prefix.startsWith("Tuple")) scalaFactoryCall(prefix, (elements map reify).toList: _*)
- else mirrorCall(prefix, (elements map reify): _*)
+ else mirrorCall(TermName(prefix), (elements map reify): _*)
}
// helper functions
@@ -49,16 +49,16 @@ trait GenUtils {
call("" + nme.MIRROR_PREFIX + name, args: _*)
def mirrorFactoryCall(value: Product, args: Tree*): Tree =
- mirrorFactoryCall(value.productPrefix, args: _*)
+ mirrorFactoryCall(TermName(value.productPrefix), args: _*)
def mirrorFactoryCall(prefix: TermName, args: Tree*): Tree =
- mirrorCall("" + prefix, args: _*)
+ mirrorCall(TermName("" + prefix), args: _*)
def scalaFactoryCall(name: TermName, args: Tree*): Tree =
call(s"scala.$name.apply", args: _*)
def scalaFactoryCall(name: String, args: Tree*): Tree =
- scalaFactoryCall(name: TermName, args: _*)
+ scalaFactoryCall(TermName(name), args: _*)
def mkList(args: List[Tree]): Tree =
scalaFactoryCall("collection.immutable.List", args: _*)
diff --git a/src/compiler/scala/tools/ant/FastScalac.scala b/src/compiler/scala/tools/ant/FastScalac.scala
index c3eb9eef9c..6f0a30aa9d 100644
--- a/src/compiler/scala/tools/ant/FastScalac.scala
+++ b/src/compiler/scala/tools/ant/FastScalac.scala
@@ -15,7 +15,7 @@ import org.apache.tools.ant.types.Path
import scala.tools.nsc.Settings
import scala.tools.nsc.io.File
import scala.tools.nsc.settings.FscSettings
-import scala.tools.nsc.util.ScalaClassLoader
+import scala.reflect.internal.util.ScalaClassLoader
/** An Ant task to compile with the fast Scala compiler (`fsc`).
*
diff --git a/src/compiler/scala/tools/ant/sabbus/Compiler.scala b/src/compiler/scala/tools/ant/sabbus/Compiler.scala
index 65cd9f41c2..81cd1f3196 100644
--- a/src/compiler/scala/tools/ant/sabbus/Compiler.scala
+++ b/src/compiler/scala/tools/ant/sabbus/Compiler.scala
@@ -12,7 +12,7 @@ package scala.tools.ant.sabbus
import java.io.File
import java.net.URL
import java.lang.reflect.InvocationTargetException
-import scala.tools.nsc.util.ScalaClassLoader
+import scala.reflect.internal.util.ScalaClassLoader
class Compiler(classpath: Array[URL], val settings: Settings)
{
diff --git a/src/compiler/scala/tools/ant/sabbus/ScalacFork.scala b/src/compiler/scala/tools/ant/sabbus/ScalacFork.scala
index 595b45ae51..cde827ba54 100644
--- a/src/compiler/scala/tools/ant/sabbus/ScalacFork.scala
+++ b/src/compiler/scala/tools/ant/sabbus/ScalacFork.scala
@@ -16,7 +16,7 @@ import org.apache.tools.ant.taskdefs.Java
import org.apache.tools.ant.util.{ GlobPatternMapper, SourceFileScanner }
import org.apache.tools.ant.BuildException
import scala.tools.nsc.io
-import scala.tools.nsc.util.ScalaClassLoader
+import scala.reflect.internal.util.ScalaClassLoader
/** An Ant task to compile with the new Scala compiler (NSC).
*
diff --git a/src/compiler/scala/tools/nsc/EvalLoop.scala b/src/compiler/scala/tools/nsc/EvalLoop.scala
index 15a296c836..73f4b9a119 100644
--- a/src/compiler/scala/tools/nsc/EvalLoop.scala
+++ b/src/compiler/scala/tools/nsc/EvalLoop.scala
@@ -6,6 +6,7 @@
package scala.tools.nsc
import scala.annotation.tailrec
+import scala.io.StdIn
import java.io.EOFException
trait EvalLoop {
@@ -14,7 +15,7 @@ trait EvalLoop {
def loop(action: (String) => Unit) {
@tailrec def inner() {
Console.print(prompt)
- val line = try Console.readLine() catch { case _: EOFException => null }
+ val line = try StdIn.readLine() catch { case _: EOFException => null }
if (line != null && line != "") {
action(line)
inner()
diff --git a/src/compiler/scala/tools/nsc/GenericRunnerCommand.scala b/src/compiler/scala/tools/nsc/GenericRunnerCommand.scala
index dbdeec809f..2584054686 100644
--- a/src/compiler/scala/tools/nsc/GenericRunnerCommand.scala
+++ b/src/compiler/scala/tools/nsc/GenericRunnerCommand.scala
@@ -6,6 +6,7 @@
package scala.tools.nsc
import GenericRunnerCommand._
+import scala.reflect.internal.util.ScalaClassLoader
/** A command for ScriptRunner */
class GenericRunnerCommand(
@@ -32,7 +33,7 @@ extends CompilerCommand(args, settings) {
private def guessHowToRun(target: String): GenericRunnerCommand.HowToRun = {
if (!ok) Error
else if (io.Jar.isJarOrZip(target)) AsJar
- else if (util.ScalaClassLoader.classExists(settings.classpathURLs, target)) AsObject
+ else if (ScalaClassLoader.classExists(settings.classpathURLs, target)) AsObject
else {
val f = io.File(target)
if (!f.hasExtension("class", "jar", "zip") && f.canRead) AsScript
diff --git a/src/compiler/scala/tools/nsc/ObjectRunner.scala b/src/compiler/scala/tools/nsc/ObjectRunner.scala
index 7c14f4943f..8e01418e8b 100644
--- a/src/compiler/scala/tools/nsc/ObjectRunner.scala
+++ b/src/compiler/scala/tools/nsc/ObjectRunner.scala
@@ -7,8 +7,8 @@
package scala.tools.nsc
import java.net.URL
-import util.ScalaClassLoader
import util.Exceptional.unwrap
+import scala.reflect.internal.util.ScalaClassLoader
trait CommonRunner {
/** Run a given object, specified by name, using a
diff --git a/src/compiler/scala/tools/nsc/Reporting.scala b/src/compiler/scala/tools/nsc/Reporting.scala
index 72a4b69536..4e7a527a5a 100644
--- a/src/compiler/scala/tools/nsc/Reporting.scala
+++ b/src/compiler/scala/tools/nsc/Reporting.scala
@@ -46,7 +46,7 @@ trait Reporting extends scala.reflect.internal.Reporting { self: ast.Positions w
private val _deprecationWarnings = new ConditionalWarning("deprecation", settings.deprecation)()
private val _uncheckedWarnings = new ConditionalWarning("unchecked", settings.unchecked)()
private val _featureWarnings = new ConditionalWarning("feature", settings.feature)()
- private val _inlinerWarnings = new ConditionalWarning("inliner", settings.YinlinerWarnings)(if (settings.isBCodeAskedFor) settings.YoptWarnings.name else settings.YinlinerWarnings.name)
+ private val _inlinerWarnings = new ConditionalWarning("inliner", settings.YinlinerWarnings)(if (settings.isBCodeActive) settings.YoptWarnings.name else settings.YinlinerWarnings.name)
private val _allConditionalWarnings = List(_deprecationWarnings, _uncheckedWarnings, _featureWarnings, _inlinerWarnings)
// TODO: remove in favor of the overload that takes a Symbol, give that argument a default (NoSymbol)
diff --git a/src/compiler/scala/tools/nsc/ast/NodePrinters.scala b/src/compiler/scala/tools/nsc/ast/NodePrinters.scala
index 9c8e13a1a9..6fe85cde7a 100644
--- a/src/compiler/scala/tools/nsc/ast/NodePrinters.scala
+++ b/src/compiler/scala/tools/nsc/ast/NodePrinters.scala
@@ -9,6 +9,7 @@ package ast
import scala.compat.Platform.EOL
import symtab.Flags._
import scala.language.postfixOps
+import scala.reflect.internal.util.ListOfNil
/** The object `nodePrinter` converts the internal tree
* representation to a string.
diff --git a/src/compiler/scala/tools/nsc/ast/Trees.scala b/src/compiler/scala/tools/nsc/ast/Trees.scala
index 3a502bdb7a..934257092f 100644
--- a/src/compiler/scala/tools/nsc/ast/Trees.scala
+++ b/src/compiler/scala/tools/nsc/ast/Trees.scala
@@ -308,7 +308,7 @@ trait Trees extends scala.reflect.internal.Trees { self: Global =>
// Erasing locally-defined symbols is useful to prevent tree corruption, but erasing external bindings is not,
// therefore we want to retain those bindings, especially given that restoring them can be impossible
// if we move these trees into lexical contexts different from their original locations.
- if (dupl.hasSymbol) {
+ if (dupl.hasSymbolField) {
val sym = dupl.symbol
val vetoScope = !brutally && !(locals contains sym) && !(locals contains sym.deSkolemize)
val vetoThis = dupl.isInstanceOf[This] && sym.isPackageClass
diff --git a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala
index 4663810003..67e91ae857 100644
--- a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala
+++ b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala
@@ -13,7 +13,7 @@ import scala.collection.{ mutable, immutable }
import mutable.{ ListBuffer, StringBuilder }
import scala.reflect.internal.{ Precedence, ModifierFlags => Flags }
import scala.reflect.internal.Chars.{ isScalaLetter }
-import scala.reflect.internal.util.{ SourceFile, Position, FreshNameCreator }
+import scala.reflect.internal.util.{ SourceFile, Position, FreshNameCreator, ListOfNil }
import Tokens._
/** Historical note: JavaParsers started life as a direct copy of Parsers
@@ -2788,7 +2788,7 @@ self =>
*/
def packageObjectDef(start: Offset): PackageDef = {
val defn = objectDef(in.offset, NoMods)
- val pidPos = o2p(defn.pos.startOrPoint)
+ val pidPos = o2p(defn.pos.start)
val pkgPos = r2p(start, pidPos.point)
gen.mkPackageObject(defn, pidPos, pkgPos)
}
diff --git a/src/compiler/scala/tools/nsc/ast/parser/SymbolicXMLBuilder.scala b/src/compiler/scala/tools/nsc/ast/parser/SymbolicXMLBuilder.scala
index 8cd915bf22..d2a999cdec 100755
--- a/src/compiler/scala/tools/nsc/ast/parser/SymbolicXMLBuilder.scala
+++ b/src/compiler/scala/tools/nsc/ast/parser/SymbolicXMLBuilder.scala
@@ -8,6 +8,7 @@ package ast.parser
import scala.collection.{ mutable, immutable }
import symtab.Flags.MUTABLE
+import scala.reflect.internal.util.ListOfNil
import scala.reflect.internal.util.StringOps.splitWhere
/** This class builds instance of `Tree` that represent XML.
diff --git a/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala b/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala
index cf52ad6636..137954b52d 100644
--- a/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala
+++ b/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala
@@ -876,13 +876,20 @@ abstract class GenICode extends SubComponent {
genLoadModule(ctx, tree)
generatedType = toTypeKind(sym.info)
} else {
- try {
- val Some(l) = ctx.method.lookupLocal(sym)
- ctx.bb.emit(LOAD_LOCAL(l), tree.pos)
- generatedType = l.kind
- } catch {
- case ex: MatchError =>
- abort("symbol " + sym + " does not exist in " + ctx.method)
+ ctx.method.lookupLocal(sym) match {
+ case Some(l) =>
+ ctx.bb.emit(LOAD_LOCAL(l), tree.pos)
+ generatedType = l.kind
+ case None =>
+ val saved = settings.uniqid
+ settings.uniqid.value = true
+ try {
+ val methodCode = unit.body.collect { case dd: DefDef
+ if dd.symbol == ctx.method.symbol => showCode(dd);
+ }.headOption.getOrElse("<unknown>")
+ abort(s"symbol $sym does not exist in ${ctx.method}, which contains locals ${ctx.method.locals.mkString(",")}. \nMethod code: $methodCode")
+ }
+ finally settings.uniqid.value = saved
}
}
}
diff --git a/src/compiler/scala/tools/nsc/backend/jvm/BCodeHelpers.scala b/src/compiler/scala/tools/nsc/backend/jvm/BCodeHelpers.scala
index 3b7dbc18da..18468f5ae3 100644
--- a/src/compiler/scala/tools/nsc/backend/jvm/BCodeHelpers.scala
+++ b/src/compiler/scala/tools/nsc/backend/jvm/BCodeHelpers.scala
@@ -780,8 +780,8 @@ abstract class BCodeHelpers extends BCodeIdiomatic with BytecodeWriters {
var fieldList = List[String]()
for (f <- fieldSymbols if f.hasGetter;
- g = f.getter(cls);
- s = f.setter(cls);
+ g = f.getterIn(cls);
+ s = f.setterIn(cls);
if g.isPublic && !(f.name startsWith "$")
) {
// inserting $outer breaks the bean
diff --git a/src/compiler/scala/tools/nsc/backend/jvm/BTypes.scala b/src/compiler/scala/tools/nsc/backend/jvm/BTypes.scala
index d8a17e975e..d690542f0e 100644
--- a/src/compiler/scala/tools/nsc/backend/jvm/BTypes.scala
+++ b/src/compiler/scala/tools/nsc/backend/jvm/BTypes.scala
@@ -11,11 +11,12 @@ import scala.collection.concurrent.TrieMap
import scala.reflect.internal.util.Position
import scala.tools.asm
import asm.Opcodes
-import scala.tools.asm.tree.{MethodInsnNode, InnerClassNode, ClassNode}
+import scala.tools.asm.tree.{MethodNode, MethodInsnNode, InnerClassNode, ClassNode}
import scala.tools.nsc.backend.jvm.BTypes.{InlineInfo, MethodInlineInfo}
import scala.tools.nsc.backend.jvm.BackendReporting._
import scala.tools.nsc.backend.jvm.opt._
import scala.collection.convert.decorateAsScala._
+import scala.tools.nsc.settings.ScalaSettings
/**
* The BTypes component defines The BType class hierarchy. A BType stores all type information
@@ -39,6 +40,8 @@ abstract class BTypes {
*/
val byteCodeRepository: ByteCodeRepository
+ val localOpt: LocalOpt[this.type]
+
val inliner: Inliner[this.type]
val callGraph: CallGraph[this.type]
@@ -48,14 +51,9 @@ abstract class BTypes {
// Allows to define per-run caches here and in the CallGraph component, which don't have a global
def recordPerRunCache[T <: collection.generic.Clearable](cache: T): T
- // When building the call graph, we need to know if global inlining is allowed (the component doesn't have a global)
- def inlineGlobalEnabled: Boolean
-
- // When the inliner is not enabled, there's no point in adding InlineInfos to all ClassBTypes
- def inlinerEnabled: Boolean
+ // Allows access to the compiler settings for backend components that don't have a global in scope
+ def compilerSettings: ScalaSettings
- // Settings that define what kind of optimizer warnings are emitted.
- def warnSettings: WarnSettings
/**
* A map from internal names to ClassBTypes. Every ClassBType is added to this map on its
@@ -83,6 +81,18 @@ abstract class BTypes {
val javaDefinedClasses: collection.mutable.Set[InternalName] = recordPerRunCache(collection.mutable.Set.empty)
/**
+ * Cache, contains methods whose unreachable instructions are eliminated.
+ *
+ * The ASM Analyzer class does not compute any frame information for unreachable instructions.
+ * Transformations that use an analyzer (including inlining) therefore require unreachable code
+ * to be eliminated.
+ *
+ * This cache allows running dead code elimination whenever an analyzer is used. If the method
+ * is already optimized, DCE can return early.
+ */
+ val unreachableCodeEliminated: collection.mutable.Set[MethodNode] = recordPerRunCache(collection.mutable.Set.empty)
+
+ /**
* Obtain the BType for a type descriptor or internal name. For class descriptors, the ClassBType
* is constructed by parsing the corresponding classfile.
*
@@ -229,7 +239,7 @@ abstract class BTypes {
// The InlineInfo is built from the classfile (not from the symbol) for all classes that are NOT
// being compiled. For those classes, the info is only needed if the inliner is enabled, othewise
// we can save the memory.
- if (!inlinerEnabled) BTypes.EmptyInlineInfo
+ if (!compilerSettings.YoptInlinerEnabled) BTypes.EmptyInlineInfo
else fromClassfileAttribute getOrElse fromClassfileWithoutAttribute
}
diff --git a/src/compiler/scala/tools/nsc/backend/jvm/BTypesFromSymbols.scala b/src/compiler/scala/tools/nsc/backend/jvm/BTypesFromSymbols.scala
index eeb6ed24a2..1b9fd5e298 100644
--- a/src/compiler/scala/tools/nsc/backend/jvm/BTypesFromSymbols.scala
+++ b/src/compiler/scala/tools/nsc/backend/jvm/BTypesFromSymbols.scala
@@ -7,9 +7,10 @@ package scala.tools.nsc
package backend.jvm
import scala.tools.asm
-import scala.tools.nsc.backend.jvm.opt.{CallGraph, Inliner, ByteCodeRepository}
+import scala.tools.nsc.backend.jvm.opt.{LocalOpt, CallGraph, Inliner, ByteCodeRepository}
import scala.tools.nsc.backend.jvm.BTypes.{InlineInfo, MethodInlineInfo, InternalName}
import BackendReporting._
+import scala.tools.nsc.settings.ScalaSettings
/**
* This class mainly contains the method classBTypeFromSymbol, which extracts the necessary
@@ -37,6 +38,8 @@ class BTypesFromSymbols[G <: Global](val global: G) extends BTypes {
val byteCodeRepository = new ByteCodeRepository(global.classPath, javaDefinedClasses, recordPerRunCache(collection.concurrent.TrieMap.empty))
+ val localOpt: LocalOpt[this.type] = new LocalOpt(this)
+
val inliner: Inliner[this.type] = new Inliner(this)
val callGraph: CallGraph[this.type] = new CallGraph(this)
@@ -49,19 +52,7 @@ class BTypesFromSymbols[G <: Global](val global: G) extends BTypes {
def recordPerRunCache[T <: collection.generic.Clearable](cache: T): T = perRunCaches.recordCache(cache)
- def inlineGlobalEnabled: Boolean = settings.YoptInlineGlobal
-
- def inlinerEnabled: Boolean = settings.YoptInlinerEnabled
-
- def warnSettings: WarnSettings = {
- val c = settings.YoptWarningsChoices
- // cannot extract settings.YoptWarnings into a local val due to some dependent typing issue.
- WarnSettings(
- !settings.YoptWarnings.isSetByUser || settings.YoptWarnings.contains(c.atInlineFailedSummary.name) || settings.YoptWarnings.contains(c.atInlineFailed.name),
- settings.YoptWarnings.contains(c.noInlineMixed.name),
- settings.YoptWarnings.contains(c.noInlineMissingBytecode.name),
- settings.YoptWarnings.contains(c.noInlineMissingScalaInlineInfoAttr.name))
- }
+ def compilerSettings: ScalaSettings = settings
// helpers that need access to global.
// TODO @lry create a separate component, they don't belong to BTypesFromSymbols
@@ -418,8 +409,8 @@ class BTypesFromSymbols[G <: Global](val global: G) extends BTypes {
// phase travel required, see implementation of `compiles`. for nested classes, it checks if the
// enclosingTopLevelClass is being compiled. after flatten, all classes are considered top-level,
// so `compiles` would return `false`.
- if (exitingPickler(currentRun.compiles(classSym))) buildFromSymbol // InlineInfo required for classes being compiled, we have to create the classfile attribute
- else if (!inlinerEnabled) BTypes.EmptyInlineInfo // For other classes, we need the InlineInfo only inf the inliner is enabled.
+ if (exitingPickler(currentRun.compiles(classSym))) buildFromSymbol // InlineInfo required for classes being compiled, we have to create the classfile attribute
+ else if (!compilerSettings.YoptInlinerEnabled) BTypes.EmptyInlineInfo // For other classes, we need the InlineInfo only inf the inliner is enabled.
else {
// For classes not being compiled, the InlineInfo is read from the classfile attribute. This
// fixes an issue with mixed-in methods: the mixin phase enters mixin methods only to class
diff --git a/src/compiler/scala/tools/nsc/backend/jvm/BackendReporting.scala b/src/compiler/scala/tools/nsc/backend/jvm/BackendReporting.scala
index a06fb4bab8..d641f708d2 100644
--- a/src/compiler/scala/tools/nsc/backend/jvm/BackendReporting.scala
+++ b/src/compiler/scala/tools/nsc/backend/jvm/BackendReporting.scala
@@ -4,6 +4,8 @@ package backend.jvm
import scala.tools.asm.tree.{AbstractInsnNode, MethodNode}
import scala.tools.nsc.backend.jvm.BTypes.InternalName
import scala.reflect.internal.util.Position
+import scala.tools.nsc.settings.ScalaSettings
+import scala.util.control.ControlThrowable
/**
* Interface for emitting inline warnings. The interface is required because the implementation
@@ -73,24 +75,22 @@ object BackendReporting {
}
}
- case class Invalid[A](e: A) extends Exception
+ case class Invalid[A](e: A) extends ControlThrowable
/**
* See documentation of orThrow above.
*/
def tryEither[A, B](op: => Either[A, B]): Either[A, B] = try { op } catch { case Invalid(e) => Left(e.asInstanceOf[A]) }
- final case class WarnSettings(atInlineFailed: Boolean, noInlineMixed: Boolean, noInlineMissingBytecode: Boolean, noInlineMissingScalaInlineInfoAttr: Boolean)
-
sealed trait OptimizerWarning {
- def emitWarning(settings: WarnSettings): Boolean
+ def emitWarning(settings: ScalaSettings): Boolean
}
// Method filter in RightBiasedEither requires an implicit empty value. Taking the value here
// in scope allows for-comprehensions that desugar into filter calls (for example when using a
// tuple de-constructor).
implicit object emptyOptimizerWarning extends OptimizerWarning {
- def emitWarning(settings: WarnSettings): Boolean = false
+ def emitWarning(settings: ScalaSettings): Boolean = false
}
sealed trait MissingBytecodeWarning extends OptimizerWarning {
@@ -112,17 +112,17 @@ object BackendReporting {
missingClass.map(c => s" Reason:\n$c").getOrElse("")
}
- def emitWarning(settings: WarnSettings): Boolean = this match {
+ def emitWarning(settings: ScalaSettings): Boolean = this match {
case ClassNotFound(_, javaDefined) =>
- if (javaDefined) settings.noInlineMixed
- else settings.noInlineMissingBytecode
+ if (javaDefined) settings.YoptWarningNoInlineMixed
+ else settings.YoptWarningNoInlineMissingBytecode
case m @ MethodNotFound(_, _, _, missing) =>
if (m.isArrayMethod) false
- else settings.noInlineMissingBytecode || missing.exists(_.emitWarning(settings))
+ else settings.YoptWarningNoInlineMissingBytecode || missing.exists(_.emitWarning(settings))
case FieldNotFound(_, _, _, missing) =>
- settings.noInlineMissingBytecode || missing.exists(_.emitWarning(settings))
+ settings.YoptWarningNoInlineMissingBytecode || missing.exists(_.emitWarning(settings))
}
}
@@ -141,9 +141,9 @@ object BackendReporting {
s"Failed to get the type of class symbol $classFullName due to SI-9111."
}
- def emitWarning(settings: WarnSettings): Boolean = this match {
+ def emitWarning(settings: ScalaSettings): Boolean = this match {
case NoClassBTypeInfoMissingBytecode(cause) => cause.emitWarning(settings)
- case NoClassBTypeInfoClassSymbolInfoFailedSI9111(_) => settings.noInlineMissingBytecode
+ case NoClassBTypeInfoClassSymbolInfoFailedSI9111(_) => settings.YoptWarningNoInlineMissingBytecode
}
}
@@ -175,11 +175,11 @@ object BackendReporting {
cause.toString
}
- def emitWarning(settings: WarnSettings): Boolean = this match {
+ def emitWarning(settings: ScalaSettings): Boolean = this match {
case MethodInlineInfoIncomplete(_, _, _, cause) => cause.emitWarning(settings)
case MethodInlineInfoMissing(_, _, _, Some(cause)) => cause.emitWarning(settings)
- case MethodInlineInfoMissing(_, _, _, None) => settings.noInlineMissingBytecode
+ case MethodInlineInfoMissing(_, _, _, None) => settings.YoptWarningNoInlineMissingBytecode
case MethodInlineInfoError(_, _, _, cause) => cause.emitWarning(settings)
@@ -214,11 +214,21 @@ object BackendReporting {
case SynchronizedMethod(_, _, _) =>
s"Method $calleeMethodSig cannot be inlined because it is synchronized."
+
+ case StrictfpMismatch(_, _, _, callsiteClass, callsiteName, callsiteDesc) =>
+ s"""The callsite method ${BackendReporting.methodSignature(callsiteClass, callsiteName, callsiteDesc)}
+ |does not have the same strictfp mode as the callee $calleeMethodSig.
+ """.stripMargin
+
+ case ResultingMethodTooLarge(_, _, _, callsiteClass, callsiteName, callsiteDesc) =>
+ s"""The size of the callsite method ${BackendReporting.methodSignature(callsiteClass, callsiteName, callsiteDesc)}
+ |would exceed the JVM method size limit after inlining $calleeMethodSig.
+ """.stripMargin
}
- def emitWarning(settings: WarnSettings): Boolean = this match {
- case _: IllegalAccessInstruction | _: MethodWithHandlerCalledOnNonEmptyStack | _: SynchronizedMethod =>
- settings.atInlineFailed
+ def emitWarning(settings: ScalaSettings): Boolean = this match {
+ case _: IllegalAccessInstruction | _: MethodWithHandlerCalledOnNonEmptyStack | _: SynchronizedMethod | _: StrictfpMismatch | _: ResultingMethodTooLarge =>
+ settings.YoptWarningEmitAtInlineFailed
case IllegalAccessCheckFailed(_, _, _, _, _, cause) =>
cause.emitWarning(settings)
@@ -231,6 +241,10 @@ object BackendReporting {
case class MethodWithHandlerCalledOnNonEmptyStack(calleeDeclarationClass: InternalName, name: String, descriptor: String,
callsiteClass: InternalName, callsiteName: String, callsiteDesc: String) extends CannotInlineWarning
case class SynchronizedMethod(calleeDeclarationClass: InternalName, name: String, descriptor: String) extends CannotInlineWarning
+ case class StrictfpMismatch(calleeDeclarationClass: InternalName, name: String, descriptor: String,
+ callsiteClass: InternalName, callsiteName: String, callsiteDesc: String) extends CannotInlineWarning
+ case class ResultingMethodTooLarge(calleeDeclarationClass: InternalName, name: String, descriptor: String,
+ callsiteClass: InternalName, callsiteName: String, callsiteDesc: String) extends CannotInlineWarning
/**
* Used in the InlineInfo of a ClassBType, when some issue occurred obtaining the inline information.
@@ -250,11 +264,11 @@ object BackendReporting {
s"Cannot read ScalaInlineInfo version $version in classfile $internalName. Use a more recent compiler."
}
- def emitWarning(settings: WarnSettings): Boolean = this match {
- case NoInlineInfoAttribute(_) => settings.noInlineMissingScalaInlineInfoAttr
+ def emitWarning(settings: ScalaSettings): Boolean = this match {
+ case NoInlineInfoAttribute(_) => settings.YoptWarningNoInlineMissingScalaInlineInfoAttr
case ClassNotFoundWhenBuildingInlineInfoFromSymbol(cause) => cause.emitWarning(settings)
- case ClassSymbolInfoFailureSI9111(_) => settings.noInlineMissingBytecode
- case UnknownScalaInlineInfoVersion(_, _) => settings.noInlineMissingScalaInlineInfoAttr
+ case ClassSymbolInfoFailureSI9111(_) => settings.YoptWarningNoInlineMissingBytecode
+ case UnknownScalaInlineInfoVersion(_, _) => settings.YoptWarningNoInlineMissingScalaInlineInfoAttr
}
}
diff --git a/src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala b/src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala
index 86a69b92ea..f866c0d038 100644
--- a/src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala
+++ b/src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala
@@ -689,7 +689,7 @@ abstract class GenASM extends SubComponent with BytecodeWriters { self =>
null
else {
val outerName = javaName(innerSym.rawowner)
- if (isTopLevelModule(innerSym.rawowner)) "" + nme.stripModuleSuffix(newTermName(outerName))
+ if (isTopLevelModule(innerSym.rawowner)) "" + TermName(outerName).dropModule
else outerName
}
}
@@ -2054,7 +2054,7 @@ abstract class GenASM extends SubComponent with BytecodeWriters { self =>
seen ::= LocVarEntry(lv, start, end)
case _ =>
// TODO SI-6049 track down the cause for these.
- debugwarn(s"$iPos: Visited SCOPE_EXIT before visiting corresponding SCOPE_ENTER. SI-6191")
+ devWarning(s"$iPos: Visited SCOPE_EXIT before visiting corresponding SCOPE_ENTER. SI-6191")
}
}
@@ -2424,7 +2424,7 @@ abstract class GenASM extends SubComponent with BytecodeWriters { self =>
// SI-6102: Determine whether eliding this JUMP results in an empty range being covered by some EH.
// If so, emit a NOP in place of the elided JUMP, to avoid "java.lang.ClassFormatError: Illegal exception table range"
else if (newNormal.isJumpOnly(b) && m.exh.exists(eh => eh.covers(b))) {
- debugwarn("Had a jump only block that wasn't collapsed")
+ devWarning("Had a jump only block that wasn't collapsed")
emit(asm.Opcodes.NOP)
}
@@ -2883,8 +2883,8 @@ abstract class GenASM extends SubComponent with BytecodeWriters { self =>
var fieldList = List[String]()
for (f <- clasz.fields if f.symbol.hasGetter;
- g = f.symbol.getter(clasz.symbol);
- s = f.symbol.setter(clasz.symbol)
+ g = f.symbol.getterIn(clasz.symbol);
+ s = f.symbol.setterIn(clasz.symbol)
if g.isPublic && !(f.symbol.name startsWith "$")
) {
// inserting $outer breaks the bean
@@ -3136,13 +3136,13 @@ abstract class GenASM extends SubComponent with BytecodeWriters { self =>
val (remappings, cycles) = detour partition {case (source, target) => source != target}
for ((source, target) <- remappings) {
debuglog(s"Will elide jump only block $source because it can be jumped around to get to $target.")
- if (m.startBlock == source) debugwarn("startBlock should have been re-wired by now")
+ if (m.startBlock == source) devWarning("startBlock should have been re-wired by now")
}
val sources = remappings.keySet
val targets = remappings.values.toSet
val intersection = sources intersect targets
- if (intersection.nonEmpty) debugwarn(s"contradiction: we seem to have some source and target overlap in blocks ${intersection.mkString}. Map was ${detour.mkString}")
+ if (intersection.nonEmpty) devWarning(s"contradiction: we seem to have some source and target overlap in blocks ${intersection.mkString}. Map was ${detour.mkString}")
for ((source, _) <- cycles) {
debuglog(s"Block $source is in a do-nothing infinite loop. Did the user write 'while(true){}'?")
diff --git a/src/compiler/scala/tools/nsc/backend/jvm/GenBCode.scala b/src/compiler/scala/tools/nsc/backend/jvm/GenBCode.scala
index be1595dc29..c6ee36d7b2 100644
--- a/src/compiler/scala/tools/nsc/backend/jvm/GenBCode.scala
+++ b/src/compiler/scala/tools/nsc/backend/jvm/GenBCode.scala
@@ -14,7 +14,6 @@ import scala.reflect.internal.util.Statistics
import scala.tools.asm
import scala.tools.asm.tree.ClassNode
-import scala.tools.nsc.backend.jvm.opt.LocalOpt
/*
* Prepare in-memory representations of classfiles using the ASM Tree API, and serialize them to disk.
@@ -215,17 +214,12 @@ abstract class GenBCode extends BCodeSyncAndTry {
* - converting the plain ClassNode to byte array and placing it on queue-3
*/
class Worker2 {
- lazy val localOpt = new LocalOpt(settings)
-
def runGlobalOptimizations(): Unit = {
import scala.collection.convert.decorateAsScala._
q2.asScala foreach {
case Item2(_, _, plain, _, _) =>
// skip mirror / bean: wd don't inline into tem, and they are not used in the plain class
- if (plain != null) {
- localOpt.minimalRemoveUnreachableCode(plain)
- callGraph.addClass(plain)
- }
+ if (plain != null) callGraph.addClass(plain)
}
bTypes.inliner.runInliner()
}
diff --git a/src/compiler/scala/tools/nsc/backend/jvm/opt/BytecodeUtils.scala b/src/compiler/scala/tools/nsc/backend/jvm/opt/BytecodeUtils.scala
index 14e8cccc60..201ab15177 100644
--- a/src/compiler/scala/tools/nsc/backend/jvm/opt/BytecodeUtils.scala
+++ b/src/compiler/scala/tools/nsc/backend/jvm/opt/BytecodeUtils.scala
@@ -10,6 +10,7 @@ package opt
import scala.annotation.{tailrec, switch}
import scala.collection.mutable
import scala.reflect.internal.util.Collections._
+import scala.tools.asm.commons.CodeSizeEvaluator
import scala.tools.asm.tree.analysis._
import scala.tools.asm.{MethodWriter, ClassWriter, Label, Opcodes}
import scala.tools.asm.tree._
@@ -21,6 +22,12 @@ import scala.tools.nsc.backend.jvm.BTypes._
object BytecodeUtils {
+ // http://docs.oracle.com/javase/specs/jvms/se7/html/jvms-4.html#jvms-4.9.1
+ final val maxJVMMethodSize = 65535
+
+ // 5% margin, more than enough for the instructions added by the inliner (store / load args, null check for instance methods)
+ final val maxMethodSizeAfterInline = maxJVMMethodSize - (maxJVMMethodSize / 20)
+
object Goto {
def unapply(instruction: AbstractInsnNode): Option[JumpInsnNode] = {
if (instruction.getOpcode == Opcodes.GOTO) Some(instruction.asInstanceOf[JumpInsnNode])
@@ -83,10 +90,14 @@ object BytecodeUtils {
def isSynchronizedMethod(methodNode: MethodNode): Boolean = (methodNode.access & Opcodes.ACC_SYNCHRONIZED) != 0
+ def isNativeMethod(methodNode: MethodNode): Boolean = (methodNode.access & Opcodes.ACC_NATIVE) != 0
+
def isFinalClass(classNode: ClassNode): Boolean = (classNode.access & Opcodes.ACC_FINAL) != 0
def isFinalMethod(methodNode: MethodNode): Boolean = (methodNode.access & (Opcodes.ACC_FINAL | Opcodes.ACC_PRIVATE | Opcodes.ACC_STATIC)) != 0
+ def isStrictfpMethod(methodNode: MethodNode): Boolean = (methodNode.access & Opcodes.ACC_STRICT) != 0
+
def nextExecutableInstruction(instruction: AbstractInsnNode, alsoKeep: AbstractInsnNode => Boolean = Set()): Option[AbstractInsnNode] = {
var result = instruction
do { result = result.getNext }
@@ -215,7 +226,7 @@ object BytecodeUtils {
* to create a separate visitor for computing those values, duplicating the functionality from the
* MethodWriter.
*/
- def computeMaxLocalsMaxStack(method: MethodNode) {
+ def computeMaxLocalsMaxStack(method: MethodNode): Unit = {
val cw = new ClassWriter(ClassWriter.COMPUTE_MAXS)
val excs = method.exceptions.asScala.toArray
val mw = cw.visitMethod(method.access, method.name, method.desc, method.signature, excs).asInstanceOf[MethodWriter]
@@ -224,6 +235,21 @@ object BytecodeUtils {
method.maxStack = mw.getMaxStack
}
+ def codeSizeOKForInlining(caller: MethodNode, callee: MethodNode): Boolean = {
+ // Looking at the implementation of CodeSizeEvaluator, all instructions except tableswitch and
+ // lookupswitch are <= 8 bytes. These should be rare enough for 8 to be an OK rough upper bound.
+ def roughUpperBound(methodNode: MethodNode): Int = methodNode.instructions.size * 8
+
+ def maxSize(methodNode: MethodNode): Int = {
+ val eval = new CodeSizeEvaluator(null)
+ methodNode.accept(eval)
+ eval.getMaxSize
+ }
+
+ (roughUpperBound(caller) + roughUpperBound(callee) > maxMethodSizeAfterInline) &&
+ (maxSize(caller) + maxSize(callee) > maxMethodSizeAfterInline)
+ }
+
def removeLineNumberNodes(classNode: ClassNode): Unit = {
for (m <- classNode.methods.asScala) removeLineNumberNodes(m.instructions)
}
diff --git a/src/compiler/scala/tools/nsc/backend/jvm/opt/CallGraph.scala b/src/compiler/scala/tools/nsc/backend/jvm/opt/CallGraph.scala
index 47d32c94cb..028f0f8fa6 100644
--- a/src/compiler/scala/tools/nsc/backend/jvm/opt/CallGraph.scala
+++ b/src/compiler/scala/tools/nsc/backend/jvm/opt/CallGraph.scala
@@ -43,14 +43,14 @@ class CallGraph[BT <: BTypes](val btypes: BT) {
// callee, we only check there for the methodInlineInfo, we should find it there.
calleeDeclarationClassBType.info.orThrow.inlineInfo.methodInfos.get(methodSignature) match {
case Some(methodInlineInfo) =>
- val canInlineFromSource = inlineGlobalEnabled || calleeSource == CompilationUnit
+ val canInlineFromSource = compilerSettings.YoptInlineGlobal || calleeSource == CompilationUnit
val isAbstract = BytecodeUtils.isAbstractMethod(calleeMethodNode)
// (1) A non-final method can be safe to inline if the receiver type is a final subclass. Example:
// class A { @inline def f = 1 }; object B extends A; B.f // can be inlined
//
- // TODO: type analysis can render more calls statically resolved. Example˜∫
+ // TODO: type analysis can render more calls statically resolved. Example:
// new A.f // can be inlined, the receiver type is known to be exactly A.
val isStaticallyResolved: Boolean = {
methodInlineInfo.effectivelyFinal ||
@@ -68,8 +68,13 @@ class CallGraph[BT <: BTypes](val btypes: BT) {
// (2) Final trait methods can be rewritten from the interface to the static implementation
// method to enable inlining.
CallsiteInfo(
- safeToInline = canInlineFromSource && isStaticallyResolved && !isAbstract, // (1)
- safeToRewrite = canInlineFromSource && isRewritableTraitCall, // (2)
+ safeToInline =
+ canInlineFromSource &&
+ isStaticallyResolved && // (1)
+ !isAbstract &&
+ !BytecodeUtils.isConstructor(calleeMethodNode) &&
+ !BytecodeUtils.isNativeMethod(calleeMethodNode),
+ safeToRewrite = canInlineFromSource && isRewritableTraitCall, // (2)
annotatedInline = methodInlineInfo.annotatedInline,
annotatedNoInline = methodInlineInfo.annotatedNoInline,
warning = warning)
@@ -92,6 +97,7 @@ class CallGraph[BT <: BTypes](val btypes: BT) {
// TODO: for now we run a basic analyzer to get the stack height at the call site.
// once we run a more elaborate analyzer (types, nullness), we can get the stack height out of there.
+ localOpt.minimalRemoveUnreachableCode(methodNode, definingClass.internalName)
val analyzer = new AsmAnalyzer(methodNode, definingClass.internalName)
methodNode.instructions.iterator.asScala.collect({
diff --git a/src/compiler/scala/tools/nsc/backend/jvm/opt/Inliner.scala b/src/compiler/scala/tools/nsc/backend/jvm/opt/Inliner.scala
index e14e57d3ab..ac5c9ce2e6 100644
--- a/src/compiler/scala/tools/nsc/backend/jvm/opt/Inliner.scala
+++ b/src/compiler/scala/tools/nsc/backend/jvm/opt/Inliner.scala
@@ -16,7 +16,7 @@ import scala.collection.convert.decorateAsJava._
import AsmUtils._
import BytecodeUtils._
import collection.mutable
-import scala.tools.asm.tree.analysis.{SourceInterpreter, Analyzer}
+import scala.tools.asm.tree.analysis.SourceInterpreter
import BackendReporting._
import scala.tools.nsc.backend.jvm.BTypes.InternalName
@@ -24,21 +24,39 @@ class Inliner[BT <: BTypes](val btypes: BT) {
import btypes._
import callGraph._
+ def eliminateUnreachableCodeAndUpdateCallGraph(methodNode: MethodNode, definingClass: InternalName): Unit = {
+ localOpt.minimalRemoveUnreachableCode(methodNode, definingClass) foreach {
+ case invocation: MethodInsnNode => callGraph.callsites.remove(invocation)
+ case _ =>
+ }
+ }
+
def runInliner(): Unit = {
rewriteFinalTraitMethodInvocations()
for (request <- collectAndOrderInlineRequests) {
val Right(callee) = request.callee // collectAndOrderInlineRequests returns callsites with a known callee
- val r = inline(request.callsiteInstruction, request.callsiteStackHeight, request.callsiteMethod, request.callsiteClass,
- callee.callee, callee.calleeDeclarationClass,
- receiverKnownNotNull = false, keepLineNumbers = false)
-
- for (warning <- r) {
- if ((callee.annotatedInline && btypes.warnSettings.atInlineFailed) || warning.emitWarning(warnSettings)) {
- val annotWarn = if (callee.annotatedInline) " is annotated @inline but" else ""
- val msg = s"${BackendReporting.methodSignature(callee.calleeDeclarationClass.internalName, callee.callee)}$annotWarn could not be inlined:\n$warning"
- backendReporting.inlinerWarning(request.callsitePosition, msg)
+ // Inlining a method can create unreachable code. Example:
+ // def f = throw e
+ // def g = f; println() // println is unreachable after inlining f
+ // If we have an inline request for a call to g, and f has been already inlined into g, we
+ // need to run DCE before inlining g.
+ eliminateUnreachableCodeAndUpdateCallGraph(callee.callee, callee.calleeDeclarationClass.internalName)
+
+ // DCE above removes unreachable callsites from the call graph. If the inlining request denotes
+ // such an eliminated callsite, do nothing.
+ if (callGraph.callsites contains request.callsiteInstruction) {
+ val r = inline(request.callsiteInstruction, request.callsiteStackHeight, request.callsiteMethod, request.callsiteClass,
+ callee.callee, callee.calleeDeclarationClass,
+ receiverKnownNotNull = false, keepLineNumbers = false)
+
+ for (warning <- r) {
+ if ((callee.annotatedInline && btypes.compilerSettings.YoptWarningEmitAtInlineFailed) || warning.emitWarning(compilerSettings)) {
+ val annotWarn = if (callee.annotatedInline) " is annotated @inline but" else ""
+ val msg = s"${BackendReporting.methodSignature(callee.calleeDeclarationClass.internalName, callee.callee)}$annotWarn could not be inlined:\n$warning"
+ backendReporting.inlinerWarning(request.callsitePosition, msg)
+ }
}
}
}
@@ -75,7 +93,7 @@ class Inliner[BT <: BTypes](val btypes: BT) {
val res = doInlineCallsite(callsite)
if (!res) {
- if (annotatedInline && btypes.warnSettings.atInlineFailed) {
+ if (annotatedInline && btypes.compilerSettings.YoptWarningEmitAtInlineFailed) {
// if the callsite is annotated @inline, we report an inline warning even if the underlying
// reason is, for example, mixed compilation (which has a separate -Yopt-warning flag).
def initMsg = s"${BackendReporting.methodSignature(calleeDeclClass.internalName, callee)} is annotated @inline but cannot be inlined"
@@ -86,7 +104,7 @@ class Inliner[BT <: BTypes](val btypes: BT) {
backendReporting.inlinerWarning(pos, s"$initMsg: the method is not final and may be overridden." + warnMsg)
else
backendReporting.inlinerWarning(pos, s"$initMsg." + warnMsg)
- } else if (warning.isDefined && warning.get.emitWarning(warnSettings)) {
+ } else if (warning.isDefined && warning.get.emitWarning(compilerSettings)) {
// when annotatedInline is false, and there is some warning, the callsite metadata is possibly incomplete.
backendReporting.inlinerWarning(pos, s"there was a problem determining if method ${callee.name} can be inlined: \n"+ warning.get)
}
@@ -95,7 +113,7 @@ class Inliner[BT <: BTypes](val btypes: BT) {
res
case Callsite(ins, _, _, Left(warning), _, _, pos) =>
- if (warning.emitWarning(warnSettings))
+ if (warning.emitWarning(compilerSettings))
backendReporting.inlinerWarning(pos, s"failed to determine if ${ins.name} should be inlined:\n$warning")
false
}).toList
@@ -106,7 +124,8 @@ class Inliner[BT <: BTypes](val btypes: BT) {
*/
def doInlineCallsite(callsite: Callsite): Boolean = callsite match {
case Callsite(_, _, _, Right(Callee(callee, calleeDeclClass, safeToInline, _, annotatedInline, _, warning)), _, _, pos) =>
- annotatedInline && safeToInline
+ if (compilerSettings.YoptInlineHeuristics.value == "everything") safeToInline
+ else annotatedInline && safeToInline
case _ => false
}
@@ -167,6 +186,8 @@ class Inliner[BT <: BTypes](val btypes: BT) {
// VerifyError. We run a `SourceInterpreter` to find all producer instructions of the
// receiver value and add a cast to the self type after each.
if (!selfTypeOk) {
+ // there's no need to run eliminateUnreachableCode here. building the call graph does that
+ // already, no code can become unreachable in the meantime.
val analyzer = new AsmAnalyzer(callsite.callsiteMethod, callsite.callsiteClass.internalName, new SourceInterpreter)
val receiverValue = analyzer.frameAt(callsite.callsiteInstruction).peekDown(traitMethodArgumentTypes.length)
for (i <- receiverValue.insns.asScala) {
@@ -311,6 +332,7 @@ class Inliner[BT <: BTypes](val btypes: BT) {
val localVarShift = callsiteMethod.maxLocals
clonedInstructions.iterator.asScala foreach {
case varInstruction: VarInsnNode => varInstruction.`var` += localVarShift
+ case iinc: IincInsnNode => iinc.`var` += localVarShift
case _ => ()
}
@@ -433,6 +455,9 @@ class Inliner[BT <: BTypes](val btypes: BT) {
// Remove the elided invocation from the call graph
callGraph.callsites.remove(callsiteInstruction)
+ // Inlining a method body can render some code unreachable, see example above (in runInliner).
+ unreachableCodeEliminated -= callsiteMethod
+
callsiteMethod.maxLocals += returnType.getSize + callee.maxLocals
callsiteMethod.maxStack = math.max(callsiteMethod.maxStack, callee.maxStack + callsiteStackHeight)
@@ -472,10 +497,18 @@ class Inliner[BT <: BTypes](val btypes: BT) {
callsiteStackHeight > expectedArgs
}
- if (isSynchronizedMethod(callee)) {
+ if (codeSizeOKForInlining(callsiteMethod, callee)) {
+ Some(ResultingMethodTooLarge(
+ calleeDeclarationClass.internalName, callee.name, callee.desc,
+ callsiteClass.internalName, callsiteMethod.name, callsiteMethod.desc))
+ } else if (isSynchronizedMethod(callee)) {
// Could be done by locking on the receiver, wrapping the inlined code in a try and unlocking
// in finally. But it's probably not worth the effort, scala never emits synchronized methods.
Some(SynchronizedMethod(calleeDeclarationClass.internalName, callee.name, callee.desc))
+ } else if (isStrictfpMethod(callsiteMethod) != isStrictfpMethod(callee)) {
+ Some(StrictfpMismatch(
+ calleeDeclarationClass.internalName, callee.name, callee.desc,
+ callsiteClass.internalName, callsiteMethod.name, callsiteMethod.desc))
} else if (!callee.tryCatchBlocks.isEmpty && stackHasNonParameters) {
Some(MethodWithHandlerCalledOnNonEmptyStack(
calleeDeclarationClass.internalName, callee.name, callee.desc,
diff --git a/src/compiler/scala/tools/nsc/backend/jvm/opt/LocalOpt.scala b/src/compiler/scala/tools/nsc/backend/jvm/opt/LocalOpt.scala
index f6cfc5598b..5f51a94673 100644
--- a/src/compiler/scala/tools/nsc/backend/jvm/opt/LocalOpt.scala
+++ b/src/compiler/scala/tools/nsc/backend/jvm/opt/LocalOpt.scala
@@ -14,7 +14,6 @@ import scala.tools.asm.tree._
import scala.collection.convert.decorateAsScala._
import scala.tools.nsc.backend.jvm.BTypes.InternalName
import scala.tools.nsc.backend.jvm.opt.BytecodeUtils._
-import scala.tools.nsc.settings.ScalaSettings
/**
* Optimizations within a single method.
@@ -47,18 +46,9 @@ import scala.tools.nsc.settings.ScalaSettings
* stale labels
* - eliminate labels that are not referenced, merge sequences of label definitions.
*/
-class LocalOpt(settings: ScalaSettings) {
- /**
- * Remove unreachable code from all methods of `classNode`. See of its overload.
- *
- * @param classNode The class to optimize
- * @return `true` if unreachable code was removed from any method
- */
- def minimalRemoveUnreachableCode(classNode: ClassNode): Boolean = {
- classNode.methods.asScala.foldLeft(false) {
- case (changed, method) => minimalRemoveUnreachableCode(method, classNode.name) || changed
- }
- }
+class LocalOpt[BT <: BTypes](val btypes: BT) {
+ import LocalOptImpls._
+ import btypes._
/**
* Remove unreachable code from a method.
@@ -66,25 +56,30 @@ class LocalOpt(settings: ScalaSettings) {
* This implementation only removes instructions that are unreachable for an ASM analyzer /
* interpreter. This ensures that future analyses will not produce `null` frames. The inliner
* and call graph builder depend on this property.
+ *
+ * @return A set containing the eliminated instructions
*/
- def minimalRemoveUnreachableCode(method: MethodNode, ownerClassName: InternalName): Boolean = {
- if (method.instructions.size == 0) return false // fast path for abstract methods
+ def minimalRemoveUnreachableCode(method: MethodNode, ownerClassName: InternalName): Set[AbstractInsnNode] = {
+ if (method.instructions.size == 0) return Set.empty // fast path for abstract methods
+ if (unreachableCodeEliminated(method)) return Set.empty // we know there is no unreachable code
// For correctness, after removing unreachable code, we have to eliminate empty exception
// handlers, see scaladoc of def methodOptimizations. Removing an live handler may render more
// code unreachable and therefore requires running another round.
- def removalRound(): Boolean = {
- val (codeRemoved, liveLabels) = removeUnreachableCodeImpl(method, ownerClassName)
- if (codeRemoved) {
+ def removalRound(): Set[AbstractInsnNode] = {
+ val (removedInstructions, liveLabels) = removeUnreachableCodeImpl(method, ownerClassName)
+ val removedRecursively = if (removedInstructions.nonEmpty) {
val liveHandlerRemoved = removeEmptyExceptionHandlers(method).exists(h => liveLabels(h.start))
if (liveHandlerRemoved) removalRound()
- }
- codeRemoved
+ else Set.empty
+ } else Set.empty
+ removedInstructions ++ removedRecursively
}
- val codeRemoved = removalRound()
- if (codeRemoved) removeUnusedLocalVariableNodes(method)()
- codeRemoved
+ val removedInstructions = removalRound()
+ if (removedInstructions.nonEmpty) removeUnusedLocalVariableNodes(method)()
+ unreachableCodeEliminated += method
+ removedInstructions
}
/**
@@ -95,7 +90,7 @@ class LocalOpt(settings: ScalaSettings) {
* @return `true` if unreachable code was eliminated in some method, `false` otherwise.
*/
def methodOptimizations(clazz: ClassNode): Boolean = {
- !settings.YoptNone && clazz.methods.asScala.foldLeft(false) {
+ !compilerSettings.YoptNone && clazz.methods.asScala.foldLeft(false) {
case (changed, method) => methodOptimizations(method, clazz.name) || changed
}
}
@@ -144,15 +139,15 @@ class LocalOpt(settings: ScalaSettings) {
def removalRound(): Boolean = {
// unreachable-code, empty-handlers and simplify-jumps run until reaching a fixpoint (see doc on class LocalOpt)
- val (codeRemoved, handlersRemoved, liveHandlerRemoved) = if (settings.YoptUnreachableCode) {
- val (codeRemoved, liveLabels) = removeUnreachableCodeImpl(method, ownerClassName)
+ val (codeRemoved, handlersRemoved, liveHandlerRemoved) = if (compilerSettings.YoptUnreachableCode) {
+ val (removedInstructions, liveLabels) = removeUnreachableCodeImpl(method, ownerClassName)
val removedHandlers = removeEmptyExceptionHandlers(method)
- (codeRemoved, removedHandlers.nonEmpty, removedHandlers.exists(h => liveLabels(h.start)))
+ (removedInstructions.nonEmpty, removedHandlers.nonEmpty, removedHandlers.exists(h => liveLabels(h.start)))
} else {
(false, false, false)
}
- val jumpsChanged = if (settings.YoptSimplifyJumps) simplifyJumps(method) else false
+ val jumpsChanged = if (compilerSettings.YoptSimplifyJumps) simplifyJumps(method) else false
// Eliminating live handlers and simplifying jump instructions may render more code
// unreachable, so we need to run another round.
@@ -165,13 +160,13 @@ class LocalOpt(settings: ScalaSettings) {
// (*) Removing stale local variable descriptors is required for correctness of unreachable-code
val localsRemoved =
- if (settings.YoptCompactLocals) compactLocalVariables(method) // also removes unused
- else if (settings.YoptUnreachableCode) removeUnusedLocalVariableNodes(method)() // (*)
+ if (compilerSettings.YoptCompactLocals) compactLocalVariables(method) // also removes unused
+ else if (compilerSettings.YoptUnreachableCode) removeUnusedLocalVariableNodes(method)() // (*)
else false
- val lineNumbersRemoved = if (settings.YoptEmptyLineNumbers) removeEmptyLineNumbers(method) else false
+ val lineNumbersRemoved = if (compilerSettings.YoptEmptyLineNumbers) removeEmptyLineNumbers(method) else false
- val labelsRemoved = if (settings.YoptEmptyLabels) removeEmptyLabelNodes(method) else false
+ val labelsRemoved = if (compilerSettings.YoptEmptyLabels) removeEmptyLabelNodes(method) else false
// assert that local variable annotations are empty (we don't emit them) - otherwise we'd have
// to eliminate those covering an empty range, similar to removeUnusedLocalVariableNodes.
@@ -179,15 +174,22 @@ class LocalOpt(settings: ScalaSettings) {
assert(nullOrEmpty(method.visibleLocalVariableAnnotations), method.visibleLocalVariableAnnotations)
assert(nullOrEmpty(method.invisibleLocalVariableAnnotations), method.invisibleLocalVariableAnnotations)
+ unreachableCodeEliminated += method
+
codeHandlersOrJumpsChanged || localsRemoved || lineNumbersRemoved || labelsRemoved
}
+}
+
+object LocalOptImpls {
/**
* Removes unreachable basic blocks.
*
* TODO: rewrite, don't use computeMaxLocalsMaxStack (runs a ClassWriter) / Analyzer. Too slow.
+ *
+ * @return A set containing eliminated instructions, and a set containing all live label nodes.
*/
- def removeUnreachableCodeImpl(method: MethodNode, ownerClassName: InternalName): (Boolean, Set[LabelNode]) = {
+ def removeUnreachableCodeImpl(method: MethodNode, ownerClassName: InternalName): (Set[AbstractInsnNode], Set[LabelNode]) = {
// The data flow analysis requires the maxLocals / maxStack fields of the method to be computed.
computeMaxLocalsMaxStack(method)
val a = new Analyzer(new BasicInterpreter)
@@ -197,6 +199,7 @@ class LocalOpt(settings: ScalaSettings) {
val initialSize = method.instructions.size
var i = 0
var liveLabels = Set.empty[LabelNode]
+ var removedInstructions = Set.empty[AbstractInsnNode]
val itr = method.instructions.iterator()
while (itr.hasNext) {
itr.next() match {
@@ -209,11 +212,12 @@ class LocalOpt(settings: ScalaSettings) {
// Instruction iterators allow removing during iteration.
// Removing is O(1): instructions are doubly linked list elements.
itr.remove()
+ removedInstructions += ins
}
}
i += 1
}
- (method.instructions.size != initialSize, liveLabels)
+ (removedInstructions, liveLabels)
}
/**
diff --git a/src/compiler/scala/tools/nsc/javac/JavaParsers.scala b/src/compiler/scala/tools/nsc/javac/JavaParsers.scala
index 9433ddcf31..d34c14be0f 100644
--- a/src/compiler/scala/tools/nsc/javac/JavaParsers.scala
+++ b/src/compiler/scala/tools/nsc/javac/JavaParsers.scala
@@ -13,6 +13,7 @@ import symtab.Flags
import JavaTokens._
import scala.language.implicitConversions
import scala.reflect.internal.util.Position
+import scala.reflect.internal.util.ListOfNil
trait JavaParsers extends ast.parser.ParsersCommon with JavaScanners {
val global : Global
@@ -125,7 +126,7 @@ trait JavaParsers extends ast.parser.ParsersCommon with JavaScanners {
def makeSyntheticParam(count: Int, tpt: Tree): ValDef =
makeParam(nme.syntheticParamName(count), tpt)
def makeParam(name: String, tpt: Tree): ValDef =
- makeParam(name: TermName, tpt)
+ makeParam(TermName(name), tpt)
def makeParam(name: TermName, tpt: Tree): ValDef =
ValDef(Modifiers(Flags.JAVA | Flags.PARAM), name, tpt, EmptyTree)
diff --git a/src/compiler/scala/tools/nsc/plugins/Plugin.scala b/src/compiler/scala/tools/nsc/plugins/Plugin.scala
index 7837f9a11a..1a5529140c 100644
--- a/src/compiler/scala/tools/nsc/plugins/Plugin.scala
+++ b/src/compiler/scala/tools/nsc/plugins/Plugin.scala
@@ -7,7 +7,7 @@ package scala.tools.nsc
package plugins
import scala.tools.nsc.io.{ Jar }
-import scala.tools.nsc.util.ScalaClassLoader
+import scala.reflect.internal.util.ScalaClassLoader
import scala.reflect.io.{ Directory, File, Path }
import java.io.InputStream
import java.util.zip.ZipException
@@ -60,6 +60,8 @@ abstract class Plugin {
* @return true to continue, or false to opt out
*/
def init(options: List[String], error: String => Unit): Boolean = {
+ // call to deprecated method required here, we must continue to support
+ // code that subclasses that override `processOptions`.
processOptions(options, error)
true
}
diff --git a/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala b/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala
index d273995e6e..03fd0976e5 100644
--- a/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala
+++ b/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala
@@ -256,6 +256,13 @@ trait ScalaSettings extends AbsScalaSettings
def YoptInlineGlobal = Yopt.contains(YoptChoices.inlineGlobal)
def YoptInlinerEnabled = YoptInlineProject || YoptInlineGlobal
+ val YoptInlineHeuristics = ChoiceSetting(
+ name = "-Yopt-inline-heuristics",
+ helpArg = "strategy",
+ descr = "Set the heuristics for inlining decisions.",
+ choices = List("at-inline-annotated", "everything"),
+ default = "at-inline-annotated")
+
object YoptWarningsChoices extends MultiChoiceEnumeration {
val none = Choice("none" , "No optimizer warnings.")
val atInlineFailedSummary = Choice("at-inline-failed-summary" , "One-line summary if there were @inline method calls that could not be inlined.")
@@ -267,7 +274,7 @@ trait ScalaSettings extends AbsScalaSettings
val YoptWarnings = MultiChoiceSetting(
name = "-Yopt-warnings",
- helpArg = "warnings",
+ helpArg = "warning",
descr = "Enable optimizer warnings",
domain = YoptWarningsChoices,
default = Some(List(YoptWarningsChoices.atInlineFailed.name))) withPostSetHook (self => {
@@ -275,6 +282,15 @@ trait ScalaSettings extends AbsScalaSettings
else YinlinerWarnings.value = true
})
+ def YoptWarningEmitAtInlineFailed =
+ !YoptWarnings.isSetByUser ||
+ YoptWarnings.contains(YoptWarningsChoices.atInlineFailedSummary) ||
+ YoptWarnings.contains(YoptWarningsChoices.atInlineFailed)
+
+ def YoptWarningNoInlineMixed = YoptWarnings.contains(YoptWarningsChoices.noInlineMixed)
+ def YoptWarningNoInlineMissingBytecode = YoptWarnings.contains(YoptWarningsChoices.noInlineMissingBytecode)
+ def YoptWarningNoInlineMissingScalaInlineInfoAttr = YoptWarnings.contains(YoptWarningsChoices.noInlineMissingScalaInlineInfoAttr)
+
private def removalIn212 = "This flag is scheduled for removal in 2.12. If you have a case where you need this flag then please report a bug."
object YstatisticsPhases extends MultiChoiceEnumeration { val parser, typer, patmat, erasure, cleanup, jvm = Value }
@@ -345,12 +361,7 @@ trait ScalaSettings extends AbsScalaSettings
/** Test whether this is scaladoc we're looking at */
def isScaladoc = false
- /**
- * Helper utilities for use by checkConflictingSettings()
- */
- def isBCodeActive = !isICodeAskedFor
- def isBCodeAskedFor = (Ybackend.value != "GenASM")
- def isICodeAskedFor = ((Ybackend.value == "GenASM") || optimiseSettings.exists(_.value) || writeICode.isSetByUser)
+ def isBCodeActive = Ybackend.value == "GenBCode"
object MacroExpand {
val None = "none"
diff --git a/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala b/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala
index 4d08be3c24..994bcd8359 100644
--- a/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala
+++ b/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala
@@ -15,6 +15,7 @@ import scala.collection.mutable.{ ListBuffer, ArrayBuffer }
import scala.annotation.switch
import scala.reflect.internal.{ JavaAccFlags }
import scala.reflect.internal.pickling.{PickleBuffer, ByteCodecs}
+import scala.reflect.io.NoAbstractFile
import scala.tools.nsc.io.AbstractFile
import scala.tools.nsc.util.ClassFileLookup
@@ -807,10 +808,10 @@ abstract class ClassfileParser {
val c = pool.getConstant(u2)
val c1 = convertTo(c, symtype)
if (c1 ne null) sym.setInfo(ConstantType(c1))
- else debugwarn(s"failure to convert $c to $symtype")
+ else devWarning(s"failure to convert $c to $symtype")
case tpnme.ScalaSignatureATTR =>
if (!isScalaAnnot) {
- debugwarn(s"symbol ${sym.fullName} has pickled signature in attribute")
+ devWarning(s"symbol ${sym.fullName} has pickled signature in attribute")
unpickler.unpickle(in.buf, in.bp, clazz, staticModule, in.file.name)
}
in.skip(attrLen)
@@ -1022,11 +1023,18 @@ abstract class ClassfileParser {
val sflags = jflags.toScalaFlags
val owner = ownerForFlags(jflags)
val scope = getScope(jflags)
- val innerClass = owner.newClass(name.toTypeName, NoPosition, sflags) setInfo completer
- val innerModule = owner.newModule(name.toTermName, NoPosition, sflags) setInfo completer
+ def newStub(name: Name) =
+ owner.newStubSymbol(name, s"Class file for ${entry.externalName} not found").setFlag(JAVA)
- innerModule.moduleClass setInfo loaders.moduleClassLoader
- List(innerClass, innerModule.moduleClass) foreach (_.associatedFile = file)
+ val (innerClass, innerModule) = if (file == NoAbstractFile) {
+ (newStub(name.toTypeName), newStub(name.toTermName))
+ } else {
+ val cls = owner.newClass(name.toTypeName, NoPosition, sflags) setInfo completer
+ val mod = owner.newModule(name.toTermName, NoPosition, sflags) setInfo completer
+ mod.moduleClass setInfo loaders.moduleClassLoader
+ List(cls, mod.moduleClass) foreach (_.associatedFile = file)
+ (cls, mod)
+ }
scope enter innerClass
scope enter innerModule
@@ -1046,10 +1054,8 @@ abstract class ClassfileParser {
for (entry <- innerClasses.entries) {
// create a new class member for immediate inner classes
if (entry.outerName == currentClass) {
- val file = classFileLookup.findClassFile(entry.externalName.toString) getOrElse {
- throw new AssertionError(s"Class file for ${entry.externalName} not found")
- }
- enterClassAndModule(entry, file)
+ val file = classFileLookup.findClassFile(entry.externalName.toString)
+ enterClassAndModule(entry, file.getOrElse(NoAbstractFile))
}
}
}
@@ -1103,7 +1109,7 @@ abstract class ClassfileParser {
def enclosing = if (jflags.isStatic) enclModule else enclClass
// The name of the outer class, without its trailing $ if it has one.
- private def strippedOuter = nme stripModuleSuffix outerName
+ private def strippedOuter = outerName.dropModule
private def isInner = innerClasses contains strippedOuter
private def enclClass = if (isInner) innerClasses innerSymbol strippedOuter else classNameToSymbol(strippedOuter)
private def enclModule = enclClass.companionModule
@@ -1123,7 +1129,7 @@ abstract class ClassfileParser {
def add(entry: InnerClassEntry): Unit = {
inners get entry.externalName foreach (existing =>
- debugwarn(s"Overwriting inner class entry! Was $existing, now $entry")
+ devWarning(s"Overwriting inner class entry! Was $existing, now $entry")
)
inners(entry.externalName) = entry
}
diff --git a/src/compiler/scala/tools/nsc/symtab/classfile/ICodeReader.scala b/src/compiler/scala/tools/nsc/symtab/classfile/ICodeReader.scala
index bd1fa4e707..ea46116976 100644
--- a/src/compiler/scala/tools/nsc/symtab/classfile/ICodeReader.scala
+++ b/src/compiler/scala/tools/nsc/symtab/classfile/ICodeReader.scala
@@ -74,7 +74,7 @@ abstract class ICodeReader extends ClassfileParser {
first != CONSTANT_METHODREF &&
first != CONSTANT_INTFMETHODREF) errorBadTag(start)
val ownerTpe = getClassOrArrayType(in.getChar(start + 1).toInt)
- debuglog("getMemberSymbol(static: " + static + "): owner type: " + ownerTpe + " " + ownerTpe.typeSymbol.originalName)
+ debuglog("getMemberSymbol(static: " + static + "): owner type: " + ownerTpe + " " + ownerTpe.typeSymbol.unexpandedName)
val (name0, tpe0) = getNameAndType(in.getChar(start + 3).toInt, ownerTpe)
debuglog("getMemberSymbol: name and tpe: " + name0 + ": " + tpe0)
diff --git a/src/compiler/scala/tools/nsc/transform/AddInterfaces.scala b/src/compiler/scala/tools/nsc/transform/AddInterfaces.scala
index 3591372bbe..79776485de 100644
--- a/src/compiler/scala/tools/nsc/transform/AddInterfaces.scala
+++ b/src/compiler/scala/tools/nsc/transform/AddInterfaces.scala
@@ -207,7 +207,7 @@ abstract class AddInterfaces extends InfoTransform { self: Erasure =>
}
def transformMixinInfo(tp: Type): Type = tp match {
- case ClassInfoType(parents, decls, clazz) =>
+ case ClassInfoType(parents, decls, clazz) if clazz.isPackageClass || !clazz.isJavaDefined =>
if (clazz.needsImplClass)
implClass(clazz setFlag lateINTERFACE) // generate an impl class
diff --git a/src/compiler/scala/tools/nsc/transform/Constructors.scala b/src/compiler/scala/tools/nsc/transform/Constructors.scala
index 362cbde04f..d0fca12e6a 100644
--- a/src/compiler/scala/tools/nsc/transform/Constructors.scala
+++ b/src/compiler/scala/tools/nsc/transform/Constructors.scala
@@ -8,6 +8,7 @@ package transform
import scala.collection.{ mutable, immutable }
import scala.collection.mutable.ListBuffer
+import scala.reflect.internal.util.ListOfNil
import symtab.Flags._
/** This phase converts classes with parameters into Java-like classes with
diff --git a/src/compiler/scala/tools/nsc/transform/Erasure.scala b/src/compiler/scala/tools/nsc/transform/Erasure.scala
index 438d39bc86..9fdc3a9d72 100644
--- a/src/compiler/scala/tools/nsc/transform/Erasure.scala
+++ b/src/compiler/scala/tools/nsc/transform/Erasure.scala
@@ -1038,7 +1038,7 @@ abstract class Erasure extends AddInterfaces
// See SI-5568.
tree setSymbol Object_getClass
} else {
- debugwarn(s"The symbol '${fn.symbol}' was interecepted but didn't match any cases, that means the intercepted methods set doesn't match the code")
+ devWarning(s"The symbol '${fn.symbol}' was interecepted but didn't match any cases, that means the intercepted methods set doesn't match the code")
tree
}
} else qual match {
diff --git a/src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala b/src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala
index 6225b486c2..540de2cfe1 100644
--- a/src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala
+++ b/src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala
@@ -207,7 +207,7 @@ abstract class ExplicitOuter extends InfoTransform
// class needs to have a common naming scheme, independently of whether
// the field was accessed from an inner class or not. See #2946
if (sym.owner.isTrait && sym.isLocalToThis &&
- (sym.getter(sym.owner.toInterface) == NoSymbol))
+ (sym.getterIn(sym.owner.toInterface) == NoSymbol))
sym.makeNotPrivate(sym.owner)
tp
}
diff --git a/src/compiler/scala/tools/nsc/transform/Mixin.scala b/src/compiler/scala/tools/nsc/transform/Mixin.scala
index 7927875583..408f4466e1 100644
--- a/src/compiler/scala/tools/nsc/transform/Mixin.scala
+++ b/src/compiler/scala/tools/nsc/transform/Mixin.scala
@@ -232,13 +232,13 @@ abstract class Mixin extends InfoTransform with ast.TreeDSL {
for (member <- impl.info.decls) {
if (!member.isMethod && !member.isModule && !member.isModuleVar) {
assert(member.isTerm && !member.isDeferred, member)
- if (member.getter(impl).isPrivate) {
+ if (member.getterIn(impl).isPrivate) {
member.makeNotPrivate(clazz) // this will also make getter&setter not private
}
- val getter = member.getter(clazz)
+ val getter = member.getterIn(clazz)
if (getter == NoSymbol) addMember(clazz, newGetter(member))
if (!member.tpe.isInstanceOf[ConstantType] && !member.isLazy) {
- val setter = member.setter(clazz)
+ val setter = member.setterIn(clazz)
if (setter == NoSymbol) addMember(clazz, newSetter(member))
}
}
@@ -267,7 +267,7 @@ abstract class Mixin extends InfoTransform with ast.TreeDSL {
/* Mix in members of implementation class mixinClass into class clazz */
def mixinImplClassMembers(mixinClass: Symbol, mixinInterface: Symbol) {
- if (!mixinClass.isImplClass) debugwarn ("Impl class flag is not set " +
+ if (!mixinClass.isImplClass) devWarning ("Impl class flag is not set " +
((mixinClass.debugLocationString, mixinInterface.debugLocationString)))
for (member <- mixinClass.info.decls ; if isForwarded(member)) {
@@ -872,7 +872,7 @@ abstract class Mixin extends InfoTransform with ast.TreeDSL {
}
def mkCheckedAccessor(clazz: Symbol, retVal: Tree, offset: Int, pos: Position, fieldSym: Symbol): Tree = {
- val sym = fieldSym.getter(fieldSym.owner)
+ val sym = fieldSym.getterIn(fieldSym.owner)
val bitmapSym = bitmapFor(clazz, offset, sym)
val kind = bitmapKind(sym)
val mask = maskForOffset(offset, sym, kind)
@@ -921,7 +921,7 @@ abstract class Mixin extends InfoTransform with ast.TreeDSL {
deriveDefDef(stat)(addInitBits(clazz, _))
}
else if (settings.checkInit && !clazz.isTrait && sym.isSetter) {
- val getter = sym.getter(clazz)
+ val getter = sym.getterIn(clazz)
if (needsInitFlag(getter) && fieldOffset.isDefinedAt(getter))
deriveDefDef(stat)(rhs => Block(List(rhs, localTyper.typed(mkSetFlag(clazz, fieldOffset(getter), getter, bitmapKind(getter)))), UNIT))
else stat
@@ -1057,7 +1057,7 @@ abstract class Mixin extends InfoTransform with ast.TreeDSL {
def isOverriddenSetter(sym: Symbol) =
nme.isTraitSetterName(sym.name) && {
val other = sym.nextOverriddenSymbol
- isOverriddenAccessor(other.getter(other.owner), clazz.info.baseClasses)
+ isOverriddenAccessor(other.getterIn(other.owner), clazz.info.baseClasses)
}
// for all symbols `sym` in the class definition, which are mixed in:
@@ -1232,7 +1232,7 @@ abstract class Mixin extends InfoTransform with ast.TreeDSL {
// refer to fields in some implementation class via an abstract
// getter in the interface.
val iface = toInterface(sym.owner.tpe).typeSymbol
- val ifaceGetter = sym getter iface
+ val ifaceGetter = sym getterIn iface
if (ifaceGetter == NoSymbol) abort("No getter for " + sym + " in " + iface)
else typedPos(tree.pos)((qual DOT ifaceGetter)())
@@ -1240,7 +1240,7 @@ abstract class Mixin extends InfoTransform with ast.TreeDSL {
case Assign(Apply(lhs @ Select(qual, _), List()), rhs) =>
// assign to fields in some implementation class via an abstract
// setter in the interface.
- def setter = lhs.symbol.setter(toInterface(lhs.symbol.owner.tpe).typeSymbol) setPos lhs.pos
+ def setter = lhs.symbol.setterIn(toInterface(lhs.symbol.owner.tpe).typeSymbol) setPos lhs.pos
typedPos(tree.pos)((qual DOT setter)(rhs))
diff --git a/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala b/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala
index 1691b01e3e..086512677e 100644
--- a/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala
+++ b/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala
@@ -699,7 +699,7 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers {
} else if (m.isValue && !m.isMethod && !m.hasFlag(LAZY)) { // concrete value definition
def mkAccessor(field: Symbol, name: Name) = {
- val newFlags = (SPECIALIZED | m.getter(clazz).flags) & ~(LOCAL | CASEACCESSOR | PARAMACCESSOR)
+ val newFlags = (SPECIALIZED | m.getterIn(clazz).flags) & ~(LOCAL | CASEACCESSOR | PARAMACCESSOR)
// we rely on the super class to initialize param accessors
val sym = sClass.newMethod(name.toTermName, field.pos, newFlags)
info(sym) = SpecializedAccessor(field)
@@ -720,7 +720,7 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers {
if (nme.isLocalName(m.name)) {
val specGetter = mkAccessor(specVal, specVal.getterName) setInfo MethodType(Nil, specVal.info)
- val origGetter = overrideIn(sClass, m.getter(clazz))
+ val origGetter = overrideIn(sClass, m.getterIn(clazz))
info(origGetter) = Forward(specGetter)
enterMember(specGetter)
enterMember(origGetter)
@@ -733,12 +733,12 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers {
debuglog("override case field accessor %s -> %s".format(m.name.decode, cfaGetter.name.decode))
}
- if (specVal.isVariable && m.setter(clazz) != NoSymbol) {
+ if (specVal.isVariable && m.setterIn(clazz) != NoSymbol) {
val specSetter = mkAccessor(specVal, specGetter.setterName)
.resetFlag(STABLE)
specSetter.setInfo(MethodType(specSetter.newSyntheticValueParams(List(specVal.info)),
UnitTpe))
- val origSetter = overrideIn(sClass, m.setter(clazz))
+ val origSetter = overrideIn(sClass, m.setterIn(clazz))
info(origSetter) = Forward(specSetter)
enterMember(specSetter)
enterMember(origSetter)
diff --git a/src/compiler/scala/tools/nsc/transform/UnCurry.scala b/src/compiler/scala/tools/nsc/transform/UnCurry.scala
index e1cf53059a..3330fbcae2 100644
--- a/src/compiler/scala/tools/nsc/transform/UnCurry.scala
+++ b/src/compiler/scala/tools/nsc/transform/UnCurry.scala
@@ -10,6 +10,7 @@ package transform
import symtab.Flags._
import scala.collection.{ mutable, immutable }
import scala.language.postfixOps
+import scala.reflect.internal.util.ListOfNil
/*<export> */
/** - uncurry all symbol and tree types (@see UnCurryPhase) -- this includes normalizing all proper types.
@@ -206,7 +207,7 @@ abstract class UnCurry extends InfoTransform
// (() => Int) { def apply(): Int @typeConstraint }
case RefinedType(List(funTp), decls) =>
debuglog(s"eliminate refinement from function type ${fun.tpe}")
- fun.tpe = funTp
+ fun.setType(funTp)
case _ =>
()
}
diff --git a/src/compiler/scala/tools/nsc/transform/patmat/Logic.scala b/src/compiler/scala/tools/nsc/transform/patmat/Logic.scala
index 0b53dc37de..4ea569c8e6 100644
--- a/src/compiler/scala/tools/nsc/transform/patmat/Logic.scala
+++ b/src/compiler/scala/tools/nsc/transform/patmat/Logic.scala
@@ -9,8 +9,7 @@ package tools.nsc.transform.patmat
import scala.language.postfixOps
import scala.collection.mutable
-import scala.reflect.internal.util.Statistics
-import scala.reflect.internal.util.HashSet
+import scala.reflect.internal.util.{NoPosition, Position, Statistics, HashSet}
trait Logic extends Debugging {
import PatternMatchingStats._
@@ -71,6 +70,8 @@ trait Logic extends Debugging {
def unapply(v: Var): Some[Tree]
}
+ def uncheckedWarning(pos: Position, msg: String): Unit
+
def reportWarning(message: String): Unit
// resets hash consing -- only supposed to be called by TreeMakersToProps
@@ -283,6 +284,23 @@ trait Logic extends Debugging {
}
}
+ // to govern how much time we spend analyzing matches for unreachability/exhaustivity
+ object AnalysisBudget {
+ val maxDPLLdepth = global.settings.YpatmatExhaustdepth.value
+ val maxFormulaSize = 100 * math.min(Int.MaxValue / 100, maxDPLLdepth)
+
+ private def advice =
+ s"Please try with scalac -Ypatmat-exhaust-depth ${maxDPLLdepth * 2} or -Ypatmat-exhaust-depth off."
+
+ def recursionDepthReached =
+ s"Exhaustivity analysis reached max recursion depth, not all missing cases are reported.\n($advice)"
+
+ abstract class Exception(val advice: String) extends RuntimeException("CNF budget exceeded")
+
+ object formulaSizeExceeded extends Exception(s"The analysis required more space than allowed.\n$advice")
+
+ }
+
// TODO: remove since deprecated
val budgetProp = scala.sys.Prop[String]("scalac.patmat.analysisBudget")
if (budgetProp.isSet) {
@@ -385,7 +403,7 @@ trait Logic extends Debugging {
def findModelFor(solvable: Solvable): Model
- def findAllModelsFor(solvable: Solvable): List[Solution]
+ def findAllModelsFor(solvable: Solvable, pos: Position = NoPosition): List[Solution]
}
}
diff --git a/src/compiler/scala/tools/nsc/transform/patmat/MatchAnalysis.scala b/src/compiler/scala/tools/nsc/transform/patmat/MatchAnalysis.scala
index 34ebbc7463..cecb5c37be 100644
--- a/src/compiler/scala/tools/nsc/transform/patmat/MatchAnalysis.scala
+++ b/src/compiler/scala/tools/nsc/transform/patmat/MatchAnalysis.scala
@@ -399,6 +399,7 @@ trait MatchAnalysis extends MatchApproximation {
trait MatchAnalyzer extends MatchApproximator {
def uncheckedWarning(pos: Position, msg: String) = currentRun.reporting.uncheckedWarning(pos, msg)
+ def warn(pos: Position, ex: AnalysisBudget.Exception, kind: String) = uncheckedWarning(pos, s"Cannot check match for $kind.\n${ex.advice}")
def reportWarning(message: String) = global.reporter.warning(typer.context.tree.pos, message)
// TODO: model dependencies between variables: if V1 corresponds to (x: List[_]) and V2 is (x.hd), V2 cannot be assigned when V1 = null or V1 = Nil
@@ -429,44 +430,50 @@ trait MatchAnalysis extends MatchApproximation {
val propsCasesOk = approximate(True) map caseWithoutBodyToProp
val propsCasesFail = approximate(False) map (t => Not(caseWithoutBodyToProp(t)))
- val (eqAxiomsFail, symbolicCasesFail) = removeVarEq(propsCasesFail, modelNull = true)
- val (eqAxiomsOk, symbolicCasesOk) = removeVarEq(propsCasesOk, modelNull = true)
- val eqAxioms = simplify(And(eqAxiomsOk, eqAxiomsFail)) // I'm pretty sure eqAxiomsOk == eqAxiomsFail, but not 100% sure.
-
- val prefix = mutable.ArrayBuffer[Prop]()
- prefix += eqAxioms
-
- var prefixRest = symbolicCasesFail
- var current = symbolicCasesOk
- var reachable = true
- var caseIndex = 0
-
- debug.patmat("reachability, vars:\n" + ((propsCasesFail flatMap gatherVariables).distinct map (_.describe) mkString ("\n")))
- debug.patmat(s"equality axioms:\n$eqAxiomsOk")
-
- // invariant (prefixRest.length == current.length) && (prefix.reverse ++ prefixRest == symbolicCasesFail)
- // termination: prefixRest.length decreases by 1
- while (prefixRest.nonEmpty && reachable) {
- val prefHead = prefixRest.head
- caseIndex += 1
- prefixRest = prefixRest.tail
- if (prefixRest.isEmpty) reachable = true
- else {
- prefix += prefHead
- current = current.tail
+ try {
+ val (eqAxiomsFail, symbolicCasesFail) = removeVarEq(propsCasesFail, modelNull = true)
+ val (eqAxiomsOk, symbolicCasesOk) = removeVarEq(propsCasesOk, modelNull = true)
+ val eqAxioms = simplify(And(eqAxiomsOk, eqAxiomsFail)) // I'm pretty sure eqAxiomsOk == eqAxiomsFail, but not 100% sure.
+
+ val prefix = mutable.ArrayBuffer[Prop]()
+ prefix += eqAxioms
+
+ var prefixRest = symbolicCasesFail
+ var current = symbolicCasesOk
+ var reachable = true
+ var caseIndex = 0
+
+ debug.patmat("reachability, vars:\n" + ((propsCasesFail flatMap gatherVariables).distinct map (_.describe) mkString ("\n")))
+ debug.patmat(s"equality axioms:\n$eqAxiomsOk")
+
+ // invariant (prefixRest.length == current.length) && (prefix.reverse ++ prefixRest == symbolicCasesFail)
+ // termination: prefixRest.length decreases by 1
+ while (prefixRest.nonEmpty && reachable) {
+ val prefHead = prefixRest.head
+ caseIndex += 1
+ prefixRest = prefixRest.tail
+ if (prefixRest.isEmpty) reachable = true
+ else {
+ prefix += prefHead
+ current = current.tail
val and = And((current.head +: prefix): _*)
val model = findModelFor(eqFreePropToSolvable(and))
- // debug.patmat("trying to reach:\n"+ cnfString(current.head) +"\nunder prefix:\n"+ cnfString(prefix))
- // if (NoModel ne model) debug.patmat("reached: "+ modelString(model))
+ // debug.patmat("trying to reach:\n"+ cnfString(current.head) +"\nunder prefix:\n"+ cnfString(prefix))
+ // if (NoModel ne model) debug.patmat("reached: "+ modelString(model))
- reachable = NoModel ne model
+ reachable = NoModel ne model
+ }
}
- }
- if (Statistics.canEnable) Statistics.stopTimer(patmatAnaReach, start)
+ if (Statistics.canEnable) Statistics.stopTimer(patmatAnaReach, start)
- if (reachable) None else Some(caseIndex)
+ if (reachable) None else Some(caseIndex)
+ } catch {
+ case ex: AnalysisBudget.Exception =>
+ warn(prevBinder.pos, ex, "unreachability")
+ None // CNF budget exceeded
+ }
}
// exhaustivity
@@ -507,32 +514,38 @@ trait MatchAnalysis extends MatchApproximation {
// when does the match fail?
val matchFails = Not(\/(symbolicCases))
- // debug output:
+ // debug output:
debug.patmat("analysing:")
showTreeMakers(cases)
// debug.patmat("\nvars:\n"+ (vars map (_.describe) mkString ("\n")))
// debug.patmat("\nmatchFails as CNF:\n"+ cnfString(propToSolvable(matchFails)))
- // find the models (under which the match fails)
- val matchFailModels = findAllModelsFor(propToSolvable(matchFails))
+ try {
+ // find the models (under which the match fails)
+ val matchFailModels = findAllModelsFor(propToSolvable(matchFails), prevBinder.pos)
- val scrutVar = Var(prevBinderTree)
- val counterExamples = {
- matchFailModels.flatMap {
- model =>
- val varAssignments = expandModel(model)
- varAssignments.flatMap(modelToCounterExample(scrutVar) _)
+ val scrutVar = Var(prevBinderTree)
+ val counterExamples = {
+ matchFailModels.flatMap {
+ model =>
+ val varAssignments = expandModel(model)
+ varAssignments.flatMap(modelToCounterExample(scrutVar) _)
+ }
}
- }
-
- // sorting before pruning is important here in order to
- // keep neg/t7020.scala stable
- // since e.g. List(_, _) would cover List(1, _)
- val pruned = CounterExample.prune(counterExamples.sortBy(_.toString)).map(_.toString)
- if (Statistics.canEnable) Statistics.stopTimer(patmatAnaExhaust, start)
- pruned
+ // sorting before pruning is important here in order to
+ // keep neg/t7020.scala stable
+ // since e.g. List(_, _) would cover List(1, _)
+ val pruned = CounterExample.prune(counterExamples.sortBy(_.toString)).map(_.toString)
+
+ if (Statistics.canEnable) Statistics.stopTimer(patmatAnaExhaust, start)
+ pruned
+ } catch {
+ case ex: AnalysisBudget.Exception =>
+ warn(prevBinder.pos, ex, "exhaustivity")
+ Nil // CNF budget exceeded
+ }
}
}
diff --git a/src/compiler/scala/tools/nsc/transform/patmat/MatchTreeMaking.scala b/src/compiler/scala/tools/nsc/transform/patmat/MatchTreeMaking.scala
index b703b5bc6d..e1fe220556 100644
--- a/src/compiler/scala/tools/nsc/transform/patmat/MatchTreeMaking.scala
+++ b/src/compiler/scala/tools/nsc/transform/patmat/MatchTreeMaking.scala
@@ -577,8 +577,6 @@ trait MatchTreeMaking extends MatchCodeGen with Debugging {
lengthMax3(casesNoSubstOnly) > 2
}
val requireSwitch = hasSwitchAnnotation && exceedsTwoCasesOrAlts
- if (hasSwitchAnnotation && !requireSwitch)
- reporter.warning(scrut.pos, "matches with two cases or fewer are emitted using if-then-else instead of switch")
(suppression, requireSwitch)
case _ =>
(Suppression.NoSuppression, false)
diff --git a/src/compiler/scala/tools/nsc/transform/patmat/Solving.scala b/src/compiler/scala/tools/nsc/transform/patmat/Solving.scala
index 27217f0dc2..c43f1b6209 100644
--- a/src/compiler/scala/tools/nsc/transform/patmat/Solving.scala
+++ b/src/compiler/scala/tools/nsc/transform/patmat/Solving.scala
@@ -11,6 +11,7 @@ import scala.reflect.internal.util.Statistics
import scala.language.postfixOps
import scala.collection.mutable
import scala.reflect.internal.util.Collections._
+import scala.reflect.internal.util.Position
// a literal is a (possibly negated) variable
class Lit(val v: Int) extends AnyVal {
@@ -64,7 +65,12 @@ trait Solving extends Logic {
def size = symbols.size
}
- case class Solvable(cnf: Cnf, symbolMapping: SymbolMapping)
+ final case class Solvable(cnf: Cnf, symbolMapping: SymbolMapping) {
+ def ++(other: Solvable) = {
+ require(this.symbolMapping eq other.symbolMapping)
+ Solvable(cnf ++ other.cnf, symbolMapping)
+ }
+ }
trait CnfBuilder {
private[this] val buff = ArrayBuffer[Clause]()
@@ -95,7 +101,11 @@ trait Solving extends Logic {
}
}
- def buildCnf: Array[Clause] = buff.toArray
+ def buildCnf: Array[Clause] = {
+ val cnf = buff.toArray
+ buff.clear()
+ cnf
+ }
}
@@ -244,19 +254,54 @@ trait Solving extends Logic {
def eqFreePropToSolvable(p: Prop): Solvable = {
+ def doesFormulaExceedSize(p: Prop): Boolean = {
+ p match {
+ case And(ops) =>
+ if (ops.size > AnalysisBudget.maxFormulaSize) {
+ true
+ } else {
+ ops.exists(doesFormulaExceedSize)
+ }
+ case Or(ops) =>
+ if (ops.size > AnalysisBudget.maxFormulaSize) {
+ true
+ } else {
+ ops.exists(doesFormulaExceedSize)
+ }
+ case Not(a) => doesFormulaExceedSize(a)
+ case _ => false
+ }
+ }
+
+ val simplified = simplify(p)
+ if (doesFormulaExceedSize(simplified)) {
+ throw AnalysisBudget.formulaSizeExceeded
+ }
+
// collect all variables since after simplification / CNF conversion
// they could have been removed from the formula
val symbolMapping = new SymbolMapping(gatherSymbols(p))
-
- val simplified = simplify(p)
val cnfExtractor = new AlreadyInCNF(symbolMapping)
+ val cnfTransformer = new TransformToCnf(symbolMapping)
+
+ def cnfFor(prop: Prop): Solvable = {
+ prop match {
+ case cnfExtractor.ToCnf(solvable) =>
+ // this is needed because t6942 would generate too many clauses with Tseitin
+ // already in CNF, just add clauses
+ solvable
+ case p =>
+ cnfTransformer.apply(p)
+ }
+ }
+
simplified match {
- case cnfExtractor.ToCnf(solvable) =>
- // this is needed because t6942 would generate too many clauses with Tseitin
- // already in CNF, just add clauses
- solvable
- case p =>
- new TransformToCnf(symbolMapping).apply(p)
+ case And(props) =>
+ // SI-6942:
+ // CNF(P1 /\ ... /\ PN) == CNF(P1) ++ CNF(...) ++ CNF(PN)
+ props.map(cnfFor).reduce(_ ++ _)
+ case p =>
+ cnfFor(p)
}
}
}
@@ -288,7 +333,7 @@ trait Solving extends Logic {
val NoTseitinModel: TseitinModel = null
// returns all solutions, if any (TODO: better infinite recursion backstop -- detect fixpoint??)
- def findAllModelsFor(solvable: Solvable): List[Solution] = {
+ def findAllModelsFor(solvable: Solvable, pos: Position): List[Solution] = {
debug.patmat("find all models for\n"+ cnfString(solvable.cnf))
// we must take all vars from non simplified formula
@@ -308,13 +353,12 @@ trait Solving extends Logic {
final case class TseitinSolution(model: TseitinModel, unassigned: List[Int]) {
def projectToSolution(symForVar: Map[Int, Sym]) = Solution(projectToModel(model, symForVar), unassigned map symForVar)
}
+
def findAllModels(clauses: Array[Clause],
models: List[TseitinSolution],
- recursionDepthAllowed: Int = global.settings.YpatmatExhaustdepth.value): List[TseitinSolution]=
+ recursionDepthAllowed: Int = AnalysisBudget.maxDPLLdepth): List[TseitinSolution]=
if (recursionDepthAllowed == 0) {
- val maxDPLLdepth = global.settings.YpatmatExhaustdepth.value
- reportWarning("(Exhaustivity analysis reached max recursion depth, not all missing cases are reported. " +
- s"Please try with scalac -Ypatmat-exhaust-depth ${maxDPLLdepth * 2} or -Ypatmat-exhaust-depth off.)")
+ uncheckedWarning(pos, AnalysisBudget.recursionDepthReached)
models
} else {
debug.patmat("find all models for\n" + cnfString(clauses))
diff --git a/src/compiler/scala/tools/nsc/typechecker/Implicits.scala b/src/compiler/scala/tools/nsc/typechecker/Implicits.scala
index d3cd26f256..5ecca5abce 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Implicits.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Implicits.scala
@@ -276,7 +276,7 @@ trait Implicits {
/** An extractor for types of the form ? { name: (? >: argtpe <: Any*)restp }
*/
object HasMethodMatching {
- val dummyMethod = NoSymbol.newTermSymbol("typer$dummy") setInfo NullaryMethodType(AnyTpe)
+ val dummyMethod = NoSymbol.newTermSymbol(TermName("typer$dummy")) setInfo NullaryMethodType(AnyTpe)
def templateArgType(argtpe: Type) = new BoundedWildcardType(TypeBounds.lower(argtpe))
@@ -893,7 +893,7 @@ trait Implicits {
try improves(firstPending, alt)
catch {
case e: CyclicReference =>
- debugwarn(s"Discarding $firstPending during implicit search due to cyclic reference.")
+ devWarning(s"Discarding $firstPending during implicit search due to cyclic reference.")
true
}
)
diff --git a/src/compiler/scala/tools/nsc/typechecker/Infer.scala b/src/compiler/scala/tools/nsc/typechecker/Infer.scala
index cf97474d9a..27e17fc65f 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Infer.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Infer.scala
@@ -553,9 +553,8 @@ trait Infer extends Checkable {
// ...or lower bound of a type param, since they're asking for it.
def canWarnAboutAny = {
val loBounds = tparams map (_.info.bounds.lo)
- val hasAny = pt :: restpe :: formals ::: argtpes ::: loBounds exists (t =>
- (t contains AnyClass) || (t contains AnyValClass)
- )
+ def containsAny(t: Type) = (t contains AnyClass) || (t contains AnyValClass)
+ val hasAny = pt :: restpe :: formals ::: argtpes ::: loBounds exists (_.dealiasWidenChain exists containsAny)
!hasAny
}
def argumentPosition(idx: Int): Position = context.tree match {
diff --git a/src/compiler/scala/tools/nsc/typechecker/Macros.scala b/src/compiler/scala/tools/nsc/typechecker/Macros.scala
index da7b8b09aa..10aefae20b 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Macros.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Macros.scala
@@ -3,13 +3,14 @@ package typechecker
import java.lang.Math.min
import symtab.Flags._
-import scala.tools.nsc.util._
+import scala.reflect.internal.util.ScalaClassLoader
import scala.reflect.runtime.ReflectionUtils
import scala.collection.mutable.ListBuffer
import scala.reflect.ClassTag
import scala.reflect.internal.util.Statistics
import scala.reflect.macros.util._
import scala.util.control.ControlThrowable
+import scala.reflect.internal.util.ListOfNil
import scala.reflect.macros.runtime.{AbortMacroException, MacroRuntimes}
import scala.reflect.runtime.{universe => ru}
import scala.reflect.macros.compiler.DefaultMacroCompiler
diff --git a/src/compiler/scala/tools/nsc/typechecker/MethodSynthesis.scala b/src/compiler/scala/tools/nsc/typechecker/MethodSynthesis.scala
index 0aa62d771e..f90e32ce8a 100644
--- a/src/compiler/scala/tools/nsc/typechecker/MethodSynthesis.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/MethodSynthesis.scala
@@ -8,6 +8,7 @@ package typechecker
import symtab.Flags._
import scala.reflect.internal.util.StringOps.{ ojoin }
import scala.reflect.ClassTag
+import scala.reflect.internal.util.ListOfNil
import scala.reflect.runtime.{ universe => ru }
import scala.language.higherKinds
@@ -384,7 +385,7 @@ trait MethodSynthesis {
}
}
case class Getter(tree: ValDef) extends BaseGetter(tree) {
- override def derivedSym = if (mods.isDeferred) basisSym else basisSym.getter(enclClass)
+ override def derivedSym = if (mods.isDeferred) basisSym else basisSym.getterIn(enclClass)
private def derivedRhs = if (mods.isDeferred) EmptyTree else fieldSelection
private def derivedTpt = {
// For existentials, don't specify a type for the getter, even one derived
@@ -451,7 +452,7 @@ trait MethodSynthesis {
def flagsMask = SetterFlags
def flagsExtra = ACCESSOR
- override def derivedSym = basisSym.setter(enclClass)
+ override def derivedSym = basisSym.setterIn(enclClass)
}
case class Field(tree: ValDef) extends DerivedFromValDef {
def name = tree.localName
diff --git a/src/compiler/scala/tools/nsc/typechecker/Namers.scala b/src/compiler/scala/tools/nsc/typechecker/Namers.scala
index 711cfba24d..24238b8e41 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Namers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Namers.scala
@@ -10,6 +10,7 @@ import scala.collection.mutable
import scala.annotation.tailrec
import symtab.Flags._
import scala.language.postfixOps
+import scala.reflect.internal.util.ListOfNil
/** This trait declares methods to create symbols and to enter them into scopes.
*
@@ -464,7 +465,7 @@ trait Namers extends MethodSynthesis {
def enterModuleSymbol(tree : ModuleDef): Symbol = {
var m: Symbol = context.scope lookupModule tree.name
val moduleFlags = tree.mods.flags | MODULE
- if (m.isModule && !m.isPackage && inCurrentScope(m) && (currentRun.canRedefine(m) || m.isSynthetic)) {
+ if (m.isModule && !m.hasPackageFlag && inCurrentScope(m) && (currentRun.canRedefine(m) || m.isSynthetic)) {
// This code accounts for the way the package objects found in the classpath are opened up
// early by the completer of the package itself. If the `packageobjects` phase then finds
// the same package object in sources, we have to clean the slate and remove package object
@@ -487,7 +488,7 @@ trait Namers extends MethodSynthesis {
m.moduleClass setFlag moduleClassFlags(moduleFlags)
setPrivateWithin(tree, m.moduleClass)
}
- if (m.isTopLevel && !m.isPackage) {
+ if (m.isTopLevel && !m.hasPackageFlag) {
m.moduleClass.associatedFile = contextFile
currentRun.symSource(m) = m.moduleClass.sourceFile
registerTopLevelSym(m)
@@ -844,7 +845,7 @@ trait Namers extends MethodSynthesis {
private def widenIfNecessary(sym: Symbol, tpe: Type, pt: Type): Type = {
val getter =
if (sym.isValue && sym.owner.isClass && sym.isPrivate)
- sym.getter(sym.owner)
+ sym.getterIn(sym.owner)
else sym
def isHidden(tp: Type): Boolean = tp match {
case SingleType(pre, sym) =>
@@ -1305,7 +1306,7 @@ trait Namers extends MethodSynthesis {
// by martin: the null case can happen in IDE; this is really an ugly hack on top of an ugly hack but it seems to work
case Some(cda) =>
if (cda.companionModuleClassNamer == null) {
- debugwarn(s"SI-6576 The companion module namer for $meth was unexpectedly null")
+ devWarning(s"SI-6576 The companion module namer for $meth was unexpectedly null")
return
}
val p = (cda.classWithDefault, cda.companionModuleClassNamer)
diff --git a/src/compiler/scala/tools/nsc/typechecker/PatternTypers.scala b/src/compiler/scala/tools/nsc/typechecker/PatternTypers.scala
index fa4a764f1b..8a66c7d274 100644
--- a/src/compiler/scala/tools/nsc/typechecker/PatternTypers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/PatternTypers.scala
@@ -268,7 +268,7 @@ trait PatternTypers {
def freshArgType(tp: Type): Type = tp match {
case MethodType(param :: _, _) => param.tpe
- case PolyType(tparams, restpe) => createFromClonedSymbols(tparams, freshArgType(restpe))(polyType)
+ case PolyType(tparams, restpe) => createFromClonedSymbols(tparams, freshArgType(restpe))(genPolyType)
case OverloadedType(_, _) => OverloadedUnapplyError(fun) ; ErrorType
case _ => UnapplyWithSingleArgError(fun) ; ErrorType
}
diff --git a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala
index d2931ff9e1..5abfbe850f 100644
--- a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala
@@ -718,7 +718,7 @@ abstract class RefChecks extends InfoTransform with scala.reflect.internal.trans
// Check the remainder for invalid absoverride.
for (member <- rest ; if (member.isAbstractOverride && member.isIncompleteIn(clazz))) {
- val other = member.superSymbol(clazz)
+ val other = member.superSymbolIn(clazz)
val explanation =
if (other != NoSymbol) " and overrides incomplete superclass member " + infoString(other)
else ", but no concrete implementation could be found in a base class"
@@ -1684,9 +1684,9 @@ abstract class RefChecks extends InfoTransform with scala.reflect.internal.trans
case _ =>
}
if (skipBounds) {
- tree.tpe = tree.tpe.map {
+ tree.setType(tree.tpe.map {
_.filterAnnotations(_.symbol != UncheckedBoundsClass)
- }
+ })
}
tree
diff --git a/src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala b/src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala
index db81eecdf5..e0d96df062 100644
--- a/src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala
@@ -322,7 +322,7 @@ abstract class SuperAccessors extends transform.Transform with transform.TypingT
case Super(_, mix) =>
if (sym.isValue && !sym.isMethod || sym.hasAccessorFlag) {
if (!settings.overrideVars)
- reporter.error(tree.pos, "super may be not be used on " + sym.accessedOrSelf)
+ reporter.error(tree.pos, "super may not be used on " + sym.accessedOrSelf)
} else if (isDisallowed(sym)) {
reporter.error(tree.pos, "super not allowed here: use this." + name.decode + " instead")
}
diff --git a/src/compiler/scala/tools/nsc/typechecker/SyntheticMethods.scala b/src/compiler/scala/tools/nsc/typechecker/SyntheticMethods.scala
index d2046a158c..966e8f1abe 100644
--- a/src/compiler/scala/tools/nsc/typechecker/SyntheticMethods.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/SyntheticMethods.scala
@@ -344,7 +344,7 @@ trait SyntheticMethods extends ast.TreeDSL {
// Without a means to suppress this warning, I've thought better of it.
if (settings.warnValueOverrides) {
(clazz.info nonPrivateMember m.name) filter (m => (m.owner != AnyClass) && (m.owner != clazz) && !m.isDeferred) andAlso { m =>
- currentUnit.warning(clazz.pos, s"Implementation of ${m.name} inherited from ${m.owner} overridden in $clazz to enforce value class semantics")
+ typer.context.warning(clazz.pos, s"Implementation of ${m.name} inherited from ${m.owner} overridden in $clazz to enforce value class semantics")
}
}
true
diff --git a/src/compiler/scala/tools/nsc/typechecker/TreeCheckers.scala b/src/compiler/scala/tools/nsc/typechecker/TreeCheckers.scala
index 02356580cc..a7d48ceb89 100644
--- a/src/compiler/scala/tools/nsc/typechecker/TreeCheckers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/TreeCheckers.scala
@@ -300,8 +300,8 @@ abstract class TreeCheckers extends Analyzer {
checkSym(tree)
/* XXX: lots of syms show up here with accessed == NoSymbol. */
if (accessed != NoSymbol) {
- val agetter = accessed.getter(sym.owner)
- val asetter = accessed.setter(sym.owner)
+ val agetter = accessed.getterIn(sym.owner)
+ val asetter = accessed.setterIn(sym.owner)
assertFn(agetter == sym || asetter == sym,
sym + " is getter or setter, but accessed sym " + accessed + " shows " + agetter + " and " + asetter
@@ -311,7 +311,7 @@ abstract class TreeCheckers extends Analyzer {
}
case ValDef(_, _, _, _) =>
if (sym.hasGetter && !sym.isOuterField && !sym.isOuterAccessor) {
- assertFn(sym.getter(sym.owner) != NoSymbol, ownerstr(sym) + " has getter but cannot be found. " + sym.ownerChain)
+ assertFn(sym.getterIn(sym.owner) != NoSymbol, ownerstr(sym) + " has getter but cannot be found. " + sym.ownerChain)
}
case Apply(fn, args) =>
if (args exists (_ == EmptyTree))
diff --git a/src/compiler/scala/tools/nsc/typechecker/TypeDiagnostics.scala b/src/compiler/scala/tools/nsc/typechecker/TypeDiagnostics.scala
index 0f90c6a478..059981aa37 100644
--- a/src/compiler/scala/tools/nsc/typechecker/TypeDiagnostics.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/TypeDiagnostics.scala
@@ -141,8 +141,8 @@ trait TypeDiagnostics {
if (!member.hasAccessorFlag) member
else if (!member.isDeferred) member.accessed
else {
- val getter = if (member.isSetter) member.getter(member.owner) else member
- val flags = if (getter.setter(member.owner) != NoSymbol) DEFERRED.toLong | MUTABLE else DEFERRED
+ val getter = if (member.isSetter) member.getterIn(member.owner) else member
+ val flags = if (getter.setterIn(member.owner) != NoSymbol) DEFERRED.toLong | MUTABLE else DEFERRED
getter.owner.newValue(getter.name.toTermName, getter.pos, flags) setInfo getter.tpe.resultType
}
@@ -439,7 +439,7 @@ trait TypeDiagnostics {
context.warning(pos, "imported `%s' is permanently hidden by definition of %s".format(hidden, defn.fullLocationString))
object checkUnused {
- val ignoreNames = Set[TermName]("readResolve", "readObject", "writeObject", "writeReplace")
+ val ignoreNames: Set[TermName] = Set(TermName("readResolve"), TermName("readObject"), TermName("writeObject"), TermName("writeReplace"))
class UnusedPrivates extends Traverser {
val defnTrees = ListBuffer[MemberDef]()
diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
index d01e4f84ba..391ef9e337 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
@@ -14,7 +14,7 @@ package tools.nsc
package typechecker
import scala.collection.{mutable, immutable}
-import scala.reflect.internal.util.{ BatchSourceFile, Statistics, shortClassOfInstance }
+import scala.reflect.internal.util.{ BatchSourceFile, Statistics, shortClassOfInstance, ListOfNil }
import mutable.ListBuffer
import symtab.Flags._
import Mode._
@@ -245,7 +245,7 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper
case TypeRef(_, sym, _) if sym.isAliasType =>
val tp0 = tp.dealias
if (tp eq tp0) {
- debugwarn(s"dropExistential did not progress dealiasing $tp, see SI-7126")
+ devWarning(s"dropExistential did not progress dealiasing $tp, see SI-7126")
tp
} else {
val tp1 = dropExistential(tp0)
@@ -2044,7 +2044,7 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper
if (mexists(vparamss)(_.symbol == superArg.symbol)) {
val alias = (
superAcc.initialize.alias
- orElse (superAcc getter superAcc.owner)
+ orElse (superAcc getterIn superAcc.owner)
filter (alias => superClazz.info.nonPrivateMember(alias.name) == alias)
)
if (alias.exists && !alias.accessed.isVariable && !isRepeatedParamType(alias.accessed.info)) {
@@ -2565,7 +2565,7 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper
val default = methodSym newValueParameter (newTermName("default"), tree.pos.focus, SYNTHETIC) setInfo functionType(List(A1.tpe), B1.tpe)
val paramSyms = List(x, default)
- methodSym setInfo polyType(List(A1, B1), MethodType(paramSyms, B1.tpe))
+ methodSym setInfo genPolyType(List(A1, B1), MethodType(paramSyms, B1.tpe))
val methodBodyTyper = newTyper(context.makeNewScope(context.tree, methodSym))
if (!paramSynthetic) methodBodyTyper.context.scope enter x
@@ -2865,7 +2865,7 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper
ClassDef(Modifiers(FINAL), tpnme.ANON_FUN_NAME, tparams = Nil,
gen.mkTemplate(
parents = TypeTree(samClassTpFullyDefined) :: serializableParentAddendum,
- self = emptyValDef,
+ self = noSelfType,
constrMods = NoMods,
vparamss = ListOfNil,
body = List(samDef),
@@ -2934,7 +2934,7 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper
var issuedMissingParameterTypeError = false
foreach2(fun.vparams, argpts) { (vparam, argpt) =>
if (vparam.tpt.isEmpty) {
- vparam.tpt.tpe =
+ val vparamType =
if (isFullyDefined(argpt)) argpt
else {
fun match {
@@ -2953,6 +2953,7 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper
issuedMissingParameterTypeError = true
ErrorType
}
+ vparam.tpt.setType(vparamType)
if (!vparam.tpt.pos.isDefined) vparam.tpt setPos vparam.pos.focus
}
}
@@ -3387,7 +3388,6 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper
// defaults are needed. they are added to the argument list in named style as
// calls to the default getters. Example:
// foo[Int](a)() ==> foo[Int](a)(b = foo$qual.foo$default$2[Int](a))
- checkNotMacro()
// SI-8111 transformNamedApplication eagerly shuffles around the application to preserve
// evaluation order. During this process, it calls `changeOwner` on symbols that
@@ -3434,6 +3434,7 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper
duplErrTree
} else if (lencmp2 == 0) {
// useful when a default doesn't match parameter type, e.g. def f[T](x:T="a"); f[Int]()
+ checkNotMacro()
context.diagUsedDefaults = true
doTypedApply(tree, if (blockIsEmpty) fun else fun1, allArgs, mode, pt)
} else {
@@ -4365,7 +4366,7 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper
def narrowRhs(tp: Type) = { val sym = context.tree.symbol
context.tree match {
case ValDef(mods, _, _, Apply(Select(`tree`, _), _)) if !mods.isMutable && sym != null && sym != NoSymbol =>
- val sym1 = if (sym.owner.isClass && sym.getter(sym.owner) != NoSymbol) sym.getter(sym.owner)
+ val sym1 = if (sym.owner.isClass && sym.getterIn(sym.owner) != NoSymbol) sym.getterIn(sym.owner)
else sym.lazyAccessorOrSelf
val pre = if (sym1.owner.isClass) sym1.owner.thisType else NoPrefix
intersectionType(List(tp, singleType(pre, sym1)))
@@ -5198,15 +5199,12 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper
def warn(message: String) = context.warning(lit.pos, s"possible missing interpolator: $message")
def suspiciousSym(name: TermName) = context.lookupSymbol(name, _ => true).symbol
def suspiciousExpr = InterpolatorCodeRegex findFirstIn s
- def suspiciousIdents = InterpolatorIdentRegex findAllIn s map (s => suspiciousSym(s drop 1))
+ def suspiciousIdents = InterpolatorIdentRegex findAllIn s map (s => suspiciousSym(TermName(s drop 1)))
- // heuristics - no warning on e.g. a string with only "$asInstanceOf"
- if (s contains ' ') (
- if (suspiciousExpr.nonEmpty)
- warn("detected an interpolated expression") // "${...}"
- else
- suspiciousIdents find isPlausible foreach (sym => warn(s"detected interpolated identifier `$$${sym.name}`")) // "$id"
- )
+ if (suspiciousExpr.nonEmpty)
+ warn("detected an interpolated expression") // "${...}"
+ else
+ suspiciousIdents find isPlausible foreach (sym => warn(s"detected interpolated identifier `$$${sym.name}`")) // "$id"
}
lit match {
case Literal(Constant(s: String)) if !isRecognizablyNotForInterpolation => maybeWarn(s)
@@ -5384,8 +5382,8 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper
)
def runTyper(): Tree = {
if (retypingOk) {
- tree.tpe = null
- if (tree.hasSymbol) tree.symbol = NoSymbol
+ tree.setType(null)
+ if (tree.hasSymbolField) tree.symbol = NoSymbol
}
val alreadyTyped = tree.tpe ne null
val shouldPrint = !alreadyTyped && !phase.erasedTypes
diff --git a/src/compiler/scala/tools/nsc/typechecker/Unapplies.scala b/src/compiler/scala/tools/nsc/typechecker/Unapplies.scala
index fc1f45e358..22fb0728e6 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Unapplies.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Unapplies.scala
@@ -7,6 +7,7 @@ package scala.tools.nsc
package typechecker
import symtab.Flags._
+import scala.reflect.internal.util.ListOfNil
/*
* @author Martin Odersky
diff --git a/src/compiler/scala/tools/reflect/ToolBoxFactory.scala b/src/compiler/scala/tools/reflect/ToolBoxFactory.scala
index 1643e0061f..47c88f2c00 100644
--- a/src/compiler/scala/tools/reflect/ToolBoxFactory.scala
+++ b/src/compiler/scala/tools/reflect/ToolBoxFactory.scala
@@ -7,7 +7,7 @@ import scala.tools.nsc.Global
import scala.tools.nsc.reporters._
import scala.tools.nsc.CompilerCommand
import scala.tools.nsc.io.{AbstractFile, VirtualDirectory}
-import scala.tools.nsc.util.AbstractFileClassLoader
+import scala.reflect.internal.util.AbstractFileClassLoader
import scala.reflect.internal.Flags._
import scala.reflect.internal.util.{BatchSourceFile, NoSourceFile, NoFile}
import java.lang.{Class => jClass}
diff --git a/src/library/scala/annotation/switch.scala b/src/library/scala/annotation/switch.scala
index 23e3923407..00124cf88b 100644
--- a/src/library/scala/annotation/switch.scala
+++ b/src/library/scala/annotation/switch.scala
@@ -22,6 +22,9 @@ package scala.annotation
}
}}}
*
+ * Note: for pattern matches with one or two cases, the compiler generates jump instructions.
+ * Annotating such a match with `@switch` does not issue any warning.
+ *
* @author Paul Phillips
* @since 2.8
*/
diff --git a/src/library/scala/collection/GenTraversableOnce.scala b/src/library/scala/collection/GenTraversableOnce.scala
index 8c7c754af8..f77462ce88 100644
--- a/src/library/scala/collection/GenTraversableOnce.scala
+++ b/src/library/scala/collection/GenTraversableOnce.scala
@@ -278,7 +278,7 @@ trait GenTraversableOnce[+A] extends Any {
*
* @param op the binary operator.
* @tparam B the result type of the binary operator.
- * @return an option value containing the result of `reduceLeft(op)` is this $coll is nonempty,
+ * @return an option value containing the result of `reduceLeft(op)` if this $coll is nonempty,
* `None` otherwise.
*/
def reduceLeftOption[B >: A](op: (B, A) => B): Option[B]
@@ -290,7 +290,7 @@ trait GenTraversableOnce[+A] extends Any {
*
* @param op the binary operator.
* @tparam B the result type of the binary operator.
- * @return an option value containing the result of `reduceRight(op)` is this $coll is nonempty,
+ * @return an option value containing the result of `reduceRight(op)` if this $coll is nonempty,
* `None` otherwise.
*/
def reduceRightOption[B >: A](op: (A, B) => B): Option[B]
diff --git a/src/library/scala/collection/TraversableLike.scala b/src/library/scala/collection/TraversableLike.scala
index 32d31f0be8..96374ef653 100644
--- a/src/library/scala/collection/TraversableLike.scala
+++ b/src/library/scala/collection/TraversableLike.scala
@@ -54,7 +54,7 @@ import scala.language.higherKinds
* `HashMap` of objects. The traversal order for hash maps will
* depend on the hash codes of its elements, and these hash codes might
* differ from one run to the next. By contrast, a `LinkedHashMap`
- * is ordered because it's `foreach` method visits elements in the
+ * is ordered because its `foreach` method visits elements in the
* order they were inserted into the `HashMap`.
*
* @author Martin Odersky
diff --git a/src/library/scala/collection/TraversableOnce.scala b/src/library/scala/collection/TraversableOnce.scala
index 2eab58009c..c5b0d0f085 100644
--- a/src/library/scala/collection/TraversableOnce.scala
+++ b/src/library/scala/collection/TraversableOnce.scala
@@ -128,8 +128,21 @@ trait TraversableOnce[+A] extends Any with GenTraversableOnce[A] {
* @example `Seq("a", 1, 5L).collectFirst({ case x: Int => x*10 }) = Some(10)`
*/
def collectFirst[B](pf: PartialFunction[A, B]): Option[B] = {
- // make sure to use an iterator or `seq`
- self.toIterator.foreach(pf.runWith(b => return Some(b)))
+ // TODO 2.12 -- move out alternate implementations into child classes
+ val i: Iterator[A] = self match {
+ case it: Iterator[A] => it
+ case _: GenIterable[_] => self.toIterator // If it might be parallel, be sure to .seq or use iterator!
+ case _ => // Not parallel, not iterable--just traverse
+ self.foreach(pf.runWith(b => return Some(b)))
+ return None
+ }
+ // Presumably the fastest way to get in and out of a partial function is for a sentinel function to return itself
+ // (Tested to be lower-overhead than runWith. Would be better yet to not need to (formally) allocate it--change in 2.12.)
+ val sentinel: Function1[A, Any] = new scala.runtime.AbstractFunction1[A, Any]{ def apply(a: A) = this }
+ while (i.hasNext) {
+ val x = pf.applyOrElse(i.next, sentinel)
+ if (x.asInstanceOf[AnyRef] ne sentinel) return Some(x.asInstanceOf[B])
+ }
None
}
diff --git a/src/library/scala/runtime/BoxesRunTime.java b/src/library/scala/runtime/BoxesRunTime.java
index 82a3b00ac4..9cb1dee41c 100644
--- a/src/library/scala/runtime/BoxesRunTime.java
+++ b/src/library/scala/runtime/BoxesRunTime.java
@@ -28,7 +28,7 @@ import scala.math.ScalaNumber;
* @version 2.0 */
public final class BoxesRunTime
{
- private static final int CHAR = 0, BYTE = 1, SHORT = 2, INT = 3, LONG = 4, FLOAT = 5, DOUBLE = 6, OTHER = 7;
+ private static final int CHAR = 0, /* BYTE = 1, SHORT = 2, */ INT = 3, LONG = 4, FLOAT = 5, DOUBLE = 6, OTHER = 7;
/** We don't need to return BYTE and SHORT, as everything which might
* care widens to INT.
@@ -43,10 +43,6 @@ public final class BoxesRunTime
return OTHER;
}
- private static String boxDescription(Object a) {
- return "" + a.getClass().getSimpleName() + "(" + a + ")";
- }
-
/* BOXING ... BOXING ... BOXING ... BOXING ... BOXING ... BOXING ... BOXING ... BOXING */
public static java.lang.Boolean boxToBoolean(boolean b) {
diff --git a/src/reflect/scala/reflect/api/Names.scala b/src/reflect/scala/reflect/api/Names.scala
index 472da60338..cc01225287 100644
--- a/src/reflect/scala/reflect/api/Names.scala
+++ b/src/reflect/scala/reflect/api/Names.scala
@@ -30,15 +30,15 @@ import scala.language.implicitConversions
*/
trait Names {
/** An implicit conversion from String to TermName.
- * Enables an alternative notation `"map": TermName` as opposed to `TermName("map")`.
- * @group Names
+ * Enables an alternative notation `"map": TermName` as opposed to `TermName("map")`.
+ * @group Names
*/
@deprecated("Use explicit `TermName(s)` instead", "2.11.0")
implicit def stringToTermName(s: String): TermName = TermName(s)
/** An implicit conversion from String to TypeName.
- * Enables an alternative notation `"List": TypeName` as opposed to `TypeName("List")`.
- * @group Names
+ * Enables an alternative notation `"List": TypeName` as opposed to `TypeName("List")`.
+ * @group Names
*/
@deprecated("Use explicit `TypeName(s)` instead", "2.11.0")
implicit def stringToTypeName(s: String): TypeName = TypeName(s)
diff --git a/src/reflect/scala/reflect/api/StandardLiftables.scala b/src/reflect/scala/reflect/api/StandardLiftables.scala
index 66ac62cc9e..ebf15e4f57 100644
--- a/src/reflect/scala/reflect/api/StandardLiftables.scala
+++ b/src/reflect/scala/reflect/api/StandardLiftables.scala
@@ -230,6 +230,6 @@ trait StandardLiftables { self: Universe =>
val Symbol = TermName("Symbol")
val util = TermName("util")
val Vector = TermName("Vector")
- val WILDCARD = self.nme.WILDCARD
+ val WILDCARD = self.termNames.WILDCARD
}
}
diff --git a/src/reflect/scala/reflect/api/Trees.scala b/src/reflect/scala/reflect/api/Trees.scala
index 9ecd87c17e..2bf407ee19 100644
--- a/src/reflect/scala/reflect/api/Trees.scala
+++ b/src/reflect/scala/reflect/api/Trees.scala
@@ -2661,7 +2661,7 @@ trait Trees { self: Universe =>
* @group Traversal
*/
abstract class ModifiersExtractor {
- def apply(): Modifiers = Modifiers(NoFlags, tpnme.EMPTY, List())
+ def apply(): Modifiers = Modifiers(NoFlags, typeNames.EMPTY, List())
def apply(flags: FlagSet, privateWithin: Name, annotations: List[Tree]): Modifiers
def unapply(mods: Modifiers): Option[(FlagSet, Name, List[Tree])]
}
@@ -2674,7 +2674,7 @@ trait Trees { self: Universe =>
/** The factory for `Modifiers` instances.
* @group Traversal
*/
- def Modifiers(flags: FlagSet): Modifiers = Modifiers(flags, tpnme.EMPTY)
+ def Modifiers(flags: FlagSet): Modifiers = Modifiers(flags, typeNames.EMPTY)
/** An empty `Modifiers` object: no flags, empty visibility annotation and no Scala annotations.
* @group Traversal
diff --git a/src/reflect/scala/reflect/api/Types.scala b/src/reflect/scala/reflect/api/Types.scala
index f6995dd5de..cd7648a44a 100644
--- a/src/reflect/scala/reflect/api/Types.scala
+++ b/src/reflect/scala/reflect/api/Types.scala
@@ -469,7 +469,7 @@ trait Types {
def unapply(tpe: SingleType): Option[(Type, Symbol)]
/** @see [[InternalApi.singleType]] */
- @deprecated("Use `ClassSymbol.thisPrefix` or `internal.singleType` instead")
+ @deprecated("Use `ClassSymbol.thisPrefix` or `internal.singleType` instead", "2.11.0")
def apply(pre: Type, sym: Symbol)(implicit token: CompatToken): Type = internal.singleType(pre, sym)
}
diff --git a/src/reflect/scala/reflect/internal/Definitions.scala b/src/reflect/scala/reflect/internal/Definitions.scala
index 9f4ec3e6d1..756ed870ca 100644
--- a/src/reflect/scala/reflect/internal/Definitions.scala
+++ b/src/reflect/scala/reflect/internal/Definitions.scala
@@ -156,11 +156,11 @@ trait Definitions extends api.StandardDefinitions {
// It becomes tricky to create dedicated objects for other symbols because
// of initialization order issues.
- lazy val JavaLangPackage = getPackage("java.lang")
+ lazy val JavaLangPackage = getPackage(TermName("java.lang"))
lazy val JavaLangPackageClass = JavaLangPackage.moduleClass.asClass
- lazy val ScalaPackage = getPackage("scala")
+ lazy val ScalaPackage = getPackage(TermName("scala"))
lazy val ScalaPackageClass = ScalaPackage.moduleClass.asClass
- lazy val RuntimePackage = getPackage("scala.runtime")
+ lazy val RuntimePackage = getPackage(TermName("scala.runtime"))
lazy val RuntimePackageClass = RuntimePackage.moduleClass.asClass
def javaTypeToValueClass(jtype: Class[_]): Symbol = jtype match {
@@ -453,7 +453,7 @@ trait Definitions extends api.StandardDefinitions {
// XML
lazy val ScalaXmlTopScope = getModuleIfDefined("scala.xml.TopScope")
- lazy val ScalaXmlPackage = getPackageIfDefined("scala.xml")
+ lazy val ScalaXmlPackage = getPackageIfDefined(TermName("scala.xml"))
// scala.reflect
lazy val ReflectPackage = requiredModule[scala.reflect.`package`.type]
@@ -1148,7 +1148,7 @@ trait Definitions extends api.StandardDefinitions {
// Trying to allow for deprecated locations
sym.isAliasType && isMetaAnnotation(sym.info.typeSymbol)
)
- lazy val metaAnnotations: Set[Symbol] = getPackage("scala.annotation.meta").info.members filter (_ isSubClass StaticAnnotationClass) toSet
+ lazy val metaAnnotations: Set[Symbol] = getPackage(TermName("scala.annotation.meta")).info.members filter (_ isSubClass StaticAnnotationClass) toSet
// According to the scala.annotation.meta package object:
// * By default, annotations on (`val`-, `var`- or plain) constructor parameters
@@ -1462,7 +1462,7 @@ trait Definitions extends api.StandardDefinitions {
)
lazy val TagSymbols = TagMaterializers.keySet
lazy val Predef_conforms = (getMemberIfDefined(PredefModule, nme.conforms)
- orElse getMemberMethod(PredefModule, "conforms": TermName)) // TODO: predicate on -Xsource:2.10 (for now, needed for transition from M8 -> RC1)
+ orElse getMemberMethod(PredefModule, TermName("conforms"))) // TODO: predicate on -Xsource:2.10 (for now, needed for transition from M8 -> RC1)
lazy val Predef_classOf = getMemberMethod(PredefModule, nme.classOf)
lazy val Predef_implicitly = getMemberMethod(PredefModule, nme.implicitly)
lazy val Predef_wrapRefArray = getMemberMethod(PredefModule, nme.wrapRefArray)
diff --git a/src/reflect/scala/reflect/internal/Importers.scala b/src/reflect/scala/reflect/internal/Importers.scala
index dc4ad25ef2..494f62af06 100644
--- a/src/reflect/scala/reflect/internal/Importers.scala
+++ b/src/reflect/scala/reflect/internal/Importers.scala
@@ -301,7 +301,7 @@ trait Importers { to: SymbolTable =>
case (their: from.TypeTree, my: to.TypeTree) =>
if (their.wasEmpty) my.defineType(importType(their.tpe)) else my.setType(importType(their.tpe))
case (_, _) =>
- my.tpe = importType(their.tpe)
+ my.setType(importType(their.tpe))
}
}
}
diff --git a/src/reflect/scala/reflect/internal/Printers.scala b/src/reflect/scala/reflect/internal/Printers.scala
index 98b2c48379..b44c4022f6 100644
--- a/src/reflect/scala/reflect/internal/Printers.scala
+++ b/src/reflect/scala/reflect/internal/Printers.scala
@@ -1006,7 +1006,7 @@ trait Printers extends api.Printers { self: SymbolTable =>
printSuper(st, printedName(qual), checkSymbol = false)
case th @ This(qual) =>
- if (tree.hasExistingSymbol && tree.symbol.isPackage) print(tree.symbol.fullName)
+ if (tree.hasExistingSymbol && tree.symbol.hasPackageFlag) print(tree.symbol.fullName)
else printThis(th, printedName(qual))
// remove this prefix from constructor invocation in typechecked trees: this.this -> this
@@ -1023,7 +1023,7 @@ trait Printers extends api.Printers { self: SymbolTable =>
}) && (tr match { // check that Select contains package
case Select(q, _) => checkRootPackage(q)
case _: Ident | _: This => val sym = tr.symbol
- tr.hasExistingSymbol && sym.isPackage && sym.name != nme.ROOTPKG
+ tr.hasExistingSymbol && sym.hasPackageFlag && sym.name != nme.ROOTPKG
case _ => false
})
diff --git a/src/reflect/scala/reflect/internal/Symbols.scala b/src/reflect/scala/reflect/internal/Symbols.scala
index d23a102b28..d85ec22a84 100644
--- a/src/reflect/scala/reflect/internal/Symbols.scala
+++ b/src/reflect/scala/reflect/internal/Symbols.scala
@@ -155,11 +155,11 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
def toTypeConstructor: Type = typeConstructor
def setAnnotations(annots: AnnotationInfo*): this.type = { setAnnotations(annots.toList); this }
- def getter: Symbol = getter(owner)
- def setter: Symbol = setter(owner)
+ def getter: Symbol = getterIn(owner)
+ def setter: Symbol = setterIn(owner)
def companion: Symbol = {
- if (isModule && !isPackage) companionSymbol
+ if (isModule && !hasPackageFlag) companionSymbol
else if (isModuleClass && !isPackageClass) sourceModule.companionSymbol
else if (isClass && !isModuleClass && !isPackageClass) companionSymbol
else NoSymbol
@@ -1047,7 +1047,7 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
final def isIncompleteIn(base: Symbol): Boolean =
this.isDeferred ||
(this hasFlag ABSOVERRIDE) && {
- val supersym = superSymbol(base)
+ val supersym = superSymbolIn(base)
supersym == NoSymbol || supersym.isIncompleteIn(base)
}
@@ -2375,13 +2375,13 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
Nil
)
+ @deprecated("Use `superSymbolIn` instead", "2.11.0")
+ final def superSymbol(base: Symbol): Symbol = superSymbolIn(base)
+
/** The symbol accessed by a super in the definition of this symbol when
* seen from class `base`. This symbol is always concrete.
* pre: `this.owner` is in the base class sequence of `base`.
*/
- @deprecated("Use `superSymbolIn` instead", "2.11.0")
- final def superSymbol(base: Symbol): Symbol = superSymbolIn(base)
-
final def superSymbolIn(base: Symbol): Symbol = {
var bcs = base.info.baseClasses dropWhile (owner != _) drop 1
var sym: Symbol = NoSymbol
@@ -2393,12 +2393,10 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
sym
}
- /** The getter of this value or setter definition in class `base`, or NoSymbol if
- * none exists.
- */
@deprecated("Use `getterIn` instead", "2.11.0")
final def getter(base: Symbol): Symbol = getterIn(base)
+ /** The getter of this value or setter definition in class `base`, or NoSymbol if none exists. */
final def getterIn(base: Symbol): Symbol =
base.info decl getterName filter (_.hasAccessorFlag)
@@ -2406,11 +2404,11 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
def setterName: TermName = name.setterName
def localName: TermName = name.localName
- /** The setter of this value or getter definition, or NoSymbol if none exists */
@deprecated("Use `setterIn` instead", "2.11.0")
final def setter(base: Symbol, hasExpandedName: Boolean = needsExpandedSetterName): Symbol =
setterIn(base, hasExpandedName)
+ /** The setter of this value or getter definition, or NoSymbol if none exists. */
final def setterIn(base: Symbol, hasExpandedName: Boolean = needsExpandedSetterName): Symbol =
base.info decl setterNameInBase(base, hasExpandedName) filter (_.hasAccessorFlag)
@@ -2538,7 +2536,7 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
else if (isInstanceOf[FreeTermSymbol]) ("free term", "free term", "FTE")
else if (isInstanceOf[FreeTypeSymbol]) ("free type", "free type", "FTY")
else if (isPackageClass) ("package class", "package", "PKC")
- else if (isPackage) ("package", "package", "PK")
+ else if (hasPackageFlag) ("package", "package", "PK")
else if (isPackageObject) ("package object", "package", "PKO")
else if (isPackageObjectClass) ("package object class", "package", "PKOC")
else if (isAnonymousClass) ("anonymous class", "anonymous class", "AC")
@@ -2822,7 +2820,7 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
override def outerSource: Symbol =
// SI-6888 Approximate the name to workaround the deficiencies in `nme.originalName`
// in the face of classes named '$'. SI-2806 remains open to address the deeper problem.
- if (originalName endsWith (nme.OUTER)) initialize.referenced
+ if (unexpandedName endsWith (nme.OUTER)) initialize.referenced
else NoSymbol
def setModuleClass(clazz: Symbol): TermSymbol = {
@@ -2852,8 +2850,8 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
accessed.expandName(base)
}
else if (hasGetter) {
- getter(owner).expandName(base)
- setter(owner).expandName(base)
+ getterIn(owner).expandName(base)
+ setterIn(owner).expandName(base)
}
name = nme.expandedName(name.toTermName, base)
}
diff --git a/src/reflect/scala/reflect/internal/TreeGen.scala b/src/reflect/scala/reflect/internal/TreeGen.scala
index b3e11a826e..75a1969d22 100644
--- a/src/reflect/scala/reflect/internal/TreeGen.scala
+++ b/src/reflect/scala/reflect/internal/TreeGen.scala
@@ -362,7 +362,7 @@ abstract class TreeGen {
if (body forall treeInfo.isInterfaceMember) None
else Some(
atPos(wrappingPos(superPos, lvdefs)) (
- DefDef(NoMods, nme.MIXIN_CONSTRUCTOR, Nil, ListOfNil, TypeTree(), Block(lvdefs, Literal(Constant())))))
+ DefDef(NoMods, nme.MIXIN_CONSTRUCTOR, Nil, ListOfNil, TypeTree(), Block(lvdefs, Literal(Constant(()))))))
}
else {
// convert (implicit ... ) to ()(implicit ... ) if its the only parameter section
@@ -376,7 +376,7 @@ abstract class TreeGen {
// therefore here we emit a dummy which gets populated when the template is named and typechecked
Some(
atPos(wrappingPos(superPos, lvdefs ::: vparamss1.flatten).makeTransparent) (
- DefDef(constrMods, nme.CONSTRUCTOR, List(), vparamss1, TypeTree(), Block(lvdefs ::: List(superCall), Literal(Constant())))))
+ DefDef(constrMods, nme.CONSTRUCTOR, List(), vparamss1, TypeTree(), Block(lvdefs ::: List(superCall), Literal(Constant(()))))))
}
}
constr foreach (ensureNonOverlapping(_, parents ::: gvdefs, focus = false))
diff --git a/src/reflect/scala/reflect/internal/Trees.scala b/src/reflect/scala/reflect/internal/Trees.scala
index fd918b8595..e3f95f9fd8 100644
--- a/src/reflect/scala/reflect/internal/Trees.scala
+++ b/src/reflect/scala/reflect/internal/Trees.scala
@@ -87,7 +87,7 @@ trait Trees extends api.Trees {
private[scala] def copyAttrs(tree: Tree): this.type = {
rawatt = tree.rawatt
- tpe = tree.tpe
+ setType(tree.tpe)
if (hasSymbolField) symbol = tree.symbol
this
}
diff --git a/src/reflect/scala/reflect/internal/Types.scala b/src/reflect/scala/reflect/internal/Types.scala
index 8f114caac0..86a53a1b02 100644
--- a/src/reflect/scala/reflect/internal/Types.scala
+++ b/src/reflect/scala/reflect/internal/Types.scala
@@ -209,7 +209,7 @@ trait Types
case object UnmappableTree extends TermTree {
override def toString = "<unmappable>"
- super.tpe_=(NoType)
+ super.setType(NoType)
override def tpe_=(t: Type) = if (t != NoType) {
throw new UnsupportedOperationException("tpe_=("+t+") inapplicable for <empty>")
}
@@ -247,7 +247,7 @@ trait Types
def companion = {
val sym = typeSymbolDirect
- if (sym.isModule && !sym.isPackage) sym.companionSymbol.tpe
+ if (sym.isModule && !sym.hasPackageFlag) sym.companionSymbol.tpe
else if (sym.isModuleClass && !sym.isPackageClass) sym.sourceModule.companionSymbol.tpe
else if (sym.isClass && !sym.isModuleClass && !sym.isPackageClass) sym.companionSymbol.info
else NoType
diff --git a/src/reflect/scala/reflect/runtime/JavaMirrors.scala b/src/reflect/scala/reflect/runtime/JavaMirrors.scala
index 3b497227e7..237efd004f 100644
--- a/src/reflect/scala/reflect/runtime/JavaMirrors.scala
+++ b/src/reflect/scala/reflect/runtime/JavaMirrors.scala
@@ -142,7 +142,7 @@ private[scala] trait JavaMirrors extends internal.SymbolTable with api.JavaUnive
object ConstantArg {
def enumToSymbol(enum: Enum[_]): Symbol = {
val staticPartOfEnum = classToScala(enum.getClass).companionSymbol
- staticPartOfEnum.info.declaration(enum.name: TermName)
+ staticPartOfEnum.info.declaration(TermName(enum.name))
}
def unapply(schemaAndValue: (jClass[_], Any)): Option[Any] = schemaAndValue match {
@@ -172,7 +172,7 @@ private[scala] trait JavaMirrors extends internal.SymbolTable with api.JavaUnive
// currently I'm simply sorting the methods to guarantee stability of the output
override lazy val assocs: List[(Name, ClassfileAnnotArg)] = (
jann.annotationType.getDeclaredMethods.sortBy(_.getName).toList map (m =>
- (m.getName: TermName) -> toAnnotArg(m.getReturnType -> m.invoke(jann))
+ TermName(m.getName) -> toAnnotArg(m.getReturnType -> m.invoke(jann))
)
)
}
@@ -940,7 +940,7 @@ private[scala] trait JavaMirrors extends internal.SymbolTable with api.JavaUnive
val ownerModule: ModuleSymbol =
if (split > 0) packageNameToScala(fullname take split) else this.RootPackage
val owner = ownerModule.moduleClass
- val name = (fullname: TermName) drop split + 1
+ val name = TermName(fullname) drop split + 1
val opkg = owner.info decl name
if (opkg.hasPackageFlag)
opkg.asModule
@@ -991,7 +991,7 @@ private[scala] trait JavaMirrors extends internal.SymbolTable with api.JavaUnive
if (name.startsWith(nme.NAME_JOIN_STRING)) coreLookup(name drop 1) else NoSymbol
}
if (nme.isModuleName(simpleName))
- coreLookup(nme.stripModuleSuffix(simpleName).toTermName) map (_.moduleClass)
+ coreLookup(simpleName.dropModule.toTermName) map (_.moduleClass)
else
coreLookup(simpleName)
}
@@ -1285,16 +1285,12 @@ private[scala] trait JavaMirrors extends internal.SymbolTable with api.JavaUnive
jclazz getDeclaredConstructor (effectiveParamClasses: _*)
}
- private def jArrayClass(elemClazz: jClass[_]): jClass[_] = {
- jArray.newInstance(elemClazz, 0).getClass
- }
-
/** The Java class that corresponds to given Scala type.
* Pre: Scala type is already transformed to Java level.
*/
def typeToJavaClass(tpe: Type): jClass[_] = tpe match {
case ExistentialType(_, rtpe) => typeToJavaClass(rtpe)
- case TypeRef(_, ArrayClass, List(elemtpe)) => jArrayClass(typeToJavaClass(elemtpe))
+ case TypeRef(_, ArrayClass, List(elemtpe)) => ScalaRunTime.arrayClass(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)
diff --git a/src/reflect/scala/reflect/runtime/SymbolLoaders.scala b/src/reflect/scala/reflect/runtime/SymbolLoaders.scala
index 50ea8d9868..9ce6331e33 100644
--- a/src/reflect/scala/reflect/runtime/SymbolLoaders.scala
+++ b/src/reflect/scala/reflect/runtime/SymbolLoaders.scala
@@ -107,7 +107,8 @@ private[reflect] trait SymbolLoaders { self: SymbolTable =>
if (isCompilerUniverse) super.enter(sym)
else {
val existing = super.lookupEntry(sym.name)
- assert(existing == null || existing.sym.isMethod, s"pkgClass = $pkgClass, sym = $sym, existing = $existing")
+ def eitherIsMethod(sym1: Symbol, sym2: Symbol) = sym1.isMethod || sym2.isMethod
+ assert(existing == null || eitherIsMethod(existing.sym, sym), s"pkgClass = $pkgClass, sym = $sym, existing = $existing")
super.enter(sym)
}
}
diff --git a/src/reflect/scala/reflect/runtime/package.scala b/src/reflect/scala/reflect/runtime/package.scala
index e240bed0a7..77eb610a84 100644
--- a/src/reflect/scala/reflect/runtime/package.scala
+++ b/src/reflect/scala/reflect/runtime/package.scala
@@ -30,9 +30,9 @@ package runtime {
import c.universe._
val runtimeClass = c.reifyEnclosingRuntimeClass
if (runtimeClass.isEmpty) c.abort(c.enclosingPosition, "call site does not have an enclosing class")
- val scalaPackage = Select(Ident(newTermName("_root_")), newTermName("scala"))
- val runtimeUniverse = Select(Select(Select(scalaPackage, newTermName("reflect")), newTermName("runtime")), newTermName("universe"))
- val currentMirror = Apply(Select(runtimeUniverse, newTermName("runtimeMirror")), List(Select(runtimeClass, newTermName("getClassLoader"))))
+ val scalaPackage = Select(Ident(TermName("_root_")), TermName("scala"))
+ val runtimeUniverse = Select(Select(Select(scalaPackage, TermName("reflect")), TermName("runtime")), TermName("universe"))
+ val currentMirror = Apply(Select(runtimeUniverse, TermName("runtimeMirror")), List(Select(runtimeClass, TermName("getClassLoader"))))
c.Expr[Nothing](currentMirror)(c.WeakTypeTag.Nothing)
}
}
diff --git a/src/repl/scala/tools/nsc/interpreter/IMain.scala b/src/repl/scala/tools/nsc/interpreter/IMain.scala
index 0347622cf4..c281126d5f 100644
--- a/src/repl/scala/tools/nsc/interpreter/IMain.scala
+++ b/src/repl/scala/tools/nsc/interpreter/IMain.scala
@@ -309,7 +309,7 @@ class IMain(@BeanProperty val factory: ScriptEngineFactory, initialSettings: Set
def shift[T](op: => T): T = exitingFlatten(op)
}
- def originalPath(name: String): String = originalPath(name: TermName)
+ def originalPath(name: String): String = originalPath(TermName(name))
def originalPath(name: Name): String = typerOp path name
def originalPath(sym: Symbol): String = typerOp path sym
def flatPath(sym: Symbol): String = flatOp shift sym.javaClassName
@@ -1106,8 +1106,8 @@ class IMain(@BeanProperty val factory: ScriptEngineFactory, initialSettings: Set
def tryTwice(op: => Symbol): Symbol = exitingTyper(op) orElse exitingFlatten(op)
def symbolOfIdent(id: String): Symbol = symbolOfType(id) orElse symbolOfTerm(id)
- def symbolOfType(id: String): Symbol = tryTwice(replScope lookup (id: TypeName))
- def symbolOfTerm(id: String): Symbol = tryTwice(replScope lookup (id: TermName))
+ def symbolOfType(id: String): Symbol = tryTwice(replScope lookup TypeName(id))
+ def symbolOfTerm(id: String): Symbol = tryTwice(replScope lookup TermName(id))
def symbolOfName(id: Name): Symbol = replScope lookup id
def runtimeClassAndTypeOfTerm(id: String): Option[(JClass, Type)] = {
diff --git a/src/scaladoc/scala/tools/nsc/doc/base/CommentFactoryBase.scala b/src/scaladoc/scala/tools/nsc/doc/base/CommentFactoryBase.scala
index d31b877262..fb4ed34571 100755
--- a/src/scaladoc/scala/tools/nsc/doc/base/CommentFactoryBase.scala
+++ b/src/scaladoc/scala/tools/nsc/doc/base/CommentFactoryBase.scala
@@ -281,13 +281,16 @@ trait CommentFactoryBase { this: MemberLookupBase =>
parse0(docBody, tags + (key -> value), Some(key), ls, inCodeBlock)
case line :: ls if (lastTagKey.isDefined) =>
- val key = lastTagKey.get
- val value =
- ((tags get key): @unchecked) match {
- case Some(b :: bs) => (b + endOfLine + line) :: bs
- case None => oops("lastTagKey set when no tag exists for key")
- }
- parse0(docBody, tags + (key -> value), lastTagKey, ls, inCodeBlock)
+ val newtags = if (!line.isEmpty) {
+ val key = lastTagKey.get
+ val value =
+ ((tags get key): @unchecked) match {
+ case Some(b :: bs) => (b + endOfLine + line) :: bs
+ case None => oops("lastTagKey set when no tag exists for key")
+ }
+ tags + (key -> value)
+ } else tags
+ parse0(docBody, newtags, lastTagKey, ls, inCodeBlock)
case line :: ls =>
if (docBody.length > 0) docBody append endOfLine
@@ -315,18 +318,18 @@ trait CommentFactoryBase { this: MemberLookupBase =>
val bodyTags: mutable.Map[TagKey, List[Body]] =
mutable.Map(tagsWithoutDiagram mapValues {tag => tag map (parseWikiAtSymbol(_, pos, site))} toSeq: _*)
- def oneTag(key: SimpleTagKey): Option[Body] =
+ def oneTag(key: SimpleTagKey, filterEmpty: Boolean = true): Option[Body] =
((bodyTags remove key): @unchecked) match {
- case Some(r :: rs) =>
+ case Some(r :: rs) if !(filterEmpty && r.blocks.isEmpty) =>
if (!rs.isEmpty) reporter.warning(pos, "Only one '@" + key.name + "' tag is allowed")
Some(r)
- case None => None
+ case _ => None
}
def allTags(key: SimpleTagKey): List[Body] =
- (bodyTags remove key) getOrElse Nil
+ (bodyTags remove key).getOrElse(Nil).filterNot(_.blocks.isEmpty)
- def allSymsOneTag(key: TagKey): Map[String, Body] = {
+ def allSymsOneTag(key: TagKey, filterEmpty: Boolean = true): Map[String, Body] = {
val keys: Seq[SymbolTagKey] =
bodyTags.keys.toSeq flatMap {
case stk: SymbolTagKey if (stk.name == key.name) => Some(stk)
@@ -342,11 +345,11 @@ trait CommentFactoryBase { this: MemberLookupBase =>
reporter.warning(pos, "Only one '@" + key.name + "' tag for symbol " + key.symbol + " is allowed")
(key.symbol, bs.head)
}
- Map.empty[String, Body] ++ pairs
+ Map.empty[String, Body] ++ (if (filterEmpty) pairs.filterNot(_._2.blocks.isEmpty) else pairs)
}
def linkedExceptions: Map[String, Body] = {
- val m = allSymsOneTag(SimpleTagKey("throws"))
+ val m = allSymsOneTag(SimpleTagKey("throws"), filterEmpty = false)
m.map { case (name,body) =>
val link = memberLookup(pos, name, site)
@@ -372,7 +375,7 @@ trait CommentFactoryBase { this: MemberLookupBase =>
version0 = oneTag(SimpleTagKey("version")),
since0 = oneTag(SimpleTagKey("since")),
todo0 = allTags(SimpleTagKey("todo")),
- deprecated0 = oneTag(SimpleTagKey("deprecated")),
+ deprecated0 = oneTag(SimpleTagKey("deprecated"), filterEmpty = false),
note0 = allTags(SimpleTagKey("note")),
example0 = allTags(SimpleTagKey("example")),
constructor0 = oneTag(SimpleTagKey("constructor")),
diff --git a/src/scaladoc/scala/tools/nsc/doc/html/HtmlPage.scala b/src/scaladoc/scala/tools/nsc/doc/html/HtmlPage.scala
index ce75749859..86155845b0 100644
--- a/src/scaladoc/scala/tools/nsc/doc/html/HtmlPage.scala
+++ b/src/scaladoc/scala/tools/nsc/doc/html/HtmlPage.scala
@@ -206,25 +206,42 @@ abstract class HtmlPage extends Page { thisPage =>
case tpl :: tpls => templateToHtml(tpl) ++ sep ++ templatesToHtml(tpls, sep)
}
- /** Returns the _big image name corresponding to the DocTemplate Entity (upper left icon) */
- def docEntityKindToBigImage(ety: DocTemplateEntity) =
- if (ety.isTrait && !ety.companion.isEmpty && ety.companion.get.visibility.isPublic && ety.companion.get.inSource != None) "trait_to_object_big.png"
- else if (ety.isTrait) "trait_big.png"
- else if (ety.isClass && !ety.companion.isEmpty && ety.companion.get.visibility.isPublic && ety.companion.get.inSource != None) "class_to_object_big.png"
- else if (ety.isClass) "class_big.png"
- else if ((ety.isAbstractType || ety.isAliasType) && !ety.companion.isEmpty && ety.companion.get.visibility.isPublic && ety.companion.get.inSource != None) "type_to_object_big.png"
- else if ((ety.isAbstractType || ety.isAliasType)) "type_big.png"
- else if (ety.isObject && !ety.companion.isEmpty && ety.companion.get.visibility.isPublic && ety.companion.get.inSource != None && ety.companion.get.isClass) "object_to_class_big.png"
- else if (ety.isObject && !ety.companion.isEmpty && ety.companion.get.visibility.isPublic && ety.companion.get.inSource != None && ety.companion.get.isTrait) "object_to_trait_big.png"
- else if (ety.isObject && !ety.companion.isEmpty && ety.companion.get.visibility.isPublic && ety.companion.get.inSource != None && (ety.companion.get.isAbstractType || ety.companion.get.isAliasType)) "object_to_trait_big.png"
- else if (ety.isObject) "object_big.png"
- else if (ety.isPackage) "package_big.png"
- else "class_big.png" // FIXME: an entity *should* fall into one of the above categories, but AnyRef is somehow not
+ object Image extends Enumeration {
+ val Trait, Class, Type, Object, Package = Value
+ }
+
+ /** Returns the _big image name and the alt attribute
+ * corresponding to the DocTemplate Entity (upper left icon) */
+ def docEntityKindToBigImage(ety: DocTemplateEntity) = {
+ def entityToImage(e: DocTemplateEntity) =
+ if (e.isTrait) Image.Trait
+ else if (e.isClass) Image.Class
+ else if (e.isAbstractType || e.isAliasType) Image.Type
+ else if (e.isObject) Image.Object
+ else if (e.isPackage) Image.Package
+ else {
+ // FIXME: an entity *should* fall into one of the above categories,
+ // but AnyRef is somehow not
+ Image.Class
+ }
+
+ val image = entityToImage(ety)
+ val companionImage = ety.companion filter {
+ e => e.visibility.isPublic && ! e.inSource.isEmpty
+ } map { entityToImage }
+
+ (image, companionImage) match {
+ case (from, Some(to)) =>
+ ((from + "_to_" + to + "_big.png").toLowerCase, from + "/" + to)
+ case (from, None) =>
+ ((from + "_big.png").toLowerCase, from.toString)
+ }
+ }
def permalink(template: Entity, isSelf: Boolean = true): Elem =
<span class="permalink">
<a href={ memberToUrl(template, isSelf) } title="Permalink" target="_top">
- <img src={ relativeLinkTo(List("permalink.png", "lib")) } />
+ <img src={ relativeLinkTo(List("permalink.png", "lib")) } alt="Permalink" />
</a>
</span>
diff --git a/src/scaladoc/scala/tools/nsc/doc/html/SyntaxHigh.scala b/src/scaladoc/scala/tools/nsc/doc/html/SyntaxHigh.scala
index 910148532d..9ab3999447 100644
--- a/src/scaladoc/scala/tools/nsc/doc/html/SyntaxHigh.scala
+++ b/src/scaladoc/scala/tools/nsc/doc/html/SyntaxHigh.scala
@@ -52,7 +52,7 @@ private[html] object SyntaxHigh {
"Triple", "TypeTag", "Unit")
def apply(data: String): NodeSeq = {
- val buf = data.getBytes
+ val buf = data.toCharArray
val out = new StringBuilder
def compare(offset: Int, key: String): Int = {
@@ -60,7 +60,7 @@ private[html] object SyntaxHigh {
var j = 0
val l = key.length
while (i < buf.length && j < l) {
- val bch = buf(i).toChar
+ val bch = buf(i)
val kch = key charAt j
if (bch < kch) return -1
else if (bch > kch) return 1
@@ -94,13 +94,13 @@ private[html] object SyntaxHigh {
def line(i: Int): Int =
if (i == buf.length || buf(i) == '\n') i
else {
- out append buf(i).toChar
+ out append buf(i)
line(i+1)
}
var level = 0
def multiline(i: Int, star: Boolean): Int = {
if (i == buf.length) return i
- val ch = buf(i).toChar
+ val ch = buf(i)
out append ch
ch match {
case '*' =>
@@ -127,7 +127,7 @@ private[html] object SyntaxHigh {
if (i == buf.length) i
else if (i > j+6) { out setLength 0; j }
else {
- val ch = buf(i).toChar
+ val ch = buf(i)
out append ch
ch match {
case '\\' =>
@@ -148,7 +148,7 @@ private[html] object SyntaxHigh {
val out = new StringBuilder("\"")
def strlit0(i: Int, bslash: Boolean): Int = {
if (i == buf.length) return i
- val ch = buf(i).toChar
+ val ch = buf(i)
out append ch
ch match {
case '\\' =>
@@ -167,7 +167,7 @@ private[html] object SyntaxHigh {
val out = new StringBuilder
def intg(i: Int): Int = {
if (i == buf.length) return i
- val ch = buf(i).toChar
+ val ch = buf(i)
ch match {
case '.' =>
out append ch
@@ -181,7 +181,7 @@ private[html] object SyntaxHigh {
}
def frac(i: Int): Int = {
if (i == buf.length) return i
- val ch = buf(i).toChar
+ val ch = buf(i)
ch match {
case 'e' | 'E' =>
out append ch
@@ -195,7 +195,7 @@ private[html] object SyntaxHigh {
}
def expo(i: Int, signed: Boolean): Int = {
if (i == buf.length) return i
- val ch = buf(i).toChar
+ val ch = buf(i)
ch match {
case '+' | '-' if !signed =>
out append ch
@@ -222,7 +222,7 @@ private[html] object SyntaxHigh {
case '&' =>
parse("&amp;", i+1)
case '<' if i+1 < buf.length =>
- val ch = buf(i+1).toChar
+ val ch = buf(i+1)
if (ch == '-' || ch == ':' || ch == '%')
parse("<span class=\"kw\">&lt;"+ch+"</span>", i+2)
else
@@ -236,19 +236,19 @@ private[html] object SyntaxHigh {
if (i+1 < buf.length && buf(i+1) == '>')
parse("<span class=\"kw\">=&gt;</span>", i+2)
else
- parse(buf(i).toChar.toString, i+1)
+ parse(buf(i).toString, i+1)
case '/' =>
if (i+1 < buf.length && (buf(i+1) == '/' || buf(i+1) == '*')) {
val c = comment(i+1)
parse("<span class=\"cmt\">"+c+"</span>", i+c.length)
} else
- parse(buf(i).toChar.toString, i+1)
+ parse(buf(i).toString, i+1)
case '\'' =>
val s = charlit(i+1)
if (s.length > 0)
parse("<span class=\"lit\">"+s+"</span>", i+s.length)
else
- parse(buf(i).toChar.toString, i+1)
+ parse(buf(i).toString, i+1)
case '"' =>
val s = strlit(i+1)
parse("<span class=\"lit\">"+s+"</span>", i+s.length)
@@ -257,9 +257,9 @@ private[html] object SyntaxHigh {
if (k >= 0)
parse("<span class=\"ano\">@"+annotations(k)+"</span>", i+annotations(k).length+1)
else
- parse(buf(i).toChar.toString, i+1)
+ parse(buf(i).toString, i+1)
case _ =>
- if (i == 0 || (i >= 1 && !Character.isJavaIdentifierPart(buf(i-1).toChar))) {
+ if (i == 0 || (i >= 1 && !Character.isJavaIdentifierPart(buf(i-1)))) {
if (Character.isDigit(buf(i).toInt) ||
(buf(i) == '.' && i + 1 < buf.length && Character.isDigit(buf(i+1).toInt))) {
val s = numlit(i)
@@ -273,11 +273,11 @@ private[html] object SyntaxHigh {
if (k >= 0)
parse("<span class=\"std\">"+standards(k)+"</span>", i+standards(k).length)
else
- parse(buf(i).toChar.toString, i+1)
+ parse(buf(i).toString, i+1)
}
}
} else
- parse(buf(i).toChar.toString, i+1)
+ parse(buf(i).toString, i+1)
}
}
diff --git a/src/scaladoc/scala/tools/nsc/doc/html/page/Template.scala b/src/scaladoc/scala/tools/nsc/doc/html/page/Template.scala
index e10c54a414..c384ed7034 100644
--- a/src/scaladoc/scala/tools/nsc/doc/html/page/Template.scala
+++ b/src/scaladoc/scala/tools/nsc/doc/html/page/Template.scala
@@ -103,11 +103,13 @@ class Template(universe: doc.Universe, generator: DiagramGenerator, tpl: DocTemp
<body class={ if (tpl.isType) "type" else "value" }>
<div id="definition">
{
+ val (src, alt) = docEntityKindToBigImage(tpl)
+
tpl.companion match {
case Some(companion) if (companion.visibility.isPublic && companion.inSource != None) =>
- <a href={relativeLinkTo(companion)} title={docEntityKindToCompanionTitle(tpl)}><img src={ relativeLinkTo(List(docEntityKindToBigImage(tpl), "lib")) }/></a>
+ <a href={relativeLinkTo(companion)} title={docEntityKindToCompanionTitle(tpl)}><img alt={alt} src={ relativeLinkTo(List(src, "lib")) }/></a>
case _ =>
- <img src={ relativeLinkTo(List(docEntityKindToBigImage(tpl), "lib")) }/>
+ <img alt={alt} src={ relativeLinkTo(List(src, "lib")) }/>
}}
{ owner }
<h1>{ displayName }</h1>{
diff --git a/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/template.css b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/template.css
index e129e6cf6a..e84d7c1ca6 100644
--- a/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/template.css
+++ b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/template.css
@@ -210,6 +210,7 @@ dl.attributes > dd {
display: block;
padding-left: 10em;
margin-bottom: 5px;
+ min-height: 15px;
}
#template .values > h3 {
@@ -669,6 +670,7 @@ div.fullcomment dl.paramcmts > dd {
padding-left: 10px;
margin-bottom: 5px;
margin-left: 70px;
+ min-height: 15px;
}
/* Members filter tool */
diff --git a/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/template.js b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/template.js
index 1ebcb67f04..798a2d430b 100644
--- a/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/template.js
+++ b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/template.js
@@ -179,7 +179,7 @@ $(document).ready(function(){
filter();
});
- $("#visbl > ol > li.public").click(function() {
+ $("#order > ol > li.alpha").click(function() {
if ($(this).hasClass("out")) {
orderAlpha();
}
diff --git a/test/files/jvm/t8689.scala b/test/files/jvm/t8689.scala
index ef43a1df63..3ee20d711a 100644
--- a/test/files/jvm/t8689.scala
+++ b/test/files/jvm/t8689.scala
@@ -4,10 +4,15 @@ object Test {
import ExecutionContext.Implicits.global
val source1 = Promise[Int]()
val source2 = Promise[Int]()
+ val done = Promise[Unit]()
source2.completeWith(source1.future).future.onComplete {
- case _ => print("success")
+ case _ =>
+ print("success")
+ done.success(())
}
source2.tryFailure(new TimeoutException)
source1.success(123)
+ import duration._
+ Await.result(done.future, 120.seconds)
}
-} \ No newline at end of file
+}
diff --git a/test/files/neg/case-collision2.flags b/test/files/neg/case-collision2.flags
index 5bfa9da5c5..bea46902c9 100644
--- a/test/files/neg/case-collision2.flags
+++ b/test/files/neg/case-collision2.flags
@@ -1 +1 @@
--Ynooptimize -Ybackend:GenBCode -Xfatal-warnings
+-Ybackend:GenBCode -Xfatal-warnings
diff --git a/test/files/neg/inlineMaxSize.check b/test/files/neg/inlineMaxSize.check
new file mode 100644
index 0000000000..d218a8b6e2
--- /dev/null
+++ b/test/files/neg/inlineMaxSize.check
@@ -0,0 +1,9 @@
+inlineMaxSize.scala:7: warning: C::i()I is annotated @inline but could not be inlined:
+The size of the callsite method C::j()I
+would exceed the JVM method size limit after inlining C::i()I.
+
+ @inline final def j = i + i
+ ^
+error: No warnings can be incurred under -Xfatal-warnings.
+one warning found
+one error found
diff --git a/test/files/neg/inlineMaxSize.flags b/test/files/neg/inlineMaxSize.flags
new file mode 100644
index 0000000000..9c6b811622
--- /dev/null
+++ b/test/files/neg/inlineMaxSize.flags
@@ -0,0 +1 @@
+-Ybackend:GenBCode -Ydelambdafy:method -Yopt:l:classpath -Yopt-warnings -Xfatal-warnings \ No newline at end of file
diff --git a/test/files/neg/inlineMaxSize.scala b/test/files/neg/inlineMaxSize.scala
new file mode 100644
index 0000000000..16dc0d9538
--- /dev/null
+++ b/test/files/neg/inlineMaxSize.scala
@@ -0,0 +1,8 @@
+// not a JUnit test because of https://github.com/scala-opt/scala/issues/23
+class C {
+ @inline final def f = 0
+ @inline final def g = f + f + f + f + f + f + f + f + f + f
+ @inline final def h = g + g + g + g + g + g + g + g + g + g
+ @inline final def i = h + h + h + h + h + h + h + h + h + h
+ @inline final def j = i + i
+}
diff --git a/test/files/neg/macro-invalidusage-badargs.check b/test/files/neg/macro-invalidusage-badargs.check
index 4c1115418b..19ac6528d3 100644
--- a/test/files/neg/macro-invalidusage-badargs.check
+++ b/test/files/neg/macro-invalidusage-badargs.check
@@ -9,7 +9,8 @@ Macros_Test_2.scala:6: error: too few argument lists for macro invocation
Macros_Test_2.scala:7: error: Int does not take parameters
foo(4)(2)
^
-Macros_Test_2.scala:8: error: macro applications do not support named and/or default arguments
+Macros_Test_2.scala:8: error: not enough arguments for macro method foo: (x: Int)Int.
+Unspecified value parameter x.
foo()
^
Macros_Test_2.scala:9: error: too many arguments for macro method foo: (x: Int)Int
diff --git a/test/files/neg/reflection-names-neg.check b/test/files/neg/reflection-names-neg.check
deleted file mode 100644
index f941ec8dc1..0000000000
--- a/test/files/neg/reflection-names-neg.check
+++ /dev/null
@@ -1,13 +0,0 @@
-reflection-names-neg.scala:5: error: type mismatch;
- found : String("abc")
- required: reflect.runtime.universe.Name
-Note that implicit conversions are not applicable because they are ambiguous:
- both method stringToTermName in trait Names of type (s: String)reflect.runtime.universe.TermName
- and method stringToTypeName in trait Names of type (s: String)reflect.runtime.universe.TypeName
- are possible conversion functions from String("abc") to reflect.runtime.universe.Name
- val x2 = ("abc": Name) drop 1 // error
- ^
-reflection-names-neg.scala:5: error: value drop is not a member of reflect.runtime.universe.Name
- val x2 = ("abc": Name) drop 1 // error
- ^
-two errors found
diff --git a/test/files/neg/reflection-names-neg.scala b/test/files/neg/reflection-names-neg.scala
deleted file mode 100644
index 7283d16db9..0000000000
--- a/test/files/neg/reflection-names-neg.scala
+++ /dev/null
@@ -1,6 +0,0 @@
-import scala.reflect.runtime.universe._
-
-object Test {
- val x1 = "abc" drop 1 // "bc": String
- val x2 = ("abc": Name) drop 1 // error
-}
diff --git a/test/files/neg/t0899.check b/test/files/neg/t0899.check
index 8b71be8e0c..28cb06ae5a 100644
--- a/test/files/neg/t0899.check
+++ b/test/files/neg/t0899.check
@@ -1,10 +1,10 @@
-t0899.scala:9: error: super may be not be used on value o
+t0899.scala:9: error: super may not be used on value o
override val o = "Ha! " + super.o
^
-t0899.scala:11: error: super may be not be used on variable v
+t0899.scala:11: error: super may not be used on variable v
super.v = "aa"
^
-t0899.scala:12: error: super may be not be used on variable v
+t0899.scala:12: error: super may not be used on variable v
println(super.v)
^
three errors found
diff --git a/test/files/neg/t562.check b/test/files/neg/t562.check
index 8c3823642a..95be075af1 100644
--- a/test/files/neg/t562.check
+++ b/test/files/neg/t562.check
@@ -1,4 +1,4 @@
-t562.scala:10: error: super may be not be used on value y
+t562.scala:10: error: super may not be used on value y
override val y = super.y;
^
one error found
diff --git a/test/files/neg/t7157.check b/test/files/neg/t7157.check
index c6a7af9a23..3988460d4b 100644
--- a/test/files/neg/t7157.check
+++ b/test/files/neg/t7157.check
@@ -7,7 +7,8 @@ Test_2.scala:6: error: too many arguments for macro method m1_0_0: ()Unit
Test_2.scala:7: error: too many arguments for macro method m1_0_0: ()Unit
m1_0_0(1, 2, 3)
^
-Test_2.scala:9: error: macro applications do not support named and/or default arguments
+Test_2.scala:9: error: not enough arguments for macro method m1_1_1: (x: Int)Unit.
+Unspecified value parameter x.
m1_1_1()
^
Test_2.scala:11: error: too many arguments for macro method m1_1_1: (x: Int)Unit
@@ -16,22 +17,27 @@ Test_2.scala:11: error: too many arguments for macro method m1_1_1: (x: Int)Unit
Test_2.scala:12: error: too many arguments for macro method m1_1_1: (x: Int)Unit
m1_1_1(1, 2, 3)
^
-Test_2.scala:14: error: macro applications do not support named and/or default arguments
+Test_2.scala:14: error: not enough arguments for macro method m1_2_2: (x: Int, y: Int)Unit.
+Unspecified value parameters x, y.
m1_2_2()
^
-Test_2.scala:15: error: macro applications do not support named and/or default arguments
+Test_2.scala:15: error: not enough arguments for macro method m1_2_2: (x: Int, y: Int)Unit.
+Unspecified value parameter y.
m1_2_2(1)
^
Test_2.scala:17: error: too many arguments for macro method m1_2_2: (x: Int, y: Int)Unit
m1_2_2(1, 2, 3)
^
-Test_2.scala:24: error: macro applications do not support named and/or default arguments
+Test_2.scala:24: error: not enough arguments for macro method m1_1_inf: (x: Int, y: Int*)Unit.
+Unspecified value parameters x, y.
m1_1_inf()
^
-Test_2.scala:29: error: macro applications do not support named and/or default arguments
+Test_2.scala:29: error: not enough arguments for macro method m1_2_inf: (x: Int, y: Int, z: Int*)Unit.
+Unspecified value parameters x, y, z.
m1_2_inf()
^
-Test_2.scala:30: error: macro applications do not support named and/or default arguments
+Test_2.scala:30: error: not enough arguments for macro method m1_2_inf: (x: Int, y: Int, z: Int*)Unit.
+Unspecified value parameters y, z.
m1_2_inf(1)
^
Test_2.scala:35: error: too many arguments for macro method m2_0_0: ()Unit
@@ -43,7 +49,8 @@ Test_2.scala:36: error: too many arguments for macro method m2_0_0: ()Unit
Test_2.scala:37: error: too many arguments for macro method m2_0_0: ()Unit
m2_0_0()(1, 2, 3)
^
-Test_2.scala:39: error: macro applications do not support named and/or default arguments
+Test_2.scala:39: error: not enough arguments for macro method m2_1_1: (x: Int)Unit.
+Unspecified value parameter x.
m2_1_1()()
^
Test_2.scala:41: error: too many arguments for macro method m2_1_1: (x: Int)Unit
@@ -52,22 +59,27 @@ Test_2.scala:41: error: too many arguments for macro method m2_1_1: (x: Int)Unit
Test_2.scala:42: error: too many arguments for macro method m2_1_1: (x: Int)Unit
m2_1_1()(1, 2, 3)
^
-Test_2.scala:44: error: macro applications do not support named and/or default arguments
+Test_2.scala:44: error: not enough arguments for macro method m2_2_2: (x: Int, y: Int)Unit.
+Unspecified value parameters x, y.
m2_2_2()()
^
-Test_2.scala:45: error: macro applications do not support named and/or default arguments
+Test_2.scala:45: error: not enough arguments for macro method m2_2_2: (x: Int, y: Int)Unit.
+Unspecified value parameter y.
m2_2_2()(1)
^
Test_2.scala:47: error: too many arguments for macro method m2_2_2: (x: Int, y: Int)Unit
m2_2_2()(1, 2, 3)
^
-Test_2.scala:54: error: macro applications do not support named and/or default arguments
+Test_2.scala:54: error: not enough arguments for macro method m2_1_inf: (x: Int, y: Int*)Unit.
+Unspecified value parameters x, y.
m2_1_inf()()
^
-Test_2.scala:59: error: macro applications do not support named and/or default arguments
+Test_2.scala:59: error: not enough arguments for macro method m2_2_inf: (x: Int, y: Int, z: Int*)Unit.
+Unspecified value parameters x, y, z.
m2_2_inf()()
^
-Test_2.scala:60: error: macro applications do not support named and/or default arguments
+Test_2.scala:60: error: not enough arguments for macro method m2_2_inf: (x: Int, y: Int, z: Int*)Unit.
+Unspecified value parameters y, z.
m2_2_inf()(1)
^
24 errors found
diff --git a/test/files/neg/t7848-interp-warn.check b/test/files/neg/t7848-interp-warn.check
index 4cf9d55ffd..637fc8941a 100644
--- a/test/files/neg/t7848-interp-warn.check
+++ b/test/files/neg/t7848-interp-warn.check
@@ -4,9 +4,12 @@ t7848-interp-warn.scala:8: warning: possible missing interpolator: detected inte
t7848-interp-warn.scala:12: warning: possible missing interpolator: detected an interpolated expression
"A doubly important ${foo * 2} message!"
^
+t7848-interp-warn.scala:15: warning: possible missing interpolator: detected interpolated identifier `$bar`
+ def i = s"Try using '${ "$bar" }' instead." // was: no warn on space test
+ ^
t7848-interp-warn.scala:16: warning: possible missing interpolator: detected interpolated identifier `$bar`
def j = s"Try using '${ "something like $bar" }' instead." // warn
^
error: No warnings can be incurred under -Xfatal-warnings.
-three warnings found
+four warnings found
one error found
diff --git a/test/files/neg/t7848-interp-warn.scala b/test/files/neg/t7848-interp-warn.scala
index 3887aff8de..a76141041d 100644
--- a/test/files/neg/t7848-interp-warn.scala
+++ b/test/files/neg/t7848-interp-warn.scala
@@ -12,7 +12,7 @@ object Test {
"A doubly important ${foo * 2} message!"
}
def h = s"Try using '$$bar' instead." // no warn
- def i = s"Try using '${ "$bar" }' instead." // no warn on space test
+ def i = s"Try using '${ "$bar" }' instead." // was: no warn on space test
def j = s"Try using '${ "something like $bar" }' instead." // warn
def k = f"Try using '$bar' instead." // no warn on other std interps
}
diff --git a/test/files/neg/t8731.check b/test/files/neg/t8731.check
index 2a9af475fc..d47bd55b45 100644
--- a/test/files/neg/t8731.check
+++ b/test/files/neg/t8731.check
@@ -1,9 +1,6 @@
-t8731.scala:5: warning: matches with two cases or fewer are emitted using if-then-else instead of switch
- def f(x: Int) = (x: @annotation.switch) match {
- ^
t8731.scala:10: warning: could not emit switch for @switch annotated match
def g(x: Int) = (x: @annotation.switch) match {
^
error: No warnings can be incurred under -Xfatal-warnings.
-two warnings found
+one warning found
one error found
diff --git a/test/files/neg/t9127.check b/test/files/neg/t9127.check
new file mode 100644
index 0000000000..2ecf8af464
--- /dev/null
+++ b/test/files/neg/t9127.check
@@ -0,0 +1,12 @@
+t9127.scala:4: warning: possible missing interpolator: detected interpolated identifier `$s`
+ val t = "$s"
+ ^
+t9127.scala:5: warning: possible missing interpolator: detected an interpolated expression
+ val u = "a${s}b"
+ ^
+t9127.scala:6: warning: possible missing interpolator: detected interpolated identifier `$s`
+ val v = "a$s b"
+ ^
+error: No warnings can be incurred under -Xfatal-warnings.
+three warnings found
+one error found
diff --git a/test/files/neg/t9127.flags b/test/files/neg/t9127.flags
new file mode 100644
index 0000000000..b0d7bc25cb
--- /dev/null
+++ b/test/files/neg/t9127.flags
@@ -0,0 +1 @@
+-Xlint:missing-interpolator -Xfatal-warnings
diff --git a/test/files/neg/t9127.scala b/test/files/neg/t9127.scala
new file mode 100644
index 0000000000..c0746144eb
--- /dev/null
+++ b/test/files/neg/t9127.scala
@@ -0,0 +1,7 @@
+
+trait X {
+ val s = "hello"
+ val t = "$s"
+ val u = "a${s}b"
+ val v = "a$s b"
+}
diff --git a/test/files/pos/t6942.flags b/test/files/pos/t6942.flags
index e8fb65d50c..0f96f1f872 100644
--- a/test/files/pos/t6942.flags
+++ b/test/files/pos/t6942.flags
@@ -1 +1 @@
--Xfatal-warnings \ No newline at end of file
+-nowarn \ No newline at end of file
diff --git a/test/files/pos/t8861.flags b/test/files/pos/t8861.flags
new file mode 100644
index 0000000000..99a6391058
--- /dev/null
+++ b/test/files/pos/t8861.flags
@@ -0,0 +1 @@
+-Xlint:infer-any -Xfatal-warnings
diff --git a/test/files/pos/t8861.scala b/test/files/pos/t8861.scala
new file mode 100644
index 0000000000..816d15700e
--- /dev/null
+++ b/test/files/pos/t8861.scala
@@ -0,0 +1,11 @@
+
+trait Test {
+ type R = PartialFunction[Any, Unit]
+
+ val x: R = { case "" => }
+ val y: R = { case "" => }
+
+ val z: R = x orElse y
+ val zz = x orElse y
+}
+
diff --git a/test/files/pos/t9181.flags b/test/files/pos/t9181.flags
new file mode 100644
index 0000000000..0f96f1f872
--- /dev/null
+++ b/test/files/pos/t9181.flags
@@ -0,0 +1 @@
+-nowarn \ No newline at end of file
diff --git a/test/files/pos/t9181.scala b/test/files/pos/t9181.scala
new file mode 100644
index 0000000000..2edf6fe4a3
--- /dev/null
+++ b/test/files/pos/t9181.scala
@@ -0,0 +1,806 @@
+sealed trait C
+case object C1 extends C
+case object C2 extends C
+case object C3 extends C
+case object C4 extends C
+case object C5 extends C
+case object C6 extends C
+case object C7 extends C
+case object C8 extends C
+case object C9 extends C
+case object C10 extends C
+case object C11 extends C
+case object C12 extends C
+case object C13 extends C
+case object C14 extends C
+case object C15 extends C
+case object C16 extends C
+case object C17 extends C
+case object C18 extends C
+case object C19 extends C
+case object C20 extends C
+case object C21 extends C
+case object C22 extends C
+case object C23 extends C
+case object C24 extends C
+case object C25 extends C
+case object C26 extends C
+case object C27 extends C
+case object C28 extends C
+case object C29 extends C
+case object C30 extends C
+case object C31 extends C
+case object C32 extends C
+case object C33 extends C
+case object C34 extends C
+case object C35 extends C
+case object C36 extends C
+case object C37 extends C
+case object C38 extends C
+case object C39 extends C
+case object C40 extends C
+case object C41 extends C
+case object C42 extends C
+case object C43 extends C
+case object C44 extends C
+case object C45 extends C
+case object C46 extends C
+case object C47 extends C
+case object C48 extends C
+case object C49 extends C
+case object C50 extends C
+case object C51 extends C
+case object C52 extends C
+case object C53 extends C
+case object C54 extends C
+case object C55 extends C
+case object C56 extends C
+case object C57 extends C
+case object C58 extends C
+case object C59 extends C
+case object C60 extends C
+case object C61 extends C
+case object C62 extends C
+case object C63 extends C
+case object C64 extends C
+case object C65 extends C
+case object C66 extends C
+case object C67 extends C
+case object C68 extends C
+case object C69 extends C
+case object C70 extends C
+case object C71 extends C
+case object C72 extends C
+case object C73 extends C
+case object C74 extends C
+case object C75 extends C
+case object C76 extends C
+case object C77 extends C
+case object C78 extends C
+case object C79 extends C
+case object C80 extends C
+case object C81 extends C
+case object C82 extends C
+case object C83 extends C
+case object C84 extends C
+case object C85 extends C
+case object C86 extends C
+case object C87 extends C
+case object C88 extends C
+case object C89 extends C
+case object C90 extends C
+case object C91 extends C
+case object C92 extends C
+case object C93 extends C
+case object C94 extends C
+case object C95 extends C
+case object C96 extends C
+case object C97 extends C
+case object C98 extends C
+case object C99 extends C
+case object C100 extends C
+case object C101 extends C
+case object C102 extends C
+case object C103 extends C
+case object C104 extends C
+case object C105 extends C
+case object C106 extends C
+case object C107 extends C
+case object C108 extends C
+case object C109 extends C
+case object C110 extends C
+case object C111 extends C
+case object C112 extends C
+case object C113 extends C
+case object C114 extends C
+case object C115 extends C
+case object C116 extends C
+case object C117 extends C
+case object C118 extends C
+case object C119 extends C
+case object C120 extends C
+case object C121 extends C
+case object C122 extends C
+case object C123 extends C
+case object C124 extends C
+case object C125 extends C
+case object C126 extends C
+case object C127 extends C
+case object C128 extends C
+case object C129 extends C
+case object C130 extends C
+case object C131 extends C
+case object C132 extends C
+case object C133 extends C
+case object C134 extends C
+case object C135 extends C
+case object C136 extends C
+case object C137 extends C
+case object C138 extends C
+case object C139 extends C
+case object C140 extends C
+case object C141 extends C
+case object C142 extends C
+case object C143 extends C
+case object C144 extends C
+case object C145 extends C
+case object C146 extends C
+case object C147 extends C
+case object C148 extends C
+case object C149 extends C
+case object C150 extends C
+case object C151 extends C
+case object C152 extends C
+case object C153 extends C
+case object C154 extends C
+case object C155 extends C
+case object C156 extends C
+case object C157 extends C
+case object C158 extends C
+case object C159 extends C
+case object C160 extends C
+case object C161 extends C
+case object C162 extends C
+case object C163 extends C
+case object C164 extends C
+case object C165 extends C
+case object C166 extends C
+case object C167 extends C
+case object C168 extends C
+case object C169 extends C
+case object C170 extends C
+case object C171 extends C
+case object C172 extends C
+case object C173 extends C
+case object C174 extends C
+case object C175 extends C
+case object C176 extends C
+case object C177 extends C
+case object C178 extends C
+case object C179 extends C
+case object C180 extends C
+case object C181 extends C
+case object C182 extends C
+case object C183 extends C
+case object C184 extends C
+case object C185 extends C
+case object C186 extends C
+case object C187 extends C
+case object C188 extends C
+case object C189 extends C
+case object C190 extends C
+case object C191 extends C
+case object C192 extends C
+case object C193 extends C
+case object C194 extends C
+case object C195 extends C
+case object C196 extends C
+case object C197 extends C
+case object C198 extends C
+case object C199 extends C
+case object C200 extends C
+case object C201 extends C
+case object C202 extends C
+case object C203 extends C
+case object C204 extends C
+case object C205 extends C
+case object C206 extends C
+case object C207 extends C
+case object C208 extends C
+case object C209 extends C
+case object C210 extends C
+case object C211 extends C
+case object C212 extends C
+case object C213 extends C
+case object C214 extends C
+case object C215 extends C
+case object C216 extends C
+case object C217 extends C
+case object C218 extends C
+case object C219 extends C
+case object C220 extends C
+case object C221 extends C
+case object C222 extends C
+case object C223 extends C
+case object C224 extends C
+case object C225 extends C
+case object C226 extends C
+case object C227 extends C
+case object C228 extends C
+case object C229 extends C
+case object C230 extends C
+case object C231 extends C
+case object C232 extends C
+case object C233 extends C
+case object C234 extends C
+case object C235 extends C
+case object C236 extends C
+case object C237 extends C
+case object C238 extends C
+case object C239 extends C
+case object C240 extends C
+case object C241 extends C
+case object C242 extends C
+case object C243 extends C
+case object C244 extends C
+case object C245 extends C
+case object C246 extends C
+case object C247 extends C
+case object C248 extends C
+case object C249 extends C
+case object C250 extends C
+case object C251 extends C
+case object C252 extends C
+case object C253 extends C
+case object C254 extends C
+case object C255 extends C
+case object C256 extends C
+case object C257 extends C
+case object C258 extends C
+case object C259 extends C
+case object C260 extends C
+case object C261 extends C
+case object C262 extends C
+case object C263 extends C
+case object C264 extends C
+case object C265 extends C
+case object C266 extends C
+case object C267 extends C
+case object C268 extends C
+case object C269 extends C
+case object C270 extends C
+case object C271 extends C
+case object C272 extends C
+case object C273 extends C
+case object C274 extends C
+case object C275 extends C
+case object C276 extends C
+case object C277 extends C
+case object C278 extends C
+case object C279 extends C
+case object C280 extends C
+case object C281 extends C
+case object C282 extends C
+case object C283 extends C
+case object C284 extends C
+case object C285 extends C
+case object C286 extends C
+case object C287 extends C
+case object C288 extends C
+case object C289 extends C
+case object C290 extends C
+case object C291 extends C
+case object C292 extends C
+case object C293 extends C
+case object C294 extends C
+case object C295 extends C
+case object C296 extends C
+case object C297 extends C
+case object C298 extends C
+case object C299 extends C
+case object C300 extends C
+case object C301 extends C
+case object C302 extends C
+case object C303 extends C
+case object C304 extends C
+case object C305 extends C
+case object C306 extends C
+case object C307 extends C
+case object C308 extends C
+case object C309 extends C
+case object C310 extends C
+case object C311 extends C
+case object C312 extends C
+case object C313 extends C
+case object C314 extends C
+case object C315 extends C
+case object C316 extends C
+case object C317 extends C
+case object C318 extends C
+case object C319 extends C
+case object C320 extends C
+case object C321 extends C
+case object C322 extends C
+case object C323 extends C
+case object C324 extends C
+case object C325 extends C
+case object C326 extends C
+case object C327 extends C
+case object C328 extends C
+case object C329 extends C
+case object C330 extends C
+case object C331 extends C
+case object C332 extends C
+case object C333 extends C
+case object C334 extends C
+case object C335 extends C
+case object C336 extends C
+case object C337 extends C
+case object C338 extends C
+case object C339 extends C
+case object C340 extends C
+case object C341 extends C
+case object C342 extends C
+case object C343 extends C
+case object C344 extends C
+case object C345 extends C
+case object C346 extends C
+case object C347 extends C
+case object C348 extends C
+case object C349 extends C
+case object C350 extends C
+case object C351 extends C
+case object C352 extends C
+case object C353 extends C
+case object C354 extends C
+case object C355 extends C
+case object C356 extends C
+case object C357 extends C
+case object C358 extends C
+case object C359 extends C
+case object C360 extends C
+case object C361 extends C
+case object C362 extends C
+case object C363 extends C
+case object C364 extends C
+case object C365 extends C
+case object C366 extends C
+case object C367 extends C
+case object C368 extends C
+case object C369 extends C
+case object C370 extends C
+case object C371 extends C
+case object C372 extends C
+case object C373 extends C
+case object C374 extends C
+case object C375 extends C
+case object C376 extends C
+case object C377 extends C
+case object C378 extends C
+case object C379 extends C
+case object C380 extends C
+case object C381 extends C
+case object C382 extends C
+case object C383 extends C
+case object C384 extends C
+case object C385 extends C
+case object C386 extends C
+case object C387 extends C
+case object C388 extends C
+case object C389 extends C
+case object C390 extends C
+case object C391 extends C
+case object C392 extends C
+case object C393 extends C
+case object C394 extends C
+case object C395 extends C
+case object C396 extends C
+case object C397 extends C
+case object C398 extends C
+case object C399 extends C
+case object C400 extends C
+
+object M {
+ def f(c: C): Int = c match {
+ case C1 => 1
+ case C2 => 2
+ case C3 => 3
+ case C4 => 4
+ case C5 => 5
+ case C6 => 6
+ case C7 => 7
+ case C8 => 8
+ case C9 => 9
+ case C10 => 10
+ case C11 => 11
+ case C12 => 12
+ case C13 => 13
+ case C14 => 14
+ case C15 => 15
+ case C16 => 16
+ case C17 => 17
+ case C18 => 18
+ case C19 => 19
+ case C20 => 20
+ case C21 => 21
+ case C22 => 22
+ case C23 => 23
+ case C24 => 24
+ case C25 => 25
+ case C26 => 26
+ case C27 => 27
+ case C28 => 28
+ case C29 => 29
+ case C30 => 30
+ case C31 => 31
+ case C32 => 32
+ case C33 => 33
+ case C34 => 34
+ case C35 => 35
+ case C36 => 36
+ case C37 => 37
+ case C38 => 38
+ case C39 => 39
+ case C40 => 40
+ case C41 => 41
+ case C42 => 42
+ case C43 => 43
+ case C44 => 44
+ case C45 => 45
+ case C46 => 46
+ case C47 => 47
+ case C48 => 48
+ case C49 => 49
+ case C50 => 50
+ case C51 => 51
+ case C52 => 52
+ case C53 => 53
+ case C54 => 54
+ case C55 => 55
+ case C56 => 56
+ case C57 => 57
+ case C58 => 58
+ case C59 => 59
+ case C60 => 60
+ case C61 => 61
+ case C62 => 62
+ case C63 => 63
+ case C64 => 64
+ case C65 => 65
+ case C66 => 66
+ case C67 => 67
+ case C68 => 68
+ case C69 => 69
+ case C70 => 70
+ case C71 => 71
+ case C72 => 72
+ case C73 => 73
+ case C74 => 74
+ case C75 => 75
+ case C76 => 76
+ case C77 => 77
+ case C78 => 78
+ case C79 => 79
+ case C80 => 80
+ case C81 => 81
+ case C82 => 82
+ case C83 => 83
+ case C84 => 84
+ case C85 => 85
+ case C86 => 86
+ case C87 => 87
+ case C88 => 88
+ case C89 => 89
+ case C90 => 90
+ case C91 => 91
+ case C92 => 92
+ case C93 => 93
+ case C94 => 94
+ case C95 => 95
+ case C96 => 96
+ case C97 => 97
+ case C98 => 98
+ case C99 => 99
+ case C100 => 100
+ case C101 => 101
+ case C102 => 102
+ case C103 => 103
+ case C104 => 104
+ case C105 => 105
+ case C106 => 106
+ case C107 => 107
+ case C108 => 108
+ case C109 => 109
+ case C110 => 110
+ case C111 => 111
+ case C112 => 112
+ case C113 => 113
+ case C114 => 114
+ case C115 => 115
+ case C116 => 116
+ case C117 => 117
+ case C118 => 118
+ case C119 => 119
+ case C120 => 120
+ case C121 => 121
+ case C122 => 122
+ case C123 => 123
+ case C124 => 124
+ case C125 => 125
+ case C126 => 126
+ case C127 => 127
+ case C128 => 128
+ case C129 => 129
+ case C130 => 130
+ case C131 => 131
+ case C132 => 132
+ case C133 => 133
+ case C134 => 134
+ case C135 => 135
+ case C136 => 136
+ case C137 => 137
+ case C138 => 138
+ case C139 => 139
+ case C140 => 140
+ case C141 => 141
+ case C142 => 142
+ case C143 => 143
+ case C144 => 144
+ case C145 => 145
+ case C146 => 146
+ case C147 => 147
+ case C148 => 148
+ case C149 => 149
+ case C150 => 150
+ case C151 => 151
+ case C152 => 152
+ case C153 => 153
+ case C154 => 154
+ case C155 => 155
+ case C156 => 156
+ case C157 => 157
+ case C158 => 158
+ case C159 => 159
+ case C160 => 160
+ case C161 => 161
+ case C162 => 162
+ case C163 => 163
+ case C164 => 164
+ case C165 => 165
+ case C166 => 166
+ case C167 => 167
+ case C168 => 168
+ case C169 => 169
+ case C170 => 170
+ case C171 => 171
+ case C172 => 172
+ case C173 => 173
+ case C174 => 174
+ case C175 => 175
+ case C176 => 176
+ case C177 => 177
+ case C178 => 178
+ case C179 => 179
+ case C180 => 180
+ case C181 => 181
+ case C182 => 182
+ case C183 => 183
+ case C184 => 184
+ case C185 => 185
+ case C186 => 186
+ case C187 => 187
+ case C188 => 188
+ case C189 => 189
+ case C190 => 190
+ case C191 => 191
+ case C192 => 192
+ case C193 => 193
+ case C194 => 194
+ case C195 => 195
+ case C196 => 196
+ case C197 => 197
+ case C198 => 198
+ case C199 => 199
+ case C200 => 200
+ case C201 => 201
+ case C202 => 202
+ case C203 => 203
+ case C204 => 204
+ case C205 => 205
+ case C206 => 206
+ case C207 => 207
+ case C208 => 208
+ case C209 => 209
+ case C210 => 210
+ case C211 => 211
+ case C212 => 212
+ case C213 => 213
+ case C214 => 214
+ case C215 => 215
+ case C216 => 216
+ case C217 => 217
+ case C218 => 218
+ case C219 => 219
+ case C220 => 220
+ case C221 => 221
+ case C222 => 222
+ case C223 => 223
+ case C224 => 224
+ case C225 => 225
+ case C226 => 226
+ case C227 => 227
+ case C228 => 228
+ case C229 => 229
+ case C230 => 230
+ case C231 => 231
+ case C232 => 232
+ case C233 => 233
+ case C234 => 234
+ case C235 => 235
+ case C236 => 236
+ case C237 => 237
+ case C238 => 238
+ case C239 => 239
+ case C240 => 240
+ case C241 => 241
+ case C242 => 242
+ case C243 => 243
+ case C244 => 244
+ case C245 => 245
+ case C246 => 246
+ case C247 => 247
+ case C248 => 248
+ case C249 => 249
+ case C250 => 250
+ case C251 => 251
+ case C252 => 252
+ case C253 => 253
+ case C254 => 254
+ case C255 => 255
+ case C256 => 256
+ case C257 => 257
+ case C258 => 258
+ case C259 => 259
+ case C260 => 260
+ case C261 => 261
+ case C262 => 262
+ case C263 => 263
+ case C264 => 264
+ case C265 => 265
+ case C266 => 266
+ case C267 => 267
+ case C268 => 268
+ case C269 => 269
+ case C270 => 270
+ case C271 => 271
+ case C272 => 272
+ case C273 => 273
+ case C274 => 274
+ case C275 => 275
+ case C276 => 276
+ case C277 => 277
+ case C278 => 278
+ case C279 => 279
+ case C280 => 280
+ case C281 => 281
+ case C282 => 282
+ case C283 => 283
+ case C284 => 284
+ case C285 => 285
+ case C286 => 286
+ case C287 => 287
+ case C288 => 288
+ case C289 => 289
+ case C290 => 290
+ case C291 => 291
+ case C292 => 292
+ case C293 => 293
+ case C294 => 294
+ case C295 => 295
+ case C296 => 296
+ case C297 => 297
+ case C298 => 298
+ case C299 => 299
+ case C300 => 300
+ case C301 => 301
+ case C302 => 302
+ case C303 => 303
+ case C304 => 304
+ case C305 => 305
+ case C306 => 306
+ case C307 => 307
+ case C308 => 308
+ case C309 => 309
+ case C310 => 310
+ case C311 => 311
+ case C312 => 312
+ case C313 => 313
+ case C314 => 314
+ case C315 => 315
+ case C316 => 316
+ case C317 => 317
+ case C318 => 318
+ case C319 => 319
+ case C320 => 320
+ case C321 => 321
+ case C322 => 322
+ case C323 => 323
+ case C324 => 324
+ case C325 => 325
+ case C326 => 326
+ case C327 => 327
+ case C328 => 328
+ case C329 => 329
+ case C330 => 330
+ case C331 => 331
+ case C332 => 332
+ case C333 => 333
+ case C334 => 334
+ case C335 => 335
+ case C336 => 336
+ case C337 => 337
+ case C338 => 338
+ case C339 => 339
+ case C340 => 340
+ case C341 => 341
+ case C342 => 342
+ case C343 => 343
+ case C344 => 344
+ case C345 => 345
+ case C346 => 346
+ case C347 => 347
+ case C348 => 348
+ case C349 => 349
+ case C350 => 350
+ case C351 => 351
+ case C352 => 352
+ case C353 => 353
+ case C354 => 354
+ case C355 => 355
+ case C356 => 356
+ case C357 => 357
+ case C358 => 358
+ case C359 => 359
+ case C360 => 360
+ case C361 => 361
+ case C362 => 362
+ case C363 => 363
+ case C364 => 364
+ case C365 => 365
+ case C366 => 366
+ case C367 => 367
+ case C368 => 368
+ case C369 => 369
+ case C370 => 370
+ case C371 => 371
+ case C372 => 372
+ case C373 => 373
+ case C374 => 374
+ case C375 => 375
+ case C376 => 376
+ case C377 => 377
+ case C378 => 378
+ case C379 => 379
+ case C380 => 380
+ case C381 => 381
+ case C382 => 382
+ case C383 => 383
+ case C384 => 384
+ case C385 => 385
+ case C386 => 386
+ case C387 => 387
+ case C388 => 388
+ case C389 => 389
+ case C390 => 390
+ case C391 => 391
+ case C392 => 392
+ case C393 => 393
+ case C394 => 394
+ case C395 => 395
+ case C396 => 396
+ case C397 => 397
+ case C398 => 398
+ case C399 => 399
+ case C400 => 400
+ }
+}
diff --git a/test/files/run/t7407.flags b/test/files/run/t7407.flags
index be4ef0798a..ffc65f4b81 100644
--- a/test/files/run/t7407.flags
+++ b/test/files/run/t7407.flags
@@ -1 +1 @@
--Ynooptimise -Yopt:l:none -Ybackend:GenBCode
+-Yopt:l:none -Ybackend:GenBCode
diff --git a/test/files/run/t7407b.flags b/test/files/run/t7407b.flags
index c8547a27dc..c30091d3de 100644
--- a/test/files/run/t7407b.flags
+++ b/test/files/run/t7407b.flags
@@ -1 +1 @@
--Ynooptimise -Ybackend:GenBCode
+-Ybackend:GenBCode
diff --git a/test/files/run/t7741a/GroovyInterface$1Dump.java b/test/files/run/t7741a/GroovyInterface$1Dump.java
new file mode 100644
index 0000000000..0c0eab3f1b
--- /dev/null
+++ b/test/files/run/t7741a/GroovyInterface$1Dump.java
@@ -0,0 +1,222 @@
+import java.util.*;
+import scala.tools.asm.*;
+
+// generated with
+// git clone alewando/scala_groovy_interop
+// SCALA_HOME=... GROOVY_HOME=... ant
+// cd /code/scala2
+// java -classpath build/asm/classes:/Users/jason/code/scala_groovy_interop/classes:/code/scala2/build/pack/lib/scala-library.jar:/usr/local/Cellar/groovy/2.4.1/libexec/embeddable/groovy-all-2.4.1.jar scala.tools.asm.util.ASMifier 'GroovyInterface$1'
+// java -classpath build/asm/classes:/Users/jason/code/scala_groovy_interop/classes:/code/scala2/build/pack/lib/scala-library.jar:/usr/local/Cellar/groovy/2.4.1/libexec/embeddable/groovy-all-2.4.1.jar scala.tools.asm.util.ASMifier 'GroovyInterface$1'
+public class GroovyInterface$1Dump implements Opcodes {
+
+ public static byte[] dump () throws Exception {
+
+ ClassWriter cw = new ClassWriter(0);
+ FieldVisitor fv;
+ MethodVisitor mv;
+ AnnotationVisitor av0;
+
+ cw.visit(V1_5, ACC_SUPER + ACC_SYNTHETIC, "GroovyInterface$1", null, "java/lang/Object", new String[] {});
+
+ cw.visitInnerClass("GroovyInterface$1", "GroovyInterface", "1", ACC_SYNTHETIC);
+
+ {
+ fv = cw.visitField(ACC_STATIC + ACC_SYNTHETIC, "$class$GroovyInterface", "Ljava/lang/Class;", null, null);
+ fv.visitEnd();
+ }
+ {
+ fv = cw.visitField(ACC_PRIVATE + ACC_STATIC + ACC_SYNTHETIC, "$staticClassInfo", "Lorg/codehaus/groovy/reflection/ClassInfo;", null, null);
+ fv.visitEnd();
+ }
+ {
+ fv = cw.visitField(ACC_PUBLIC + ACC_STATIC + ACC_TRANSIENT + ACC_SYNTHETIC, "__$stMC", "Z", null, null);
+ fv.visitEnd();
+ }
+ {
+ fv = cw.visitField(ACC_PRIVATE + ACC_TRANSIENT + ACC_SYNTHETIC, "metaClass", "Lgroovy/lang/MetaClass;", null, null);
+ fv.visitEnd();
+ }
+ {
+ fv = cw.visitField(ACC_PRIVATE + ACC_STATIC + ACC_SYNTHETIC, "$callSiteArray", "Ljava/lang/ref/SoftReference;", null, null);
+ fv.visitEnd();
+ }
+ {
+ mv = cw.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null);
+ mv.visitCode();
+ mv.visitVarInsn(ALOAD, 0);
+ mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V", false);
+ mv.visitMethodInsn(INVOKESTATIC, "GroovyInterface$1", "$getCallSiteArray", "()[Lorg/codehaus/groovy/runtime/callsite/CallSite;", false);
+ mv.visitVarInsn(ASTORE, 1);
+ mv.visitVarInsn(ALOAD, 0);
+ mv.visitMethodInsn(INVOKEVIRTUAL, "GroovyInterface$1", "$getStaticMetaClass", "()Lgroovy/lang/MetaClass;", false);
+ mv.visitVarInsn(ASTORE, 2);
+ mv.visitVarInsn(ALOAD, 2);
+ mv.visitVarInsn(ALOAD, 0);
+ mv.visitInsn(SWAP);
+ mv.visitFieldInsn(PUTFIELD, "GroovyInterface$1", "metaClass", "Lgroovy/lang/MetaClass;");
+ mv.visitVarInsn(ALOAD, 2);
+ mv.visitInsn(POP);
+ mv.visitInsn(RETURN);
+ mv.visitMaxs(2, 3);
+ mv.visitEnd();
+ }
+ {
+ mv = cw.visitMethod(ACC_PROTECTED + ACC_SYNTHETIC, "$getStaticMetaClass", "()Lgroovy/lang/MetaClass;", null, null);
+ mv.visitCode();
+ mv.visitVarInsn(ALOAD, 0);
+ mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Object", "getClass", "()Ljava/lang/Class;", false);
+ mv.visitLdcInsn(Type.getType("LGroovyInterface$1;"));
+ Label l0 = new Label();
+ mv.visitJumpInsn(IF_ACMPEQ, l0);
+ mv.visitVarInsn(ALOAD, 0);
+ mv.visitMethodInsn(INVOKESTATIC, "org/codehaus/groovy/runtime/ScriptBytecodeAdapter", "initMetaClass", "(Ljava/lang/Object;)Lgroovy/lang/MetaClass;", false);
+ mv.visitInsn(ARETURN);
+ mv.visitLabel(l0);
+ mv.visitFieldInsn(GETSTATIC, "GroovyInterface$1", "$staticClassInfo", "Lorg/codehaus/groovy/reflection/ClassInfo;");
+ mv.visitVarInsn(ASTORE, 1);
+ mv.visitVarInsn(ALOAD, 1);
+ Label l1 = new Label();
+ mv.visitJumpInsn(IFNONNULL, l1);
+ mv.visitVarInsn(ALOAD, 0);
+ mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Object", "getClass", "()Ljava/lang/Class;", false);
+ mv.visitMethodInsn(INVOKESTATIC, "org/codehaus/groovy/reflection/ClassInfo", "getClassInfo", "(Ljava/lang/Class;)Lorg/codehaus/groovy/reflection/ClassInfo;", false);
+ mv.visitInsn(DUP);
+ mv.visitVarInsn(ASTORE, 1);
+ mv.visitFieldInsn(PUTSTATIC, "GroovyInterface$1", "$staticClassInfo", "Lorg/codehaus/groovy/reflection/ClassInfo;");
+ mv.visitLabel(l1);
+ mv.visitVarInsn(ALOAD, 1);
+ mv.visitMethodInsn(INVOKEVIRTUAL, "org/codehaus/groovy/reflection/ClassInfo", "getMetaClass", "()Lgroovy/lang/MetaClass;", false);
+ mv.visitInsn(ARETURN);
+ mv.visitMaxs(2, 2);
+ mv.visitEnd();
+ }
+ {
+ mv = cw.visitMethod(ACC_PUBLIC + ACC_SYNTHETIC, "getMetaClass", "()Lgroovy/lang/MetaClass;", null, null);
+ mv.visitCode();
+ mv.visitVarInsn(ALOAD, 0);
+ mv.visitFieldInsn(GETFIELD, "GroovyInterface$1", "metaClass", "Lgroovy/lang/MetaClass;");
+ mv.visitInsn(DUP);
+ Label l0 = new Label();
+ mv.visitJumpInsn(IFNULL, l0);
+ mv.visitInsn(ARETURN);
+ mv.visitLabel(l0);
+ mv.visitInsn(POP);
+ mv.visitVarInsn(ALOAD, 0);
+ mv.visitInsn(DUP);
+ mv.visitMethodInsn(INVOKEVIRTUAL, "GroovyInterface$1", "$getStaticMetaClass", "()Lgroovy/lang/MetaClass;", false);
+ mv.visitFieldInsn(PUTFIELD, "GroovyInterface$1", "metaClass", "Lgroovy/lang/MetaClass;");
+ mv.visitVarInsn(ALOAD, 0);
+ mv.visitFieldInsn(GETFIELD, "GroovyInterface$1", "metaClass", "Lgroovy/lang/MetaClass;");
+ mv.visitInsn(ARETURN);
+ mv.visitMaxs(2, 1);
+ mv.visitEnd();
+ }
+ {
+ mv = cw.visitMethod(ACC_PUBLIC + ACC_SYNTHETIC, "setMetaClass", "(Lgroovy/lang/MetaClass;)V", null, null);
+ mv.visitCode();
+ mv.visitVarInsn(ALOAD, 0);
+ mv.visitVarInsn(ALOAD, 1);
+ mv.visitFieldInsn(PUTFIELD, "GroovyInterface$1", "metaClass", "Lgroovy/lang/MetaClass;");
+ mv.visitInsn(RETURN);
+ mv.visitMaxs(2, 2);
+ mv.visitEnd();
+ }
+ {
+ mv = cw.visitMethod(ACC_PUBLIC + ACC_SYNTHETIC, "invokeMethod", "(Ljava/lang/String;Ljava/lang/Object;)Ljava/lang/Object;", null, null);
+ mv.visitCode();
+ mv.visitVarInsn(ALOAD, 0);
+ mv.visitMethodInsn(INVOKEVIRTUAL, "GroovyInterface$1", "getMetaClass", "()Lgroovy/lang/MetaClass;", false);
+ mv.visitVarInsn(ALOAD, 0);
+ mv.visitVarInsn(ALOAD, 1);
+ mv.visitVarInsn(ALOAD, 2);
+ mv.visitMethodInsn(INVOKEINTERFACE, "groovy/lang/MetaClass", "invokeMethod", "(Ljava/lang/Object;Ljava/lang/String;Ljava/lang/Object;)Ljava/lang/Object;", true);
+ mv.visitInsn(ARETURN);
+ mv.visitMaxs(4, 3);
+ mv.visitEnd();
+ }
+ {
+ mv = cw.visitMethod(ACC_PUBLIC + ACC_SYNTHETIC, "getProperty", "(Ljava/lang/String;)Ljava/lang/Object;", null, null);
+ mv.visitCode();
+ mv.visitVarInsn(ALOAD, 0);
+ mv.visitMethodInsn(INVOKEVIRTUAL, "GroovyInterface$1", "getMetaClass", "()Lgroovy/lang/MetaClass;", false);
+ mv.visitVarInsn(ALOAD, 0);
+ mv.visitVarInsn(ALOAD, 1);
+ mv.visitMethodInsn(INVOKEINTERFACE, "groovy/lang/MetaClass", "getProperty", "(Ljava/lang/Object;Ljava/lang/String;)Ljava/lang/Object;", true);
+ mv.visitInsn(ARETURN);
+ mv.visitMaxs(3, 2);
+ mv.visitEnd();
+ }
+ {
+ mv = cw.visitMethod(ACC_PUBLIC + ACC_SYNTHETIC, "setProperty", "(Ljava/lang/String;Ljava/lang/Object;)V", null, null);
+ mv.visitCode();
+ mv.visitVarInsn(ALOAD, 0);
+ mv.visitMethodInsn(INVOKEVIRTUAL, "GroovyInterface$1", "getMetaClass", "()Lgroovy/lang/MetaClass;", false);
+ mv.visitVarInsn(ALOAD, 0);
+ mv.visitVarInsn(ALOAD, 1);
+ mv.visitVarInsn(ALOAD, 2);
+ mv.visitMethodInsn(INVOKEINTERFACE, "groovy/lang/MetaClass", "setProperty", "(Ljava/lang/Object;Ljava/lang/String;Ljava/lang/Object;)V", true);
+ mv.visitInsn(RETURN);
+ mv.visitMaxs(4, 3);
+ mv.visitEnd();
+ }
+ {
+ mv = cw.visitMethod(ACC_STATIC, "<clinit>", "()V", null, null);
+ mv.visitCode();
+ mv.visitLdcInsn(Type.getType("LGroovyInterface;"));
+ mv.visitVarInsn(ASTORE, 0);
+ mv.visitVarInsn(ALOAD, 0);
+ mv.visitFieldInsn(PUTSTATIC, "GroovyInterface$1", "$class$GroovyInterface", "Ljava/lang/Class;");
+ mv.visitVarInsn(ALOAD, 0);
+ mv.visitInsn(POP);
+ mv.visitInsn(RETURN);
+ mv.visitMaxs(1, 1);
+ mv.visitEnd();
+ }
+ {
+ mv = cw.visitMethod(ACC_PRIVATE + ACC_STATIC + ACC_SYNTHETIC, "$createCallSiteArray", "()Lorg/codehaus/groovy/runtime/callsite/CallSiteArray;", null, null);
+ mv.visitCode();
+ mv.visitLdcInsn(new Integer(0));
+ mv.visitTypeInsn(ANEWARRAY, "java/lang/String");
+ mv.visitVarInsn(ASTORE, 0);
+ mv.visitTypeInsn(NEW, "org/codehaus/groovy/runtime/callsite/CallSiteArray");
+ mv.visitInsn(DUP);
+ mv.visitLdcInsn(Type.getType("LGroovyInterface$1;"));
+ mv.visitVarInsn(ALOAD, 0);
+ mv.visitMethodInsn(INVOKESPECIAL, "org/codehaus/groovy/runtime/callsite/CallSiteArray", "<init>", "(Ljava/lang/Class;[Ljava/lang/String;)V", false);
+ mv.visitInsn(ARETURN);
+ mv.visitMaxs(4, 1);
+ mv.visitEnd();
+ }
+ {
+ mv = cw.visitMethod(ACC_PUBLIC + ACC_STATIC + ACC_SYNTHETIC, "$getCallSiteArray", "()[Lorg/codehaus/groovy/runtime/callsite/CallSite;", null, null);
+ mv.visitCode();
+ mv.visitFieldInsn(GETSTATIC, "GroovyInterface$1", "$callSiteArray", "Ljava/lang/ref/SoftReference;");
+ Label l0 = new Label();
+ mv.visitJumpInsn(IFNULL, l0);
+ mv.visitFieldInsn(GETSTATIC, "GroovyInterface$1", "$callSiteArray", "Ljava/lang/ref/SoftReference;");
+ mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/ref/SoftReference", "get", "()Ljava/lang/Object;", false);
+ mv.visitTypeInsn(CHECKCAST, "org/codehaus/groovy/runtime/callsite/CallSiteArray");
+ mv.visitInsn(DUP);
+ mv.visitVarInsn(ASTORE, 0);
+ Label l1 = new Label();
+ mv.visitJumpInsn(IFNONNULL, l1);
+ mv.visitLabel(l0);
+ mv.visitMethodInsn(INVOKESTATIC, "GroovyInterface$1", "$createCallSiteArray", "()Lorg/codehaus/groovy/runtime/callsite/CallSiteArray;", false);
+ mv.visitVarInsn(ASTORE, 0);
+ mv.visitTypeInsn(NEW, "java/lang/ref/SoftReference");
+ mv.visitInsn(DUP);
+ mv.visitVarInsn(ALOAD, 0);
+ mv.visitMethodInsn(INVOKESPECIAL, "java/lang/ref/SoftReference", "<init>", "(Ljava/lang/Object;)V", false);
+ mv.visitFieldInsn(PUTSTATIC, "GroovyInterface$1", "$callSiteArray", "Ljava/lang/ref/SoftReference;");
+ mv.visitLabel(l1);
+ mv.visitVarInsn(ALOAD, 0);
+ mv.visitFieldInsn(GETFIELD, "org/codehaus/groovy/runtime/callsite/CallSiteArray", "array", "[Lorg/codehaus/groovy/runtime/callsite/CallSite;");
+ mv.visitInsn(ARETURN);
+ mv.visitMaxs(3, 1);
+ mv.visitEnd();
+ }
+ cw.visitEnd();
+
+ return cw.toByteArray();
+ }
+}
diff --git a/test/files/run/t7741a/GroovyInterfaceDump.java b/test/files/run/t7741a/GroovyInterfaceDump.java
new file mode 100644
index 0000000000..87c09e272f
--- /dev/null
+++ b/test/files/run/t7741a/GroovyInterfaceDump.java
@@ -0,0 +1,51 @@
+import java.util.*;
+import scala.tools.asm.*;
+
+// generated with
+// git clone alewando/scala_groovy_interop
+// SCALA_HOME=... GROOVY_HOME=... ant
+// cd /code/scala2
+// java -classpath build/asm/classes:/Users/jason/code/scala_groovy_interop/classes:/code/scala2/build/pack/lib/scala-library.jar:/usr/local/Cellar/groovy/2.4.1/libexec/embeddable/groovy-all-2.4.1.jar scala.tools.asm.util.ASMifier 'GroovyInterface$1'
+// java -classpath build/asm/classes:/Users/jason/code/scala_groovy_interop/classes:/code/scala2/build/pack/lib/scala-library.jar:/usr/local/Cellar/groovy/2.4.1/libexec/embeddable/groovy-all-2.4.1.jar scala.tools.asm.util.ASMifier 'GroovyInterface$1'
+public class GroovyInterfaceDump implements Opcodes {
+
+ public static byte[] dump () throws Exception {
+
+ ClassWriter cw = new ClassWriter(0);
+ FieldVisitor fv;
+ MethodVisitor mv;
+ AnnotationVisitor av0;
+
+ cw.visit(V1_5, ACC_PUBLIC + ACC_ABSTRACT + ACC_INTERFACE, "GroovyInterface", null, "java/lang/Object", null);
+
+ cw.visitInnerClass("GroovyInterface$1", "GroovyInterface", "1", ACC_SYNTHETIC);
+
+ cw.visitInnerClass("GroovyInterface$__clinit__closure1", null, null, 0);
+
+ {
+ fv = cw.visitField(ACC_PUBLIC + ACC_FINAL + ACC_STATIC, "closure", "Ljava/lang/Object;", null, null);
+ fv.visitEnd();
+ }
+ {
+ mv = cw.visitMethod(ACC_STATIC, "<clinit>", "()V", null, null);
+ mv.visitCode();
+ mv.visitTypeInsn(NEW, "GroovyInterface$__clinit__closure1");
+ mv.visitInsn(DUP);
+ mv.visitFieldInsn(GETSTATIC, "GroovyInterface$1", "$class$GroovyInterface", "Ljava/lang/Class;");
+ mv.visitFieldInsn(GETSTATIC, "GroovyInterface$1", "$class$GroovyInterface", "Ljava/lang/Class;");
+ mv.visitMethodInsn(INVOKESPECIAL, "GroovyInterface$__clinit__closure1", "<init>", "(Ljava/lang/Object;Ljava/lang/Object;)V", false);
+ mv.visitVarInsn(ASTORE, 0);
+ mv.visitVarInsn(ALOAD, 0);
+ mv.visitFieldInsn(PUTSTATIC, "GroovyInterface", "closure", "Ljava/lang/Object;");
+ mv.visitVarInsn(ALOAD, 0);
+ mv.visitInsn(POP);
+ mv.visitInsn(RETURN);
+ mv.visitMaxs(4, 1);
+ mv.visitEnd();
+ }
+ cw.visitEnd();
+
+ return cw.toByteArray();
+ }
+}
+
diff --git a/test/files/run/t7741a/Test.scala b/test/files/run/t7741a/Test.scala
new file mode 100644
index 0000000000..a75cb6c9eb
--- /dev/null
+++ b/test/files/run/t7741a/Test.scala
@@ -0,0 +1,47 @@
+import java.io.{ByteArrayInputStream, FileOutputStream, BufferedOutputStream}
+import java.util
+
+import java.io.File
+
+import scala.tools.partest.DirectTest
+
+object Test extends DirectTest {
+
+ def code = ""
+
+ override def show(): Unit = {
+
+ val class1: Array[Byte] = GroovyInterfaceDump.dump()
+ val class2: Array[Byte] = GroovyInterface$1Dump.dump()
+ def writeFile(contents: Array[Byte], f: java.io.File): Unit = {
+ val out = new BufferedOutputStream(new FileOutputStream(f))
+ try {
+ out.write(contents)
+ } finally out.close()
+ }
+
+ val outdir = testOutput.jfile
+
+ // interface GroovyInterface {
+ //
+ // // This is the line that causes scalac to choke.
+ // // It results in a GroovyInterface$1 class, which is a non-static inner class but it's constructor does not
+ // // include the implicit parameter that is the immediate enclosing instance.
+ // // See http://jira.codehaus.org/browse/GROOVY-7312
+ // //
+ // // Scalac error:
+ // // [scalac] error: error while loading 1, class file '..../scala_groovy_interop/classes/com/example/groovy/GroovyInterface$1.class' is broken
+ // // [scalac] (class java.util.NoSuchElementException/head of empty list)
+ // final static def closure = { x -> "banana" }
+ //
+ // }
+ writeFile(GroovyInterfaceDump.dump(), new File(outdir, "GroovyInterface.class"))
+ writeFile(GroovyInterface$1Dump.dump(), new File(outdir, "GroovyInterface$1.class"))
+ compileCode("object Test { def foo(g: GroovyInterface) = g.toString }")
+ }
+
+ def compileCode(code: String) = {
+ val classpath = List(sys.props("partest.lib"), testOutput.path) mkString sys.props("path.separator")
+ compileString(newCompiler("-cp", classpath, "-d", testOutput.path))(code)
+ }
+}
diff --git a/test/files/run/t7741b.check b/test/files/run/t7741b.check
new file mode 100644
index 0000000000..a19e54aa3a
--- /dev/null
+++ b/test/files/run/t7741b.check
@@ -0,0 +1,3 @@
+1. Don't refer to Inner
+2. Refering to Inner
+pos: NoPosition Class file for HasInner$Inner not found ERROR
diff --git a/test/files/run/t7741b/HasInner.java b/test/files/run/t7741b/HasInner.java
new file mode 100644
index 0000000000..a1d0d0d81a
--- /dev/null
+++ b/test/files/run/t7741b/HasInner.java
@@ -0,0 +1,3 @@
+class HasInner {
+ class Inner {}
+}
diff --git a/test/files/run/t7741b/Test.scala b/test/files/run/t7741b/Test.scala
new file mode 100644
index 0000000000..569ae6b679
--- /dev/null
+++ b/test/files/run/t7741b/Test.scala
@@ -0,0 +1,29 @@
+import java.io.File
+
+import scala.tools.partest.StoreReporterDirectTest
+
+object Test extends StoreReporterDirectTest {
+
+ def code = ""
+
+ override def show(): Unit = {
+ deleteClass("HasInner$Inner")
+ println("1. Don't refer to Inner")
+ compileCode("class Test { def test(x: HasInner) = x }")
+ assert(filteredInfos.isEmpty, filteredInfos)
+ println("2. Refering to Inner")
+ compileCode("class Test { def test(x: HasInner#Inner) = x }")
+ println(filteredInfos.mkString("\n"))
+ }
+
+ def deleteClass(name: String) {
+ val classFile = new File(testOutput.path, name + ".class")
+ assert(classFile.exists)
+ assert(classFile.delete())
+ }
+
+ def compileCode(code: String) = {
+ val classpath = List(sys.props("partest.lib"), testOutput.path) mkString sys.props("path.separator")
+ compileString(newCompiler("-cp", classpath, "-d", testOutput.path))(code)
+ }
+}
diff --git a/test/files/run/t8845.flags b/test/files/run/t8845.flags
index aada25f80d..c30091d3de 100644
--- a/test/files/run/t8845.flags
+++ b/test/files/run/t8845.flags
@@ -1 +1 @@
--Ybackend:GenBCode -Ynooptimize
+-Ybackend:GenBCode
diff --git a/test/files/run/t8925.flags b/test/files/run/t8925.flags
index be4ef0798a..ffc65f4b81 100644
--- a/test/files/run/t8925.flags
+++ b/test/files/run/t8925.flags
@@ -1 +1 @@
--Ynooptimise -Yopt:l:none -Ybackend:GenBCode
+-Yopt:l:none -Ybackend:GenBCode
diff --git a/test/files/run/t9182.check b/test/files/run/t9182.check
new file mode 100644
index 0000000000..80e8b6c558
--- /dev/null
+++ b/test/files/run/t9182.check
@@ -0,0 +1,3 @@
+constructor package
+method A
+object A
diff --git a/test/files/run/t9182.scala b/test/files/run/t9182.scala
new file mode 100644
index 0000000000..1768aa688e
--- /dev/null
+++ b/test/files/run/t9182.scala
@@ -0,0 +1,12 @@
+// Main.scala
+package object ops {
+ object A
+ def A(a: Any) = ()
+}
+
+object Test {
+ def main(args: Array[String]): Unit = {
+ val pack = scala.reflect.runtime.currentMirror.staticModule("ops.package")
+ println(pack.info.decls.toList.map(_.toString).sorted.mkString("\n"))
+ }
+}
diff --git a/test/files/run/t9252.check b/test/files/run/t9252.check
new file mode 100644
index 0000000000..b00d748f7f
--- /dev/null
+++ b/test/files/run/t9252.check
@@ -0,0 +1 @@
+class [Lscala.runtime.BoxedUnit;
diff --git a/test/files/run/t9252.scala b/test/files/run/t9252.scala
new file mode 100644
index 0000000000..da698948e1
--- /dev/null
+++ b/test/files/run/t9252.scala
@@ -0,0 +1,5 @@
+import scala.reflect.runtime.universe._
+
+object Test extends App {
+ println(rootMirror.runtimeClass(typeOf[Array[Unit]]))
+} \ No newline at end of file
diff --git a/test/junit/scala/tools/nsc/backend/jvm/CodeGenTools.scala b/test/junit/scala/tools/nsc/backend/jvm/CodeGenTools.scala
index 5d5215d887..d0ffd06b01 100644
--- a/test/junit/scala/tools/nsc/backend/jvm/CodeGenTools.scala
+++ b/test/junit/scala/tools/nsc/backend/jvm/CodeGenTools.scala
@@ -8,7 +8,6 @@ import scala.reflect.io.VirtualDirectory
import scala.tools.asm.Opcodes
import scala.tools.asm.tree.{ClassNode, MethodNode}
import scala.tools.cmd.CommandLineParser
-import scala.tools.nsc.backend.jvm.opt.LocalOpt
import scala.tools.nsc.io.AbstractFile
import scala.tools.nsc.reporters.StoreReporter
import scala.tools.nsc.settings.MutableSettings
@@ -157,12 +156,6 @@ object CodeGenTools {
assertTrue(h.start == insVec(startIndex) && h.end == insVec(endIndex) && h.handler == insVec(handlerIndex))
}
- val localOpt = {
- val settings = new MutableSettings(msg => throw new IllegalArgumentException(msg))
- settings.processArguments(List("-Yopt:l:method"), processAll = true)
- new LocalOpt(settings)
- }
-
import scala.language.implicitConversions
implicit def aliveInstruction(ins: Instruction): (Instruction, Boolean) = (ins, true)
diff --git a/test/junit/scala/tools/nsc/backend/jvm/opt/EmptyExceptionHandlersTest.scala b/test/junit/scala/tools/nsc/backend/jvm/opt/EmptyExceptionHandlersTest.scala
index 7b0504fec0..cb01f3d164 100644
--- a/test/junit/scala/tools/nsc/backend/jvm/opt/EmptyExceptionHandlersTest.scala
+++ b/test/junit/scala/tools/nsc/backend/jvm/opt/EmptyExceptionHandlersTest.scala
@@ -40,7 +40,7 @@ class EmptyExceptionHandlersTest extends ClearAfterClass {
Op(RETURN)
)
assertTrue(convertMethod(asmMethod).handlers.length == 1)
- localOpt.removeEmptyExceptionHandlers(asmMethod)
+ LocalOptImpls.removeEmptyExceptionHandlers(asmMethod)
assertTrue(convertMethod(asmMethod).handlers.isEmpty)
}
@@ -61,7 +61,7 @@ class EmptyExceptionHandlersTest extends ClearAfterClass {
Op(RETURN)
)
assertTrue(convertMethod(asmMethod).handlers.length == 1)
- localOpt.removeEmptyExceptionHandlers(asmMethod)
+ LocalOptImpls.removeEmptyExceptionHandlers(asmMethod)
assertTrue(convertMethod(asmMethod).handlers.isEmpty)
}
diff --git a/test/junit/scala/tools/nsc/backend/jvm/opt/EmptyLabelsAndLineNumbersTest.scala b/test/junit/scala/tools/nsc/backend/jvm/opt/EmptyLabelsAndLineNumbersTest.scala
index 8c0168826e..7283e20745 100644
--- a/test/junit/scala/tools/nsc/backend/jvm/opt/EmptyLabelsAndLineNumbersTest.scala
+++ b/test/junit/scala/tools/nsc/backend/jvm/opt/EmptyLabelsAndLineNumbersTest.scala
@@ -42,14 +42,14 @@ class EmptyLabelsAndLineNumbersTest {
)
val method = genMethod()(ops.map(_._1): _*)
- assertTrue(localOpt.removeEmptyLineNumbers(method))
+ assertTrue(LocalOptImpls.removeEmptyLineNumbers(method))
assertSameCode(instructionsFromMethod(method), ops.filter(_._2).map(_._1))
}
@Test
def badlyLocatedLineNumbers(): Unit = {
def t(ops: Instruction*) =
- assertThrows[AssertionError](localOpt.removeEmptyLineNumbers(genMethod()(ops: _*)))
+ assertThrows[AssertionError](LocalOptImpls.removeEmptyLineNumbers(genMethod()(ops: _*)))
// line numbers have to be right after their referenced label node
t(LineNumber(0, Label(1)), Label(1))
@@ -88,7 +88,7 @@ class EmptyLabelsAndLineNumbersTest {
)
val method = genMethod(handlers = handler)(ops(2, 3, 8, 8, 9, 11).map(_._1): _*)
- assertTrue(localOpt.removeEmptyLabelNodes(method))
+ assertTrue(LocalOptImpls.removeEmptyLabelNodes(method))
val m = convertMethod(method)
assertSameCode(m.instructions, ops(1, 1, 7, 7, 7, 10).filter(_._2).map(_._1))
assertTrue(m.handlers match {
diff --git a/test/junit/scala/tools/nsc/backend/jvm/opt/InlineWarningTest.scala b/test/junit/scala/tools/nsc/backend/jvm/opt/InlineWarningTest.scala
index fedc074a15..029caa995c 100644
--- a/test/junit/scala/tools/nsc/backend/jvm/opt/InlineWarningTest.scala
+++ b/test/junit/scala/tools/nsc/backend/jvm/opt/InlineWarningTest.scala
@@ -143,4 +143,52 @@ class InlineWarningTest extends ClearAfterClass {
compileClasses(newCompiler(extraArgs = InlineWarningTest.argsNoWarn + " -Yopt-warnings:no-inline-mixed"))(scalaCode, List((javaCode, "A.java")), allowMessage = i => {c += 1; warns.exists(i.msg contains _)})
assert(c == 2, c)
}
+
+ @Test
+ def cannotInlinePrivateCallIntoDifferentClass(): Unit = {
+ val code =
+ """class M {
+ | @inline final def f = {
+ | @noinline def nested = 0
+ | nested
+ | }
+ |
+ | def t = f // ok
+ |}
+ |
+ |class N {
+ | def t(a: M) = a.f // not possible
+ |}
+ """.stripMargin
+
+ val warn =
+ """M::f()I is annotated @inline but could not be inlined:
+ |The callee M::f()I contains the instruction INVOKESPECIAL M.nested$1 ()I
+ |that would cause an IllegalAccessError when inlined into class N""".stripMargin
+
+ var c = 0
+ compile(code, allowMessage = i => { c += 1; i.msg contains warn })
+ assert(c == 1, c)
+ }
+
+ @Test
+ def cannotMixStrictfp(): Unit = {
+ val code =
+ """import annotation.strictfp
+ |class C {
+ | @strictfp @inline final def f = 0
+ | @strictfp def t1 = f
+ | def t2 = f
+ |}
+ """.stripMargin
+
+ val warn =
+ """C::f()I is annotated @inline but could not be inlined:
+ |The callsite method C::t2()I
+ |does not have the same strictfp mode as the callee C::f()I.""".stripMargin
+
+ var c = 0
+ compile(code, allowMessage = i => { c += 1; i.msg contains warn })
+ assert(c == 1, c)
+ }
}
diff --git a/test/junit/scala/tools/nsc/backend/jvm/opt/InlinerTest.scala b/test/junit/scala/tools/nsc/backend/jvm/opt/InlinerTest.scala
index 39fb28570e..17724aecb1 100644
--- a/test/junit/scala/tools/nsc/backend/jvm/opt/InlinerTest.scala
+++ b/test/junit/scala/tools/nsc/backend/jvm/opt/InlinerTest.scala
@@ -152,7 +152,7 @@ class InlinerTest extends ClearAfterClass {
assertSameCode(convertMethod(g).instructions.dropNonOp.take(4), expectedInlined)
- localOpt.methodOptimizations(g, "C")
+ compiler.genBCode.bTypes.localOpt.methodOptimizations(g, "C")
assertSameCode(convertMethod(g).instructions.dropNonOp,
expectedInlined ++ List(VarOp(ASTORE, 2), VarOp(ALOAD, 2), Op(ATHROW)))
}
@@ -950,4 +950,29 @@ class InlinerTest extends ClearAfterClass {
assertInvoke(getSingleMethod(t, "t3"), "B", "<init>")
assertInvoke(getSingleMethod(t, "t4"), "B", "<init>")
}
+
+ @Test
+ def dontInlineNative(): Unit = {
+ val code =
+ """class C {
+ | def t = System.arraycopy(null, 0, null, 0, 0)
+ |}
+ """.stripMargin
+ val List(c) = compileClasses(newCompiler(extraArgs = InlinerTest.args + " -Yopt-inline-heuristics:everything"))(code)
+ assertInvoke(getSingleMethod(c, "t"), "java/lang/System", "arraycopy")
+ }
+
+ @Test
+ def inlineMayRenderCodeDead(): Unit = {
+ val code =
+ """class C {
+ | @inline final def f: String = throw new Error("")
+ | @inline final def g: String = "a" + f + "b" // after inlining f, need to run DCE, because the rest of g becomes dead.
+ | def t = g // the inliner requires no dead code when inlining g (uses an Analyzer).
+ |}
+ """.stripMargin
+
+ val List(c) = compile(code)
+ assertInvoke(getSingleMethod(c, "t"), "java/lang/Error", "<init>")
+ }
}
diff --git a/test/junit/scala/tools/nsc/backend/jvm/opt/SimplifyJumpsTest.scala b/test/junit/scala/tools/nsc/backend/jvm/opt/SimplifyJumpsTest.scala
index 360fa1d23d..a685ae7dd5 100644
--- a/test/junit/scala/tools/nsc/backend/jvm/opt/SimplifyJumpsTest.scala
+++ b/test/junit/scala/tools/nsc/backend/jvm/opt/SimplifyJumpsTest.scala
@@ -26,7 +26,7 @@ class SimplifyJumpsTest {
Op(RETURN)
)
val method = genMethod()(ops: _*)
- assertTrue(localOpt.simplifyJumps(method))
+ assertTrue(LocalOptImpls.simplifyJumps(method))
assertSameCode(instructionsFromMethod(method), Op(RETURN) :: ops.tail)
}
@@ -45,7 +45,7 @@ class SimplifyJumpsTest {
Jump(GOTO, Label(2)) :: // replaced by ATHROW
rest: _*
)
- assertTrue(localOpt.simplifyJumps(method))
+ assertTrue(LocalOptImpls.simplifyJumps(method))
assertSameCode(instructionsFromMethod(method), Op(ACONST_NULL) :: Op(ATHROW) :: rest)
}
@@ -66,11 +66,11 @@ class SimplifyJumpsTest {
Op(RETURN)
)
val method = genMethod(handlers = handler)(initialInstrs: _*)
- assertFalse(localOpt.simplifyJumps(method))
+ assertFalse(LocalOptImpls.simplifyJumps(method))
assertSameCode(instructionsFromMethod(method), initialInstrs)
val optMethod = genMethod()(initialInstrs: _*) // no handler
- assertTrue(localOpt.simplifyJumps(optMethod))
+ assertTrue(LocalOptImpls.simplifyJumps(optMethod))
assertSameCode(instructionsFromMethod(optMethod).take(3), List(Label(1), Op(ACONST_NULL), Op(ATHROW)))
}
@@ -91,7 +91,7 @@ class SimplifyJumpsTest {
Op(IRETURN)
)
val method = genMethod()(begin ::: rest: _*)
- assertTrue(localOpt.simplifyJumps(method))
+ assertTrue(LocalOptImpls.simplifyJumps(method))
assertSameCode(
instructionsFromMethod(method),
List(VarOp(ILOAD, 1), Jump(IFLT, Label(3))) ::: rest.tail )
@@ -99,7 +99,7 @@ class SimplifyJumpsTest {
// no label allowed between begin and rest. if there's another label, then there could be a
// branch that label. eliminating the GOTO would change the behavior.
val nonOptMethod = genMethod()(begin ::: Label(22) :: rest: _*)
- assertFalse(localOpt.simplifyJumps(nonOptMethod))
+ assertFalse(LocalOptImpls.simplifyJumps(nonOptMethod))
}
@Test
@@ -116,7 +116,7 @@ class SimplifyJumpsTest {
// ensures that the goto is safely removed. ASM supports removing while iterating, but not the
// next element of the current. Here, the current is the IFGE, the next is the GOTO.
val method = genMethod()(code(Jump(IFGE, Label(2)), Jump(GOTO, Label(3))): _*)
- assertTrue(localOpt.simplifyJumps(method))
+ assertTrue(LocalOptImpls.simplifyJumps(method))
assertSameCode(instructionsFromMethod(method), code(Jump(IFLT, Label(3))))
}
@@ -131,7 +131,7 @@ class SimplifyJumpsTest {
Op(IRETURN)
)
val method = genMethod()(ops: _*)
- assertTrue(localOpt.simplifyJumps(method))
+ assertTrue(LocalOptImpls.simplifyJumps(method))
assertSameCode(instructionsFromMethod(method), ops.tail)
}
@@ -157,7 +157,7 @@ class SimplifyJumpsTest {
Op(IRETURN)
)
val method = genMethod()(ops(1, 2, 3): _*)
- assertTrue(localOpt.simplifyJumps(method))
+ assertTrue(LocalOptImpls.simplifyJumps(method))
assertSameCode(instructionsFromMethod(method), ops(3, 3, 3))
}
@@ -181,7 +181,7 @@ class SimplifyJumpsTest {
)
val method = genMethod()(ops(2): _*)
- assertTrue(localOpt.simplifyJumps(method))
+ assertTrue(LocalOptImpls.simplifyJumps(method))
assertSameCode(instructionsFromMethod(method), ops(3))
}
@@ -202,7 +202,7 @@ class SimplifyJumpsTest {
)
val method = genMethod()(ops(Jump(IFGE, Label(1))): _*)
- assertTrue(localOpt.simplifyJumps(method))
+ assertTrue(LocalOptImpls.simplifyJumps(method))
assertSameCode(instructionsFromMethod(method), ops(Op(POP)))
}
@@ -215,7 +215,7 @@ class SimplifyJumpsTest {
Jump(GOTO, Label(1))
)
val method = genMethod()(ops(List(Jump(IF_ICMPGE, Label(1)))): _*)
- assertTrue(localOpt.simplifyJumps(method))
+ assertTrue(LocalOptImpls.simplifyJumps(method))
assertSameCode(instructionsFromMethod(method), ops(List(Op(POP), Op(POP))))
}
}
diff --git a/test/junit/scala/tools/nsc/backend/jvm/opt/UnreachableCodeTest.scala b/test/junit/scala/tools/nsc/backend/jvm/opt/UnreachableCodeTest.scala
index da9853148b..902af7b7fa 100644
--- a/test/junit/scala/tools/nsc/backend/jvm/opt/UnreachableCodeTest.scala
+++ b/test/junit/scala/tools/nsc/backend/jvm/opt/UnreachableCodeTest.scala
@@ -44,7 +44,7 @@ class UnreachableCodeTest extends ClearAfterClass {
def assertEliminateDead(code: (Instruction, Boolean)*): Unit = {
val method = genMethod()(code.map(_._1): _*)
- localOpt.removeUnreachableCodeImpl(method, "C")
+ LocalOptImpls.removeUnreachableCodeImpl(method, "C")
val nonEliminated = instructionsFromMethod(method)
val expectedLive = code.filter(_._2).map(_._1).toList
assertSameCode(nonEliminated, expectedLive)
diff --git a/test/junit/scala/tools/nsc/doc/html/HtmlDocletTest.scala b/test/junit/scala/tools/nsc/doc/html/HtmlDocletTest.scala
new file mode 100644
index 0000000000..13a955b55d
--- /dev/null
+++ b/test/junit/scala/tools/nsc/doc/html/HtmlDocletTest.scala
@@ -0,0 +1,22 @@
+package scala.tools.nsc.doc.html
+
+import org.junit.Test
+import org.junit.Assert._
+import org.junit.runner.RunWith
+import org.junit.runners.JUnit4
+
+import scala.tools.testing.AssertUtil._
+
+@RunWith(classOf[JUnit4])
+class HtmlDocletTest {
+ @Test
+ def testSyntaxHighlightningUnicode() {
+ val in = "unicode: …"
+
+ val out = SyntaxHigh(in).toString
+
+ // SI-9038, this failed with
+ // "unicode: …" != "unicode: ¬タᆭ"
+ assertEquals(in, out)
+ }
+}
diff --git a/test/junit/scala/tools/nsc/symtab/SymbolTableTest.scala b/test/junit/scala/tools/nsc/symtab/SymbolTableTest.scala
index 895ad9d683..5a921a5eda 100644
--- a/test/junit/scala/tools/nsc/symtab/SymbolTableTest.scala
+++ b/test/junit/scala/tools/nsc/symtab/SymbolTableTest.scala
@@ -33,10 +33,10 @@ class SymbolTableTest {
import symbolTable._
symbolTable.definitions.init()
val rootClass = symbolTable.rootMirror.RootClass
- val fooSymbol = rootClass.newClassSymbol("Foo": TypeName, NoPosition, 0)
+ val fooSymbol = rootClass.newClassSymbol(TypeName("Foo"), NoPosition, 0)
val fooType = new ClassInfoType(Nil, EmptyScope, fooSymbol)
fooSymbol.info = fooType
- val barSymbol = rootClass.newClassSymbol("Bar": TypeName, NoPosition, 0)
+ val barSymbol = rootClass.newClassSymbol(TypeName("Bar"), NoPosition, 0)
val fooTypeRef = TypeRef(fooSymbol.owner.tpe, fooSymbol, Nil)
val barType = new ClassInfoType(List(fooTypeRef), EmptyScope, barSymbol)
barSymbol.info = barType
diff --git a/test/junit/scala/tools/nsc/transform/patmat/SolvingTest.scala b/test/junit/scala/tools/nsc/transform/patmat/SolvingTest.scala
index 1fff9c9a32..1fe7b19056 100644
--- a/test/junit/scala/tools/nsc/transform/patmat/SolvingTest.scala
+++ b/test/junit/scala/tools/nsc/transform/patmat/SolvingTest.scala
@@ -6,6 +6,7 @@ import org.junit.runner.RunWith
import org.junit.runners.JUnit4
import scala.collection.mutable
+import scala.reflect.internal.util.Position
import scala.tools.nsc.{Global, Settings}
object TestSolver extends Logic with Solving {
@@ -72,6 +73,8 @@ object TestSolver extends Logic with Solving {
def prepareNewAnalysis() = {}
+ def uncheckedWarning(pos: Position, msg: String) = sys.error(msg)
+
def reportWarning(msg: String) = sys.error(msg)
/**
diff --git a/test/scaladoc/run/t5795.check b/test/scaladoc/run/t5795.check
new file mode 100644
index 0000000000..d08ab619ed
--- /dev/null
+++ b/test/scaladoc/run/t5795.check
@@ -0,0 +1,4 @@
+newSource:16: warning: Could not find any member to link for "Exception".
+ /**
+ ^
+Done.
diff --git a/test/scaladoc/run/t5795.scala b/test/scaladoc/run/t5795.scala
new file mode 100644
index 0000000000..767e4f1a72
--- /dev/null
+++ b/test/scaladoc/run/t5795.scala
@@ -0,0 +1,63 @@
+import scala.tools.nsc.doc.model._
+import scala.tools.partest.ScaladocModelTest
+
+object Test extends ScaladocModelTest {
+
+ override def code = """
+/**
+ * Only the 'deprecated' tag should stay.
+ *
+ * @author
+ * @since
+ * @todo
+ * @note
+ * @see
+ * @version
+ * @deprecated
+ * @example
+ * @constructor
+ */
+object Test {
+ /**
+ * Only the 'throws' tag should stay.
+ * @param foo
+ * @param bar
+ * @param baz
+ * @return
+ * @throws Exception
+ * @tparam T
+ */
+ def foo[T](foo: Any, bar: Any, baz: Any): Int = 1
+}
+ """
+
+ def scaladocSettings = ""
+
+ def test(b: Boolean, text: => String): Unit = if (!b) println(text)
+
+ def testModel(root: Package) = {
+ import access._
+ val obj = root._object("Test")
+ val c = obj.comment.get
+
+ test(c.authors.isEmpty, s"expected no authors, found: ${c.authors}")
+ test(!c.since.isDefined, s"expected no since tag, found: ${c.since}")
+ test(c.todo.isEmpty, s"expected no todos, found: ${c.todo}")
+ test(c.note.isEmpty, s"expected no note, found: ${c.note}")
+ test(c.see.isEmpty, s"expected no see, found: ${c.see}")
+ test(!c.version.isDefined, s"expected no version tag, found: ${c.version}")
+ // deprecated stays
+ test(c.deprecated.isDefined, s"expected deprecated tag, found none")
+ test(c.example.isEmpty, s"expected no example, found: ${c.example}")
+ test(!c.constructor.isDefined, s"expected no constructor tag, found: ${c.constructor}")
+
+ val method = obj._method("foo")
+ val mc = method.comment.get
+
+ test(mc.valueParams.isEmpty, s"expected empty value params, found: ${mc.valueParams}")
+ test(mc.typeParams.isEmpty, s"expected empty type params, found: ${mc.typeParams}")
+ test(!mc.result.isDefined, s"expected no result tag, found: ${mc.result}")
+ // throws stay
+ test(!mc.throws.isEmpty, s"expected an exception tag, found: ${mc.throws}")
+ }
+}
diff --git a/test/scaladoc/scalacheck/CommentFactoryTest.scala b/test/scaladoc/scalacheck/CommentFactoryTest.scala
index ff64a25602..d30b78087c 100644
--- a/test/scaladoc/scalacheck/CommentFactoryTest.scala
+++ b/test/scaladoc/scalacheck/CommentFactoryTest.scala
@@ -24,8 +24,11 @@ class Factory(val g: Global, val s: doc.Settings)
}
}
+ def getComment(s: String): Comment =
+ parse(s, "", scala.tools.nsc.util.NoPosition, null)
+
def parseComment(s: String): Option[Inline] =
- strip(parse(s, "", scala.tools.nsc.util.NoPosition, null))
+ strip(getComment(s))
def createBody(s: String) =
parse(s, "", scala.tools.nsc.util.NoPosition, null).body
@@ -166,4 +169,19 @@ object Test extends Properties("CommentFactory") {
}
}
+ property("Empty parameter text should be empty") = {
+ // used to fail with
+ // body == Body(List(Paragraph(Chain(List(Summary(Text('\n')))))))
+ factory.getComment(
+ """
+/**
+ * @deprecated
+ */
+ """).deprecated match {
+ case Some(Body(l)) if l.isEmpty => true
+ case other =>
+ println(other)
+ false
+ }
+ }
}
diff --git a/test/scaladoc/scalacheck/HtmlFactoryTest.scala b/test/scaladoc/scalacheck/HtmlFactoryTest.scala
index 51633be440..6a6b1f8901 100644
--- a/test/scaladoc/scalacheck/HtmlFactoryTest.scala
+++ b/test/scaladoc/scalacheck/HtmlFactoryTest.scala
@@ -685,7 +685,7 @@ object Test extends Properties("HtmlFactory") {
case node: scala.xml.Node => {
val s = node.toString
s.contains("<h6>Author:</h6>") &&
- s.contains("<p>The Only Author\n</p>")
+ s.contains("<p>The Only Author</p>")
}
case _ => false
}
@@ -699,7 +699,7 @@ object Test extends Properties("HtmlFactory") {
val s = node.toString
s.contains("<h6>Authors:</h6>") &&
s.contains("<p>The First Author</p>") &&
- s.contains("<p>The Second Author\n</p>")
+ s.contains("<p>The Second Author</p>")
}
case _ => false
}
diff --git a/versions.properties b/versions.properties
index 096108a21f..2ecfd23800 100644
--- a/versions.properties
+++ b/versions.properties
@@ -27,7 +27,7 @@ actors-migration.version.number=1.1.0
jline.version=2.12.1
# external modules, used internally (not shipped)
-partest.version.number=1.0.5
+partest.version.number=1.0.6
scalacheck.version.number=1.11.4
# TODO: modularize the compiler