summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Phillips <paulp@improving.org>2013-05-16 22:30:24 -0700
committerPaul Phillips <paulp@improving.org>2013-05-16 22:34:16 -0700
commit0c3ca2248d55eeeee2db6693e5fc46b9ba049eda (patch)
tree71686d0b99fc1d4a245ddb24efe50398b0c00c78
parentc663ecf8677eda3fe8c91170b614eb7166b18711 (diff)
parent13b4628aabb8e7a293a382dcab6db5848f672f94 (diff)
downloadscala-0c3ca2248d55eeeee2db6693e5fc46b9ba049eda.tar.gz
scala-0c3ca2248d55eeeee2db6693e5fc46b9ba049eda.tar.bz2
scala-0c3ca2248d55eeeee2db6693e5fc46b9ba049eda.zip
Merge branch 'master' into HEAD
* master: SI-7469 Remove @deprecated scala.util.logging SI-3943 Test case for already-fixed Java interop bug Fix formatting for couple of docs in the compiler SI-7476 Add documentation to GenericTraversableTemplate SI-7469 Remove @deprecated scala.util.parsing.ast SI-7469 Remove @deprecated MurmurHash elements SI-7469 Remove deprecated elements in s.u.parsing.combinator SI-7469 Make @deprecated elems in scala.concurrent private[scala] removes duplication in inferImplicitValue SI-7047 fixes silent for c.inferImplicitXXX SI-7167 implicit macros decide what is divergence macroExpandAll is now triggered in all invocations of typed SI-5923 instantiates targs in deferred macro applications SI-6406 Restore deprecated API SI-6039 Harden against irrelevant filesystem details Limit unnecessary calls to Type#toString. fix typo in comment SI-7432 add testcases SI-7432 Range.min should throw NoSuchElementException on empty range AbstractFile.getDirectory does not return null when outDir is "." Conflicts: src/compiler/scala/tools/nsc/typechecker/Typers.scala
-rw-r--r--src/compiler/scala/reflect/macros/runtime/Aliases.scala4
-rw-r--r--src/compiler/scala/reflect/macros/runtime/Enclosures.scala24
-rw-r--r--src/compiler/scala/reflect/macros/runtime/Typers.scala23
-rw-r--r--src/compiler/scala/tools/nsc/symtab/SymbolLoaders.scala8
-rw-r--r--src/compiler/scala/tools/nsc/transform/TailCalls.scala12
-rw-r--r--src/compiler/scala/tools/nsc/transform/patmat/PatternMatching.scala8
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Contexts.scala2
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Implicits.scala35
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Macros.scala25
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Typers.scala23
-rw-r--r--src/compiler/scala/tools/nsc/util/ClassPath.scala2
-rw-r--r--src/compiler/scala/tools/reflect/ToolBoxFactory.scala11
-rw-r--r--src/library/scala/collection/generic/GenericTraversableTemplate.scala54
-rw-r--r--src/library/scala/collection/immutable/Range.scala4
-rw-r--r--src/library/scala/concurrent/Future.scala2
-rw-r--r--src/library/scala/concurrent/FutureTaskRunner.scala2
-rw-r--r--src/library/scala/concurrent/ManagedBlocker.scala2
-rw-r--r--src/library/scala/concurrent/SyncVar.scala4
-rw-r--r--src/library/scala/concurrent/TaskRunner.scala2
-rw-r--r--src/library/scala/concurrent/ThreadPoolRunner.scala2
-rw-r--r--src/library/scala/util/MurmurHash.scala198
-rw-r--r--src/library/scala/util/hashing/MurmurHash3.scala8
-rw-r--r--src/library/scala/util/logging/ConsoleLogger.scala27
-rw-r--r--src/library/scala/util/logging/Logged.scala34
-rw-r--r--src/library/scala/util/matching/Regex.scala14
-rw-r--r--src/library/scala/util/parsing/ast/AbstractSyntax.scala33
-rw-r--r--src/library/scala/util/parsing/ast/Binders.scala348
-rw-r--r--src/library/scala/util/parsing/combinator/Parsers.scala6
-rw-r--r--src/library/scala/util/parsing/combinator/testing/RegexTest.scala28
-rw-r--r--src/library/scala/util/parsing/combinator/testing/Tester.scala45
-rw-r--r--src/library/scala/xml/factory/LoggedNodeFactory.scala10
-rwxr-xr-xsrc/library/scala/xml/parsing/MarkupHandler.scala8
-rw-r--r--src/library/scala/xml/parsing/ValidatingMarkupHandler.scala18
-rw-r--r--src/library/scala/xml/persistent/CachedFileStorage.scala7
-rw-r--r--src/reflect/scala/reflect/io/Path.scala2
-rw-r--r--src/reflect/scala/reflect/macros/Enclosures.scala8
-rw-r--r--src/reflect/scala/reflect/macros/Typers.scala21
-rw-r--r--test/files/jvm/xml01.scala1
-rw-r--r--test/files/neg/macro-divergence-controlled.check4
-rw-r--r--test/files/neg/macro-divergence-controlled/Impls_Macros_1.scala23
-rw-r--r--test/files/neg/macro-divergence-controlled/Test_2.scala3
-rw-r--r--test/files/neg/t6406-regextract.check9
-rw-r--r--test/files/neg/tailrec-2.check2
-rw-r--r--test/files/pos/t1648.scala4
-rw-r--r--test/files/pos/t3943/Client_2.scala7
-rw-r--r--test/files/pos/t3943/Outer_1.java14
-rw-r--r--test/files/pos/t5692c.check0
-rw-r--r--test/files/pos/t5692c.scala4
-rw-r--r--test/files/run/macro-divergence-spurious.check1
-rw-r--r--test/files/run/macro-divergence-spurious/Impls_Macros_1.scala23
-rw-r--r--test/files/run/macro-divergence-spurious/Test_2.scala3
-rw-r--r--test/files/run/macro-sip19-revised/Impls_Macros_1.scala2
-rw-r--r--test/files/run/macro-sip19/Impls_Macros_1.scala2
-rw-r--r--test/files/run/range.scala11
-rw-r--r--test/files/run/t5923a.check3
-rw-r--r--test/files/run/t5923a/Macros_1.scala14
-rw-r--r--test/files/run/t5923a/Test_2.scala5
-rw-r--r--test/files/run/t5923b.check3
-rw-r--r--test/files/run/t5923b/Test.scala7
-rw-r--r--test/files/run/t6039.scala18
-rw-r--r--test/files/run/t7047.check0
-rw-r--r--test/files/run/t7047/Impls_Macros_1.scala19
-rw-r--r--test/files/run/t7047/Test_2.scala3
-rw-r--r--test/files/scalacheck/avl.scala4
64 files changed, 396 insertions, 857 deletions
diff --git a/src/compiler/scala/reflect/macros/runtime/Aliases.scala b/src/compiler/scala/reflect/macros/runtime/Aliases.scala
index ff870e728e..1c6703aeee 100644
--- a/src/compiler/scala/reflect/macros/runtime/Aliases.scala
+++ b/src/compiler/scala/reflect/macros/runtime/Aliases.scala
@@ -28,4 +28,8 @@ trait Aliases {
override def typeTag[T](implicit ttag: TypeTag[T]) = ttag
override def weakTypeOf[T](implicit attag: WeakTypeTag[T]): Type = attag.tpe
override def typeOf[T](implicit ttag: TypeTag[T]): Type = ttag.tpe
+
+ implicit class RichOpenImplicit(oi: universe.analyzer.OpenImplicit) {
+ def toImplicitCandidate = ImplicitCandidate(oi.info.pre, oi.info.sym, oi.pt, oi.tree)
+ }
} \ No newline at end of file
diff --git a/src/compiler/scala/reflect/macros/runtime/Enclosures.scala b/src/compiler/scala/reflect/macros/runtime/Enclosures.scala
index 8fe0b09700..f3f92550de 100644
--- a/src/compiler/scala/reflect/macros/runtime/Enclosures.scala
+++ b/src/compiler/scala/reflect/macros/runtime/Enclosures.scala
@@ -21,16 +21,16 @@ trait Enclosures {
// vals are eager to simplify debugging
// after all we wouldn't save that much time by making them lazy
- val macroApplication: Tree = expandee
- def enclosingPackage: PackageDef = strictEnclosure[PackageDef]
- val enclosingClass: Tree = lenientEnclosure[ImplDef]
- def enclosingImpl: ImplDef = strictEnclosure[ImplDef]
- def enclosingTemplate: Template = strictEnclosure[Template]
- val enclosingImplicits: List[(Type, Tree)] = site.openImplicits
- val enclosingMacros: List[Context] = this :: universe.analyzer.openMacros // include self
- val enclosingMethod: Tree = lenientEnclosure[DefDef]
- def enclosingDef: DefDef = strictEnclosure[DefDef]
- val enclosingPosition: Position = if (enclPoses.isEmpty) NoPosition else enclPoses.head.pos
- val enclosingUnit: CompilationUnit = universe.currentRun.currentUnit
- val enclosingRun: Run = universe.currentRun
+ val macroApplication: Tree = expandee
+ def enclosingPackage: PackageDef = strictEnclosure[PackageDef]
+ val enclosingClass: Tree = lenientEnclosure[ImplDef]
+ def enclosingImpl: ImplDef = strictEnclosure[ImplDef]
+ def enclosingTemplate: Template = strictEnclosure[Template]
+ val enclosingImplicits: List[ImplicitCandidate] = site.openImplicits.map(_.toImplicitCandidate)
+ val enclosingMacros: List[Context] = this :: universe.analyzer.openMacros // include self
+ val enclosingMethod: Tree = lenientEnclosure[DefDef]
+ def enclosingDef: DefDef = strictEnclosure[DefDef]
+ val enclosingPosition: Position = if (enclPoses.isEmpty) NoPosition else enclPoses.head.pos
+ val enclosingUnit: CompilationUnit = universe.currentRun.currentUnit
+ val enclosingRun: Run = universe.currentRun
}
diff --git a/src/compiler/scala/reflect/macros/runtime/Typers.scala b/src/compiler/scala/reflect/macros/runtime/Typers.scala
index 0ebcf43de0..f60b8dfeb4 100644
--- a/src/compiler/scala/reflect/macros/runtime/Typers.scala
+++ b/src/compiler/scala/reflect/macros/runtime/Typers.scala
@@ -8,7 +8,7 @@ trait Typers {
def openMacros: List[Context] = this :: universe.analyzer.openMacros
- def openImplicits: List[(Type, Tree)] = callsiteTyper.context.openImplicits
+ def openImplicits: List[ImplicitCandidate] = callsiteTyper.context.openImplicits.map(_.toImplicitCandidate)
/**
* @see [[scala.tools.reflect.ToolBox.typeCheck]]
@@ -37,30 +37,13 @@ trait Typers {
def inferImplicitValue(pt: Type, silent: Boolean = true, withMacrosDisabled: Boolean = false, pos: Position = enclosingPosition): Tree = {
macroLogVerbose("inferring implicit value of type %s, macros = %s".format(pt, !withMacrosDisabled))
- inferImplicit(universe.EmptyTree, pt, isView = false, silent = silent, withMacrosDisabled = withMacrosDisabled, pos = pos)
+ universe.analyzer.inferImplicit(universe.EmptyTree, pt, false, callsiteTyper.context, silent, withMacrosDisabled, pos, (pos, msg) => throw TypecheckException(pos, msg))
}
def inferImplicitView(tree: Tree, from: Type, to: Type, silent: Boolean = true, withMacrosDisabled: Boolean = false, pos: Position = enclosingPosition): Tree = {
macroLogVerbose("inferring implicit view from %s to %s for %s, macros = %s".format(from, to, tree, !withMacrosDisabled))
val viewTpe = universe.appliedType(universe.definitions.FunctionClass(1).toTypeConstructor, List(from, to))
- inferImplicit(tree, viewTpe, isView = true, silent = silent, withMacrosDisabled = withMacrosDisabled, pos = pos)
- }
-
- private def inferImplicit(tree: Tree, pt: Type, isView: Boolean, silent: Boolean, withMacrosDisabled: Boolean, pos: Position): Tree = {
- import universe.analyzer.SearchResult
- val context = callsiteTyper.context
- val wrapper1 = if (!withMacrosDisabled) (context.withMacrosEnabled[SearchResult] _) else (context.withMacrosDisabled[SearchResult] _)
- def wrapper (inference: => SearchResult) = wrapper1(inference)
- wrapper(universe.analyzer.inferImplicit(tree, pt, reportAmbiguous = true, isView = isView, context = context, saveAmbiguousDivergent = !silent, pos = pos)) match {
- case failure if failure.tree.isEmpty =>
- macroLogVerbose("implicit search has failed. to find out the reason, turn on -Xlog-implicits")
- context.firstError match {
- case Some(err) => throw new TypecheckException(err.errPos, err.errMsg)
- case None => universe.EmptyTree
- }
- case success =>
- success.tree
- }
+ universe.analyzer.inferImplicit(tree, viewTpe, true, callsiteTyper.context, silent, withMacrosDisabled, pos, (pos, msg) => throw TypecheckException(pos, msg))
}
def resetAllAttrs(tree: Tree): Tree = universe.resetAllAttrs(tree)
diff --git a/src/compiler/scala/tools/nsc/symtab/SymbolLoaders.scala b/src/compiler/scala/tools/nsc/symtab/SymbolLoaders.scala
index 250feb69bf..98fb6bd0ef 100644
--- a/src/compiler/scala/tools/nsc/symtab/SymbolLoaders.scala
+++ b/src/compiler/scala/tools/nsc/symtab/SymbolLoaders.scala
@@ -234,10 +234,14 @@ abstract class SymbolLoaders {
}
}
if (!root.isEmptyPackageClass) {
+ // Only enter packages which contain a class or a non-empty package
for (pkg <- classpath.packages) {
- enterPackage(root, pkg.name, new PackageLoader(pkg))
+ if (pkg.isEmptyOfClassfiles) {
+ log(s"Discarding $root/$pkg as it contains no classfiles.")
+ }
+ else
+ enterPackage(root, pkg.name, new PackageLoader(pkg))
}
-
openPackageModule(root)
}
}
diff --git a/src/compiler/scala/tools/nsc/transform/TailCalls.scala b/src/compiler/scala/tools/nsc/transform/TailCalls.scala
index 9e867917f9..6f422fcc90 100644
--- a/src/compiler/scala/tools/nsc/transform/TailCalls.scala
+++ b/src/compiler/scala/tools/nsc/transform/TailCalls.scala
@@ -89,12 +89,12 @@ abstract class TailCalls extends Transform {
*/
class TailCallElimination(unit: CompilationUnit) extends Transformer {
private def defaultReason = "it contains a recursive call not in tail position"
- private val failPositions = perRunCaches.newMap[TailContext, Position]()
- private val failReasons = perRunCaches.newMap[TailContext, String]()
+ private val failPositions = perRunCaches.newMap[TailContext, Position]() withDefault (_.methodPos)
+ private val failReasons = perRunCaches.newMap[TailContext, String]() withDefaultValue defaultReason
private def tailrecFailure(ctx: TailContext) {
- val method = ctx.method
- val failReason = failReasons.getOrElse(ctx, defaultReason)
- val failPos = failPositions.getOrElse(ctx, ctx.methodPos)
+ val method = ctx.method
+ val failReason = failReasons(ctx)
+ val failPos = failPositions(ctx)
unit.error(failPos, s"could not optimize @tailrec annotated $method: $failReason")
}
@@ -237,7 +237,7 @@ abstract class TailCalls extends Transform {
if (!ctx.isEligible) fail("it is neither private nor final so can be overridden")
else if (!isRecursiveCall) {
- if (receiverIsSuper) failHere("it contains a recursive call targeting supertype " + receiver.tpe)
+ if (receiverIsSuper) failHere("it contains a recursive call targeting a supertype")
else failHere(defaultReason)
}
else if (!matchesTypeArgs) failHere("it is called recursively with different type arguments")
diff --git a/src/compiler/scala/tools/nsc/transform/patmat/PatternMatching.scala b/src/compiler/scala/tools/nsc/transform/patmat/PatternMatching.scala
index 8be8b72130..63834ae51e 100644
--- a/src/compiler/scala/tools/nsc/transform/patmat/PatternMatching.scala
+++ b/src/compiler/scala/tools/nsc/transform/patmat/PatternMatching.scala
@@ -129,8 +129,9 @@ trait Interface extends ast.TreeDSL {
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/** Interface with user-defined match monad?
- * if there's a `__match` in scope, we use this as the match strategy, assuming it conforms to MatchStrategy as defined below:
+ * if there's a <code>__match</code> in scope, we use this as the match strategy, assuming it conforms to MatchStrategy as defined below:
+ {{{
type Matcher[P[_], M[+_], A] = {
def flatMap[B](f: P[A] => M[B]): M[B]
def orElse[B >: A](alternative: => M[B]): M[B]
@@ -144,12 +145,14 @@ trait Interface extends ast.TreeDSL {
def one[T](x: P[T]): M[T]
def guard[T](cond: P[Boolean], then: => P[T]): M[T]
}
+ }}}
* P and M are derived from one's signature (`def one[T](x: P[T]): M[T]`)
- * if no `__match` is found, we assume the following implementation (and generate optimized code accordingly)
+ * if no <code>__match</code> is found, we assume the following implementation (and generate optimized code accordingly)
+ {{{
object __match extends MatchStrategy[({type Id[x] = x})#Id, Option] {
def zero = None
def one[T](x: T) = Some(x)
@@ -157,6 +160,7 @@ trait Interface extends ast.TreeDSL {
def guard[T](cond: Boolean, then: => T): Option[T] = if(cond) Some(then) else None
def runOrElse[T, U](x: T)(f: T => Option[U]): U = f(x) getOrElse (throw new MatchError(x))
}
+ }}}
*/
trait MatchMonadInterface {
diff --git a/src/compiler/scala/tools/nsc/typechecker/Contexts.scala b/src/compiler/scala/tools/nsc/typechecker/Contexts.scala
index 21c33aad0d..9794497667 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Contexts.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Contexts.scala
@@ -213,7 +213,7 @@ trait Contexts { self: Analyzer =>
def isRootImport: Boolean = false
/** Types for which implicit arguments are currently searched */
- var openImplicits: List[(Type,Tree)] = List()
+ var openImplicits: List[OpenImplicit] = List()
/* For a named application block (`Tree`) the corresponding `NamedApplyInfo`. */
var namedApplyBlockInfo: Option[(Tree, NamedApplyInfo)] = None
diff --git a/src/compiler/scala/tools/nsc/typechecker/Implicits.scala b/src/compiler/scala/tools/nsc/typechecker/Implicits.scala
index f27c15180e..05db86635a 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Implicits.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Implicits.scala
@@ -100,6 +100,21 @@ trait Implicits {
result
}
+ /** A friendly wrapper over inferImplicit to be used in macro contexts and toolboxes.
+ */
+ def inferImplicit(tree: Tree, pt: Type, isView: Boolean, context: Context, silent: Boolean, withMacrosDisabled: Boolean, pos: Position, onError: (Position, String) => Unit): Tree = {
+ val wrapper1 = if (!withMacrosDisabled) (context.withMacrosEnabled[SearchResult] _) else (context.withMacrosDisabled[SearchResult] _)
+ def wrapper(inference: => SearchResult) = wrapper1(inference)
+ val result = wrapper(inferImplicit(tree, pt, reportAmbiguous = true, isView = isView, context = context, saveAmbiguousDivergent = !silent, pos = pos))
+ if (result.isFailure && !silent) {
+ val err = context.firstError
+ val errPos = err.map(_.errPos).getOrElse(pos)
+ val errMsg = err.map(_.errMsg).getOrElse("implicit search has failed. to find out the reason, turn on -Xlog-implicits")
+ onError(errPos, errMsg)
+ }
+ result.tree
+ }
+
/** Find all views from type `tp` (in which `tpars` are free)
*
* Note that the trees in the search results in the returned list share the same type variables.
@@ -224,6 +239,10 @@ trait Implicits {
)
}
+ /** A class which is used to track pending implicits to prevent infinite implicit searches.
+ */
+ case class OpenImplicit(info: ImplicitInfo, pt: Type, tree: Tree)
+
/** A sentinel indicating no implicit was found */
val NoImplicitInfo = new ImplicitInfo(null, NoType, NoSymbol) {
// equals used to be implemented in ImplicitInfo with an `if(this eq NoImplicitInfo)`
@@ -407,13 +426,25 @@ trait Implicits {
* @pre `info.tpe` does not contain an error
*/
private def typedImplicit(info: ImplicitInfo, ptChecked: Boolean, isLocal: Boolean): SearchResult = {
- (context.openImplicits find { case (tp, tree1) => tree1.symbol == tree.symbol && dominates(pt, tp)}) match {
+ // SI-7167 let implicit macros decide what amounts for a divergent implicit search
+ // imagine a macro writer which wants to synthesize a complex implicit Complex[T] by making recursive calls to Complex[U] for its parts
+ // e.g. we have `class Foo(val bar: Bar)` and `class Bar(val x: Int)`
+ // then it's quite reasonable for the macro writer to synthesize Complex[Foo] by calling `inferImplicitValue(typeOf[Complex[Bar])`
+ // however if we didn't insert the `info.sym.isMacro` check here, then under some circumstances
+ // (e.g. as described here http://groups.google.com/group/scala-internals/browse_thread/thread/545462b377b0ac0a)
+ // `dominates` might decide that `Bar` dominates `Foo` and therefore a recursive implicit search should be prohibited
+ // now when we yield control of divergent expansions to the macro writer, what happens next?
+ // in the worst case, if the macro writer is careless, we'll get a StackOverflowException from repeated macro calls
+ // otherwise, the macro writer could check `c.openMacros` and `c.openImplicits` and do `c.abort` when expansions are deemed to be divergent
+ // upon receiving `c.abort` the typechecker will decide that the corresponding implicit search has failed
+ // which will fail the entire stack of implicit searches, producing a nice error message provided by the programmer
+ (context.openImplicits find { case OpenImplicit(info, tp, tree1) => !info.sym.isMacro && tree1.symbol == tree.symbol && dominates(pt, tp)}) match {
case Some(pending) =>
//println("Pending implicit "+pending+" dominates "+pt+"/"+undetParams) //@MDEBUG
DivergentSearchFailure
case None =>
try {
- context.openImplicits = (pt, tree) :: context.openImplicits
+ context.openImplicits = OpenImplicit(info, pt, tree) :: context.openImplicits
// println(" "*context.openImplicits.length+"typed implicit "+info+" for "+pt) //@MDEBUG
val result = typedImplicit0(info, ptChecked, isLocal)
if (result.isDivergent) {
diff --git a/src/compiler/scala/tools/nsc/typechecker/Macros.scala b/src/compiler/scala/tools/nsc/typechecker/Macros.scala
index 31cc8bd93c..2cd2f9380b 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Macros.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Macros.scala
@@ -396,7 +396,7 @@ trait Macros extends scala.tools.reflect.FastTrack with Traces {
case Fallback(fallback) =>
typed1Expr(fallback)
case Delayed(delayed) =>
- delayed
+ typer.instantiate(delayed, EXPRmode, WildcardType)
case Skipped(skipped) =>
skipped
case Failure(failure) =>
@@ -780,6 +780,29 @@ trait Macros extends scala.tools.reflect.FastTrack with Traces {
expanded2
}
}
+ override def onDelayed(delayed: Tree) = {
+ // If we've been delayed (i.e. bailed out of the expansion because of undetermined type params present in the expandee),
+ // then there are two possible situations we're in:
+ // 1) We're in POLYmode, when the typer tests the waters wrt type inference
+ // (e.g. as in typedArgToPoly in doTypedApply).
+ // 2) We're out of POLYmode, which means that the typer is out of tricks to infer our type
+ // (e.g. if we're an argument to a function call, then this means that no previous argument lists
+ // can determine our type variables for us).
+ //
+ // Situation #1 is okay for us, since there's no pressure. In POLYmode we're just verifying that
+ // there's nothing outrageously wrong with our undetermined type params (from what I understand!).
+ //
+ // Situation #2 requires measures to be taken. If we're in it, then noone's going to help us infer
+ // the undetermined type params. Therefore we need to do something ourselves or otherwise this
+ // expandee will forever remaing not expanded (see SI-5692). A traditional way out of this conundrum
+ // is to call `instantiate` and let the inferencer try to find the way out. It works for simple cases,
+ // but sometimes, if the inferencer lacks information, it will be forced to approximate. This prevents
+ // an important class of macros, fundep materializers, from working, which I perceive is a problem we need to solve.
+ // For details see SI-7470.
+ val shouldInstantiate = typer.context.undetparams.nonEmpty && !mode.inPolyMode
+ if (shouldInstantiate) typer.instantiatePossiblyExpectingUnit(delayed, mode, pt)
+ else delayed
+ }
}
expander(expandee)
}
diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
index 5cce4865cc..5b1f7160b7 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
@@ -1233,29 +1233,21 @@ trait Typers extends Adaptations with Tags {
}
if (tree.isType)
adaptType()
+ else if (mode.typingExprNotFun && treeInfo.isMacroApplication(tree))
+ macroExpandApply(this, tree, mode, pt)
else if (mode.typingPatternFun)
adaptConstrPattern()
else if (shouldInsertApply(tree))
insertApply()
else if (hasUndetsInMonoMode) { // (9)
assert(!context.inTypeConstructor, context) //@M
- if (mode.typingExprNotFun && pt.typeSymbol == UnitClass)
- instantiateExpectingUnit(tree, mode)
- else
- instantiate(tree, mode, pt)
+ instantiatePossiblyExpectingUnit(tree, mode, pt)
}
else if (tree.tpe <:< pt)
tree
else
fallbackAfterVanillaAdapt()
}
- def expandMacroAndVanillaAdapt(): Tree = {
- if (mode.typingExprNotFun && treeInfo.isMacroApplication(tree)) {
- val tree1 = macroExpandApply(this, tree, mode, pt)
- if (tree == tree1) vanillaAdapt(tree) else tree1
- }
- else vanillaAdapt(tree)
- }
// begin adapt
tree.tpe match {
@@ -1294,7 +1286,7 @@ trait Typers extends Adaptations with Tags {
case mt: MethodType if mode.typingExprNotFunNotLhs && !hasUndetsInMonoMode && !treeInfo.isMacroApplicationOrBlock(tree) =>
instantiateToMethodType(mt)
case _ =>
- expandMacroAndVanillaAdapt()
+ vanillaAdapt(tree)
}
}
@@ -1315,6 +1307,13 @@ trait Typers extends Adaptations with Tags {
}
}
+ def instantiatePossiblyExpectingUnit(tree: Tree, mode: Mode, pt: Type): Tree = {
+ if (mode.typingExprNotFun && pt.typeSymbol == UnitClass)
+ instantiateExpectingUnit(tree, mode)
+ else
+ instantiate(tree, mode, pt)
+ }
+
private def isAdaptableWithView(qual: Tree) = {
val qtpe = qual.tpe.widen
( !isPastTyper
diff --git a/src/compiler/scala/tools/nsc/util/ClassPath.scala b/src/compiler/scala/tools/nsc/util/ClassPath.scala
index 7f9b81e1ec..536a281e6c 100644
--- a/src/compiler/scala/tools/nsc/util/ClassPath.scala
+++ b/src/compiler/scala/tools/nsc/util/ClassPath.scala
@@ -211,6 +211,8 @@ abstract class ClassPath[T] {
def validPackage(name: String) = (name != "META-INF") && (name != "") && (name.charAt(0) != '.')
def validSourceFile(name: String) = endsScala(name) || endsJava(name)
+ def isEmptyOfClassfiles: Boolean = classes.isEmpty && packages.forall(_.isEmptyOfClassfiles)
+
/**
* Find a ClassRep given a class name of the form "package.subpackage.ClassName".
* Does not support nested classes on .NET
diff --git a/src/compiler/scala/tools/reflect/ToolBoxFactory.scala b/src/compiler/scala/tools/reflect/ToolBoxFactory.scala
index 602982337f..59408096a3 100644
--- a/src/compiler/scala/tools/reflect/ToolBoxFactory.scala
+++ b/src/compiler/scala/tools/reflect/ToolBoxFactory.scala
@@ -180,16 +180,7 @@ abstract class ToolBoxFactory[U <: JavaUniverse](val u: U) { factorySelf =>
transformDuringTyper(tree, withImplicitViewsDisabled = false, withMacrosDisabled = withMacrosDisabled)(
(currentTyper, tree) => {
trace("inferring implicit %s (macros = %s): ".format(if (isView) "view" else "value", !withMacrosDisabled))(showAttributed(pt, true, true, settings.Yshowsymkinds.value))
- val context = currentTyper.context
- val result = analyzer.inferImplicit(tree, pt, reportAmbiguous = true, isView = isView, context = context, saveAmbiguousDivergent = !silent, pos = pos)
- if (result.isFailure) {
- // @H: what's the point of tracing an empty tree?
- trace("implicit search has failed. to find out the reason, turn on -Xlog-implicits: ")(result.tree)
- context.firstError foreach { err =>
- throw ToolBoxError("reflective implicit search has failed: %s".format(err.errMsg))
- }
- }
- result.tree
+ analyzer.inferImplicit(tree, pt, isView, currentTyper.context, silent, withMacrosDisabled, pos, (pos, msg) => throw ToolBoxError(msg))
})
def compile(expr0: Tree): () => Any = {
diff --git a/src/library/scala/collection/generic/GenericTraversableTemplate.scala b/src/library/scala/collection/generic/GenericTraversableTemplate.scala
index adf4319bb8..cd48cd23f4 100644
--- a/src/library/scala/collection/generic/GenericTraversableTemplate.scala
+++ b/src/library/scala/collection/generic/GenericTraversableTemplate.scala
@@ -74,11 +74,20 @@ trait GenericTraversableTemplate[+A, +CC[X] <: GenTraversable[X]] extends HasNew
/** Converts this $coll of pairs into two collections of the first and second
* half of each pair.
*
+ * {{{
+ * val xs = $Coll(
+ * (1, "one"),
+ * (2, "two"),
+ * (3, "three")).unzip
+ * // xs == ($Coll(1, 2, 3),
+ * // $Coll(one, two, three))
+ * }}}
+ *
* @tparam A1 the type of the first half of the element pairs
* @tparam A2 the type of the second half of the element pairs
* @param asPair an implicit conversion which asserts that the element type
* of this $coll is a pair.
- * @return a pair ${coll}s, containing the first, respectively second
+ * @return a pair of ${coll}s, containing the first, respectively second
* half of each element pair of this $coll.
*/
def unzip[A1, A2](implicit asPair: A => (A1, A2)): (CC[A1], CC[A2]) = {
@@ -95,12 +104,22 @@ trait GenericTraversableTemplate[+A, +CC[X] <: GenTraversable[X]] extends HasNew
/** Converts this $coll of triples into three collections of the first, second,
* and third element of each triple.
*
+ * {{{
+ * val xs = $Coll(
+ * (1, "one", '1'),
+ * (2, "two", '2'),
+ * (3, "three", '3')).unzip3
+ * // xs == ($Coll(1, 2, 3),
+ * // $Coll(one, two, three),
+ * // $Coll(1, 2, 3))
+ * }}}
+ *
* @tparam A1 the type of the first member of the element triples
* @tparam A2 the type of the second member of the element triples
* @tparam A3 the type of the third member of the element triples
* @param asTriple an implicit conversion which asserts that the element type
* of this $coll is a triple.
- * @return a triple ${coll}s, containing the first, second, respectively
+ * @return a triple of ${coll}s, containing the first, second, respectively
* third member of each element triple of this $coll.
*/
def unzip3[A1, A2, A3](implicit asTriple: A => (A1, A2, A3)): (CC[A1], CC[A2], CC[A3]) = {
@@ -134,10 +153,16 @@ trait GenericTraversableTemplate[+A, +CC[X] <: GenTraversable[X]] extends HasNew
* static type of $coll. For example:
*
* {{{
- * val xs = List(Set(1, 2, 3), Set(1, 2, 3))
+ * val xs = List(
+ * Set(1, 2, 3),
+ * Set(1, 2, 3)
+ * ).flatten
* // xs == List(1, 2, 3, 1, 2, 3)
*
- * val ys = Set(List(1, 2, 3), List(3, 2, 1))
+ * val ys = Set(
+ * List(1, 2, 3),
+ * List(3, 2, 1)
+ * ).flatten
* // ys == Set(1, 2, 3)
* }}}
*/
@@ -151,6 +176,27 @@ trait GenericTraversableTemplate[+A, +CC[X] <: GenTraversable[X]] extends HasNew
/** Transposes this $coll of traversable collections into
* a $coll of ${coll}s.
*
+ * The resulting collection's type will be guided by the
+ * static type of $coll. For example:
+ *
+ * {{{
+ * val xs = List(
+ * Set(1, 2, 3),
+ * Set(4, 5, 6)).transpose
+ * // xs == List(
+ * // List(1, 4),
+ * // List(2, 5),
+ * // List(3, 6))
+ *
+ * val ys = Vector(
+ * List(1, 2, 3),
+ * List(4, 5, 6)).transpose
+ * // ys == Vector(
+ * // Vector(1, 4),
+ * // Vector(2, 5),
+ * // Vector(3, 6))
+ * }}}
+ *
* @tparam B the type of the elements of each traversable collection.
* @param asTraversable an implicit conversion which asserts that the
* element type of this $coll is a `Traversable`.
diff --git a/src/library/scala/collection/immutable/Range.scala b/src/library/scala/collection/immutable/Range.scala
index 4c424b31f4..09f8143b55 100644
--- a/src/library/scala/collection/immutable/Range.scala
+++ b/src/library/scala/collection/immutable/Range.scala
@@ -82,14 +82,14 @@ extends scala.collection.AbstractSeq[Int]
override def min[A1 >: Int](implicit ord: Ordering[A1]): Int =
if (ord eq Ordering.Int) {
- if (step > 0) start
+ if (step > 0) head
else last
} else super.min(ord)
override def max[A1 >: Int](implicit ord: Ordering[A1]): Int =
if (ord eq Ordering.Int) {
if (step > 0) last
- else start
+ else head
} else super.max(ord)
protected def copy(start: Int, end: Int, step: Int): Range = new Range(start, end, step)
diff --git a/src/library/scala/concurrent/Future.scala b/src/library/scala/concurrent/Future.scala
index 95b393dd0e..c444050e3d 100644
--- a/src/library/scala/concurrent/Future.scala
+++ b/src/library/scala/concurrent/Future.scala
@@ -71,7 +71,7 @@ import scala.reflect.ClassTag
* val g = future { 3 }
* val h = for {
* x: Int <- f // returns Future(5)
- * y: Int <- g // returns Future(5)
+ * y: Int <- g // returns Future(3)
* } yield x + y
* }}}
*
diff --git a/src/library/scala/concurrent/FutureTaskRunner.scala b/src/library/scala/concurrent/FutureTaskRunner.scala
index 9e27ce65b9..089e67cedd 100644
--- a/src/library/scala/concurrent/FutureTaskRunner.scala
+++ b/src/library/scala/concurrent/FutureTaskRunner.scala
@@ -16,7 +16,7 @@ import scala.language.{implicitConversions, higherKinds}
* @author Philipp Haller
*/
@deprecated("Use `ExecutionContext` instead.", "2.10.0")
-trait FutureTaskRunner extends TaskRunner {
+private[scala] trait FutureTaskRunner extends TaskRunner {
/** The type of the futures that the underlying task runner supports.
*/
diff --git a/src/library/scala/concurrent/ManagedBlocker.scala b/src/library/scala/concurrent/ManagedBlocker.scala
index 7b2966c663..b5a6e21893 100644
--- a/src/library/scala/concurrent/ManagedBlocker.scala
+++ b/src/library/scala/concurrent/ManagedBlocker.scala
@@ -13,7 +13,7 @@ package scala.concurrent
* @author Philipp Haller
*/
@deprecated("Use `blocking` instead.", "2.10.0")
-trait ManagedBlocker {
+private[scala] trait ManagedBlocker {
/**
* Possibly blocks the current thread, for example waiting for
diff --git a/src/library/scala/concurrent/SyncVar.scala b/src/library/scala/concurrent/SyncVar.scala
index 6d25ffe19e..d22471ac0f 100644
--- a/src/library/scala/concurrent/SyncVar.scala
+++ b/src/library/scala/concurrent/SyncVar.scala
@@ -79,7 +79,7 @@ class SyncVar[A] {
// whether or not the SyncVar is already defined. So, set has been
// deprecated in order to eventually be able to make "setting" private
@deprecated("Use `put` instead, as `set` is potentionally error-prone", "2.10.0")
- def set(x: A): Unit = setVal(x)
+ private[scala] def set(x: A): Unit = setVal(x)
/** Places a value in the SyncVar. If the SyncVar already has a stored value,
* it waits until another thread takes it */
@@ -98,7 +98,7 @@ class SyncVar[A] {
// whether or not the SyncVar is already defined. So, unset has been
// deprecated in order to eventually be able to make "unsetting" private
@deprecated("Use `take` instead, as `unset` is potentionally error-prone", "2.10.0")
- def unset(): Unit = synchronized {
+ private[scala] def unset(): Unit = synchronized {
isDefined = false
value = None
notifyAll()
diff --git a/src/library/scala/concurrent/TaskRunner.scala b/src/library/scala/concurrent/TaskRunner.scala
index a939a3f070..98c212d9fa 100644
--- a/src/library/scala/concurrent/TaskRunner.scala
+++ b/src/library/scala/concurrent/TaskRunner.scala
@@ -15,7 +15,7 @@ import scala.language.{higherKinds, implicitConversions}
* @author Philipp Haller
*/
@deprecated("Use `ExecutionContext` instead.", "2.10.0")
-trait TaskRunner {
+private[scala] trait TaskRunner {
type Task[T]
diff --git a/src/library/scala/concurrent/ThreadPoolRunner.scala b/src/library/scala/concurrent/ThreadPoolRunner.scala
index afa14ed2fa..7784681f71 100644
--- a/src/library/scala/concurrent/ThreadPoolRunner.scala
+++ b/src/library/scala/concurrent/ThreadPoolRunner.scala
@@ -17,7 +17,7 @@ import scala.language.implicitConversions
* @author Philipp Haller
*/
@deprecated("Use `ExecutionContext` instead.", "2.10.0")
-trait ThreadPoolRunner extends FutureTaskRunner {
+private[scala] trait ThreadPoolRunner extends FutureTaskRunner {
type Task[T] = Callable[T] with Runnable
type Future[T] = java.util.concurrent.Future[T]
diff --git a/src/library/scala/util/MurmurHash.scala b/src/library/scala/util/MurmurHash.scala
deleted file mode 100644
index 7d1c57ef77..0000000000
--- a/src/library/scala/util/MurmurHash.scala
+++ /dev/null
@@ -1,198 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2003-2013, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-\* */
-
-package scala
-package util
-
-/** An implementation of Austin Appleby's MurmurHash 3.0 algorithm
- * (32 bit version); reference: http://code.google.com/p/smhasher
- *
- * This is the hash used by collections and case classes (including
- * tuples).
- *
- * @author Rex Kerr
- * @version 2.9
- * @since 2.9
- */
-
-import java.lang.Integer.{ rotateLeft => rotl }
-import scala.collection.Iterator
-
-/** A class designed to generate well-distributed non-cryptographic
- * hashes. It is designed to be passed to a collection's foreach method,
- * or can take individual hash values with append. Its own hash code is
- * set equal to the hash code of whatever it is hashing.
- */
-@deprecated("Use the object MurmurHash3 instead.", "2.10.0")
-class MurmurHash[@specialized(Int,Long,Float,Double) T](seed: Int) extends (T => Unit) {
- import MurmurHash._
-
- private var h = startHash(seed)
- private var c = hiddenMagicA
- private var k = hiddenMagicB
- private var hashed = false
- private var hashvalue = h
-
- /** Begin a new hash using the same seed. */
- def reset() {
- h = startHash(seed)
- c = hiddenMagicA
- k = hiddenMagicB
- hashed = false
- }
-
- /** Incorporate the hash value of one item. */
- def apply(t: T) {
- h = extendHash(h,t.##,c,k)
- c = nextMagicA(c)
- k = nextMagicB(k)
- hashed = false
- }
-
- /** Incorporate a known hash value. */
- def append(i: Int) {
- h = extendHash(h,i,c,k)
- c = nextMagicA(c)
- k = nextMagicB(k)
- hashed = false
- }
-
- /** Retrieve the hash value */
- def hash = {
- if (!hashed) {
- hashvalue = finalizeHash(h)
- hashed = true
- }
- hashvalue
- }
- override def hashCode = hash
-}
-
-/** An object designed to generate well-distributed non-cryptographic
- * hashes. It is designed to hash a collection of integers; along with
- * the integers to hash, it generates two magic streams of integers to
- * increase the distribution of repetitive input sequences. Thus,
- * three methods need to be called at each step (to start and to
- * incorporate a new integer) to update the values. Only one method
- * needs to be called to finalize the hash.
- */
-@deprecated("Use the object MurmurHash3 instead.", "2.10.0")
-object MurmurHash {
- // Magic values used for MurmurHash's 32 bit hash.
- // Don't change these without consulting a hashing expert!
- final private val visibleMagic = 0x971e137b
- final private val hiddenMagicA = 0x95543787
- final private val hiddenMagicB = 0x2ad7eb25
- final private val visibleMixer = 0x52dce729
- final private val hiddenMixerA = 0x7b7d159c
- final private val hiddenMixerB = 0x6bce6396
- final private val finalMixer1 = 0x85ebca6b
- final private val finalMixer2 = 0xc2b2ae35
-
- // Arbitrary values used for hashing certain classes
- final private val seedString = 0xf7ca7fd2
- final private val seedArray = 0x3c074a61
-
- /** The first 23 magic integers from the first stream are stored here */
- val storedMagicA =
- Iterator.iterate(hiddenMagicA)(nextMagicA).take(23).toArray
-
- /** The first 23 magic integers from the second stream are stored here */
- val storedMagicB =
- Iterator.iterate(hiddenMagicB)(nextMagicB).take(23).toArray
-
- /** Begin a new hash with a seed value. */
- def startHash(seed: Int) = seed ^ visibleMagic
-
- /** The initial magic integers in the first stream. */
- def startMagicA = hiddenMagicA
-
- /** The initial magic integer in the second stream. */
- def startMagicB = hiddenMagicB
-
- /** Incorporates a new value into an existing hash.
- *
- * @param hash the prior hash value
- * @param value the new value to incorporate
- * @param magicA a magic integer from the stream
- * @param magicB a magic integer from a different stream
- * @return the updated hash value
- */
- def extendHash(hash: Int, value: Int, magicA: Int, magicB: Int) = {
- (hash ^ rotl(value*magicA,11)*magicB)*3 + visibleMixer
- }
-
- /** Given a magic integer from the first stream, compute the next */
- def nextMagicA(magicA: Int) = magicA*5 + hiddenMixerA
-
- /** Given a magic integer from the second stream, compute the next */
- def nextMagicB(magicB: Int) = magicB*5 + hiddenMixerB
-
- /** Once all hashes have been incorporated, this performs a final mixing */
- def finalizeHash(hash: Int) = {
- var i = (hash ^ (hash>>>16))
- i *= finalMixer1
- i ^= (i >>> 13)
- i *= finalMixer2
- i ^= (i >>> 16)
- i
- }
-
- /** Compute a high-quality hash of an array */
- def arrayHash[@specialized T](a: Array[T]) = {
- var h = startHash(a.length * seedArray)
- var c = hiddenMagicA
- var k = hiddenMagicB
- var j = 0
- while (j < a.length) {
- h = extendHash(h, a(j).##, c, k)
- c = nextMagicA(c)
- k = nextMagicB(k)
- j += 1
- }
- finalizeHash(h)
- }
-
- /** Compute a high-quality hash of a string */
- def stringHash(s: String) = {
- var h = startHash(s.length * seedString)
- var c = hiddenMagicA
- var k = hiddenMagicB
- var j = 0
- while (j+1 < s.length) {
- val i = (s.charAt(j)<<16) + s.charAt(j+1)
- h = extendHash(h,i,c,k)
- c = nextMagicA(c)
- k = nextMagicB(k)
- j += 2
- }
- if (j < s.length) h = extendHash(h,s.charAt(j),c,k)
- finalizeHash(h)
- }
-
- /** Compute a hash that is symmetric in its arguments--that is,
- * where the order of appearance of elements does not matter.
- * This is useful for hashing sets, for example.
- */
- def symmetricHash[T](xs: scala.collection.TraversableOnce[T], seed: Int) = {
- var a,b,n = 0
- var c = 1
- xs.seq.foreach(i => {
- val h = i.##
- a += h
- b ^= h
- if (h != 0) c *= h
- n += 1
- })
- var h = startHash(seed * n)
- h = extendHash(h, a, storedMagicA(0), storedMagicB(0))
- h = extendHash(h, b, storedMagicA(1), storedMagicB(1))
- h = extendHash(h, c, storedMagicA(2), storedMagicB(2))
- finalizeHash(h)
- }
-}
diff --git a/src/library/scala/util/hashing/MurmurHash3.scala b/src/library/scala/util/hashing/MurmurHash3.scala
index af0b12d8ba..c38d0f4da5 100644
--- a/src/library/scala/util/hashing/MurmurHash3.scala
+++ b/src/library/scala/util/hashing/MurmurHash3.scala
@@ -275,12 +275,4 @@ object MurmurHash3 extends MurmurHash3 {
finalizeHash(h, n)
}
*/
-
- @deprecated("Use unorderedHash", "2.10.0")
- final def symmetricHash[T](xs: scala.collection.GenTraversableOnce[T], seed: Int = symmetricSeed): Int =
- unorderedHash(xs.seq, seed)
-
- @deprecated("Use orderedHash", "2.10.0")
- final def traversableHash[T](xs: scala.collection.GenTraversableOnce[T], seed: Int = traversableSeed): Int =
- orderedHash(xs.seq, seed)
}
diff --git a/src/library/scala/util/logging/ConsoleLogger.scala b/src/library/scala/util/logging/ConsoleLogger.scala
deleted file mode 100644
index 5e3d957534..0000000000
--- a/src/library/scala/util/logging/ConsoleLogger.scala
+++ /dev/null
@@ -1,27 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2003-2013, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-\* */
-
-
-
-package scala
-package util.logging
-
-/**
- * The trait `ConsoleLogger` is mixed into a concrete class who
- * has class `Logged` among its base classes.
- *
- * @author Burak Emir
- * @version 1.0
- */
-@deprecated("This class will be removed.", "2.10.0")
-trait ConsoleLogger extends Logged {
-
- /** logs argument to Console using [[scala.Console.println]]
- */
- override def log(msg: String): Unit = Console.println(msg)
-}
diff --git a/src/library/scala/util/logging/Logged.scala b/src/library/scala/util/logging/Logged.scala
deleted file mode 100644
index 1fc12588db..0000000000
--- a/src/library/scala/util/logging/Logged.scala
+++ /dev/null
@@ -1,34 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2003-2013, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-\* */
-
-package scala
-package util.logging
-
-/** Mixing in Logged indicates that a class provides support for logging.
- *
- * For instance:
- * {{{
- * // The developer of the library writes:
- * class MyClass extends Logged {
- * // do stuff, call log
- * }
- *
- * // The user of the library instantiates:
- * val x = new MyClass() with ConsoleLogger
- * }}}
- * and the logging is sent to the [[scala.util.logging.ConsoleLogger]] object.
- */
-@deprecated("This class will be removed.", "2.10.0")
-trait Logged {
- /** This method should log the message given as argument somewhere
- * as a side-effect.
- *
- * @param msg message to be logged
- */
- def log(msg: String): Unit = {}
-}
diff --git a/src/library/scala/util/matching/Regex.scala b/src/library/scala/util/matching/Regex.scala
index 8d135ecf02..8eac0a2520 100644
--- a/src/library/scala/util/matching/Regex.scala
+++ b/src/library/scala/util/matching/Regex.scala
@@ -205,6 +205,20 @@ class Regex private[matching](val pattern: Pattern, groupNames: String*) extends
else if (m.matcher.pattern == this.pattern) Some(1 to m.groupCount map m.group)
else unapplySeq(m.matched)
+ /** Tries to match target.
+ * @param target The string to match
+ * @return The matches
+ */
+ @deprecated("Extracting a match result from anything but a CharSequence or Match is deprecated", "2.11.0")
+ def unapplySeq(target: Any): Option[List[String]] = target match {
+ case s: CharSequence =>
+ val m = pattern matcher s
+ if (runMatcher(m)) Some((1 to m.groupCount).toList map m.group)
+ else None
+ case m: Match => unapplySeq(m.matched)
+ case _ => None
+ }
+
// @see UnanchoredRegex
protected def runMatcher(m: Matcher) = m.matches()
diff --git a/src/library/scala/util/parsing/ast/AbstractSyntax.scala b/src/library/scala/util/parsing/ast/AbstractSyntax.scala
deleted file mode 100644
index 3a2e990036..0000000000
--- a/src/library/scala/util/parsing/ast/AbstractSyntax.scala
+++ /dev/null
@@ -1,33 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2006-2013, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-\* */
-
-package scala
-package util.parsing.ast
-
-import scala.util.parsing.input.Positional
-
-/** This component provides the core abstractions for representing an Abstract Syntax Tree
- *
- * @author Adriaan Moors
- */
-@deprecated("This class will be removed", "2.10.0")
-trait AbstractSyntax {
- /** The base class for elements of the abstract syntax tree.
- */
- trait Element extends Positional
-
- /** The base class for elements in the AST that represent names [[scala.util.parsing.ast.Binders]].
- */
- trait NameElement extends Element {
- def name: String
- override def equals(that: Any): Boolean = that match {
- case n: NameElement => n.name == name
- case _ => false
- }
- }
-}
diff --git a/src/library/scala/util/parsing/ast/Binders.scala b/src/library/scala/util/parsing/ast/Binders.scala
deleted file mode 100644
index 990c603ac5..0000000000
--- a/src/library/scala/util/parsing/ast/Binders.scala
+++ /dev/null
@@ -1,348 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2006-2013, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-\* */
-
-package scala
-package util.parsing.ast
-
-import scala.collection.AbstractIterable
-import scala.collection.mutable
-import scala.language.implicitConversions
-
-//DISCLAIMER: this code is highly experimental!
-
- // TODO: avoid clashes when substituting
- // TODO: check binders in the same scope are distinct
-
-/** This trait provides the core ''Scrap-Your-Boilerplate'' abstractions as
- * well as implementations for common datatypes.
- *
- * (Based on Ralf Lämmel's [[http://homepages.cwi.nl/~ralf/syb3/ SYB papers]].)
- *
- * @author Adriaan Moors
- */
-@deprecated("This class will be removed", "2.10.0")
-trait Mappable {
- trait Mapper { def apply[T <% Mappable[T]](x: T): T } /* TODO: having type `Forall T. T => T` is too strict:
- sometimes we want to allow `Forall T >: precision. T => T` for some type `precision`, so that,
- beneath a certain threshold, we have some leeway.
- concretely: to use gmap for substitution, we simply require that ast nodes are mapped to ast nodes,
- we can't require that the type is preserved precisely: a Name may map to e.g., a MethodCall
- */
-
- trait Mappable[T] {
- // one-layer traversal
- def gmap(f: Mapper): T
- // everywhere f x = f (gmapT (everywhere f) x)
- def everywhere(f: Mapper)(implicit c: T => Mappable[T]): T =
- f(gmap(new Mapper { def apply[T <% Mappable[T]](x: T): T = x.everywhere(f)}))
- }
-
- implicit def StringIsMappable(s: String): Mappable[String] =
- new Mappable[String] {
- def gmap(f: Mapper): String = f(s)
- }
-
- implicit def ListIsMappable[t <% Mappable[t]](xs: List[t]): Mappable[List[t]] =
- new Mappable[List[t]] {
- def gmap(f: Mapper): List[t] = (for (x <- xs) yield f(x)).toList
- }
-
- implicit def OptionIsMappable[t <% Mappable[t]](xs: Option[t]): Mappable[Option[t]] =
- new Mappable[Option[t]] {
- def gmap(f: Mapper): Option[t] = (for (x <- xs) yield f(x))
- }
-}
-
-/** This component provides functionality for enforcing variable binding
- * during parse-time.
- *
- * When parsing simple languages, like Featherweight Scala, these parser
- * combinators will fully enforce the binding discipline. When names are
- * allowed to be left unqualified, these mechanisms would have to be
- * complemented by an extra phase that resolves names that couldn't be
- * resolved using the naive binding rules. (Maybe some machinery to
- * model `implicit` binders (e.g., `this` and imported qualifiers)
- * and selection on a binder will suffice?)
- *
- * @author Adriaan Moors
- */
-trait Binders extends AbstractSyntax with Mappable {
- /** A `Scope` keeps track of one or more syntactic elements that represent bound names.
- * The elements it contains share the same scope and must all be distinct, as determined by `==`.
- *
- * A `NameElement` `n` in the AST that is conceptually bound by a `Scope` `s`, is replaced by a
- * `BoundElement(n, s)`. (For example, in `val x:Int=x+1`, the first `x` is modelled by a
- * Scope `s` that contains `x` and the second `x` is represented by a `BoundElement(x, s)`)
- * The term (`x+1`) in scope of the Scope becomes an `UnderBinder(s, x+1)`.
- *
- * A `NameElement` `n` is bound by a `Scope` `s` if it is wrapped as a `BoundElement(n, s)`, and
- * `s` has a binder element that is semantically equal (`equals` or `==`) to `n`.
- *
- * A `Scope` is represented textually by its list of binder elements, followed by the scope's `id`.
- * For example: `[x, y]!1` represents the scope with `id` `1` and binder elements `x` and `y`.
- * (`id` is solely used for this textual representation.)
- */
- class Scope[binderType <: NameElement] extends AbstractIterable[binderType] with Iterable[binderType] {
- private val substitution: mutable.Map[binderType, Element] =
- new mutable.LinkedHashMap[binderType, Element] // a LinkedHashMap is ordered by insertion order -- important!
-
- /** Returns a unique number identifying this Scope (only used for representation purposes). */
- val id: Int = _Binder.genId
-
- /** Returns the binders in this scope.
- * For a typical let-binding, this is just the variable name. For an argument list to a method body,
- * there is one binder per formal argument.
- */
- def iterator = substitution.keysIterator
-
- /** Return the `i`th binder in this scope. */
- def apply(i: Int): binderType = this.iterator.toList(i)
-
- /** Returns true if this container has a binder equal (as determined by `==`) to `b`. */
- def binds(b: binderType): Boolean = substitution.contains(b)
-
- def indexFor(b: binderType): Option[Int] = {
- val iter = this.iterator.zipWithIndex
- for ((that, count) <- iter) {
- if (that.name == b.name) // TODO: why do name equals and structural equals differ?
- return Some(count + 1)
- else
- Console.println(that+"!="+b)
- }
-
- None
- }
-
- /** Adds a new binder, for example the variable name in a local variable declaration.
- *
- * @param b a new binder that is distinct from the existing binders in this scope,
- * and shares their conceptual scope. `canAddBinder(b)` must hold.
- * @return `binds(b)` and `getElementFor(b) eq b` will hold.
- */
- def addBinder(b: binderType) { substitution += Pair(b, b) }
-
- // TODO: strengthen this condition so that no binders may be added after this scope has been
- // linked to its `UnderBinder` (i.e., while parsing, BoundElements may be added to the Scope
- // associated to the UnderBinder, but after that, no changes are allowed, except for substitution)?
- /** `canAddElement` indicates whether `b` may be added to this scope.
- *
- *
- * @return true if `b` had not been added yet
- */
- def canAddBinder(b: binderType): Boolean = !binds(b)
-
- /** ''Replaces'' the bound occurrences of a contained binder by their new value.
- * The bound occurrences of `b` are not actually replaced; the scope keeps track
- * of a substitution that maps every binder to its current value. Since a `BoundElement` is
- * a proxy for the element it is bound to by its binder, `substitute` may thus be thought of
- * as replacing all the bound occurrences of the given binder `b` by their new value `value`.
- *
- * @param b the binder whose bound occurrences should be given a new value. `binds(b)` must hold.
- * @param value the new value for the bound occurrences of `b`
- * @return `getElementFor(b) eq value` will hold.
- */
- def substitute(b: binderType, value: Element): Unit = substitution(b) = value
-
- /** Returns the current value for the bound occurrences of `b`.
- *
- * @param b the contained binder whose current value should be returned `binds(b)` must hold.
- */
- def getElementFor(b: binderType): Element = substitution(b)
-
- override def toString: String = this.iterator.toList.mkString("[",", ","]")+"!"+id // TODO show substitution?
-
- /** Returns a list of strings that represent the binder elements, each tagged with this scope's id. */
- def bindersToString: List[String] = (for(b <- this.iterator) yield b+"!"+id).toList
-
- /** Return a new inheriting scope that won't check whether binding is respected until the scope is left (so as to support forward references). */
- def allowForwardRef: Scope[binderType] = this // TODO
-
- /** Return a nested scope -- binders entered into it won't be visible in this scope, but if this scope allows forward references,
- * the binding in the returned scope also does, and thus the check that all variables are bound is deferred until this scope is left.
- */
- def nested: Scope[binderType] = this // TODO
-
- def onEnter() {}
- def onLeft() {}
- }
-
-
- trait BindingSensitive {
- // would like to specify this as one method:
- // def alpha_==[t <: NameElement](other: BoundElement[t]): Boolean
- // def alpha_==[bt <: binderType, st <: elementT](other: UnderBinder[bt, st]): Boolean
- }
-
- /** A `BoundElement` is bound in a certain scope `scope`, which keeps track of the actual element that
- * `el` stands for.
- *
- * A `BoundElement` is represented textually by its bound element, followed by its scope's `id`.
- * For example: `x@1` represents the variable `x` that is bound in the scope with `id` `1`.
- *
- * @note `scope.binds(el)` holds before and after.
- */
- case class BoundElement[boundElement <: NameElement](el: boundElement, scope: Scope[boundElement]) extends NameElement with Proxy with BindingSensitive {
- /** Returns the element this `BoundElement` stands for.
- * The `Proxy` trait ensures `equals`, `hashCode` and `toString` are forwarded to
- * the result of this method.
- */
- def self: Element = scope.getElementFor(el)
-
- def name = self.asInstanceOf[NameElement].name // TODO: this is only safe when substituted to a NameElement, which certainly isn't required -- I want dynamic inheritance! :)
-
- // decorate element's representation with the id of the scope it's bound in
- override def toString: String = super.toString+"@"+scope.id
-
- def alpha_==[t <: NameElement](other: BoundElement[t]): Boolean = scope.indexFor(el) == other.scope.indexFor(other.el)
- }
-
- /** A variable that escaped its scope (i.e., a free variable) -- we don't deal very well with these yet. */
- class UnboundElement[N <: NameElement](private val el: N) extends NameElement {
- def name = el.name+"@??"
- }
-
- // this is useless, as Element is a supertype of BoundElement --> the coercion will never be inferred
- // if we knew a more specific type for the element that the bound element represents, this could make sense
- // implicit def BoundElementProxy[t <: NameElement](e: BoundElement[t]): Element = e.self
-
- /** Represents an element with variables that are bound in a certain scope. */
- class UnderBinder[binderType <: NameElement, elementT <% Mappable[elementT]](val scope: Scope[binderType], private[Binders] val element: elementT) extends Element with BindingSensitive {
- override def toString: String = "(" + scope.toString + ") in { "+element.toString+" }"
-
- /** Alpha-equivalence -- TODO
- * Returns true if the `element` of the `other` `UnderBinder` is equal to this `element` up to alpha-conversion.
- *
- * That is, regular equality is used for all elements but `BoundElement`s: such an element is
- * equal to a `BoundElement` in `other` if their binders are equal. Binders are equal if they
- * are at the same index in their respective scope.
- *
- * Example:
- * {{{
- * UnderBinder([x, y]!1, x@1) alpha_== UnderBinder([a, b]!2, a@2)
- * ! (UnderBinder([x, y]!1, y@1) alpha_== UnderBinder([a, b]!2, a@2))
- * }}}
- */
- /*def alpha_==[bt <: binderType, st <: elementT](other: UnderBinder[bt, st]): Boolean = {
- var result = true
-
- // TODO: generic zip or gmap2
- element.gmap2(other.element, new Mapper2 {
- def apply[s <% Mappable[s], t <% Mappable[t]](x :{s, t}): {s, t} = x match {
- case {be1: BoundElement[_], be2: BoundElement[_]} => result == result && be1.alpha_==(be2) // monadic gmap (cheating using state directly)
- case {ub1: UnderBinder[_, _], ub2: UnderBinder[_, _]} => result == result && be1.alpha_==(be2)
- case {a, b} => result == result && a.equals(b)
- }; x
- })
- }*/
-
- def cloneElementWithSubst(subst: Map[NameElement, NameElement]) = element.gmap(new Mapper { def apply[t <% Mappable[t]](x :t): t = x match{
- case substable: NameElement if subst.contains(substable) => subst.get(substable).asInstanceOf[t] // TODO: wrong... substitution is not (necessarily) the identity function
- //Console.println("substed: "+substable+"-> "+subst.get(substable)+")");
- case x => x // Console.println("subst: "+x+"(keys: "+subst.keys+")");x
- }})
-
- // TODO
- def cloneElementNoBoundElements = element.gmap(new Mapper { def apply[t <% Mappable[t]](x :t): t = x match{
- case BoundElement(el, _) => new UnboundElement(el).asInstanceOf[t] // TODO: precision stuff
- case x => x
- }})
-
- def extract: elementT = cloneElementNoBoundElements
- def extract(subst: Map[NameElement, NameElement]): elementT = cloneElementWithSubst(subst)
-
- /** Get a string representation of element, normally we don't allow direct access to element, but just getting a string representation is ok. */
- def elementToString: String = element.toString
- }
-
- //SYB type class instances
- implicit def UnderBinderIsMappable[bt <: NameElement <% Mappable[bt], st <% Mappable[st]](ub: UnderBinder[bt, st]): Mappable[UnderBinder[bt, st]] =
- new Mappable[UnderBinder[bt, st]] {
- def gmap(f: Mapper): UnderBinder[bt, st] = UnderBinder(f(ub.scope), f(ub.element))
- }
-
- implicit def ScopeIsMappable[bt <: NameElement <% Mappable[bt]](scope: Scope[bt]): Mappable[Scope[bt]] =
- new Mappable[Scope[bt]] {
- def gmap(f: Mapper): Scope[bt] = { val newScope = new Scope[bt]()
- for(b <- scope) newScope.addBinder(f(b))
- newScope
- }
- }
-
- implicit def NameElementIsMappable(self: NameElement): Mappable[NameElement] = new Mappable[NameElement] {
- def gmap(f: Mapper): NameElement = self match {
- case BoundElement(el, scope) => BoundElement(f(el), f(scope))
- case _ => UserNameElementIsMappable(self).gmap(f)
- }
- }
-
- def UserNameElementIsMappable[t <: NameElement](self: t): Mappable[t]
-
- object UnderBinder {
- def apply[binderType <: NameElement, elementT <% Mappable[elementT]](scope: Scope[binderType], element: elementT) = new UnderBinder(scope, element)
- def unit[bt <: NameElement, elementT <% Mappable[elementT]](x: elementT) = UnderBinder(new Scope[bt](), x)
- }
-
- /** If a list of `UnderBinder`s all have the same scope, they can be turned in to an `UnderBinder`
- * containing a list of the elements in the original `UnderBinder`.
- *
- * The name `sequence` comes from the fact that this method's type is equal to the type of monadic sequence.
- *
- * @note `!orig.isEmpty` implies `orig.forall(ub => ub.scope eq orig(0).scope)`
- *
- */
- def sequence[bt <: NameElement, st <% Mappable[st]](orig: List[UnderBinder[bt, st]]): UnderBinder[bt, List[st]] =
- if(orig.isEmpty) UnderBinder.unit(Nil)
- else UnderBinder(orig(0).scope, orig.map(_.element))
-
- // couldn't come up with a better name...
- def unsequence[bt <: NameElement, st <% Mappable[st]](orig: UnderBinder[bt, List[st]]): List[UnderBinder[bt, st]] =
- orig.element.map(sc => UnderBinder(orig.scope, sc))
-
- //TODO: more documentation
- /** An environment that maps a `NameElement` to the scope in which it is bound.
- * This can be used to model scoping during parsing.
- *
- * @note This class uses similar techniques as described by ''Burak Emir'' in
- * [[http://library.epfl.ch/theses/?nr=3899 Object-oriented pattern matching]],
- * but uses `==` instead of `eq`, thus types can't be unified in general.
- */
- abstract class BinderEnv {
- def apply[A <: NameElement](v: A): Option[Scope[A]]
- def extend[a <: NameElement](v : a, x : Scope[a]) = new BinderEnv {
- def apply[b <: NameElement](w : b): Option[Scope[b]] =
- if(w == v) Some(x.asInstanceOf[Scope[b]])
- else BinderEnv.this.apply(w)
- }
- }
-
- object EmptyBinderEnv extends BinderEnv {
- def apply[A <: NameElement](v: A): Option[Scope[A]] = None
- }
-
- // TODO: move this to some utility object higher in the scala hierarchy?
- /** Returns a given result, but executes the supplied closure before returning.
- * (The effect of this closure does not influence the returned value.)
- */
- trait ReturnAndDo[T]{
- /**
- * @param block code to be executed, purely for its side-effects
- */
- def andDo(block: => Unit): T
- }
-
- def return_[T](result: T): ReturnAndDo[T] =
- new ReturnAndDo[T] {
- val r = result
- def andDo(block: => Unit): T = {block; r}
- }
-
- private object _Binder {
- private var currentId = 0
- private[Binders] def genId = return_(currentId) andDo {currentId=currentId+1}
- }
-}
diff --git a/src/library/scala/util/parsing/combinator/Parsers.scala b/src/library/scala/util/parsing/combinator/Parsers.scala
index 8fc2295d9c..4602c3cc53 100644
--- a/src/library/scala/util/parsing/combinator/Parsers.scala
+++ b/src/library/scala/util/parsing/combinator/Parsers.scala
@@ -158,12 +158,6 @@ trait Parsers {
private lazy val lastNoSuccessVar = new DynamicVariable[Option[NoSuccess]](None)
- @deprecated("lastNoSuccess was not thread-safe and will be removed in 2.11.0", "2.10.0")
- def lastNoSuccess: NoSuccess = lastNoSuccessVar.value.orNull
-
- @deprecated("lastNoSuccess was not thread-safe and will be removed in 2.11.0", "2.10.0")
- def lastNoSuccess_=(x: NoSuccess): Unit = lastNoSuccessVar.value = Option(x)
-
/** A common super-class for unsuccessful parse results. */
sealed abstract class NoSuccess(val msg: String, override val next: Input) extends ParseResult[Nothing] { // when we don't care about the difference between Failure and Error
val successful = false
diff --git a/src/library/scala/util/parsing/combinator/testing/RegexTest.scala b/src/library/scala/util/parsing/combinator/testing/RegexTest.scala
deleted file mode 100644
index 727b6caf8d..0000000000
--- a/src/library/scala/util/parsing/combinator/testing/RegexTest.scala
+++ /dev/null
@@ -1,28 +0,0 @@
-
-package scala
-package util.parsing.combinator.testing
-
-import scala.util.parsing.combinator._
-import scala.util.parsing.input._
-import scala.language.postfixOps
-
-@deprecated("This class will be removed", "2.10.0")
-case class Ident(s: String)
-@deprecated("This class will be removed", "2.10.0")
-case class Number(n: Int)
-@deprecated("This class will be removed", "2.10.0")
-case class Str(s: String)
-
-@deprecated("This class will be removed", "2.10.0")
-object RegexTest extends RegexParsers {
- val ident: Parser[Any] = """[a-zA-Z_]\w*""".r ^^ (s => Ident(s))
- val number: Parser[Any] = """\d\d*""".r ^^ (s => Number(s.toInt))
- val string: Parser[Any] = "\".*\"".r ^^ (s => Str(s.substring(1, s.length - 1)))
- val parser = (ident | number | string)*
-
- def main(args: Array[String]) = {
- val in = args mkString " "
- println("\nin : "+in)
- println(phrase[Any](parser)(new CharSequenceReader(in)))
- }
-}
diff --git a/src/library/scala/util/parsing/combinator/testing/Tester.scala b/src/library/scala/util/parsing/combinator/testing/Tester.scala
deleted file mode 100644
index 86c5d68ebe..0000000000
--- a/src/library/scala/util/parsing/combinator/testing/Tester.scala
+++ /dev/null
@@ -1,45 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2006-2013, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-\* */
-
-package scala
-package util.parsing.combinator.testing
-
-import scala.util.parsing.combinator.lexical.Lexical
-import scala.util.parsing.combinator.syntactical.TokenParsers
-
-/** Facilitates testing a given parser on various input strings.
- *
- * Example use:
- * {{{
- * val syntactic = new MyParsers
- * }}}
- * and
- * {{{
- * val parser = syntactic.term
- * }}}
- * (If `MyParsers` extends [[scala.util.parsing.combinator.syntactical.TokenParsers]]
- * with a parser called `term`.)
- *
- * @author Martin Odersky
- * @author Adriaan Moors
- */
-@deprecated("This class will be removed", "2.10.0")
-abstract class Tester {
-
- val syntactic: TokenParsers { val lexical: Lexical }
- val parser: syntactic.Parser[Any]
-
- /** Scans a String (using a `syntactic.lexical.Scanner`), parses it using
- * `phrase(parser)`, and prints the input and the parsed result to the
- * console.
- */
- def test(in: String) {
- Console.println("\nin : "+in)
- Console.println(syntactic.phrase[Any](parser)(new syntactic.lexical.Scanner(in)))
- }
-}
diff --git a/src/library/scala/xml/factory/LoggedNodeFactory.scala b/src/library/scala/xml/factory/LoggedNodeFactory.scala
index 63b4f42150..bc074bfc83 100644
--- a/src/library/scala/xml/factory/LoggedNodeFactory.scala
+++ b/src/library/scala/xml/factory/LoggedNodeFactory.scala
@@ -15,8 +15,9 @@ package factory
{{{
object testLogged extends App {
val x = new scala.xml.parsing.NoBindingFactoryAdapter
- with scala.xml.factory.LoggedNodeFactory[scala.xml.Elem]
- with scala.util.logging.ConsoleLogger
+ with scala.xml.factory.LoggedNodeFactory[scala.xml.Elem] {
+ override def log(s: String) = println(s)
+ }
Console.println("Start")
val doc = x.load(new java.net.URL("http://example.com/file.xml"))
@@ -28,7 +29,8 @@ object testLogged extends App {
* @author Burak Emir
* @version 1.0
*/
-trait LoggedNodeFactory[A <: Node] extends NodeFactory[A] with scala.util.logging.Logged {
+@deprecated("This trait will be removed.", "2.11")
+trait LoggedNodeFactory[A <: Node] extends NodeFactory[A] {
// configuration values
val logNode = true
val logText = false
@@ -83,4 +85,6 @@ trait LoggedNodeFactory[A <: Node] extends NodeFactory[A] with scala.util.loggin
super.makeProcInstr(t, s)
}
+ @deprecated("This method and its usages will be removed. Use a debugger to debug code.", "2.11")
+ def log(msg: String): Unit = {}
}
diff --git a/src/library/scala/xml/parsing/MarkupHandler.scala b/src/library/scala/xml/parsing/MarkupHandler.scala
index 0daabedf1c..1ebffb9c90 100755
--- a/src/library/scala/xml/parsing/MarkupHandler.scala
+++ b/src/library/scala/xml/parsing/MarkupHandler.scala
@@ -14,7 +14,6 @@ package parsing
import scala.collection.mutable
import scala.io.Source
-import scala.util.logging.Logged
import scala.xml.dtd._
/** class that handles markup - provides callback methods to MarkupParser.
@@ -26,8 +25,8 @@ import scala.xml.dtd._
* @todo can we ignore more entity declarations (i.e. those with extIDs)?
* @todo expanding entity references
*/
-abstract class MarkupHandler extends Logged
-{
+abstract class MarkupHandler {
+
/** returns true is this markup handler is validating */
val isValidating: Boolean = false
@@ -122,4 +121,7 @@ abstract class MarkupHandler extends Logged
def unparsedEntityDecl(name: String, extID: ExternalID, notat: String): Unit = ()
def notationDecl(notat: String, extID: ExternalID): Unit = ()
def reportSyntaxError(pos: Int, str: String): Unit
+
+ @deprecated("This method and its usages will be removed. Use a debugger to debug code.", "2.11")
+ def log(msg: String): Unit = {}
}
diff --git a/src/library/scala/xml/parsing/ValidatingMarkupHandler.scala b/src/library/scala/xml/parsing/ValidatingMarkupHandler.scala
index cec6b358ff..1b20901249 100644
--- a/src/library/scala/xml/parsing/ValidatingMarkupHandler.scala
+++ b/src/library/scala/xml/parsing/ValidatingMarkupHandler.scala
@@ -13,9 +13,8 @@ package xml
package parsing
import scala.xml.dtd._
-import scala.util.logging.Logged
-abstract class ValidatingMarkupHandler extends MarkupHandler with Logged {
+abstract class ValidatingMarkupHandler extends MarkupHandler {
var rootLabel:String = _
var qStack: List[Int] = Nil
@@ -26,20 +25,6 @@ abstract class ValidatingMarkupHandler extends MarkupHandler with Logged {
final override val isValidating = true
- override def log(msg: String) {}
-
- /*
- override def checkChildren(pos: Int, pre: String, label:String,ns:NodeSeq): Unit = {
- Console.println("checkChildren()");
- val decl = lookupElemDecl(label);
- // @todo: nice error message
- val res = decl.contentModel.validate(ns);
- Console.println("res = "+res);
- if(!res)
- //sys.error("invalid!");
- }
- */
-
override def endDTD(n:String) = {
rootLabel = n
}
@@ -116,5 +101,4 @@ abstract class ValidatingMarkupHandler extends MarkupHandler with Logged {
/** report a syntax error */
def reportValidationError(pos: Int, str: String): Unit
-
}
diff --git a/src/library/scala/xml/persistent/CachedFileStorage.scala b/src/library/scala/xml/persistent/CachedFileStorage.scala
index 347c11651c..57d512a041 100644
--- a/src/library/scala/xml/persistent/CachedFileStorage.scala
+++ b/src/library/scala/xml/persistent/CachedFileStorage.scala
@@ -14,7 +14,7 @@ import java.io.{ File, FileOutputStream }
import java.nio.ByteBuffer
import java.nio.channels.Channels
import java.lang.Thread
-import scala.util.logging.Logged
+
import scala.collection.Iterator
/** Mutable storage of immutable xml trees. Everything is kept in memory,
@@ -26,7 +26,7 @@ import scala.collection.Iterator
*
* @author Burak Emir
*/
-abstract class CachedFileStorage(private val file1: File) extends Thread with Logged {
+abstract class CachedFileStorage(private val file1: File) extends Thread {
private val file2 = new File(file1.getParent, file1.getName+"$")
@@ -123,4 +123,7 @@ abstract class CachedFileStorage(private val file1: File) extends Thread with Lo
this.dirty = true
save()
}
+
+ @deprecated("This method and its usages will be removed. Use a debugger to debug code.", "2.11")
+ def log(msg: String): Unit = {}
}
diff --git a/src/reflect/scala/reflect/io/Path.scala b/src/reflect/scala/reflect/io/Path.scala
index 0da962955c..15fce953f2 100644
--- a/src/reflect/scala/reflect/io/Path.scala
+++ b/src/reflect/scala/reflect/io/Path.scala
@@ -209,7 +209,7 @@ class Path private[io] (val jfile: JFile) {
}
def isDirectory = {
if (Statistics.canEnable) Statistics.incCounter(IOStats.fileIsDirectoryCount)
- try jfile.isDirectory() catch { case ex: SecurityException => false }
+ try jfile.isDirectory() catch { case ex: SecurityException => jfile.getPath == "." }
}
def isAbsolute = jfile.isAbsolute()
def isEmpty = path.length == 0
diff --git a/src/reflect/scala/reflect/macros/Enclosures.scala b/src/reflect/scala/reflect/macros/Enclosures.scala
index 8ea05500e4..d6ba5f39cd 100644
--- a/src/reflect/scala/reflect/macros/Enclosures.scala
+++ b/src/reflect/scala/reflect/macros/Enclosures.scala
@@ -45,13 +45,17 @@ trait Enclosures {
*/
def enclosingMacros: List[Context]
- /** Types along with corresponding trees for which implicit arguments are currently searched.
+ /** Information about one of the currently considered implicit candidates.
+ * Candidates are used in plural form, because implicit parameters may themselves have implicit parameters,
+ * hence implicit searches can recursively trigger other implicit searches.
+ *
* Can be useful to get information about an application with an implicit parameter that is materialized during current macro expansion.
+ * If we're in an implicit macro being expanded, it's included in this list.
*
* Unlike `openImplicits`, this is a val, which means that it gets initialized when the context is created
* and always stays the same regardless of whatever happens during macro expansion.
*/
- def enclosingImplicits: List[(Type, Tree)]
+ def enclosingImplicits: List[ImplicitCandidate]
/** Tries to guess a position for the enclosing application.
* But that is simple, right? Just dereference `pos` of `macroApplication`? Not really.
diff --git a/src/reflect/scala/reflect/macros/Typers.scala b/src/reflect/scala/reflect/macros/Typers.scala
index eaf79f2dab..d7aec9b3ef 100644
--- a/src/reflect/scala/reflect/macros/Typers.scala
+++ b/src/reflect/scala/reflect/macros/Typers.scala
@@ -11,8 +11,6 @@ package macros
trait Typers {
self: Context =>
- import universe._
-
/** Contexts that represent macros in-flight, including the current one. Very much like a stack trace, but for macros only.
* Can be useful for interoperating with other macros and for imposing compiler-friendly limits on macro expansion.
*
@@ -25,13 +23,26 @@ trait Typers {
*/
def openMacros: List[Context]
- /** Types along with corresponding trees for which implicit arguments are currently searched.
+ /** Information about one of the currently considered implicit candidates.
+ * Candidates are used in plural form, because implicit parameters may themselves have implicit parameters,
+ * hence implicit searches can recursively trigger other implicit searches.
+ *
+ * `pre` and `sym` provide information about the candidate itself.
+ * `pt` and `tree` store the parameters of the implicit search the candidate is participating in.
+ */
+ case class ImplicitCandidate(pre: Type, sym: Symbol, pt: Type, tree: Tree)
+
+ /** Information about one of the currently considered implicit candidates.
+ * Candidates are used in plural form, because implicit parameters may themselves have implicit parameters,
+ * hence implicit searches can recursively trigger other implicit searches.
+ *
* Can be useful to get information about an application with an implicit parameter that is materialized during current macro expansion.
+ * If we're in an implicit macro being expanded, it's included in this list.
*
* Unlike `enclosingImplicits`, this is a def, which means that it gets recalculated on every invocation,
* so it might change depending on what is going on during macro expansion.
*/
- def openImplicits: List[(Type, Tree)]
+ def openImplicits: List[ImplicitCandidate]
/** Typechecks the provided tree against the expected type `pt` in the macro callsite context.
*
@@ -46,7 +57,7 @@ trait Typers {
*
* @throws [[scala.reflect.macros.TypecheckException]]
*/
- def typeCheck(tree: Tree, pt: Type = WildcardType, silent: Boolean = false, withImplicitViewsDisabled: Boolean = false, withMacrosDisabled: Boolean = false): Tree
+ def typeCheck(tree: Tree, pt: Type = universe.WildcardType, silent: Boolean = false, withImplicitViewsDisabled: Boolean = false, withMacrosDisabled: Boolean = false): Tree
/** Infers an implicit value of the expected type `pt` in the macro callsite context.
* Optional `pos` parameter provides a position that will be associated with the implicit search.
diff --git a/test/files/jvm/xml01.scala b/test/files/jvm/xml01.scala
index 2fab650637..75777a5b94 100644
--- a/test/files/jvm/xml01.scala
+++ b/test/files/jvm/xml01.scala
@@ -1,7 +1,6 @@
import java.io.StringReader
import org.xml.sax.InputSource
-import scala.util.logging._
import scala.xml._
object Test extends App {
diff --git a/test/files/neg/macro-divergence-controlled.check b/test/files/neg/macro-divergence-controlled.check
new file mode 100644
index 0000000000..4876f7cf96
--- /dev/null
+++ b/test/files/neg/macro-divergence-controlled.check
@@ -0,0 +1,4 @@
+Test_2.scala:2: error: could not find implicit value for parameter e: Complex[Foo]
+ println(implicitly[Complex[Foo]])
+ ^
+one error found
diff --git a/test/files/neg/macro-divergence-controlled/Impls_Macros_1.scala b/test/files/neg/macro-divergence-controlled/Impls_Macros_1.scala
new file mode 100644
index 0000000000..59acaede65
--- /dev/null
+++ b/test/files/neg/macro-divergence-controlled/Impls_Macros_1.scala
@@ -0,0 +1,23 @@
+import scala.reflect.macros.Context
+import language.experimental.macros
+
+trait Complex[T]
+
+class Foo(val foo: Foo)
+
+object Complex {
+ def impl[T: c.WeakTypeTag](c: Context): c.Expr[Complex[T]] = {
+ import c.universe._
+ val tpe = weakTypeOf[T]
+ for (f <- tpe.declarations.collect{case f: TermSymbol if f.isParamAccessor && !f.isMethod => f}) {
+ val trecur = appliedType(typeOf[Complex[_]], List(f.typeSignature))
+ if (c.openImplicits.tail.exists(ic => ic.pt =:= trecur)) c.abort(c.enclosingPosition, "diverging implicit expansion. reported by a macro!")
+ val recur = c.inferImplicitValue(trecur, silent = true)
+ if (recur == EmptyTree) c.abort(c.enclosingPosition, s"couldn't synthesize $trecur")
+ }
+ c.literalNull
+ }
+
+ implicit object ComplexString extends Complex[String]
+ implicit def genComplex[T]: Complex[T] = macro impl[T]
+}
diff --git a/test/files/neg/macro-divergence-controlled/Test_2.scala b/test/files/neg/macro-divergence-controlled/Test_2.scala
new file mode 100644
index 0000000000..dcc4593335
--- /dev/null
+++ b/test/files/neg/macro-divergence-controlled/Test_2.scala
@@ -0,0 +1,3 @@
+object Test extends App {
+ println(implicitly[Complex[Foo]])
+} \ No newline at end of file
diff --git a/test/files/neg/t6406-regextract.check b/test/files/neg/t6406-regextract.check
index 4fea66f760..19425a68b0 100644
--- a/test/files/neg/t6406-regextract.check
+++ b/test/files/neg/t6406-regextract.check
@@ -1,7 +1,6 @@
-t6406-regextract.scala:4: error: cannot resolve overloaded unapply
+t6406-regextract.scala:4: warning: method unapplySeq in class Regex is deprecated: Extracting a match result from anything but a CharSequence or Match is deprecated
List(1) collect { case r(i) => i }
^
-t6406-regextract.scala:4: error: not found: value i
- List(1) collect { case r(i) => i }
- ^
-two errors found
+error: No warnings can be incurred under -Xfatal-warnings.
+one warning found
+one error found
diff --git a/test/files/neg/tailrec-2.check b/test/files/neg/tailrec-2.check
index d3432a7e76..1daad6922e 100644
--- a/test/files/neg/tailrec-2.check
+++ b/test/files/neg/tailrec-2.check
@@ -1,4 +1,4 @@
-tailrec-2.scala:8: error: could not optimize @tailrec annotated method f: it contains a recursive call targeting supertype Super[A]
+tailrec-2.scala:8: error: could not optimize @tailrec annotated method f: it contains a recursive call targeting a supertype
@annotation.tailrec final def f[B >: A](mem: List[B]): List[B] = (null: Super[A]).f(mem)
^
tailrec-2.scala:9: error: @tailrec annotated method contains no recursive calls
diff --git a/test/files/pos/t1648.scala b/test/files/pos/t1648.scala
deleted file mode 100644
index 6d53ce11ee..0000000000
--- a/test/files/pos/t1648.scala
+++ /dev/null
@@ -1,4 +0,0 @@
-object Test {
- class MyClass extends scala.util.logging.Logged { }
- val x = new MyClass with scala.util.logging.ConsoleLogger
-}
diff --git a/test/files/pos/t3943/Client_2.scala b/test/files/pos/t3943/Client_2.scala
new file mode 100644
index 0000000000..650ac9b7a9
--- /dev/null
+++ b/test/files/pos/t3943/Client_2.scala
@@ -0,0 +1,7 @@
+object Test {
+ val x: Child = new Child
+ x.getInner.foo("meh")
+// error: type mismatch;
+// found : java.lang.String("meh")
+// required: E
+}
diff --git a/test/files/pos/t3943/Outer_1.java b/test/files/pos/t3943/Outer_1.java
new file mode 100644
index 0000000000..1d38c5e76b
--- /dev/null
+++ b/test/files/pos/t3943/Outer_1.java
@@ -0,0 +1,14 @@
+class Outer<E> {
+ abstract class Inner {
+ abstract public void foo(E e);
+ }
+}
+
+class Child extends Outer<String> {
+ // the implicit prefix for Inner is Outer<E> instead of Outer<String>
+ public Inner getInner() {
+ return new Inner() {
+ public void foo(String e) { System.out.println("meh "+e); }
+ };
+ }
+}
diff --git a/test/files/pos/t5692c.check b/test/files/pos/t5692c.check
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/test/files/pos/t5692c.check
diff --git a/test/files/pos/t5692c.scala b/test/files/pos/t5692c.scala
new file mode 100644
index 0000000000..fa5f0b2dcd
--- /dev/null
+++ b/test/files/pos/t5692c.scala
@@ -0,0 +1,4 @@
+class C {
+ def foo[T: scala.reflect.ClassTag](xs: T*): Array[T] = ???
+ foo()
+} \ No newline at end of file
diff --git a/test/files/run/macro-divergence-spurious.check b/test/files/run/macro-divergence-spurious.check
new file mode 100644
index 0000000000..19765bd501
--- /dev/null
+++ b/test/files/run/macro-divergence-spurious.check
@@ -0,0 +1 @@
+null
diff --git a/test/files/run/macro-divergence-spurious/Impls_Macros_1.scala b/test/files/run/macro-divergence-spurious/Impls_Macros_1.scala
new file mode 100644
index 0000000000..bc4a9fded7
--- /dev/null
+++ b/test/files/run/macro-divergence-spurious/Impls_Macros_1.scala
@@ -0,0 +1,23 @@
+import scala.reflect.macros.Context
+import language.experimental.macros
+
+trait Complex[T]
+
+class Foo(val bar: Bar)
+class Bar(val s: String)
+
+object Complex {
+ def impl[T: c.WeakTypeTag](c: Context): c.Expr[Complex[T]] = {
+ import c.universe._
+ val tpe = weakTypeOf[T]
+ for (f <- tpe.declarations.collect{case f: TermSymbol if f.isParamAccessor && !f.isMethod => f}) {
+ val trecur = appliedType(typeOf[Complex[_]], List(f.typeSignature))
+ val recur = c.inferImplicitValue(trecur, silent = true)
+ if (recur == EmptyTree) c.abort(c.enclosingPosition, s"couldn't synthesize $trecur")
+ }
+ c.literalNull
+ }
+
+ implicit object ComplexString extends Complex[String]
+ implicit def genComplex[T]: Complex[T] = macro impl[T]
+}
diff --git a/test/files/run/macro-divergence-spurious/Test_2.scala b/test/files/run/macro-divergence-spurious/Test_2.scala
new file mode 100644
index 0000000000..dcc4593335
--- /dev/null
+++ b/test/files/run/macro-divergence-spurious/Test_2.scala
@@ -0,0 +1,3 @@
+object Test extends App {
+ println(implicitly[Complex[Foo]])
+} \ No newline at end of file
diff --git a/test/files/run/macro-sip19-revised/Impls_Macros_1.scala b/test/files/run/macro-sip19-revised/Impls_Macros_1.scala
index 5f3f61ca3f..8d7d3b5d3d 100644
--- a/test/files/run/macro-sip19-revised/Impls_Macros_1.scala
+++ b/test/files/run/macro-sip19-revised/Impls_Macros_1.scala
@@ -7,7 +7,7 @@ object Macros {
val inscope = c.inferImplicitValue(c.mirror.staticClass("SourceLocation").toType)
val outer = c.Expr[SourceLocation](if (!inscope.isEmpty) inscope else Literal(Constant(null)))
- val Apply(fun, args) = c.enclosingImplicits(0)._2
+ val Apply(fun, args) = c.enclosingImplicits(0).tree
val fileName = fun.pos.source.file.file.getName
val line = fun.pos.line
val charOffset = fun.pos.point
diff --git a/test/files/run/macro-sip19/Impls_Macros_1.scala b/test/files/run/macro-sip19/Impls_Macros_1.scala
index 535ec2ccf0..4c165ed1b8 100644
--- a/test/files/run/macro-sip19/Impls_Macros_1.scala
+++ b/test/files/run/macro-sip19/Impls_Macros_1.scala
@@ -3,7 +3,7 @@ import scala.reflect.macros.Context
object Macros {
def impl(c: Context) = {
import c.universe._
- val Apply(fun, args) = c.enclosingImplicits(0)._2
+ val Apply(fun, args) = c.enclosingImplicits(0).tree
val fileName = fun.pos.source.file.file.getName
val line = fun.pos.line
val charOffset = fun.pos.point
diff --git a/test/files/run/range.scala b/test/files/run/range.scala
index f08b2105d3..b81e67921a 100644
--- a/test/files/run/range.scala
+++ b/test/files/run/range.scala
@@ -16,6 +16,17 @@ object Test {
catch { case _: IllegalArgumentException => true }
)
assert(caught)
+ // #7432
+ val noElemAtMin = (
+ try { (10 until 10).min ; false }
+ catch { case _: NoSuchElementException => true }
+ )
+ assert(noElemAtMin)
+ val noElemAtMax = (
+ try { (10 until 10).max ; false }
+ catch { case _: NoSuchElementException => true }
+ )
+ assert(noElemAtMax)
}
case class GR[T](val x: T)(implicit val num: Integral[T]) {
diff --git a/test/files/run/t5923a.check b/test/files/run/t5923a.check
new file mode 100644
index 0000000000..7165b734ac
--- /dev/null
+++ b/test/files/run/t5923a.check
@@ -0,0 +1,3 @@
+C(Int)
+C(String)
+C(Nothing)
diff --git a/test/files/run/t5923a/Macros_1.scala b/test/files/run/t5923a/Macros_1.scala
new file mode 100644
index 0000000000..6d21362c4d
--- /dev/null
+++ b/test/files/run/t5923a/Macros_1.scala
@@ -0,0 +1,14 @@
+import scala.reflect.macros.Context
+import language.experimental.macros
+
+case class C[T](t: String)
+object C {
+ implicit def foo[T]: C[T] = macro Macros.impl[T]
+}
+
+object Macros {
+ def impl[T: c.WeakTypeTag](c: Context) = {
+ import c.universe._
+ reify(C[T](c.literal(weakTypeOf[T].toString).splice))
+ }
+} \ No newline at end of file
diff --git a/test/files/run/t5923a/Test_2.scala b/test/files/run/t5923a/Test_2.scala
new file mode 100644
index 0000000000..001ff9aea8
--- /dev/null
+++ b/test/files/run/t5923a/Test_2.scala
@@ -0,0 +1,5 @@
+object Test extends App {
+ println(implicitly[C[Int]])
+ println(implicitly[C[String]])
+ println(implicitly[C[Nothing]])
+} \ No newline at end of file
diff --git a/test/files/run/t5923b.check b/test/files/run/t5923b.check
new file mode 100644
index 0000000000..d56076f84e
--- /dev/null
+++ b/test/files/run/t5923b.check
@@ -0,0 +1,3 @@
+class [Ljava.lang.Object;
+class [Ljava.lang.Object;
+class [Ljava.lang.Object;
diff --git a/test/files/run/t5923b/Test.scala b/test/files/run/t5923b/Test.scala
new file mode 100644
index 0000000000..7c2627462a
--- /dev/null
+++ b/test/files/run/t5923b/Test.scala
@@ -0,0 +1,7 @@
+object Test extends App {
+ import scala.collection.generic.CanBuildFrom
+ val cbf = implicitly[CanBuildFrom[Nothing, Nothing, Array[Nothing]]]
+ println(cbf().result.getClass)
+ println(new Array[Nothing](0).getClass)
+ println(Array[Nothing]().getClass)
+} \ No newline at end of file
diff --git a/test/files/run/t6039.scala b/test/files/run/t6039.scala
new file mode 100644
index 0000000000..9d811b0634
--- /dev/null
+++ b/test/files/run/t6039.scala
@@ -0,0 +1,18 @@
+import scala.tools.partest._
+
+object Test extends StoreReporterDirectTest {
+ private def compileCode(): Boolean = {
+ new java.io.File("util") mkdirs
+ val classpath = List(sys.props("partest.lib"), ".") mkString sys.props("path.separator")
+ log(s"classpath = $classpath")
+ compileString(newCompiler("-cp", classpath, "-d", testOutput.path))(packageCode)
+ }
+ def code = ???
+ def packageCode = """
+package scala.bippy
+class A { new util.Random() }
+"""
+ def show(): Unit = {
+ assert(compileCode(), filteredInfos take 1 mkString "")
+ }
+}
diff --git a/test/files/run/t7047.check b/test/files/run/t7047.check
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/test/files/run/t7047.check
diff --git a/test/files/run/t7047/Impls_Macros_1.scala b/test/files/run/t7047/Impls_Macros_1.scala
new file mode 100644
index 0000000000..2992e3efe4
--- /dev/null
+++ b/test/files/run/t7047/Impls_Macros_1.scala
@@ -0,0 +1,19 @@
+import scala.reflect.macros.Context
+import language.experimental.macros
+
+class Foo
+
+object Macros {
+ def impl(c: Context) = {
+ import c.universe._
+ try {
+ c.inferImplicitValue(typeOf[Foo], silent = false)
+ c.abort(c.enclosingPosition, "silent=false is not working")
+ } catch {
+ case _: Exception =>
+ }
+ c.literalNull
+ }
+
+ def foo = macro impl
+} \ No newline at end of file
diff --git a/test/files/run/t7047/Test_2.scala b/test/files/run/t7047/Test_2.scala
new file mode 100644
index 0000000000..acfddae942
--- /dev/null
+++ b/test/files/run/t7047/Test_2.scala
@@ -0,0 +1,3 @@
+object Test extends App {
+ Macros.foo
+} \ No newline at end of file
diff --git a/test/files/scalacheck/avl.scala b/test/files/scalacheck/avl.scala
index af79ad49e3..02003bd271 100644
--- a/test/files/scalacheck/avl.scala
+++ b/test/files/scalacheck/avl.scala
@@ -2,14 +2,12 @@ import org.scalacheck.Gen
import org.scalacheck.Prop.forAll
import org.scalacheck.Properties
-import util.logging.ConsoleLogger
-
package scala.collection.mutable {
/**
* Property of an AVL Tree : Any node of the tree has a balance value beetween in [-1; 1]
*/
- abstract class AVLTreeTest(name: String) extends Properties(name) with ConsoleLogger {
+ abstract class AVLTreeTest(name: String) extends Properties(name) {
def `2^`(n: Int) = (1 to n).fold(1)((a, b) => b*2)