diff options
-rw-r--r-- | src/compiler/scala/tools/ant/templates/tool-windows.tmpl | 17 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala | 4 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/backend/opt/DeadCodeElimination.scala | 8 | ||||
-rw-r--r-- | src/interactive/scala/tools/nsc/interactive/Global.scala | 10 | ||||
-rw-r--r-- | test/files/pos/SI-4012-a.scala | 7 | ||||
-rw-r--r-- | test/files/pos/SI-4012-b.scala | 15 | ||||
-rw-r--r-- | test/files/presentation/completion-implicit-chained.check | 29 | ||||
-rw-r--r-- | test/files/presentation/completion-implicit-chained/Test.scala | 3 | ||||
-rw-r--r-- | test/files/presentation/completion-implicit-chained/src/Completions.scala | 12 | ||||
-rw-r--r-- | test/files/run/t6546.flags | 1 | ||||
-rw-r--r-- | test/files/run/t6546/A_1.scala | 6 | ||||
-rw-r--r-- | test/files/run/t6546/B_2.scala | 8 |
12 files changed, 109 insertions, 11 deletions
diff --git a/src/compiler/scala/tools/ant/templates/tool-windows.tmpl b/src/compiler/scala/tools/ant/templates/tool-windows.tmpl index 1288eb0b7c..8441f3af23 100644 --- a/src/compiler/scala/tools/ant/templates/tool-windows.tmpl +++ b/src/compiler/scala/tools/ant/templates/tool-windows.tmpl @@ -12,15 +12,18 @@ setlocal enableextensions enabledelayedexpansion set _LINE_TOOLCP= -:another_param - rem Use "%~1" to handle spaces in paths. See http://ss64.com/nt/syntax-args.html -if "%~1"=="-toolcp" ( - set _LINE_TOOLCP=%~2 - shift - shift - goto another_param +rem SI-7295 The goto here is needed to avoid problems with `scala Script.cmd "arg(with)paren"`, +rem we must not evaluate %~2 eagerly, but delayed expansion doesn't seem to allow +rem removal of quotation marks. +if not [%~1]==[-toolcp] ( + goto :notoolcp ) +shift +set _LINE_TOOLCP=%~1 +shift + +:notoolcp rem We keep in _JAVA_PARAMS all -J-prefixed and -D-prefixed arguments set _JAVA_PARAMS= diff --git a/src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala b/src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala index 8bbc382251..5e885fdd04 100644 --- a/src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala +++ b/src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala @@ -104,6 +104,7 @@ abstract class GenASM extends SubComponent with BytecodeWriters with GenJVMASM { if (settings.Xdce) for ((sym, cls) <- icodes.classes if inliner.isClosureClass(sym) && !deadCode.liveClosures(sym)) { log(s"Optimizer eliminated ${sym.fullNameString}") + deadCode.elidedClosures += sym icodes.classes -= sym } @@ -639,7 +640,8 @@ abstract class GenASM extends SubComponent with BytecodeWriters with GenJVMASM { innerClassBuffer += m } - val allInners: List[Symbol] = innerClassBuffer.toList + val allInners: List[Symbol] = innerClassBuffer.toList filterNot deadCode.elidedClosures + if (allInners.nonEmpty) { debuglog(csym.fullName('.') + " contains " + allInners.size + " inner classes.") diff --git a/src/compiler/scala/tools/nsc/backend/opt/DeadCodeElimination.scala b/src/compiler/scala/tools/nsc/backend/opt/DeadCodeElimination.scala index 193aae37b6..0cfcea87f8 100644 --- a/src/compiler/scala/tools/nsc/backend/opt/DeadCodeElimination.scala +++ b/src/compiler/scala/tools/nsc/backend/opt/DeadCodeElimination.scala @@ -41,7 +41,13 @@ abstract class DeadCodeElimination extends SubComponent { } /** closures that are instantiated at least once, after dead code elimination */ - val liveClosures: mutable.Set[Symbol] = new mutable.HashSet() + val liveClosures = perRunCaches.newSet[Symbol]() + + /** closures that are eliminated, populated by GenASM.AsmPhase.run() + * these class symbols won't have a .class physical file, thus shouldn't be included in InnerClasses JVM attribute, + * otherwise some tools get confused or slow (SI-6546) + * */ + val elidedClosures = perRunCaches.newSet[Symbol]() /** Remove dead code. */ diff --git a/src/interactive/scala/tools/nsc/interactive/Global.scala b/src/interactive/scala/tools/nsc/interactive/Global.scala index 94f9aef38b..da838e0f83 100644 --- a/src/interactive/scala/tools/nsc/interactive/Global.scala +++ b/src/interactive/scala/tools/nsc/interactive/Global.scala @@ -1056,8 +1056,15 @@ class Global(settings: Settings, _reporter: Reporter, projectName: String = "") case t => t } val context = doLocateContext(pos) + + val shouldTypeQualifier = tree0.tpe match { + case null => true + case mt: MethodType => mt.isImplicit + case _ => false + } + // TODO: guard with try/catch to deal with ill-typed qualifiers. - val tree = if (tree0.tpe eq null) analyzer newTyper context typedQualifier tree0 else tree0 + val tree = if (shouldTypeQualifier) analyzer newTyper context typedQualifier tree0 else tree0 debugLog("typeMembers at "+tree+" "+tree.tpe) val superAccess = tree.isInstanceOf[Super] @@ -1231,4 +1238,3 @@ class Global(settings: Settings, _reporter: Reporter, projectName: String = "") } object CancelException extends Exception - diff --git a/test/files/pos/SI-4012-a.scala b/test/files/pos/SI-4012-a.scala new file mode 100644 index 0000000000..7fceeea3c3 --- /dev/null +++ b/test/files/pos/SI-4012-a.scala @@ -0,0 +1,7 @@ +trait C1[+A] { + def head: A = sys.error("") +} +trait C2[@specialized +A] extends C1[A] { + override def head: A = super.head +} +class C3 extends C2[Char] diff --git a/test/files/pos/SI-4012-b.scala b/test/files/pos/SI-4012-b.scala new file mode 100644 index 0000000000..6bc8592766 --- /dev/null +++ b/test/files/pos/SI-4012-b.scala @@ -0,0 +1,15 @@ +trait Super[@specialized(Int) A] { + def superb = 0 +} + +object Sub extends Super[Int] { + // it is expected that super[Super].superb crashes, since + // specialization does parent class rewiring, and the super + // of Sub becomes Super$mcII$sp and not Super. But I consider + // this normal behavior -- if you want, I can modify duplicatiors + // to make this work, but I consider it's best to keep this + // let the user know Super is not the superclass anymore. + // super[Super].superb - Vlad + super.superb // okay + override def superb: Int = super.superb // okay +} diff --git a/test/files/presentation/completion-implicit-chained.check b/test/files/presentation/completion-implicit-chained.check new file mode 100644 index 0000000000..b34e6bc7e1 --- /dev/null +++ b/test/files/presentation/completion-implicit-chained.check @@ -0,0 +1,29 @@ +reload: Completions.scala + +askTypeCompletion at Completions.scala(11,16) +================================================================================ +[response] askCompletionAt (11,16) +retrieved 24 members +[inaccessible] protected[package lang] def clone(): Object +[inaccessible] protected[package lang] def finalize(): Unit +def equals(x$1: Any): Boolean +def hashCode(): Int +def map(x: Int => Int)(implicit a: DummyImplicit): test.O.type +def toString(): String +final def !=(x$1: Any): Boolean +final def !=(x$1: AnyRef): Boolean +final def ##(): Int +final def ==(x$1: Any): Boolean +final def ==(x$1: AnyRef): Boolean +final def asInstanceOf[T0]: T0 +final def eq(x$1: AnyRef): Boolean +final def isInstanceOf[T0]: Boolean +final def ne(x$1: AnyRef): Boolean +final def notify(): Unit +final def notifyAll(): Unit +final def synchronized[T0](x$1: T0): T0 +final def wait(): Unit +final def wait(x$1: Long): Unit +final def wait(x$1: Long,x$2: Int): Unit +private[this] val prefix123: Int +================================================================================ diff --git a/test/files/presentation/completion-implicit-chained/Test.scala b/test/files/presentation/completion-implicit-chained/Test.scala new file mode 100644 index 0000000000..bec1131c4c --- /dev/null +++ b/test/files/presentation/completion-implicit-chained/Test.scala @@ -0,0 +1,3 @@ +import scala.tools.nsc.interactive.tests.InteractiveTest + +object Test extends InteractiveTest
\ No newline at end of file diff --git a/test/files/presentation/completion-implicit-chained/src/Completions.scala b/test/files/presentation/completion-implicit-chained/src/Completions.scala new file mode 100644 index 0000000000..67922dfec0 --- /dev/null +++ b/test/files/presentation/completion-implicit-chained/src/Completions.scala @@ -0,0 +1,12 @@ +package test + +import scala.Predef.DummyImplicit // turn off other predef implicits for a cleaner .check file. + +object O { + def map(x: Int => Int)(implicit a: DummyImplicit): O.type = this + val prefix123 : Int = 0 +} + +class Foo { + O.map(x => x)./*!*/ // we want the presentation compiler to apply the implicit argument list. +} diff --git a/test/files/run/t6546.flags b/test/files/run/t6546.flags new file mode 100644 index 0000000000..eb4d19bcb9 --- /dev/null +++ b/test/files/run/t6546.flags @@ -0,0 +1 @@ +-optimise
\ No newline at end of file diff --git a/test/files/run/t6546/A_1.scala b/test/files/run/t6546/A_1.scala new file mode 100644 index 0000000000..bd086c08f8 --- /dev/null +++ b/test/files/run/t6546/A_1.scala @@ -0,0 +1,6 @@ +final class Opt { + @inline def getOrElse(x: => String): String = "" +} +class A_1 { + def f(x: Opt): String = x getOrElse null +} diff --git a/test/files/run/t6546/B_2.scala b/test/files/run/t6546/B_2.scala new file mode 100644 index 0000000000..64ec966f75 --- /dev/null +++ b/test/files/run/t6546/B_2.scala @@ -0,0 +1,8 @@ +import scala.tools.partest.BytecodeTest + +object Test extends BytecodeTest { + def show: Unit = { + val node = loadClassNode("A_1") + assert(node.innerClasses.isEmpty, node.innerClasses) + } +} |