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 /src/compiler/scala/tools/nsc/classpath/DirectoryClassPath.scala | |
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.
Diffstat (limited to 'src/compiler/scala/tools/nsc/classpath/DirectoryClassPath.scala')
-rw-r--r-- | src/compiler/scala/tools/nsc/classpath/DirectoryClassPath.scala | 24 |
1 files changed, 21 insertions, 3 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)) |