diff options
author | Jason Zaugg <jzaugg@gmail.com> | 2016-08-09 15:42:44 +1000 |
---|---|---|
committer | Jason Zaugg <jzaugg@gmail.com> | 2016-08-19 09:26:40 +1000 |
commit | c141254b97a48e47ed7a6bfa08922671cc639081 (patch) | |
tree | 5133679c28c00c65f64e8423fb5fe256f885dc86 | |
parent | b8e4d1f692c5712990b45f50625627015112df32 (diff) | |
download | scala-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.scala | 24 | ||||
-rw-r--r-- | test/files/presentation/callcc-interpreter/Runner.scala | 5 | ||||
-rw-r--r-- | test/files/run/t7747-repl.scala | 4 |
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 = """ |