summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/AnalyzerPlugins.scala2
-rw-r--r--src/library/scala/collection/SeqViewLike.scala2
-rw-r--r--src/library/scala/collection/generic/GenericTraversableTemplate.scala2
-rw-r--r--src/library/scala/collection/immutable/List.scala2
-rw-r--r--src/scaladoc/scala/tools/nsc/doc/html/resource/lib/index.js2
-rw-r--r--test/files/pos/t8801.scala21
-rw-r--r--test/files/run/macroPlugins-enterStats.check30
-rw-r--r--test/files/run/macroPlugins-enterStats.scala50
-rw-r--r--test/junit/scala/collection/ParallelConsistencyTest.scala44
-rw-r--r--test/junit/scala/collection/immutable/VectorTest.scala20
10 files changed, 150 insertions, 25 deletions
diff --git a/src/compiler/scala/tools/nsc/typechecker/AnalyzerPlugins.scala b/src/compiler/scala/tools/nsc/typechecker/AnalyzerPlugins.scala
index 5a70d4c524..2c27bdb03a 100644
--- a/src/compiler/scala/tools/nsc/typechecker/AnalyzerPlugins.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/AnalyzerPlugins.scala
@@ -447,6 +447,6 @@ trait AnalyzerPlugins { self: Analyzer =>
// performance opt
if (macroPlugins.isEmpty) stats
else macroPlugins.foldLeft(stats)((current, plugin) =>
- if (!plugin.isActive()) current else plugin.pluginsEnterStats(typer, stats))
+ if (!plugin.isActive()) current else plugin.pluginsEnterStats(typer, current))
}
}
diff --git a/src/library/scala/collection/SeqViewLike.scala b/src/library/scala/collection/SeqViewLike.scala
index 59e0e73e89..3473c8aff1 100644
--- a/src/library/scala/collection/SeqViewLike.scala
+++ b/src/library/scala/collection/SeqViewLike.scala
@@ -83,7 +83,7 @@ trait SeqViewLike[+A,
}
def length = index(self.length)
def apply(idx: Int) = {
- if (idx < 0 || idx >= self.length) throw new IndexOutOfBoundsException(idx.toString)
+ if (idx < 0 || idx >= length) throw new IndexOutOfBoundsException(idx.toString)
val row = findRow(idx, 0, self.length - 1)
mapping(self(row)).seq.toSeq(idx - index(row))
}
diff --git a/src/library/scala/collection/generic/GenericTraversableTemplate.scala b/src/library/scala/collection/generic/GenericTraversableTemplate.scala
index 54455c531a..bdd91ba7a4 100644
--- a/src/library/scala/collection/generic/GenericTraversableTemplate.scala
+++ b/src/library/scala/collection/generic/GenericTraversableTemplate.scala
@@ -216,7 +216,7 @@ trait GenericTraversableTemplate[+A, +CC[X] <: GenTraversable[X]] extends HasNew
val bs: IndexedSeq[Builder[B, CC[B]]] = IndexedSeq.fill(headSize)(genericBuilder[B])
for (xs <- sequential) {
var i = 0
- for (x <- asTraversable(xs)) {
+ for (x <- asTraversable(xs).seq) {
if (i >= headSize) fail
bs(i) += x
i += 1
diff --git a/src/library/scala/collection/immutable/List.scala b/src/library/scala/collection/immutable/List.scala
index a46b4adabb..254f14f13c 100644
--- a/src/library/scala/collection/immutable/List.scala
+++ b/src/library/scala/collection/immutable/List.scala
@@ -324,7 +324,7 @@ sealed abstract class List[+A] extends AbstractSeq[A]
var h: ::[B] = null
var t: ::[B] = null
while (rest ne Nil) {
- f(rest.head).foreach{ b =>
+ f(rest.head).seq.foreach{ b =>
if (!found) {
h = new ::(b, Nil)
t = h
diff --git a/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/index.js b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/index.js
index 3f5cfb4b52..3d9cf8d465 100644
--- a/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/index.js
+++ b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/index.js
@@ -94,7 +94,7 @@ function setFrameSrcFromUrlFragment() {
if (memberSig) {
locWithMemeberSig += "#" + memberSig;
}
- frames["template"].location.replace(locWithMemeberSig);
+ frames["template"].location.replace(location.protocol + locWithMemeberSig);
} else {
console.log("empty fragment detected");
frames["template"].location.replace("package.html");
diff --git a/test/files/pos/t8801.scala b/test/files/pos/t8801.scala
new file mode 100644
index 0000000000..695b456e12
--- /dev/null
+++ b/test/files/pos/t8801.scala
@@ -0,0 +1,21 @@
+sealed trait Nat {
+ type Prev <: Nat { type Succ = Nat.this.type }
+ type Succ <: Nat { type Prev = Nat.this.type }
+}
+
+object Nat {
+ object Zero extends Nat {
+ type Prev = Nothing
+ }
+
+ type _0 = Zero.type
+ type _1 = _0#Succ
+ type _2 = _1#Succ
+ type _3 = _2#Succ
+ type _4 = _3#Succ
+ type _5 = _4#Succ
+ type _6 = _5#Succ
+ type _7 = _6#Succ
+ type _8 = _7#Succ
+ type _9 = _8#Succ
+}
diff --git a/test/files/run/macroPlugins-enterStats.check b/test/files/run/macroPlugins-enterStats.check
new file mode 100644
index 0000000000..133b1ae1af
--- /dev/null
+++ b/test/files/run/macroPlugins-enterStats.check
@@ -0,0 +1,30 @@
+[[syntax trees at end of typer]] // newSource1.scala
+package <empty> {
+ class C extends scala.AnyRef {
+ def <init>(): C = {
+ C.super.<init>();
+ ()
+ };
+ def x: Int = 2;
+ def xmacroPlugin1: Nothing = scala.this.Predef.???;
+ def xmacroPlugin2: Nothing = scala.this.Predef.???;
+ def xmacroPlugin2macroPlugin1: Nothing = scala.this.Predef.???;
+ def y: Int = 3;
+ def ymacroPlugin1: Nothing = scala.this.Predef.???;
+ def ymacroPlugin2: Nothing = scala.this.Predef.???;
+ def ymacroPlugin2macroPlugin1: Nothing = scala.this.Predef.???
+ }
+}
+
+macroPlugin2:enterStat(class C extends scala.AnyRef { def <init>() = { super.<init>(); () }; def x = 2; def y = 3 })
+macroPlugin1:enterStat(class C extends scala.AnyRef { def <init>() = { super.<init>(); () }; def x = 2; def y = 3 })
+macroPlugin2:enterStat(def <init>() = { super.<init>(); () })
+macroPlugin2:enterStat(def x = 2)
+macroPlugin2:enterStat(def y = 3)
+macroPlugin1:enterStat(def <init>() = { super.<init>(); () })
+macroPlugin1:enterStat(def x = 2)
+macroPlugin1:enterStat(def xmacroPlugin2 = $qmark$qmark$qmark)
+macroPlugin1:enterStat(def y = 3)
+macroPlugin1:enterStat(def ymacroPlugin2 = $qmark$qmark$qmark)
+macroPlugin2:enterStat(super.<init>())
+macroPlugin1:enterStat(super.<init>())
diff --git a/test/files/run/macroPlugins-enterStats.scala b/test/files/run/macroPlugins-enterStats.scala
new file mode 100644
index 0000000000..917233e990
--- /dev/null
+++ b/test/files/run/macroPlugins-enterStats.scala
@@ -0,0 +1,50 @@
+import scala.tools.partest._
+import scala.tools.nsc._
+
+object Test extends DirectTest {
+ override def extraSettings: String = "-usejavacp -Xprint:typer"
+
+ def code = """
+ class C {
+ def x = 2
+ def y = 3
+ }
+ """.trim
+
+ def show() {
+ val global = newCompiler()
+ import global._
+ import analyzer._
+
+ val output = collection.mutable.ListBuffer[String]()
+ def log(what: String) = output += what.replace(String.format("%n"), " ")
+
+ def logEnterStat(pluginName: String, stat: Tree): Unit = log(s"$pluginName:enterStat($stat)")
+ def deriveStat(pluginName: String, typer: Typer, stat: Tree): List[Tree] = stat match {
+ case DefDef(mods, name, Nil, Nil, TypeTree(), body) =>
+ val derived = DefDef(NoMods, TermName(name + pluginName), Nil, Nil, TypeTree(), Ident(TermName("$qmark$qmark$qmark")))
+ newNamer(typer.context).enterSym(derived)
+ List(derived)
+ case _ =>
+ Nil
+ }
+
+ object macroPlugin1 extends MacroPlugin {
+ override def pluginsEnterStats(typer: Typer, stats: List[Tree]): List[Tree] = {
+ stats.foreach(stat => logEnterStat("macroPlugin1", stat))
+ stats.flatMap(stat => stat +: deriveStat("macroPlugin1", typer, stat))
+ }
+ }
+ object macroPlugin2 extends MacroPlugin {
+ override def pluginsEnterStats(typer: Typer, stats: List[Tree]): List[Tree] = {
+ stats.foreach(stat => logEnterStat("macroPlugin2", stat))
+ stats.flatMap(stat => stat +: deriveStat("macroPlugin2", typer, stat))
+ }
+ }
+
+ addMacroPlugin(macroPlugin1)
+ addMacroPlugin(macroPlugin2)
+ compileString(global)(code)
+ println(output.mkString("\n"))
+ }
+}
diff --git a/test/junit/scala/collection/ParallelConsistencyTest.scala b/test/junit/scala/collection/ParallelConsistencyTest.scala
new file mode 100644
index 0000000000..da96362413
--- /dev/null
+++ b/test/junit/scala/collection/ParallelConsistencyTest.scala
@@ -0,0 +1,44 @@
+package scala.collection.immutable
+
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.JUnit4
+
+@RunWith(classOf[JUnit4])
+class ParallelConsistencyTest {
+
+ private val theSeq = Seq(1,2,3)
+
+ // This collection will throw an exception if you do anything but call .length or .seq
+ private val mustCallSeq: collection.GenSeq[Int] = new collection.parallel.ParSeq[Int] {
+ def length = 3
+
+ // This method is surely sequential & safe -- want all access to go through here
+ def seq = theSeq
+
+ def notSeq = throw new Exception("Access to parallel collection not via .seq")
+
+ // These methods could possibly be used dangerously explicitly or internally
+ // (apply could also be used safely; if it is, do test with mustCallSeq)
+ def apply(i: Int) = notSeq
+ def splitter = notSeq
+ }
+
+ // Test Vector ++ with a small parallel collection concatenation (SI-9072).
+ @Test
+ def testPlusPlus(): Unit = {
+ assert((Vector.empty ++ mustCallSeq) == theSeq, "Vector ++ unsafe with parallel vectors")
+ }
+
+ // SI-9126, 1 of 2
+ @Test
+ def testTranspose(): Unit = {
+ assert(List(mustCallSeq).transpose.flatten == theSeq, "Transposing inner parallel collection unsafe")
+ }
+
+ // SI-9126, 2 of 2
+ @Test
+ def testList_flatMap(): Unit = {
+ assert(List(1).flatMap(_ => mustCallSeq) == theSeq, "List#flatMap on inner parallel collection unsafe")
+ }
+}
diff --git a/test/junit/scala/collection/immutable/VectorTest.scala b/test/junit/scala/collection/immutable/VectorTest.scala
deleted file mode 100644
index e7edba3e43..0000000000
--- a/test/junit/scala/collection/immutable/VectorTest.scala
+++ /dev/null
@@ -1,20 +0,0 @@
-package scala.collection.immutable
-
-import org.junit.{Assert, Test}
-import org.junit.runner.RunWith
-import org.junit.runners.JUnit4
-
-@RunWith(classOf[JUnit4])
-class VectorTest {
- /**
- * Test Vector ++ with a small parallel collection concatenation (SI-9072).
- *
- */
- @Test
- def testPlusPlus(): Unit = {
- val smallVec = (0 to 1)
- val smallParVec = smallVec.par
- val testElementsSize = (0 to 1000).map( _ => Vector.empty ++ smallParVec )
- Assert.assertTrue(testElementsSize.forall( v => v.size == 2 ))
- }
-}