summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJason Zaugg <jzaugg@gmail.com>2016-08-09 15:42:44 +1000
committerJason Zaugg <jzaugg@gmail.com>2016-08-19 09:26:40 +1000
commitc141254b97a48e47ed7a6bfa08922671cc639081 (patch)
tree5133679c28c00c65f64e8423fb5fe256f885dc86
parentb8e4d1f692c5712990b45f50625627015112df32 (diff)
downloadscala-c141254b97a48e47ed7a6bfa08922671cc639081.tar.gz
scala-c141254b97a48e47ed7a6bfa08922671cc639081.tar.bz2
scala-c141254b97a48e47ed7a6bfa08922671cc639081.zip
Determistically enter classes from directory into package scope
On Linux, the directory listing is not automatically sorted on Mac. This leads to non-determistic ids of Symbols of the classes in a directory, which in turn leads to instability of the ordering of parents within inferred refinement types. Notable, with this patch, we will stably infer: ``` scala> case class C(); case class D(); List(C(), D()).head defined class C defined class D res0: Product with Serializable = C() ``` rather than sometimes getting `Serializable with Product` on Linux. As such, I've removed the workarounds for this instability in two test cases.
-rw-r--r--src/compiler/scala/tools/nsc/classpath/DirectoryClassPath.scala24
-rw-r--r--test/files/presentation/callcc-interpreter/Runner.scala5
-rw-r--r--test/files/run/t7747-repl.scala4
3 files changed, 23 insertions, 10 deletions
diff --git a/src/compiler/scala/tools/nsc/classpath/DirectoryClassPath.scala b/src/compiler/scala/tools/nsc/classpath/DirectoryClassPath.scala
index aba941e043..0d6925e8ac 100644
--- a/src/compiler/scala/tools/nsc/classpath/DirectoryClassPath.scala
+++ b/src/compiler/scala/tools/nsc/classpath/DirectoryClassPath.scala
@@ -5,6 +5,9 @@ package scala.tools.nsc.classpath
import java.io.File
import java.net.URL
+import java.util
+import java.util.Comparator
+
import scala.reflect.io.{AbstractFile, PlainFile}
import scala.tools.nsc.util.{ClassPath, ClassRepresentation}
import FileUtils._
@@ -87,9 +90,24 @@ trait JFileDirectoryLookup[FileEntryType <: ClassRepresentation] extends Directo
if (packageDir.exists && packageDir.isDirectory) Some(packageDir)
else None
}
- protected def listChildren(dir: File, filter: Option[File => Boolean]): Array[File] = filter match {
- case Some(f) => dir.listFiles(mkFileFilter(f))
- case None => dir.listFiles()
+ protected def listChildren(dir: File, filter: Option[File => Boolean]): Array[File] = {
+ val listing = filter match {
+ case Some(f) => dir.listFiles(mkFileFilter(f))
+ case None => dir.listFiles()
+ }
+
+ // Sort by file name for stable order of directory .class entries in package scope.
+ // This gives stable results ordering of base type sequences for unrelated classes
+ // with the same base type depth.
+ //
+ // Notably, this will stably infer`Product with Serializable`
+ // as the type of `ase class C(); case class D(); List(C(), D()).head`, rather than the opposite order.
+ // On Mac, the HFS performs this sorting transparently, but on Linux the order is unspecified.
+ //
+ // Note this behaviour can be enabled with in javac with `javac -XDsortfiles`, but that's only
+ // intended to improve determinism of the compiler for compiler hackers.
+ util.Arrays.sort(listing, (o1: File, o2: File) => o1.getName.compareTo(o2.getName))
+ listing
}
protected def getName(f: File): String = f.getName
protected def toAbstractFile(f: File): AbstractFile = new PlainFile(new scala.reflect.io.File(f))
diff --git a/test/files/presentation/callcc-interpreter/Runner.scala b/test/files/presentation/callcc-interpreter/Runner.scala
index a5698be5c2..1c03e3d5ba 100644
--- a/test/files/presentation/callcc-interpreter/Runner.scala
+++ b/test/files/presentation/callcc-interpreter/Runner.scala
@@ -1,6 +1,3 @@
import scala.tools.nsc.interactive.tests._
-object Test extends InteractiveTest {
- // Normalize ordering of LUB
- override def normalize(s: String) = s.replace("Serializable with Product", "Product with Serializable")
-}
+object Test extends InteractiveTest
diff --git a/test/files/run/t7747-repl.scala b/test/files/run/t7747-repl.scala
index 0094d3ba98..8203f4c802 100644
--- a/test/files/run/t7747-repl.scala
+++ b/test/files/run/t7747-repl.scala
@@ -10,9 +10,7 @@ object Test extends ReplTest {
override def normalize(s: String) = {
// replace indylambda function names by <function0>
- val s2 = """\$Lambda.*""".r.replaceAllIn(s, "<function0>")
- // Normalize ordering of LUB
- s2.replace("Serializable with Product", "Product with Serializable")
+ """\$Lambda.*""".r.replaceAllIn(s, "<function0>")
}
def code = """