diff options
52 files changed, 2169 insertions, 319 deletions
diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000000..f90835d970 --- /dev/null +++ b/.gitignore @@ -0,0 +1,48 @@ +# +# Are you tempted to edit this file? +# +# First consider if the changes make sense for all, +# or if they are specific to your workflow/system. +# If it is the latter, you can augment this list with +# entries in .git/info/excludes +# +# see also test/files/.gitignore +# + +# +# JARs aren't checked in, they are fetched by Ant / pull_binary_libs.sh +# +# We could be more concise with /lib/**/*.jar but that assumes +# a late-model git. +# +/lib/ant/*.jar +/lib/*.jar +/test/files/codelib/*.jar +/test/files/lib/*.jar +/test/files/speclib/instrumented.jar +/tools/*.jar + +# Developer specific Ant properties +/build.properties + +# target directories for ant build +/build/ +/dists/ + +# other +/out/ +/bin/ +/sandbox/ + +# eclipse, intellij +/.classpath +/.project +/src/intellij/*.iml +/src/intellij/*.ipr +/src/intellij/*.iws +/.cache +/.idea +/.settings + +# Standard symbolic link to build/quick/bin +/qbin diff --git a/bincompat-backward.whitelist.conf b/bincompat-backward.whitelist.conf index 08d972eee1..0500ec10ab 100644 --- a/bincompat-backward.whitelist.conf +++ b/bincompat-backward.whitelist.conf @@ -267,6 +267,50 @@ filter { { matchName="scala.reflect.internal.SymbolTable.scala$reflect$internal$Trees$$duplicator" problemName=IncompatibleResultTypeProblem + }, + { + matchName="scala.reflect.internal.StdNames.compactifyName" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.util.WeakHashSet" + problemName=FinalClassProblem + }, + { + matchName="scala.reflect.internal.util.WeakReferenceWithEquals" + problemName=MissingClassProblem + }, + { + matchName="scala.reflect.internal.SymbolTable.scala$reflect$internal$Types$$uniques" + problemName=IncompatibleResultTypeProblem + }, + { + matchName="scala.reflect.internal.SymbolTable.scala$reflect$internal$Types$$uniques_=" + problemName=IncompatibleMethTypeProblem + }, + { + matchName="scala.reflect.internal.Types.scala$reflect$internal$Types$$uniques" + problemName=IncompatibleResultTypeProblem + }, + { + matchName="scala.reflect.internal.Types.scala$reflect$internal$Types$$uniques_=" + problemName=IncompatibleMethTypeProblem + }, + { + matchName="scala.reflect.internal.Types.scala$reflect$internal$Types$$uniques" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.Types.scala$reflect$internal$Types$$uniques_=" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.HasFlags.isDeferredOrDefault" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.HasFlags.isDeferredNotDefault" + problemName=MissingMethodProblem } ] } diff --git a/bincompat-forward.whitelist.conf b/bincompat-forward.whitelist.conf index 7fdd4329ea..2ece671638 100644 --- a/bincompat-forward.whitelist.conf +++ b/bincompat-forward.whitelist.conf @@ -571,6 +571,866 @@ filter { { matchName="scala.reflect.internal.SymbolTable.scala$reflect$internal$Trees$$duplicator" problemName=IncompatibleResultTypeProblem + }, + { + matchName="scala.reflect.runtime.JavaMirrors#JavaMirror.scala$reflect$runtime$JavaMirrors$JavaMirror$$PackageAndClassPattern" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.SymbolTable.compactifyName" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.StdNames.compactifyName" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.util.WeakHashSet$Diagnostics" + problemName=MissingClassProblem + }, + { + matchName="scala.reflect.internal.util.WeakHashSet$Entry" + problemName=MissingClassProblem + }, + { + matchName="scala.reflect.internal.util.WeakHashSet$" + problemName=MissingClassProblem + }, + { + matchName="scala.reflect.internal.util.WeakHashSet" + problemName=MissingTypesProblem + }, + { + matchName="scala.reflect.internal.util.WeakHashSet.newBuilder" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.util.WeakHashSet.min" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.util.WeakHashSet.initialCapacity" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.util.WeakHashSet.foldLeft" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.util.WeakHashSet.toIterable" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.util.WeakHashSet.toIterable" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.util.WeakHashSet.union" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.util.WeakHashSet.union" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.util.WeakHashSet.groupBy" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.util.WeakHashSet.groupBy" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.util.WeakHashSet.toSet" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.util.WeakHashSet.toSet" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.util.WeakHashSet.toSeq" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.util.WeakHashSet.toSeq" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.util.WeakHashSet.toIndexedSeq" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.util.WeakHashSet.unzip3" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.util.WeakHashSet.nonEmpty" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.util.WeakHashSet.slice" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.util.WeakHashSet.max" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.util.WeakHashSet.addString" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.util.WeakHashSet.addString" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.util.WeakHashSet.addString" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.util.WeakHashSet.subsetOf" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.util.WeakHashSet.fold" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.util.WeakHashSet.toIterator" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.util.WeakHashSet.foreach" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.util.WeakHashSet.flatten" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.util.WeakHashSet.headOption" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.util.WeakHashSet.mapResult" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.util.WeakHashSet.scala$reflect$internal$util$WeakHashSet$$bucketFor" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.util.WeakHashSet.toTraversable" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.util.WeakHashSet.toTraversable" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.util.WeakHashSet.filter" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.util.WeakHashSet.tails" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.util.WeakHashSet.last" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.util.WeakHashSet.collect" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.util.WeakHashSet.takeRight" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.util.WeakHashSet.lastOption" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.util.WeakHashSet.reduceRightOption" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.util.WeakHashSet.+" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.util.WeakHashSet.+" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.util.WeakHashSet.+" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.util.WeakHashSet.+" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.util.WeakHashSet.+" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.util.WeakHashSet.+" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.util.WeakHashSet.take" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.util.WeakHashSet.zipWithIndex" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.util.WeakHashSet.foldRight" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.util.WeakHashSet.hasDefiniteSize" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.util.WeakHashSet.<<" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.util.WeakHashSet.sliceWithKnownBound" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.util.WeakHashSet.to" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.util.WeakHashSet.result" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.util.WeakHashSet.result" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.util.WeakHashSet.isTraversableAgain" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.util.WeakHashSet.add" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.util.WeakHashSet.partition" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.util.WeakHashSet.toBuffer" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.util.WeakHashSet.update" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.util.WeakHashSet.view" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.util.WeakHashSet.view" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.util.WeakHashSet.view" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.util.WeakHashSet.view" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.util.WeakHashSet.tail" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.util.WeakHashSet.zipAll" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.util.WeakHashSet.retain" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.util.WeakHashSet.find" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.util.WeakHashSet.withFilter" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.util.WeakHashSet.init" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.util.WeakHashSet.findEntryOrUpdate" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.util.WeakHashSet.diagnostics" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.util.WeakHashSet.zip" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.util.WeakHashSet.drop" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.util.WeakHashSet.:\\" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.util.WeakHashSet.companion" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.util.WeakHashSet.toMap" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.util.WeakHashSet.toMap" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.util.WeakHashSet.genericBuilder" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.util.WeakHashSet.unzip" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.util.WeakHashSet.seq" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.util.WeakHashSet.seq" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.util.WeakHashSet.seq" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.util.WeakHashSet.seq" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.util.WeakHashSet.seq" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.util.WeakHashSet.seq" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.util.WeakHashSet.seq" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.util.WeakHashSet.&~" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.util.WeakHashSet.toStream" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.util.WeakHashSet.-=" + problemName=IncompatibleResultTypeProblem + }, + { + matchName="scala.reflect.internal.util.WeakHashSet.-=" + problemName=IncompatibleResultTypeProblem + }, + { + matchName="scala.reflect.internal.util.WeakHashSet.-=" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.util.WeakHashSet.splitAt" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.util.WeakHashSet.addEntry" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.util.WeakHashSet.aggregate" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.util.WeakHashSet.parCombiner" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.util.WeakHashSet.maxBy" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.util.WeakHashSet.sliding" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.util.WeakHashSet.sliding" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.util.WeakHashSet.repr" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.util.WeakHashSet.repr" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.util.WeakHashSet.scan" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.util.WeakHashSet.span" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.util.WeakHashSet.toArray" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.util.WeakHashSet.findEntry" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.util.WeakHashSet.toVector" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.util.WeakHashSet.scala$collection$SetLike$$super$map" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.util.WeakHashSet.dropWhile" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.util.WeakHashSet.forall" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.util.WeakHashSet.reduce" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.util.WeakHashSet.intersect" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.util.WeakHashSet.this" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.util.WeakHashSet.--=" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.util.WeakHashSet.loadFactor" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.util.WeakHashSet.copyToArray" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.util.WeakHashSet.copyToArray" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.util.WeakHashSet.copyToArray" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.util.WeakHashSet.canEqual" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.util.WeakHashSet.inits" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.util.WeakHashSet.sliceWithKnownDelta" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.util.WeakHashSet.grouped" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.util.WeakHashSet.minBy" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.util.WeakHashSet./:" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.util.WeakHashSet.--" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.util.WeakHashSet.--" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.util.WeakHashSet.sameElements" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.util.WeakHashSet.par" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.util.WeakHashSet.equals" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.util.WeakHashSet.sizeHint" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.util.WeakHashSet.sizeHint" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.util.WeakHashSet.sizeHint" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.util.WeakHashSet./:\\" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.util.WeakHashSet.threshhold_=" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.util.WeakHashSet.++" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.util.WeakHashSet.++" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.util.WeakHashSet.++" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.util.WeakHashSet.map" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.util.WeakHashSet.clone" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.util.WeakHashSet.clone" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.util.WeakHashSet.diff" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.util.WeakHashSet.diff" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.util.WeakHashSet.isEmpty" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.util.WeakHashSet.&" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.util.WeakHashSet.head" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.util.WeakHashSet.toCollection" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.util.WeakHashSet.toCollection" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.util.WeakHashSet.++:" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.util.WeakHashSet.++:" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.util.WeakHashSet.mkString" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.util.WeakHashSet.mkString" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.util.WeakHashSet.mkString" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.util.WeakHashSet.threshhold" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.util.WeakHashSet.iterator" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.util.WeakHashSet.toList" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.util.WeakHashSet.-" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.util.WeakHashSet.-" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.util.WeakHashSet.-" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.util.WeakHashSet.-" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.util.WeakHashSet.-" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.util.WeakHashSet.-" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.util.WeakHashSet.-" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.util.WeakHashSet.++=" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.util.WeakHashSet.takeWhile" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.util.WeakHashSet.exists" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.util.WeakHashSet.scanRight" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.util.WeakHashSet.transpose" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.util.WeakHashSet.sizeHintBounded" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.util.WeakHashSet.hashCode" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.util.WeakHashSet.scala$collection$mutable$Cloneable$$super$clone" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.util.WeakHashSet.remove" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.util.WeakHashSet.|" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.util.WeakHashSet.reduceLeft" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.util.WeakHashSet.count" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.util.WeakHashSet.scanLeft" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.util.WeakHashSet.reduceLeftOption" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.util.WeakHashSet.dropRight" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.util.WeakHashSet.collectFirst" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.util.WeakHashSet.flatMap" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.util.WeakHashSet.+=" + problemName=IncompatibleResultTypeProblem + }, + { + matchName="scala.reflect.internal.util.WeakHashSet.+=" + problemName=IncompatibleResultTypeProblem + }, + { + matchName="scala.reflect.internal.util.WeakHashSet.+=" + problemName=IncompatibleResultTypeProblem + }, + { + matchName="scala.reflect.internal.util.WeakHashSet.+=" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.util.WeakHashSet.reversed" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.util.WeakHashSet.sum" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.util.WeakHashSet.filterNot" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.util.WeakHashSet.product" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.util.WeakHashSet.thisCollection" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.util.WeakHashSet.thisCollection" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.util.WeakHashSet.copyToBuffer" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.util.WeakHashSet.subsets" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.util.WeakHashSet.subsets" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.util.WeakHashSet.reduceRight" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.util.WeakHashSet.empty" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.util.WeakHashSet.empty" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.util.WeakHashSet.empty" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.util.WeakHashSet.stringPrefix" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.util.WeakHashSet.reduceOption" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.SymbolTable.scala$reflect$internal$Types$$uniques" + problemName=IncompatibleResultTypeProblem + }, + { + matchName="scala.reflect.internal.SymbolTable.scala$reflect$internal$Types$$uniques_=" + problemName=IncompatibleMethTypeProblem + }, + { + matchName="scala.reflect.internal.Types.scala$reflect$internal$Types$$uniques" + problemName=IncompatibleResultTypeProblem + }, + { + matchName="scala.reflect.internal.Types.scala$reflect$internal$Types$$uniques_=" + problemName=IncompatibleMethTypeProblem + }, + { + matchName="scala.reflect.internal.Types.scala$reflect$internal$Types$$uniques" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.Types.scala$reflect$internal$Types$$uniques_=" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.Symbols#Symbol.isDeferredOrDefault" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.Symbols#Symbol.isDeferredNotDefault" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.HasFlags.isDeferredOrDefault" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.HasFlags.isDeferredNotDefault" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.Trees#Modifiers.isDeferredOrDefault" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.Trees#Modifiers.isDeferredNotDefault" + problemName=MissingMethodProblem } ] } @@ -364,9 +364,9 @@ TODO: <property name="sbt.lib.dir" value="${build-sbt.dir}/${sbt.latest.version}/lib"/> <property name="sbt.interface.jar" value="${sbt.lib.dir}/interface.jar"/> - <property name="sbt.interface.url" value="http://typesafe.artifactoryonline.com/typesafe/ivy-releases/org.scala-sbt/interface/${sbt.latest.version}/jars/interface.jar"/> + <property name="sbt.interface.url" value="http://private-repo.typesafe.com/typesafe/ivy-releases/org.scala-sbt/interface/${sbt.latest.version}/jars/interface.jar"/> <property name="sbt.interface.src.jar" value="${sbt.src.dir}/compiler-interface-src.jar"/> - <property name="sbt.interface.src.url" value="http://typesafe.artifactoryonline.com/typesafe/ivy-releases/org.scala-sbt/compiler-interface/${sbt.latest.version}/jars/compiler-interface-src.jar"/> + <property name="sbt.interface.src.url" value="http://private-repo.typesafe.com/typesafe/ivy-releases/org.scala-sbt/compiler-interface/${sbt.latest.version}/jars/compiler-interface-src.jar"/> <!-- Additional command line arguments for scalac. They are added to all build targets --> @@ -1240,9 +1240,11 @@ TODO: <attribute name="Class-Path" value="scala-reflect.jar scala-library.jar"/> </manifest> </pre> + <!-- script api is 2.11-only so far <jar-opts> <service type="javax.script.ScriptEngineFactory" provider="scala.tools.nsc.interpreter.IMain$Factory"/> </jar-opts> + --> </staged-pack> </target> diff --git a/docs/LICENSE b/docs/LICENSE index de950bdf57..446a1a350b 100644 --- a/docs/LICENSE +++ b/docs/LICENSE @@ -1,35 +1,27 @@ -SCALA LICENSE +Copyright (c) 2002-2013 EPFL -Copyright (c) 2002-2012 EPFL, Lausanne, unless otherwise specified. All rights reserved. -This software was developed by the Programming Methods Laboratory of the -Swiss Federal Institute of Technology (EPFL), Lausanne, Switzerland. - -Permission to use, copy, modify, and distribute this software in source -or binary form for any purpose with or without fee is hereby granted, -provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - 3. Neither the name of the EPFL nor the names of its contributors - may be used to endorse or promote products derived from this - software without specific prior written permission. - - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE -FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -SUCH DAMAGE. +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + * Neither the name of the EPFL nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/gitignore.SAMPLE b/gitignore.SAMPLE deleted file mode 100644 index 483ad4caca..0000000000 --- a/gitignore.SAMPLE +++ /dev/null @@ -1,35 +0,0 @@ -# see also test/files/.gitignore -/.gitignore -/test/files/.gitignore - -*.jar -*~ - -#sbt -/project/target/ -/project/project/target - -/target/ -/src/jline/target/ - -# target directories for ant build -/build/ -/dists/ - -# other -/out/ -/bin/ -/sandbox/ - -# eclipse, intellij -/.classpath -/.project -/src/intellij/*.iml -/src/intellij/*.ipr -/src/intellij/*.iws -/.cache -/.idea -/.settings - -# bak files produced by ./cleanup-commit -*.bak diff --git a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala index 50398824e1..996287dea8 100644 --- a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala +++ b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala @@ -2772,6 +2772,8 @@ self => List(copyValDef(vdef)(mods = mods | Flags.PRESUPER)) case tdef @ TypeDef(mods, name, tparams, rhs) => List(treeCopy.TypeDef(tdef, mods | Flags.PRESUPER, name, tparams, rhs)) + case docdef @ DocDef(comm, rhs) => + List(treeCopy.DocDef(docdef, comm, rhs)) case stat if !stat.isEmpty => syntaxError(stat.pos, "only type definitions and concrete field definitions allowed in early object initialization section", false) List() @@ -3067,7 +3069,7 @@ self => while (!isStatSeqEnd && in.token != CASE) { if (in.token == IMPORT) { stats ++= importClause() - acceptStatSep() + acceptStatSepOpt() } else if (isExprIntro) { stats += statement(InBlock) diff --git a/src/compiler/scala/tools/nsc/interpreter/ILoop.scala b/src/compiler/scala/tools/nsc/interpreter/ILoop.scala index b7e07ecdd6..6aef72a3b8 100644 --- a/src/compiler/scala/tools/nsc/interpreter/ILoop.scala +++ b/src/compiler/scala/tools/nsc/interpreter/ILoop.scala @@ -11,14 +11,14 @@ import java.io.{ BufferedReader, FileReader } import java.util.concurrent.locks.ReentrantLock import scala.sys.process.Process import session._ -import scala.util.Properties.{ jdkHome, javaVersion } +import scala.util.Properties.{ envOrNone, javaHome, jdkHome, javaVersion } import scala.tools.util.{ Javap } import scala.annotation.tailrec import scala.collection.mutable.ListBuffer import scala.concurrent.ops import util.{ ClassPath, Exceptional, stringFromWriter, stringFromStream } import interpreter._ -import io.{ File, Directory } +import io.{ File, Directory, Path } import scala.reflect.NameTransformer._ import util.ScalaClassLoader import ScalaClassLoader._ @@ -373,18 +373,29 @@ class ILoop(in0: Option[BufferedReader], protected val out: JPrintWriter) } } - private def findToolsJar() = { - val jdkPath = Directory(jdkHome) - val jar = jdkPath / "lib" / "tools.jar" toFile; + private[this] lazy val platformTools: Option[File] = { + val jarName = "tools.jar" + def jarPath(path: Path) = (path / "lib" / jarName).toFile + def jarAt(path: Path) = { + val f = jarPath(path) + if (f.isFile) Some(f) else None + } + val jdkDir = { + val d = Directory(jdkHome) + if (d.isDirectory) Some(d) else None + } + def deeply(dir: Directory) = dir.deepFiles find (_.name == jarName) - if (jar isFile) - Some(jar) - else if (jdkPath.isDirectory) - jdkPath.deepFiles find (_.name == "tools.jar") - else None - } + val home = envOrNone("JDK_HOME") orElse envOrNone("JAVA_HOME") map (p => Path(p)) + val install = Some(Path(javaHome)) + + (home flatMap jarAt) orElse + (install flatMap jarAt) orElse + (install map (_.parent) flatMap jarAt) orElse + (jdkDir flatMap deeply) + } private def addToolsJarToLoader() = { - val cl = findToolsJar match { + val cl = platformTools match { case Some(tools) => ScalaClassLoader.fromURLs(Seq(tools.toURL), intp.classLoader) case _ => intp.classLoader } diff --git a/src/compiler/scala/tools/nsc/transform/ExtensionMethods.scala b/src/compiler/scala/tools/nsc/transform/ExtensionMethods.scala index bc54054028..e0c0cd0fdb 100644 --- a/src/compiler/scala/tools/nsc/transform/ExtensionMethods.scala +++ b/src/compiler/scala/tools/nsc/transform/ExtensionMethods.scala @@ -231,9 +231,14 @@ abstract class ExtensionMethods extends Transform with TypingTransformers { .substituteThis(origThis, extensionThis) .changeOwner(origMeth -> extensionMeth) ) + val castBody = + if (extensionBody.tpe <:< extensionMono.finalResultType) + extensionBody + else + gen.mkCastPreservingAnnotations(extensionBody, extensionMono.finalResultType) // SI-7818 e.g. mismatched existential skolems // Record the extension method ( FIXME: because... ? ) - extensionDefs(companion) += atPos(tree.pos)(DefDef(extensionMeth, extensionBody)) + extensionDefs(companion) += atPos(tree.pos)(DefDef(extensionMeth, castBody)) // These three lines are assembling Foo.bar$extension[T1, T2, ...]($this) // which leaves the actual argument application for extensionCall. diff --git a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala index 09c4878b2f..83afb3a728 100644 --- a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala +++ b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala @@ -383,7 +383,7 @@ abstract class RefChecks extends InfoTransform with scala.reflect.internal.trans overrideError("cannot be used here - classes can only override abstract types"); } else if (other.isEffectivelyFinal) { // (1.2) overrideError("cannot override final member"); - } else if (!other.isDeferred && !other.hasFlag(DEFAULTMETHOD) && !member.isAnyOverride && !member.isSynthetic) { // (*) + } else if (!other.isDeferredOrDefault && !member.isAnyOverride && !member.isSynthetic) { // (*) // (*) Synthetic exclusion for (at least) default getters, fixes SI-5178. We cannot assign the OVERRIDE flag to // the default getter: one default getter might sometimes override, sometimes not. Example in comment on ticket. if (isNeitherInClass && !(other.owner isSubClass member.owner)) @@ -565,7 +565,7 @@ abstract class RefChecks extends InfoTransform with scala.reflect.internal.trans def checkNoAbstractMembers(): Unit = { // Avoid spurious duplicates: first gather any missing members. def memberList = clazz.info.nonPrivateMembersAdmitting(VBRIDGE) - val (missing, rest) = memberList partition (m => m.isDeferred && !ignoreDeferred(m)) + val (missing, rest) = memberList partition (m => m.isDeferredNotDefault && !ignoreDeferred(m)) // Group missing members by the name of the underlying symbol, // to consolidate getters and setters. val grouped = missing groupBy (sym => analyzer.underlyingSymbol(sym).name) diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala index bf2170310f..e27f540a7d 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala @@ -4107,7 +4107,7 @@ trait Typers extends Modes with Adaptations with Tags { // we need symbol-ful originals for reification // hence we go the extra mile to hand-craft tis guy val original = arg1 match { - case tt @ TypeTree() => Annotated(ann, tt.original) + case tt @ TypeTree() if tt.original != null => Annotated(ann, tt.original) // this clause is needed to correctly compile stuff like "new C @D" or "@(inline @getter)" case _ => Annotated(ann, arg1) } diff --git a/src/compiler/scala/tools/reflect/WrappedProperties.scala b/src/compiler/scala/tools/reflect/WrappedProperties.scala index c34edb8ba0..7ce0171c0b 100644 --- a/src/compiler/scala/tools/reflect/WrappedProperties.scala +++ b/src/compiler/scala/tools/reflect/WrappedProperties.scala @@ -26,9 +26,13 @@ trait WrappedProperties extends PropertiesTrait { override def envOrElse(name: String, alt: String) = wrap(super.envOrElse(name, alt)) getOrElse alt override def envOrNone(name: String) = wrap(super.envOrNone(name)).flatten - def systemProperties: Iterator[(String, String)] = { + def systemProperties: List[(String, String)] = { import scala.collection.JavaConverters._ - wrap(System.getProperties.asScala.iterator) getOrElse Iterator.empty + wrap { + val props = System.getProperties + // SI-7269 Be careful to avoid `ConcurrentModificationException` if another thread modifies the properties map + props.stringPropertyNames().asScala.toList.map(k => (k, props.get(k).asInstanceOf[String])) + } getOrElse Nil } } diff --git a/src/compiler/scala/tools/util/Javap.scala b/src/compiler/scala/tools/util/Javap.scala index c3264d0787..21137aca56 100644 --- a/src/compiler/scala/tools/util/Javap.scala +++ b/src/compiler/scala/tools/util/Javap.scala @@ -50,7 +50,7 @@ class JavapClass( tryFile(path) getOrElse tryClass(path) def apply(args: Seq[String]): List[JpResult] = { - if (failed) Nil + if (failed) List(new JpError("Could not load javap tool. Check that JAVA_HOME is correct.")) else args.toList filterNot (_ startsWith "-") map { path => val bytes = findBytes(path) if (bytes.isEmpty) new JpError("Could not find class bytes for '%s'".format(path)) diff --git a/src/library/scala/collection/mutable/MapLike.scala b/src/library/scala/collection/mutable/MapLike.scala index a53aa3b76a..42e5a0a4c4 100644 --- a/src/library/scala/collection/mutable/MapLike.scala +++ b/src/library/scala/collection/mutable/MapLike.scala @@ -209,8 +209,8 @@ trait MapLike[A, B, +This <: MapLike[A, B, This] with Map[A, B]] * @param p The test predicate */ def retain(p: (A, B) => Boolean): this.type = { - for ((k, v) <- this.seq ; if !p(k, v)) - this -= k + for ((k, v) <- this.toList) // SI-7269 toList avoids ConcurrentModificationException + if (!p(k, v)) this -= k this } diff --git a/src/library/scala/collection/mutable/SetLike.scala b/src/library/scala/collection/mutable/SetLike.scala index 01f87447ae..71da4c89dc 100644 --- a/src/library/scala/collection/mutable/SetLike.scala +++ b/src/library/scala/collection/mutable/SetLike.scala @@ -120,7 +120,9 @@ trait SetLike[A, +This <: SetLike[A, This] with Set[A]] * which `p` returns `true` are retained in the set; all others * are removed. */ - def retain(p: A => Boolean): Unit = for (elem <- this.toList) if (!p(elem)) this -= elem + def retain(p: A => Boolean): Unit = + for (elem <- this.toList) // SI-7269 toList avoids ConcurrentModificationException + if (!p(elem)) this -= elem /** Removes all elements from the set. After this operation is completed, * the set will be empty. diff --git a/src/library/scala/runtime/ScalaRunTime.scala b/src/library/scala/runtime/ScalaRunTime.scala index 1d8fe5e9ad..dcd323961e 100644 --- a/src/library/scala/runtime/ScalaRunTime.scala +++ b/src/library/scala/runtime/ScalaRunTime.scala @@ -34,21 +34,13 @@ object ScalaRunTime { clazz.isArray && (atLevel == 1 || isArrayClass(clazz.getComponentType, atLevel - 1)) def isValueClass(clazz: jClass[_]) = clazz.isPrimitive() - def isTuple(x: Any) = x != null && tupleNames(x.getClass.getName) + + // includes specialized subclasses and future proofed against hypothetical TupleN (for N > 22) + def isTuple(x: Any) = x != null && x.getClass.getName.startsWith("scala.Tuple") def isAnyVal(x: Any) = x match { case _: Byte | _: Short | _: Char | _: Int | _: Long | _: Float | _: Double | _: Boolean | _: Unit => true case _ => false } - // Avoiding boxing which messes up the specialized tests. Don't ask. - private val tupleNames = { - var i = 22 - var names: List[String] = Nil - while (i >= 1) { - names ::= ("scala.Tuple" + String.valueOf(i)) - i -= 1 - } - names.toSet - } /** Return the class object representing an array with element class `clazz`. */ @@ -75,33 +67,37 @@ object ScalaRunTime { classTag[T].runtimeClass.asInstanceOf[jClass[T]] /** Retrieve generic array element */ - def array_apply(xs: AnyRef, idx: Int): Any = xs match { - case x: Array[AnyRef] => x(idx).asInstanceOf[Any] - case x: Array[Int] => x(idx).asInstanceOf[Any] - case x: Array[Double] => x(idx).asInstanceOf[Any] - case x: Array[Long] => x(idx).asInstanceOf[Any] - case x: Array[Float] => x(idx).asInstanceOf[Any] - case x: Array[Char] => x(idx).asInstanceOf[Any] - case x: Array[Byte] => x(idx).asInstanceOf[Any] - case x: Array[Short] => x(idx).asInstanceOf[Any] - case x: Array[Boolean] => x(idx).asInstanceOf[Any] - case x: Array[Unit] => x(idx).asInstanceOf[Any] - case null => throw new NullPointerException + def array_apply(xs: AnyRef, idx: Int): Any = { + xs match { + case x: Array[AnyRef] => x(idx).asInstanceOf[Any] + case x: Array[Int] => x(idx).asInstanceOf[Any] + case x: Array[Double] => x(idx).asInstanceOf[Any] + case x: Array[Long] => x(idx).asInstanceOf[Any] + case x: Array[Float] => x(idx).asInstanceOf[Any] + case x: Array[Char] => x(idx).asInstanceOf[Any] + case x: Array[Byte] => x(idx).asInstanceOf[Any] + case x: Array[Short] => x(idx).asInstanceOf[Any] + case x: Array[Boolean] => x(idx).asInstanceOf[Any] + case x: Array[Unit] => x(idx).asInstanceOf[Any] + case null => throw new NullPointerException + } } /** update generic array element */ - def array_update(xs: AnyRef, idx: Int, value: Any): Unit = xs match { - case x: Array[AnyRef] => x(idx) = value.asInstanceOf[AnyRef] - case x: Array[Int] => x(idx) = value.asInstanceOf[Int] - case x: Array[Double] => x(idx) = value.asInstanceOf[Double] - case x: Array[Long] => x(idx) = value.asInstanceOf[Long] - case x: Array[Float] => x(idx) = value.asInstanceOf[Float] - case x: Array[Char] => x(idx) = value.asInstanceOf[Char] - case x: Array[Byte] => x(idx) = value.asInstanceOf[Byte] - case x: Array[Short] => x(idx) = value.asInstanceOf[Short] - case x: Array[Boolean] => x(idx) = value.asInstanceOf[Boolean] - case x: Array[Unit] => x(idx) = value.asInstanceOf[Unit] - case null => throw new NullPointerException + def array_update(xs: AnyRef, idx: Int, value: Any): Unit = { + xs match { + case x: Array[AnyRef] => x(idx) = value.asInstanceOf[AnyRef] + case x: Array[Int] => x(idx) = value.asInstanceOf[Int] + case x: Array[Double] => x(idx) = value.asInstanceOf[Double] + case x: Array[Long] => x(idx) = value.asInstanceOf[Long] + case x: Array[Float] => x(idx) = value.asInstanceOf[Float] + case x: Array[Char] => x(idx) = value.asInstanceOf[Char] + case x: Array[Byte] => x(idx) = value.asInstanceOf[Byte] + case x: Array[Short] => x(idx) = value.asInstanceOf[Short] + case x: Array[Boolean] => x(idx) = value.asInstanceOf[Boolean] + case x: Array[Unit] => x(idx) = value.asInstanceOf[Unit] + case null => throw new NullPointerException + } } /** Get generic array length */ diff --git a/src/reflect/scala/reflect/internal/ExistentialsAndSkolems.scala b/src/reflect/scala/reflect/internal/ExistentialsAndSkolems.scala index 3bcb793926..2c2ed351c9 100644 --- a/src/reflect/scala/reflect/internal/ExistentialsAndSkolems.scala +++ b/src/reflect/scala/reflect/internal/ExistentialsAndSkolems.scala @@ -19,6 +19,9 @@ trait ExistentialsAndSkolems { * can be deskolemized to the original type parameter. (A skolem is a * representation of a bound variable when viewed inside its scope.) * !!!Adriaan: this does not work for hk types. + * + * Skolems will be created at level 0, rather than the current value + * of `skolemizationLevel`. (See SI-7782) */ def deriveFreshSkolems(tparams: List[Symbol]): List[Symbol] = { class Deskolemizer extends LazyType { @@ -30,7 +33,11 @@ trait ExistentialsAndSkolems { sym setInfo sym.deSkolemize.info.substSym(typeParams, typeSkolems) } } - (new Deskolemizer).typeSkolems + + val saved = skolemizationLevel + skolemizationLevel = 0 + try new Deskolemizer().typeSkolems + finally skolemizationLevel = saved } def isRawParameter(sym: Symbol) = // is it a type parameter leaked by a raw type? diff --git a/src/reflect/scala/reflect/internal/HasFlags.scala b/src/reflect/scala/reflect/internal/HasFlags.scala index 4a3663b8ea..12fd3a31cd 100644 --- a/src/reflect/scala/reflect/internal/HasFlags.scala +++ b/src/reflect/scala/reflect/internal/HasFlags.scala @@ -115,6 +115,9 @@ trait HasFlags { def isSynthetic = hasFlag(SYNTHETIC) def isTrait = hasFlag(TRAIT) && !hasFlag(PARAM) + def isDeferredOrDefault = hasFlag(DEFERRED | DEFAULTMETHOD) + def isDeferredNotDefault = isDeferred && !hasFlag(DEFAULTMETHOD) + def flagBitsToString(bits: Long): String = { // Fast path for common case if (bits == 0L) "" else { diff --git a/src/reflect/scala/reflect/internal/StdNames.scala b/src/reflect/scala/reflect/internal/StdNames.scala index de7af4340d..c3b7f24a9d 100644 --- a/src/reflect/scala/reflect/internal/StdNames.scala +++ b/src/reflect/scala/reflect/internal/StdNames.scala @@ -44,6 +44,7 @@ trait StdNames { } } + private[reflect] def compactifyName(orig: String): String = compactify(orig) private final object compactify extends (String => String) { val md5 = MessageDigest.getInstance("MD5") diff --git a/src/reflect/scala/reflect/internal/SymbolTable.scala b/src/reflect/scala/reflect/internal/SymbolTable.scala index 5ccf81b4b5..6ca8900d7c 100644 --- a/src/reflect/scala/reflect/internal/SymbolTable.scala +++ b/src/reflect/scala/reflect/internal/SymbolTable.scala @@ -302,28 +302,21 @@ abstract class SymbolTable extends macros.Universe } object perRunCaches { - import java.lang.ref.WeakReference import scala.runtime.ScalaRunTime.stringOf import scala.collection.generic.Clearable // Weak references so the garbage collector will take care of // letting us know when a cache is really out of commission. - private val caches = mutable.HashSet[WeakReference[Clearable]]() + private val caches = WeakHashSet[Clearable]() def recordCache[T <: Clearable](cache: T): T = { - caches += new WeakReference(cache) + caches += cache cache } def clearAll() = { debuglog("Clearing " + caches.size + " caches.") - caches foreach { ref => - val cache = ref.get() - if (cache == null) - caches -= ref - else - cache.clear() - } + caches foreach (_.clear) } def newWeakMap[K, V]() = recordCache(mutable.WeakHashMap[K, V]()) diff --git a/src/reflect/scala/reflect/internal/Types.scala b/src/reflect/scala/reflect/internal/Types.scala index cd9f3d23c9..cfa6f927b5 100644 --- a/src/reflect/scala/reflect/internal/Types.scala +++ b/src/reflect/scala/reflect/internal/Types.scala @@ -3935,13 +3935,13 @@ trait Types extends api.Types { self: SymbolTable => // Hash consing -------------------------------------------------------------- private val initialUniquesCapacity = 4096 - private var uniques: util.HashSet[Type] = _ + private var uniques: util.WeakHashSet[Type] = _ private var uniqueRunId = NoRunId protected def unique[T <: Type](tp: T): T = { if (Statistics.canEnable) Statistics.incCounter(rawTypeCount) if (uniqueRunId != currentRunId) { - uniques = util.HashSet[Type]("uniques", initialUniquesCapacity) + uniques = util.WeakHashSet[Type](initialUniquesCapacity) perRunCaches.recordCache(uniques) uniqueRunId = currentRunId } diff --git a/src/reflect/scala/reflect/internal/util/WeakHashSet.scala b/src/reflect/scala/reflect/internal/util/WeakHashSet.scala index 9882aad5e5..fc12e31360 100644 --- a/src/reflect/scala/reflect/internal/util/WeakHashSet.scala +++ b/src/reflect/scala/reflect/internal/util/WeakHashSet.scala @@ -1,61 +1,430 @@ -package scala.reflect.internal.util +package scala +package reflect.internal.util -import scala.collection.mutable -import scala.collection.mutable.ArrayBuffer -import scala.collection.mutable.Builder -import scala.collection.mutable.SetBuilder +import java.lang.ref.{WeakReference, ReferenceQueue} +import scala.annotation.tailrec import scala.collection.generic.Clearable -import scala.runtime.AbstractFunction1 +import scala.collection.mutable.{Set => mSet} -/** A bare-bones implementation of a mutable `Set` that uses weak references - * to hold the elements. +/** + * A HashSet where the elements are stored weakly. Elements in this set are elligible for GC if no other + * hard references are associated with them. Its primary use case is as a canonical reference + * identity holder (aka "hash-consing") via findEntryOrUpdate * - * This implementation offers only add/remove/test operations, - * therefore it does not fulfill the contract of Scala collection sets. + * This Set implementation cannot hold null. Any attempt to put a null in it will result in a NullPointerException + * + * This set implmeentation is not in general thread safe without external concurrency control. However it behaves + * properly when GC concurrently collects elements in this set. */ -class WeakHashSet[T <: AnyRef] extends AbstractFunction1[T, Boolean] with Clearable { - private val underlying = mutable.HashSet[WeakReferenceWithEquals[T]]() +final class WeakHashSet[A <: AnyRef](val initialCapacity: Int, val loadFactor: Double) extends Set[A] with Function1[A, Boolean] with mSet[A] { + + import WeakHashSet._ + + def this() = this(initialCapacity = WeakHashSet.defaultInitialCapacity, loadFactor = WeakHashSet.defaultLoadFactor) + + type This = WeakHashSet[A] + + /** + * queue of Entries that hold elements scheduled for GC + * the removeStaleEntries() method works through the queue to remeove + * stale entries from the table + */ + private[this] val queue = new ReferenceQueue[A] + + /** + * the number of elements in this set + */ + private[this] var count = 0 + + /** + * from a specified initial capacity compute the capacity we'll use as being the next + * power of two equal to or greater than the specified initial capacity + */ + private def computeCapacity = { + if (initialCapacity < 0) throw new IllegalArgumentException("initial capacity cannot be less than 0"); + var candidate = 1 + while (candidate < initialCapacity) { + candidate *= 2 + } + candidate + } + + /** + * the underlying table of entries which is an array of Entry linked lists + */ + private[this] var table = new Array[Entry[A]](computeCapacity) + + /** + * the limit at which we'll increase the size of the hash table + */ + var threshhold = computeThreshHold + + private[this] def computeThreshHold: Int = (table.size * loadFactor).ceil.toInt - /** Add the given element to this set. */ - def +=(elem: T): this.type = { - underlying += new WeakReferenceWithEquals(elem) - this + /** + * find the bucket associated with an elements's hash code + */ + private[this] def bucketFor(hash: Int): Int = { + // spread the bits around to try to avoid accidental collisions using the + // same algorithm as java.util.HashMap + var h = hash + h ^= h >>> 20 ^ h >>> 12 + h ^= h >>> 7 ^ h >>> 4 + + // this is finding h % table.length, but takes advantage of the + // fact that table length is a power of 2, + // if you don't do bit flipping in your head, if table.length + // is binary 100000.. (with n 0s) then table.length - 1 + // is 1111.. with n 1's. + // In other words this masks on the last n bits in the hash + h & (table.length - 1) } - /** Remove the given element from this set. */ - def -=(elem: T): this.type = { - underlying -= new WeakReferenceWithEquals(elem) - this + /** + * remove a single entry from a linked list in a given bucket + */ + private[this] def remove(bucket: Int, prevEntry: Entry[A], entry: Entry[A]) { + prevEntry match { + case null => table(bucket) = entry.tail + case _ => prevEntry.tail = entry.tail + } + count -= 1 } - /** Does the given element belong to this set? */ - def contains(elem: T): Boolean = - underlying.contains(new WeakReferenceWithEquals(elem)) + /** + * remove entries associated with elements that have been gc'ed + */ + private[this] def removeStaleEntries() { + def poll(): Entry[A] = queue.poll().asInstanceOf[Entry[A]] - /** Does the given element belong to this set? */ - def apply(elem: T): Boolean = contains(elem) + @tailrec + def queueLoop { + val stale = poll() + if (stale != null) { + val bucket = bucketFor(stale.hash) - /** Return the number of elements in this set, including reclaimed elements. */ - def size = underlying.size + @tailrec + def linkedListLoop(prevEntry: Entry[A], entry: Entry[A]): Unit = if (stale eq entry) remove(bucket, prevEntry, entry) + else if (entry != null) linkedListLoop(entry, entry.tail) - /** Remove all elements in this set. */ - def clear() = underlying.clear() -} + linkedListLoop(null, table(bucket)) -/** A WeakReference implementation that implements equals and hashCode by - * delegating to the referent. - */ -class WeakReferenceWithEquals[T <: AnyRef](ref: T) { - def get(): T = underlying.get() + queueLoop + } + } + + queueLoop + } + + /** + * Double the size of the internal table + */ + private[this] def resize() { + val oldTable = table + table = new Array[Entry[A]](oldTable.size * 2) + threshhold = computeThreshHold + + @tailrec + def tableLoop(oldBucket: Int): Unit = if (oldBucket < oldTable.size) { + @tailrec + def linkedListLoop(entry: Entry[A]): Unit = entry match { + case null => () + case _ => { + val bucket = bucketFor(entry.hash) + val oldNext = entry.tail + entry.tail = table(bucket) + table(bucket) = entry + linkedListLoop(oldNext) + } + } + linkedListLoop(oldTable(oldBucket)) + + tableLoop(oldBucket + 1) + } + tableLoop(0) + } + + // from scala.reflect.internal.Set, find an element or null if it isn't contained + override def findEntry(elem: A): A = elem match { + case null => throw new NullPointerException("WeakHashSet cannot hold nulls") + case _ => { + removeStaleEntries() + val hash = elem.hashCode + val bucket = bucketFor(hash) + + @tailrec + def linkedListLoop(entry: Entry[A]): A = entry match { + case null => null.asInstanceOf[A] + case _ => { + val entryElem = entry.get + if (elem == entryElem) entryElem + else linkedListLoop(entry.tail) + } + } + + linkedListLoop(table(bucket)) + } + } + // add an element to this set unless it's already in there and return the element + def findEntryOrUpdate(elem: A): A = elem match { + case null => throw new NullPointerException("WeakHashSet cannot hold nulls") + case _ => { + removeStaleEntries() + val hash = elem.hashCode + val bucket = bucketFor(hash) + val oldHead = table(bucket) + + def add() = { + table(bucket) = new Entry(elem, hash, oldHead, queue) + count += 1 + if (count > threshhold) resize() + elem + } + + @tailrec + def linkedListLoop(entry: Entry[A]): A = entry match { + case null => add() + case _ => { + val entryElem = entry.get + if (elem == entryElem) entryElem + else linkedListLoop(entry.tail) + } + } + + linkedListLoop(oldHead) + } + } + + // add an element to this set unless it's already in there and return this set + override def +(elem: A): this.type = elem match { + case null => throw new NullPointerException("WeakHashSet cannot hold nulls") + case _ => { + removeStaleEntries() + val hash = elem.hashCode + val bucket = bucketFor(hash) + val oldHead = table(bucket) + + def add() { + table(bucket) = new Entry(elem, hash, oldHead, queue) + count += 1 + if (count > threshhold) resize() + } + + @tailrec + def linkedListLoop(entry: Entry[A]): Unit = entry match { + case null => add() + case _ if (elem == entry.get) => () + case _ => linkedListLoop(entry.tail) + } + + linkedListLoop(oldHead) + this + } + } + + def +=(elem: A) = this + elem + + // from scala.reflect.interanl.Set + override def addEntry(x: A) { this += x } + + // remove an element from this set and return this set + override def -(elem: A): this.type = elem match { + case null => this + case _ => { + removeStaleEntries() + val bucket = bucketFor(elem.hashCode) - override val hashCode = ref.hashCode - override def equals(other: Any): Boolean = other match { - case wf: WeakReferenceWithEquals[_] => - underlying.get() == wf.get() - case _ => - false + + @tailrec + def linkedListLoop(prevEntry: Entry[A], entry: Entry[A]): Unit = entry match { + case null => () + case _ if (elem == entry.get) => remove(bucket, prevEntry, entry) + case _ => linkedListLoop(entry, entry.tail) + } + + linkedListLoop(null, table(bucket)) + this + } } - private val underlying = new java.lang.ref.WeakReference(ref) + def -=(elem: A) = this - elem + + // empty this set + override def clear(): Unit = { + table = new Array[Entry[A]](table.size) + threshhold = computeThreshHold + count = 0 + + // drain the queue - doesn't do anything because we're throwing away all the values anyway + @tailrec def queueLoop(): Unit = if (queue.poll() != null) queueLoop() + queueLoop() + } + + // true if this set is empty + override def empty: This = new WeakHashSet[A](initialCapacity, loadFactor) + + // the number of elements in this set + override def size: Int = { + removeStaleEntries() + count + } + + override def apply(x: A): Boolean = this contains x + + override def foreach[U](f: A => U): Unit = iterator foreach f + + override def toList(): List[A] = iterator.toList + + // Iterator over all the elements in this set in no particular order + override def iterator: Iterator[A] = { + removeStaleEntries() + + new Iterator[A] { + + /** + * the bucket currently being examined. Initially it's set past the last bucket and will be decremented + */ + private[this] var currentBucket: Int = table.size + + /** + * the entry that was last examined + */ + private[this] var entry: Entry[A] = null + + /** + * the element that will be the result of the next call to next() + */ + private[this] var lookaheadelement: A = null.asInstanceOf[A] + + @tailrec + def hasNext: Boolean = { + while (entry == null && currentBucket > 0) { + currentBucket -= 1 + entry = table(currentBucket) + } + + if (entry == null) false + else { + lookaheadelement = entry.get + if (lookaheadelement == null) { + // element null means the weakref has been cleared since we last did a removeStaleEntries(), move to the next entry + entry = entry.tail + hasNext + } else { + true + } + } + } + + def next(): A = if (lookaheadelement == null) + throw new IndexOutOfBoundsException("next on an empty iterator") + else { + val result = lookaheadelement + lookaheadelement = null.asInstanceOf[A] + entry = entry.tail + result + } + } + } + + /** + * Diagnostic information about the internals of this set. Not normally + * needed by ordinary code, but may be useful for diagnosing performance problems + */ + private[util] class Diagnostics { + /** + * Verify that the internal structure of this hash set is fully consistent. + * Throws an assertion error on any problem. In order for it to be reliable + * the entries must be stable. If any are garbage collected during validation + * then an assertion may inappropriately fire. + */ + def fullyValidate { + var computedCount = 0 + var bucket = 0 + while (bucket < table.size) { + var entry = table(bucket) + while (entry != null) { + assert(entry.get != null, s"$entry had a null value indicated that gc activity was happening during diagnostic validation or that a null value was inserted") + computedCount += 1 + val cachedHash = entry.hash + val realHash = entry.get.hashCode + assert(cachedHash == realHash, s"for $entry cached hash was $cachedHash but should have been $realHash") + val computedBucket = bucketFor(realHash) + assert(computedBucket == bucket, s"for $entry the computed bucket was $computedBucket but should have been $bucket") + + entry = entry.tail + } + + bucket += 1 + } + + assert(computedCount == count, s"The computed count was $computedCount but should have been $count") + } + + /** + * Produces a diagnostic dump of the table that underlies this hash set. + */ + def dump = table.deep + + /** + * Number of buckets that hold collisions. Useful for diagnosing performance issues. + */ + def collisionBucketsCount: Int = + (table filter (entry => entry != null && entry.tail != null)).size + + /** + * Number of buckets that are occupied in this hash table. + */ + def fullBucketsCount: Int = + (table filter (entry => entry != null)).size + + /** + * Number of buckets in the table + */ + def bucketsCount: Int = table.size + + /** + * Number of buckets that don't hold anything + */ + def emptyBucketsCount = bucketsCount - fullBucketsCount + + /** + * Number of elements that are in collision. Useful for diagnosing performance issues. + */ + def collisionsCount = size - (fullBucketsCount - collisionBucketsCount) + + /** + * A map from a count of elements to the number of buckets with that count + */ + def elementCountDistribution = table map linkedListSize groupBy identity map {case (size, list) => (size, list.size)} + + private def linkedListSize(entry: Entry[A]) = { + var e = entry + var count = 0 + while (e != null) { + count += 1 + e = e.tail + } + count + } + } + + private[util] def diagnostics = new Diagnostics +} + +/** + * Companion object for WeakHashSet + */ +object WeakHashSet { + /** + * A single entry in a WeakHashSet. It's a WeakReference plus a cached hash code and + * a link to the next Entry in the same bucket + */ + private class Entry[A](element: A, val hash:Int, var tail: Entry[A], queue: ReferenceQueue[A]) extends WeakReference[A](element, queue) + + val defaultInitialCapacity = 16 + val defaultLoadFactor = .75 + + def apply[A <: AnyRef](initialCapacity: Int = WeakHashSet.defaultInitialCapacity, loadFactor: Double = WeakHashSet.defaultLoadFactor) = new WeakHashSet[A](initialCapacity, defaultLoadFactor) } diff --git a/src/reflect/scala/reflect/runtime/JavaMirrors.scala b/src/reflect/scala/reflect/runtime/JavaMirrors.scala index 22fe7f098c..6fdb238462 100644 --- a/src/reflect/scala/reflect/runtime/JavaMirrors.scala +++ b/src/reflect/scala/reflect/runtime/JavaMirrors.scala @@ -1178,6 +1178,17 @@ private[reflect] trait JavaMirrors extends internal.SymbolTable with api.JavaUni var fullNameOfJavaClass = ownerClazz.getName if (childOfClass || childOfTopLevel) fullNameOfJavaClass += "$" fullNameOfJavaClass += clazz.name + + // compactify (see SI-7779) + fullNameOfJavaClass = fullNameOfJavaClass match { + case PackageAndClassPattern(pack, clazzName) => + // in a package + pack + compactifyName(clazzName) + case _ => + // in the empty package + compactifyName(fullNameOfJavaClass) + } + if (clazz.isModuleClass) fullNameOfJavaClass += "$" // println(s"ownerChildren = ${ownerChildren.toList}") @@ -1187,6 +1198,8 @@ private[reflect] trait JavaMirrors extends internal.SymbolTable with api.JavaUni noClass } + private val PackageAndClassPattern = """(.*\.)(.*)$""".r + private def expandedName(sym: Symbol): String = if (sym.isPrivate) nme.expandedName(sym.name.toTermName, sym.owner).toString else sym.name.toString @@ -1241,6 +1254,7 @@ private[reflect] trait JavaMirrors extends internal.SymbolTable with api.JavaUni case TypeRef(_, ArrayClass, List(elemtpe)) => jArrayClass(typeToJavaClass(elemtpe)) case TypeRef(_, sym: ClassSymbol, _) => classToJava(sym.asClass) case tpe @ TypeRef(_, sym: AliasTypeSymbol, _) => typeToJavaClass(tpe.dealias) + case SingleType(_, sym: ModuleSymbol) => classToJava(sym.moduleClass.asClass) case _ => throw new NoClassDefFoundError("no Java class corresponding to "+tpe+" found") } } diff --git a/test/files/gitignore.SAMPLE b/test/files/.gitignore index 161be5b55f..161be5b55f 100644 --- a/test/files/gitignore.SAMPLE +++ b/test/files/.gitignore diff --git a/test/files/pos/t4760.scala b/test/files/pos/t4760.scala new file mode 100644 index 0000000000..767e3847f4 --- /dev/null +++ b/test/files/pos/t4760.scala @@ -0,0 +1,34 @@ + +class Test { + // parses + def f1 = { + import scala._; + } + // b.scala:7: error: ';' expected but '}' found. + // } + // ^ + // one error found + def f2 = { + import scala._ + } + def f2b = { + import scala.collection.mutable.{ Map => MMap } + } + def f(): Unit = { + locally { + import scala.util.Properties.lineSeparator + } + } + + // parses + def f3 = { + import scala._ + 5 + } + locally { (x: Int) => + import scala.util._ + } + 1 match { + case 1 => import scala.concurrent._ + } +} diff --git a/test/files/pos/t7486-named.scala b/test/files/pos/t7486-named.scala new file mode 100644 index 0000000000..253293e5f1 --- /dev/null +++ b/test/files/pos/t7486-named.scala @@ -0,0 +1,8 @@ + +object Test { + def fold(empty: Any) = () + implicit val notAnnotatedImplicit = new { + fold(empty = 0) + def empty[A]: Any = ??? + } +} diff --git a/test/pending/pos/t7486.scala b/test/files/pos/t7486.scala index 6dd7f4c4ac..6dd7f4c4ac 100644 --- a/test/pending/pos/t7486.scala +++ b/test/files/pos/t7486.scala diff --git a/test/files/pos/t7782.scala b/test/files/pos/t7782.scala new file mode 100644 index 0000000000..037bdad673 --- /dev/null +++ b/test/files/pos/t7782.scala @@ -0,0 +1,25 @@ +package pack + +object Test { + import O.empty + empty // this will trigger completion of `test` + // with skolemizationLevel = 1 +} + +object O { + // order matters (!!!) + + // this order breaks under 2.10.x + def empty[E]: C[E] = ??? + def empty(implicit a: Any): Any = ??? +} + +abstract class C[E] { + def foo[BB](f: BB) + def test[B](f: B): Any = foo(f) + // error: no type parameters for method foo: (<param> f: BB)scala.this.Unit exist so that it can be applied to arguments (B&1) + // --- because --- + // argument expression's type is not compatible with formal parameter type; + // found : B&1 + // required: ?BB +} diff --git a/test/files/pos/t7782b.scala b/test/files/pos/t7782b.scala new file mode 100644 index 0000000000..09da4a5c5b --- /dev/null +++ b/test/files/pos/t7782b.scala @@ -0,0 +1,25 @@ +package pack + +object Test { + import O.empty + empty // this will trigger completion of `test` + // with skolemizationLevel = 1 +} + +object O { + // order matters (!!!) + + // this order breaks under 2.11.x + def empty(implicit a: Any): Any = ??? + def empty[E]: C[E] = ??? +} + +abstract class C[E] { + def foo[BB](f: BB) + def test[B](f: B): Any = foo(f) + // error: no type parameters for method foo: (<param> f: BB)scala.this.Unit exist so that it can be applied to arguments (B&1) + // --- because --- + // argument expression's type is not compatible with formal parameter type; + // found : B&1 + // required: ?BB +} diff --git a/test/files/pos/t7818.scala b/test/files/pos/t7818.scala new file mode 100644 index 0000000000..77b99e7d5d --- /dev/null +++ b/test/files/pos/t7818.scala @@ -0,0 +1,10 @@ +class Observable1[+T](val asJava: JObservable[_ <: T]) extends AnyVal { + private def foo[X](a: JObservable[X]): JObservable[X] = ??? + // was generating a type error as the type of the RHS included an existential + // skolem based on the class type parameter `T`, which did not conform + // to the typer parameter of the extension method into which the RHS is + // transplanted. + def synchronize: Observable1[T] = new Observable1(foo(asJava)) +} + +class JObservable[T] diff --git a/test/files/pos/t942/Amount_1.java b/test/files/pos/t942/Amount_1.java new file mode 100644 index 0000000000..d9d37d127b --- /dev/null +++ b/test/files/pos/t942/Amount_1.java @@ -0,0 +1,5 @@ +import java.util.concurrent.Callable; + +public abstract class Amount_1<Q> extends Object + implements Callable<Amount_1<?>> { +} diff --git a/test/files/pos/t942/Test_2.scala b/test/files/pos/t942/Test_2.scala new file mode 100644 index 0000000000..3cc84dae3c --- /dev/null +++ b/test/files/pos/t942/Test_2.scala @@ -0,0 +1,3 @@ +abstract class Foo { + val x: Amount_1[Foo] +} diff --git a/test/files/run/WeakHashSetTest.scala b/test/files/run/WeakHashSetTest.scala new file mode 100644 index 0000000000..3c8f380150 --- /dev/null +++ b/test/files/run/WeakHashSetTest.scala @@ -0,0 +1,174 @@ +object Test { + def main(args: Array[String]) { + val test = scala.reflect.internal.util.WeakHashSetTest + test.checkEmpty + test.checkPlusEquals + test.checkPlusEqualsCollisions + test.checkRehashing + test.checkRehashCollisions + test.checkFindOrUpdate + test.checkMinusEquals + test.checkMinusEqualsCollisions + test.checkClear + test.checkIterator + test.checkIteratorCollisions + + // This test is commented out because it relies on gc behavior which isn't reliable enough in an automated environment + // test.checkRemoveUnreferencedObjects + } +} + +// put the main test object in the same package as WeakHashSet because +// it uses the package private "diagnostics" method +package scala.reflect.internal.util { + + object WeakHashSetTest { + // a class guaranteed to provide hash collisions + case class Collider(x : String) extends Comparable[Collider] with Serializable { + override def hashCode = 0 + def compareTo(y : Collider) = this.x compareTo y.x + } + + // basic emptiness check + def checkEmpty { + val hs = new WeakHashSet[String]() + assert(hs.size == 0) + hs.diagnostics.fullyValidate + } + + // make sure += works + def checkPlusEquals { + val hs = new WeakHashSet[String]() + val elements = List("hello", "goodbye") + elements foreach (hs += _) + assert(hs.size == 2) + assert(hs contains "hello") + assert(hs contains "goodbye") + hs.diagnostics.fullyValidate + } + + // make sure += works when there are collisions + def checkPlusEqualsCollisions { + val hs = new WeakHashSet[Collider]() + val elements = List("hello", "goodbye") map Collider + elements foreach (hs += _) + assert(hs.size == 2) + assert(hs contains Collider("hello")) + assert(hs contains Collider("goodbye")) + hs.diagnostics.fullyValidate + } + + // add a large number of elements to force rehashing and then validate + def checkRehashing { + val size = 200 + val hs = new WeakHashSet[String]() + val elements = (0 until size).toList map ("a" + _) + elements foreach (hs += _) + elements foreach {i => assert(hs contains i)} + hs.diagnostics.fullyValidate + } + + // make sure rehashing works properly when the set is rehashed + def checkRehashCollisions { + val size = 200 + val hs = new WeakHashSet[Collider]() + val elements = (0 until size).toList map {x => Collider("a" + x)} + elements foreach (hs += _) + elements foreach {i => assert(hs contains i)} + hs.diagnostics.fullyValidate + } + + // test that unreferenced objects are removed + // not run in an automated environment because gc behavior can't be relied on + def checkRemoveUnreferencedObjects { + val size = 200 + val hs = new WeakHashSet[Collider]() + val elements = (0 until size).toList map {x => Collider("a" + x)} + elements foreach (hs += _) + // don't throw the following into a retained collection so gc + // can remove them + for (i <- 0 until size) { + hs += Collider("b" + i) + } + System.gc() + Thread.sleep(1000) + assert(hs.size == 200) + elements foreach {i => assert(hs contains i)} + for (i <- 0 until size) { + assert(!(hs contains Collider("b" + i))) + } + hs.diagnostics.fullyValidate + } + + // make sure findOrUpdate returns the originally entered element + def checkFindOrUpdate { + val size = 200 + val hs = new WeakHashSet[Collider]() + val elements = (0 until size).toList map {x => Collider("a" + x)} + elements foreach {x => assert(hs findEntryOrUpdate x eq x)} + for (i <- 0 until size) { + // when we do a lookup the result should be the same reference we + // original put in + assert(hs findEntryOrUpdate(Collider("a" + i)) eq elements(i)) + } + hs.diagnostics.fullyValidate + } + + // check -= functionality + def checkMinusEquals { + val hs = new WeakHashSet[String]() + val elements = List("hello", "goodbye") + elements foreach (hs += _) + hs -= "goodbye" + assert(hs.size == 1) + assert(hs contains "hello") + assert(!(hs contains "goodbye")) + hs.diagnostics.fullyValidate + } + + // check -= when there are collisions + def checkMinusEqualsCollisions { + val hs = new WeakHashSet[Collider] + val elements = List(Collider("hello"), Collider("goodbye")) + elements foreach (hs += _) + hs -= Collider("goodbye") + assert(hs.size == 1) + assert(hs contains Collider("hello")) + assert(!(hs contains Collider("goodbye"))) + hs -= Collider("hello") + assert(hs.size == 0) + assert(!(hs contains Collider("hello"))) + hs.diagnostics.fullyValidate + } + + // check that the clear method actually cleans everything + def checkClear { + val size = 200 + val hs = new WeakHashSet[String]() + val elements = (0 until size).toList map ("a" + _) + elements foreach (hs += _) + hs.clear() + assert(hs.size == 0) + elements foreach {i => assert(!(hs contains i))} + hs.diagnostics.fullyValidate + } + + // check that the iterator covers all the contents + def checkIterator { + val hs = new WeakHashSet[String]() + val elements = (0 until 20).toList map ("a" + _) + elements foreach (hs += _) + assert(elements.iterator.toList.sorted == elements.sorted) + hs.diagnostics.fullyValidate + } + + // check that the iterator covers all the contents even when there is a collision + def checkIteratorCollisions { + val hs = new WeakHashSet[Collider] + val elements = (0 until 20).toList map {x => Collider("a" + x)} + elements foreach (hs += _) + assert(elements.iterator.toList.sorted == elements.sorted) + hs.diagnostics.fullyValidate + } + } +} diff --git a/test/files/run/predef-cycle.scala b/test/files/run/predef-cycle.scala new file mode 100644 index 0000000000..ab147688bc --- /dev/null +++ b/test/files/run/predef-cycle.scala @@ -0,0 +1,71 @@ +class Force { + val t1 = new Thread { + override def run() { + scala.`package` + } + } + val t2 = new Thread { + override def run() { + scala.Predef + } + } + t1.start() + t2.start() + t1.join() + t2.join() +} + +object Test { + def main(args: Array[String]) { + new Force() + } +} + +/* Was deadlocking: +"Thread-2" prio=5 tid=7f9637268000 nid=0x119601000 in Object.wait() [119600000] + java.lang.Thread.State: RUNNABLE + at scala.Predef$.<init>(Predef.scala:90) + at scala.Predef$.<clinit>(Predef.scala) + at Force$$anon$2.run(predef-cycle.scala:10) + +"Thread-1" prio=5 tid=7f9637267800 nid=0x1194fe000 in Object.wait() [1194fb000] + java.lang.Thread.State: RUNNABLE + at scala.collection.immutable.Set$Set4.$plus(Set.scala:127) + at scala.collection.immutable.Set$Set4.$plus(Set.scala:121) + at scala.collection.mutable.SetBuilder.$plus$eq(SetBuilder.scala:24) + at scala.collection.mutable.SetBuilder.$plus$eq(SetBuilder.scala:22) + at scala.collection.generic.Growable$$anonfun$$plus$plus$eq$1.apply(Growable.scala:48) + at scala.collection.generic.Growable$$anonfun$$plus$plus$eq$1.apply(Growable.scala:48) + at scala.collection.immutable.List.foreach(List.scala:318) + at scala.collection.generic.Growable$class.$plus$plus$eq(Growable.scala:48) + at scala.collection.mutable.SetBuilder.$plus$plus$eq(SetBuilder.scala:22) + at scala.collection.TraversableLike$class.to(TraversableLike.scala:629) + at scala.collection.AbstractTraversable.to(Traversable.scala:105) + at scala.collection.TraversableOnce$class.toSet(TraversableOnce.scala:267) + at scala.collection.AbstractTraversable.toSet(Traversable.scala:105) + at scala.runtime.ScalaRunTime$.<init>(ScalaRunTime.scala:50) + at scala.runtime.ScalaRunTime$.<clinit>(ScalaRunTime.scala) + at scala.collection.mutable.HashTable$HashUtils$class.elemHashCode(HashTable.scala) + at scala.collection.mutable.HashMap.elemHashCode(HashMap.scala:39) + at scala.collection.mutable.HashTable$class.findOrAddEntry(HashTable.scala:161) + at scala.collection.mutable.HashMap.findOrAddEntry(HashMap.scala:39) + at scala.collection.mutable.HashMap.put(HashMap.scala:75) + at scala.collection.mutable.HashMap.update(HashMap.scala:80) + at scala.sys.SystemProperties$.addHelp(SystemProperties.scala:64) + at scala.sys.SystemProperties$.bool(SystemProperties.scala:68) + at scala.sys.SystemProperties$.noTraceSupression$lzycompute(SystemProperties.scala:80) + - locked <7b8b0e228> (a scala.sys.SystemProperties$) + at scala.sys.SystemProperties$.noTraceSupression(SystemProperties.scala:80) + at scala.util.control.NoStackTrace$.<init>(NoStackTrace.scala:31) + at scala.util.control.NoStackTrace$.<clinit>(NoStackTrace.scala) + at scala.util.control.NoStackTrace$class.fillInStackTrace(NoStackTrace.scala:22) + at scala.util.control.BreakControl.fillInStackTrace(Breaks.scala:93) + at java.lang.Throwable.<init>(Throwable.java:181) + at scala.util.control.BreakControl.<init>(Breaks.scala:93) + at scala.util.control.Breaks.<init>(Breaks.scala:28) + at scala.collection.Traversable$.<init>(Traversable.scala:96) + at scala.collection.Traversable$.<clinit>(Traversable.scala) + at scala.package$.<init>(package.scala:46) + at scala.package$.<clinit>(package.scala) + at Force$$anon$1.run(predef-cycle.scala:4) + */
\ No newline at end of file diff --git a/test/files/run/t7269.scala b/test/files/run/t7269.scala new file mode 100644 index 0000000000..d22e57dfee --- /dev/null +++ b/test/files/run/t7269.scala @@ -0,0 +1,32 @@ +import scala.collection.JavaConversions._ +import scala.collection.mutable + +object Test extends App { + + def testMap(): Unit = { + val mapJ = new java.util.HashMap[Int, String] + val mapS: mutable.Map[Int, String] = mapJ + + (10 to 20).foreach(i => mapS += ((i, i.toString))) + assert(11 == mapS.size) + + // ConcurrentModificationException thrown in the following line + mapS.retain((i, str) => i % 2 == 0) + assert(6 == mapS.size) + } + + def testSet(): Unit = { + val mapJ = new java.util.HashSet[Int] + val mapS: mutable.Set[Int] = mapJ + + (10 to 20).foreach(i => mapS += i) + assert(11 == mapS.size) + + // ConcurrentModificationException thrown in the following line + mapS.retain((i) => i % 2 == 0) + assert(6 == mapS.size) + } + + testSet() + testMap() +} diff --git a/test/files/run/t7398.scala b/test/files/run/t7398.scala index dd59697b71..493c4dcf40 100644 --- a/test/files/run/t7398.scala +++ b/test/files/run/t7398.scala @@ -3,11 +3,9 @@ import scala.tools.partest._ object Test extends CompilerTest { import global._ - // This way we auto-pass on non-java8 since there's nothing to check - override lazy val units: List[CompilationUnit] = testUnderJavaAtLeast("1.8") { + override lazy val units: List[CompilationUnit] = { + // This test itself does not depend on JDK8. javaCompilationUnits(global)(defaultMethodSource) - } otherwise { - Nil } private def defaultMethodSource = """ diff --git a/test/files/run/t7775.scala b/test/files/run/t7775.scala new file mode 100644 index 0000000000..5fb0327611 --- /dev/null +++ b/test/files/run/t7775.scala @@ -0,0 +1,17 @@ +import scala.concurrent.{duration, future, Await, ExecutionContext} +import scala.tools.nsc.Settings +import ExecutionContext.Implicits.global + +// Was failing pretty regularly with a ConcurrentModificationException as +// WrappedProperties#systemProperties iterated directly over the mutable +// global system properties map. +object Test { + def main(args: Array[String]) { + val tries = 1000 // YMMV + val compiler = future { + for(_ <- 1 to tries) new Settings(_ => {}) + } + for(i <- 1 to tries * 10) System.setProperty(s"foo$i", i.toString) + Await.result(compiler, duration.Duration.Inf) + } +} diff --git a/test/files/run/t7779.scala b/test/files/run/t7779.scala new file mode 100644 index 0000000000..db32cb751f --- /dev/null +++ b/test/files/run/t7779.scala @@ -0,0 +1,67 @@ +// -Xmax-classfile-length doesn't compress top-level classes. +// class ::::::::::::::::::::::::::::::::::::::::::::::::: + +trait Marker + +class Short extends Marker + +// We just test with member classes +object O { + object ::::::::::::::::::::::::::::::::::::::::::::::::: extends Marker +} +class C { + class D { + class ::::::::::::::::::::::::::::::::::::::::::::::::: extends Marker + } +} + +package pack { + // abbreviates to: $colon$colon$colon$colon$colon$colon$colon$colon$colon$colon$colon$colon$colon$colon$colon$colon$colon$colon$colon$colon$colon$colon$colon$colon$colon$colon$colon$colon$colon$colon$colon$colon$colon$colon$colon$colon$colon$colon$colon$colon$colon$colon$colon$colon$colon$colon$colon$colon$colon to $read$$iw$$iw$$colon$colon$colon$colon$colon$colon$colon$colon$$$$c39b3f245029fbed9732fc888d44231b$$$$on$colon$colon$colon$colon$colon$colon$colon$colon$colon$colon + // class ::::::::::::::::::::::::::::::::::::::::::::::::: + + class Short extends Marker + + // We just test with member classes + object O { + object ::::::::::::::::::::::::::::::::::::::::::::::::: extends Marker + } + class C { + class D { + class ::::::::::::::::::::::::::::::::::::::::::::::::: extends Marker + } + } + package p2 { + class Short extends Marker + + object O { + object ::::::::::::::::::::::::::::::::::::::::::::::::: extends Marker + } + class C { + class D { + class ::::::::::::::::::::::::::::::::::::::::::::::::: extends Marker + } + } + } +} + + +object Test extends App { + import reflect.runtime.universe._ + def test[T: TypeTag] = { + val tt = typeTag[T] + val clz = tt.mirror.runtimeClass(tt.tpe) + assert(classOf[Marker].isAssignableFrom(clz), clz.toString) + } + + test[Short] + test[O.:::::::::::::::::::::::::::::::::::::::::::::::::.type] + test[C#D#`:::::::::::::::::::::::::::::::::::::::::::::::::`] + + test[pack.Short] + test[pack.O.:::::::::::::::::::::::::::::::::::::::::::::::::.type] + test[pack.C#D#`:::::::::::::::::::::::::::::::::::::::::::::::::`] + + test[pack.p2.Short] + test[pack.p2.O.:::::::::::::::::::::::::::::::::::::::::::::::::.type] + test[pack.p2.C#D#`:::::::::::::::::::::::::::::::::::::::::::::::::`] +} diff --git a/test/files/run/t7825.scala b/test/files/run/t7825.scala new file mode 100644 index 0000000000..65ca06fdfc --- /dev/null +++ b/test/files/run/t7825.scala @@ -0,0 +1,34 @@ +import scala.tools.partest._ + +object Test extends CompilerTest { + import global._ + + override lazy val units: List[CompilationUnit] = { + // We can test this on JDK6. + javaCompilationUnits(global)(defaultMethodSource) ++ compilationUnits(global)(scalaExtendsDefault) + } + + private def defaultMethodSource = """ +public interface Iterator<E> { + boolean hasNext(); + E next(); + default void remove() { + throw new UnsupportedOperationException("remove"); + } +} + """ + + private def scalaExtendsDefault = """ +object Test { + object X extends Iterator[String] { + def hasNext = true + def next = "!" + } +} + """ + + // We're only checking we that the Scala compilation unit passes refchecks + // No further checks are needed here. + def check(source: String, unit: global.CompilationUnit): Unit = { + } +} diff --git a/test/files/run/typed-annotated.check b/test/files/run/typed-annotated.check new file mode 100644 index 0000000000..d81cc0710e --- /dev/null +++ b/test/files/run/typed-annotated.check @@ -0,0 +1 @@ +42 diff --git a/test/files/run/typed-annotated/Macros_1.scala b/test/files/run/typed-annotated/Macros_1.scala new file mode 100644 index 0000000000..dd18c63d90 --- /dev/null +++ b/test/files/run/typed-annotated/Macros_1.scala @@ -0,0 +1,17 @@ +import scala.reflect.macros.Context +import language.experimental.macros + +class ann extends scala.annotation.StaticAnnotation + +object Macros { + def impl(c: Context) = { + import c.universe._ + // val tpt = Annotated(Apply(Select(New(Ident(newTypeName("ann"))), nme.CONSTRUCTOR), List()), Ident(newTypeName("Int"))) + val tpt = Annotated(Apply(Select(New(Ident(newTypeName("ann"))), nme.CONSTRUCTOR), List()), TypeTree(weakTypeOf[Int])) + c.Expr[Unit](Block( + List(ValDef(Modifiers(), newTermName("x"), tpt, Literal(Constant(42)))), + Apply(Ident(newTermName("println")), List(Ident(newTermName("x")))))) + } + + def foo = macro impl +}
\ No newline at end of file diff --git a/test/files/run/typed-annotated/Test_2.scala b/test/files/run/typed-annotated/Test_2.scala new file mode 100644 index 0000000000..acfddae942 --- /dev/null +++ b/test/files/run/typed-annotated/Test_2.scala @@ -0,0 +1,3 @@ +object Test extends App { + Macros.foo +}
\ No newline at end of file diff --git a/test/instrumented/boxes.patch b/test/instrumented/boxes.patch index 6c5ff23f9f..2bb3243221 100644 --- a/test/instrumented/boxes.patch +++ b/test/instrumented/boxes.patch @@ -1,5 +1,5 @@ 9c9 -< +< --- > /* INSTRUMENTED VERSION */ 51a52,59 diff --git a/test/instrumented/library/scala/runtime/BoxesRunTime.java b/test/instrumented/library/scala/runtime/BoxesRunTime.java index 172ed8ee14..57799bd9b1 100644 --- a/test/instrumented/library/scala/runtime/BoxesRunTime.java +++ b/test/instrumented/library/scala/runtime/BoxesRunTime.java @@ -1,6 +1,6 @@ /* __ *\ ** ________ ___ / / ___ Scala API ** -** / __/ __// _ | / / / _ | (c) 2006-2011, LAMP/EPFL ** +** / __/ __// _ | / / / _ | (c) 2006-2013, LAMP/EPFL ** ** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** ** /____/\___/_/ |_/____/_/ | | ** ** |/ ** @@ -244,7 +244,7 @@ public final class BoxesRunTime * as yet have not. * * Note: Among primitives, Float.NaN != Float.NaN, but the boxed - * verisons are equal. This still needs reconciliation. + * versions are equal. This still needs reconciliation. */ public static int hashFromLong(java.lang.Long n) { int iv = n.intValue(); @@ -258,6 +258,9 @@ public final class BoxesRunTime long lv = n.longValue(); if (lv == dv) return java.lang.Long.valueOf(lv).hashCode(); + + float fv = n.floatValue(); + if (fv == dv) return java.lang.Float.valueOf(fv).hashCode(); else return n.hashCode(); } public static int hashFromFloat(java.lang.Float n) { diff --git a/test/instrumented/library/scala/runtime/ScalaRunTime.scala b/test/instrumented/library/scala/runtime/ScalaRunTime.scala index 5a3f83015f..e474ae737c 100644 --- a/test/instrumented/library/scala/runtime/ScalaRunTime.scala +++ b/test/instrumented/library/scala/runtime/ScalaRunTime.scala @@ -1,6 +1,6 @@ /* __ *\ ** ________ ___ / / ___ Scala API ** -** / __/ __// _ | / / / _ | (c) 2002-2011, LAMP/EPFL ** +** / __/ __// _ | / / / _ | (c) 2002-2013, LAMP/EPFL ** ** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** ** /____/\___/_/ |_/____/_/ | | ** ** |/ ** @@ -8,7 +8,8 @@ /* INSTRUMENTED VERSION */ -package scala.runtime +package scala +package runtime import scala.collection.{ Seq, IndexedSeq, TraversableView, AbstractIterator } import scala.collection.mutable.WrappedArray @@ -17,6 +18,7 @@ import scala.collection.generic.{ Sorted } import scala.reflect.{ ClassTag, classTag } import scala.util.control.ControlThrowable import scala.xml.{ Node, MetaData } +import java.lang.{ Class => jClass } import java.lang.Double.doubleToLongBits import java.lang.reflect.{ Modifier, Method => JMethod } @@ -30,29 +32,21 @@ object ScalaRunTime { def isArray(x: Any, atLevel: Int): Boolean = x != null && isArrayClass(x.getClass, atLevel) - private def isArrayClass(clazz: Class[_], atLevel: Int): Boolean = + private def isArrayClass(clazz: jClass[_], atLevel: Int): Boolean = clazz.isArray && (atLevel == 1 || isArrayClass(clazz.getComponentType, atLevel - 1)) - def isValueClass(clazz: Class[_]) = clazz.isPrimitive() - def isTuple(x: Any) = x != null && tupleNames(x.getClass.getName) + def isValueClass(clazz: jClass[_]) = clazz.isPrimitive() + + // includes specialized subclasses and future proofed against hypothetical TupleN (for N > 22) + def isTuple(x: Any) = x != null && x.getClass.getName.startsWith("scala.Tuple") def isAnyVal(x: Any) = x match { case _: Byte | _: Short | _: Char | _: Int | _: Long | _: Float | _: Double | _: Boolean | _: Unit => true case _ => false } - // Avoiding boxing which messes up the specialized tests. Don't ask. - private val tupleNames = { - var i = 22 - var names: List[String] = Nil - while (i >= 1) { - names ::= ("scala.Tuple" + String.valueOf(i)) - i -= 1 - } - names.toSet - } /** Return the class object representing an array with element class `clazz`. */ - def arrayClass(clazz: Class[_]): Class[_] = { + def arrayClass(clazz: jClass[_]): jClass[_] = { // newInstance throws an exception if the erasure is Void.TYPE. see SI-5680 if (clazz == java.lang.Void.TYPE) classOf[Array[Unit]] else java.lang.reflect.Array.newInstance(clazz, 0).getClass @@ -60,18 +54,19 @@ object ScalaRunTime { /** Return the class object representing elements in arrays described by a given schematic. */ - def arrayElementClass(schematic: Any): Class[_] = schematic match { - case cls: Class[_] => cls.getComponentType + def arrayElementClass(schematic: Any): jClass[_] = schematic match { + case cls: jClass[_] => cls.getComponentType case tag: ClassTag[_] => tag.runtimeClass - case _ => throw new UnsupportedOperationException("unsupported schematic %s (%s)".format(schematic, if (schematic == null) "null" else schematic.getClass)) + case _ => + throw new UnsupportedOperationException(s"unsupported schematic $schematic (${schematic.getClass})") } /** Return the class object representing an unboxed value type, * e.g. classOf[int], not classOf[java.lang.Integer]. The compiler * rewrites expressions like 5.getClass to come here. */ - def anyValClass[T <: AnyVal : ClassTag](value: T): Class[T] = - classTag[T].runtimeClass.asInstanceOf[Class[T]] + def anyValClass[T <: AnyVal : ClassTag](value: T): jClass[T] = + classTag[T].runtimeClass.asInstanceOf[jClass[T]] var arrayApplyCount = 0 @@ -93,11 +88,9 @@ object ScalaRunTime { } } - var arrayUpdateCount = 0 - /** update generic array element */ def array_update(xs: AnyRef, idx: Int, value: Any): Unit = { - arrayUpdateCount += 1 + arrayApplyCount += 1 xs match { case x: Array[AnyRef] => x(idx) = value.asInstanceOf[AnyRef] case x: Array[Int] => x(idx) = value.asInstanceOf[Int] @@ -156,7 +149,7 @@ object ScalaRunTime { dest } - def toArray[T](xs: collection.Seq[T]) = { + def toArray[T](xs: scala.collection.Seq[T]) = { val arr = new Array[AnyRef](xs.length) var i = 0 for (x <- xs) { @@ -179,39 +172,10 @@ object ScalaRunTime { def checkInitialized[T <: AnyRef](x: T): T = if (x == null) throw new UninitializedError else x - abstract class Try[+A] { - def Catch[B >: A](handler: PartialFunction[Throwable, B]): B - def Finally(fin: => Unit): A - } - - def Try[A](block: => A): Try[A] = new Try[A] with Runnable { - private var result: A = _ - private var exception: Throwable = - try { run() ; null } - catch { - case e: ControlThrowable => throw e // don't catch non-local returns etc - case e: Throwable => e - } - - def run() { result = block } - - def Catch[B >: A](handler: PartialFunction[Throwable, B]): B = - if (exception == null) result - else if (handler isDefinedAt exception) handler(exception) - else throw exception - - def Finally(fin: => Unit): A = { - fin - - if (exception == null) result - else throw exception - } - } - def _toString(x: Product): String = x.productIterator.mkString(x.productPrefix + "(", ",", ")") - def _hashCode(x: Product): Int = scala.util.MurmurHash3.productHash(x) + def _hashCode(x: Product): Int = scala.util.hashing.MurmurHash3.productHash(x) /** A helper for case classes. */ def typedProductIterator[T](x: Product): Iterator[T] = { @@ -246,12 +210,12 @@ object ScalaRunTime { // Note that these are the implementations called by ##, so they // must not call ## themselves. - @inline def hash(x: Any): Int = + def hash(x: Any): Int = if (x == null) 0 else if (x.isInstanceOf[java.lang.Number]) BoxesRunTime.hashFromNumber(x.asInstanceOf[java.lang.Number]) else x.hashCode - @inline def hash(dv: Double): Int = { + def hash(dv: Double): Int = { val iv = dv.toInt if (iv == dv) return iv @@ -261,7 +225,7 @@ object ScalaRunTime { val fv = dv.toFloat if (fv == dv) fv.hashCode else dv.hashCode } - @inline def hash(fv: Float): Int = { + def hash(fv: Float): Int = { val iv = fv.toInt if (iv == fv) return iv @@ -269,29 +233,29 @@ object ScalaRunTime { if (lv == fv) return hash(lv) else fv.hashCode } - @inline def hash(lv: Long): Int = { + def hash(lv: Long): Int = { val low = lv.toInt val lowSign = low >>> 31 val high = (lv >>> 32).toInt low ^ (high + lowSign) } - @inline def hash(x: Number): Int = runtime.BoxesRunTime.hashFromNumber(x) + def hash(x: Number): Int = runtime.BoxesRunTime.hashFromNumber(x) // The remaining overloads are here for completeness, but the compiler // inlines these definitions directly so they're not generally used. - @inline def hash(x: Int): Int = x - @inline def hash(x: Short): Int = x.toInt - @inline def hash(x: Byte): Int = x.toInt - @inline def hash(x: Char): Int = x.toInt - @inline def hash(x: Boolean): Int = if (x) true.hashCode else false.hashCode - @inline def hash(x: Unit): Int = 0 + def hash(x: Int): Int = x + def hash(x: Short): Int = x.toInt + def hash(x: Byte): Int = x.toInt + def hash(x: Char): Int = x.toInt + def hash(x: Boolean): Int = if (x) true.hashCode else false.hashCode + def hash(x: Unit): Int = 0 /** A helper method for constructing case class equality methods, * because existential types get in the way of a clean outcome and * it's performing a series of Any/Any equals comparisons anyway. * See ticket #2867 for specifics. */ - def sameElements(xs1: collection.Seq[Any], xs2: collection.Seq[Any]) = xs1 sameElements xs2 + def sameElements(xs1: scala.collection.Seq[Any], xs2: scala.collection.Seq[Any]) = xs1 sameElements xs2 /** Given any Scala value, convert it to a String. * @@ -358,7 +322,7 @@ object ScalaRunTime { case x: String => if (x.head.isWhitespace || x.last.isWhitespace) "\"" + x + "\"" else x case x if useOwnToString(x) => x.toString case x: AnyRef if isArray(x) => arrayToString(x) - case x: collection.Map[_, _] => x.iterator take maxElements map mapInner mkString (x.stringPrefix + "(", ", ", ")") + case x: scala.collection.Map[_, _] => x.iterator take maxElements map mapInner mkString (x.stringPrefix + "(", ", ", ")") case x: Iterable[_] => x.iterator take maxElements map inner mkString (x.stringPrefix + "(", ", ", ")") case x: Traversable[_] => x take maxElements map inner mkString (x.stringPrefix + "(", ", ", ")") case x: Product1[_] if isTuple(x) => "(" + inner(x._1) + ",)" // that special trailing comma diff --git a/test/instrumented/srt.patch b/test/instrumented/srt.patch index 47dcfa2197..ee619b2ecb 100644 --- a/test/instrumented/srt.patch +++ b/test/instrumented/srt.patch @@ -1,67 +1,10 @@ 8a9,10 > /* INSTRUMENTED VERSION */ > -73a76,77 +68a71,72 > var arrayApplyCount = 0 > -75,86c79,93 -< def array_apply(xs: AnyRef, idx: Int): Any = xs match { -< case x: Array[AnyRef] => x(idx).asInstanceOf[Any] -< case x: Array[Int] => x(idx).asInstanceOf[Any] -< case x: Array[Double] => x(idx).asInstanceOf[Any] -< case x: Array[Long] => x(idx).asInstanceOf[Any] -< case x: Array[Float] => x(idx).asInstanceOf[Any] -< case x: Array[Char] => x(idx).asInstanceOf[Any] -< case x: Array[Byte] => x(idx).asInstanceOf[Any] -< case x: Array[Short] => x(idx).asInstanceOf[Any] -< case x: Array[Boolean] => x(idx).asInstanceOf[Any] -< case x: Array[Unit] => x(idx).asInstanceOf[Any] -< case null => throw new NullPointerException ---- -> def array_apply(xs: AnyRef, idx: Int): Any = { +70a75 +> arrayApplyCount += 1 +87a93 > arrayApplyCount += 1 -> xs match { -> case x: Array[AnyRef] => x(idx).asInstanceOf[Any] -> case x: Array[Int] => x(idx).asInstanceOf[Any] -> case x: Array[Double] => x(idx).asInstanceOf[Any] -> case x: Array[Long] => x(idx).asInstanceOf[Any] -> case x: Array[Float] => x(idx).asInstanceOf[Any] -> case x: Array[Char] => x(idx).asInstanceOf[Any] -> case x: Array[Byte] => x(idx).asInstanceOf[Any] -> case x: Array[Short] => x(idx).asInstanceOf[Any] -> case x: Array[Boolean] => x(idx).asInstanceOf[Any] -> case x: Array[Unit] => x(idx).asInstanceOf[Any] -> case null => throw new NullPointerException -> } -88a96,97 -> var arrayUpdateCount = 0 -> -90,101c99,113 -< def array_update(xs: AnyRef, idx: Int, value: Any): Unit = xs match { -< case x: Array[AnyRef] => x(idx) = value.asInstanceOf[AnyRef] -< case x: Array[Int] => x(idx) = value.asInstanceOf[Int] -< case x: Array[Double] => x(idx) = value.asInstanceOf[Double] -< case x: Array[Long] => x(idx) = value.asInstanceOf[Long] -< case x: Array[Float] => x(idx) = value.asInstanceOf[Float] -< case x: Array[Char] => x(idx) = value.asInstanceOf[Char] -< case x: Array[Byte] => x(idx) = value.asInstanceOf[Byte] -< case x: Array[Short] => x(idx) = value.asInstanceOf[Short] -< case x: Array[Boolean] => x(idx) = value.asInstanceOf[Boolean] -< case x: Array[Unit] => x(idx) = value.asInstanceOf[Unit] -< case null => throw new NullPointerException ---- -> def array_update(xs: AnyRef, idx: Int, value: Any): Unit = { -> arrayUpdateCount += 1 -> xs match { -> case x: Array[AnyRef] => x(idx) = value.asInstanceOf[AnyRef] -> case x: Array[Int] => x(idx) = value.asInstanceOf[Int] -> case x: Array[Double] => x(idx) = value.asInstanceOf[Double] -> case x: Array[Long] => x(idx) = value.asInstanceOf[Long] -> case x: Array[Float] => x(idx) = value.asInstanceOf[Float] -> case x: Array[Char] => x(idx) = value.asInstanceOf[Char] -> case x: Array[Byte] => x(idx) = value.asInstanceOf[Byte] -> case x: Array[Short] => x(idx) = value.asInstanceOf[Short] -> case x: Array[Boolean] => x(idx) = value.asInstanceOf[Boolean] -> case x: Array[Unit] => x(idx) = value.asInstanceOf[Unit] -> case null => throw new NullPointerException -> } diff --git a/test/junit/scala/runtime/ScalaRunTimeTest.scala b/test/junit/scala/runtime/ScalaRunTimeTest.scala new file mode 100644 index 0000000000..9da197c71a --- /dev/null +++ b/test/junit/scala/runtime/ScalaRunTimeTest.scala @@ -0,0 +1,70 @@ +package scala.runtime + +import org.junit.Assert._ +import org.junit.Test +import org.junit.runner.RunWith +import org.junit.runners.JUnit4 + +/** Tests for the private class DefaultPromise */ +@RunWith(classOf[JUnit4]) +class ScalaRunTimeTest { + @Test + def testIsTuple() { + import ScalaRunTime.isTuple + def check(v: Any) = { + assertTrue(v.toString, isTuple(v)) + } + + val s = "" + check(Tuple1(s)) + check((s, s)) + check((s, s, s)) + check((s, s, s, s)) + check((s, s, s, s, s)) + check((s, s, s, s, s, s)) + check((s, s, s, s, s, s, s)) + check((s, s, s, s, s, s, s, s)) + check((s, s, s, s, s, s, s, s, s)) + check((s, s, s, s, s, s, s, s, s, s)) + check((s, s, s, s, s, s, s, s, s, s, s)) + check((s, s, s, s, s, s, s, s, s, s, s, s)) + check((s, s, s, s, s, s, s, s, s, s, s, s, s)) + check((s, s, s, s, s, s, s, s, s, s, s, s, s, s)) + check((s, s, s, s, s, s, s, s, s, s, s, s, s, s, s)) + check((s, s, s, s, s, s, s, s, s, s, s, s, s, s, s, s)) + check((s, s, s, s, s, s, s, s, s, s, s, s, s, s, s, s, s)) + check((s, s, s, s, s, s, s, s, s, s, s, s, s, s, s, s, s, s)) + check((s, s, s, s, s, s, s, s, s, s, s, s, s, s, s, s, s, s, s)) + check((s, s, s, s, s, s, s, s, s, s, s, s, s, s, s, s, s, s, s, s)) + check((s, s, s, s, s, s, s, s, s, s, s, s, s, s, s, s, s, s, s, s, s)) + check((s, s, s, s, s, s, s, s, s, s, s, s, s, s, s, s, s, s, s, s, s, s)) + + // some specialized variants will have mangled classnames + check(Tuple1(0)) + check((0, 0)) + check((0, 0, 0)) + check((0, 0, 0, 0)) + check((0, 0, 0, 0, 0)) + check((0, 0, 0, 0, 0, 0)) + check((0, 0, 0, 0, 0, 0, 0)) + check((0, 0, 0, 0, 0, 0, 0, 0)) + check((0, 0, 0, 0, 0, 0, 0, 0, 0)) + check((0, 0, 0, 0, 0, 0, 0, 0, 0, 0)) + check((0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)) + check((0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)) + check((0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)) + check((0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)) + check((0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)) + check((0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)) + check((0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)) + check((0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)) + check((0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)) + check((0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)) + check((0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)) + check((0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)) + + case class C() + val c = new C() + assertFalse(c.toString, isTuple(c)) + } +} diff --git a/test/pending/pos/t7778/Foo_1.java b/test/pending/pos/t7778/Foo_1.java new file mode 100644 index 0000000000..65431ffd46 --- /dev/null +++ b/test/pending/pos/t7778/Foo_1.java @@ -0,0 +1,6 @@ +import java.util.concurrent.Callable; + +public abstract class Foo_1<T> implements Callable<Foo_1<Object>.Inner> { + public abstract class Inner { + } +} diff --git a/test/pending/pos/t7778/Test_2.scala b/test/pending/pos/t7778/Test_2.scala new file mode 100644 index 0000000000..306303a99e --- /dev/null +++ b/test/pending/pos/t7778/Test_2.scala @@ -0,0 +1,3 @@ +class Test { + null: Foo_1[_] +} diff --git a/test/scaladoc/run/t7767.check b/test/scaladoc/run/t7767.check new file mode 100644 index 0000000000..619c56180b --- /dev/null +++ b/test/scaladoc/run/t7767.check @@ -0,0 +1 @@ +Done. diff --git a/test/scaladoc/run/t7767.scala b/test/scaladoc/run/t7767.scala new file mode 100644 index 0000000000..6c9ceb511d --- /dev/null +++ b/test/scaladoc/run/t7767.scala @@ -0,0 +1,18 @@ +import scala.tools.nsc.doc.model._ +import scala.tools.partest.ScaladocModelTest + +object Test extends ScaladocModelTest { + + override def code = """ + class Docable extends { /**Doc*/ val foo = 0 } with AnyRef + """ + + // no need for special settings + def scaladocSettings = "" + + def testModel(rootPackage: Package) = { + import access._ + val comment = rootPackage._class("Docable")._value("foo").comment.map(_.body.toString.trim).getOrElse("") + assert(comment.contains("Doc"), comment) + } +} diff --git a/tools/binary-repo-lib.sh b/tools/binary-repo-lib.sh index 4fe6dd67a0..92ef3a0329 100755 --- a/tools/binary-repo-lib.sh +++ b/tools/binary-repo-lib.sh @@ -4,7 +4,7 @@ remote_urlget="http://repo.typesafe.com/typesafe/scala-sha-bootstrap/org/scala-lang/bootstrap" -remote_urlpush="http://typesafe.artifactoryonline.com/typesafe/scala-sha-bootstrap/org/scala-lang/bootstrap" +remote_urlpush="http://private-repo.typesafe.com/typesafe/scala-sha-bootstrap/org/scala-lang/bootstrap" libraryJar="$(pwd)/lib/scala-library.jar" desired_ext=".desired.sha1" push_jar="$(pwd)/tools/push.jar" |