summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/build/maven/scala-dist-pom.xml6
-rw-r--r--src/build/maven/scala-library-all-pom.xml10
-rw-r--r--src/compiler/scala/reflect/macros/contexts/Names.scala3
-rw-r--r--src/compiler/scala/reflect/macros/runtime/JavaReflectionRuntimes.scala2
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala8
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Contexts.scala4
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Implicits.scala122
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala2
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Typers.scala10
-rw-r--r--src/compiler/scala/tools/reflect/quasiquotes/Holes.scala16
-rw-r--r--src/compiler/scala/tools/reflect/quasiquotes/Reifiers.scala16
-rw-r--r--src/library/scala/collection/Iterator.scala10
-rw-r--r--src/library/scala/collection/generic/Sorted.scala3
-rw-r--r--src/reflect/scala/reflect/api/Internals.scala46
-rw-r--r--src/reflect/scala/reflect/api/Liftables.scala8
-rw-r--r--src/reflect/scala/reflect/api/Mirror.scala18
-rw-r--r--src/reflect/scala/reflect/api/Quasiquotes.scala2
-rw-r--r--src/reflect/scala/reflect/api/StandardLiftables.scala1
-rw-r--r--src/reflect/scala/reflect/internal/Definitions.scala6
-rw-r--r--src/reflect/scala/reflect/internal/Mirrors.scala2
-rw-r--r--src/reflect/scala/reflect/internal/ReificationSupport.scala139
-rw-r--r--src/reflect/scala/reflect/internal/StdNames.scala80
-rw-r--r--src/reflect/scala/reflect/internal/pickling/UnPickler.scala23
23 files changed, 388 insertions, 149 deletions
diff --git a/src/build/maven/scala-dist-pom.xml b/src/build/maven/scala-dist-pom.xml
index 9a566d231b..22a24dea21 100644
--- a/src/build/maven/scala-dist-pom.xml
+++ b/src/build/maven/scala-dist-pom.xml
@@ -39,6 +39,12 @@
<artifactId>scala-compiler</artifactId>
<version>@VERSION@</version>
</dependency>
+ <dependency>
+ <groupId>org.scala-lang.plugins</groupId>
+ <!-- plugins are fully cross-versioned. But, we don't publish with 2.11.0-SNAPSHOT, instead use full version of the last non-snapshot version -->
+ <artifactId>scala-continuations-plugin_@SCALA_FULL_VERSION@</artifactId>
+ <version>@CONTINUATIONS_PLUGIN_VERSION@</version>
+ </dependency>
<!-- duplicated from scala-compiler, where it's optional,
so that resolving scala-dist's transitive dependencies does not include jline,
even though we need to include it in the dist, but macros depending on the compiler
diff --git a/src/build/maven/scala-library-all-pom.xml b/src/build/maven/scala-library-all-pom.xml
index b649c8c525..3fcf207559 100644
--- a/src/build/maven/scala-library-all-pom.xml
+++ b/src/build/maven/scala-library-all-pom.xml
@@ -49,11 +49,11 @@
<artifactId>scala-parser-combinators_@SCALA_BINARY_VERSION@</artifactId>
<version>@PARSER_COMBINATORS_VERSION@</version>
</dependency>
- <dependency>
- <groupId>org.scala-lang.plugins</groupId>
- <artifactId>scala-continuations-plugin_@SCALA_BINARY_VERSION@</artifactId>
- <version>@CONTINUATIONS_PLUGIN_VERSION@</version>
- </dependency>
+ <!--
+ the continuations plugin is a dependency of scala-dist, as scala-library-all should be
+ a drop-in replacement for scala-library, and as such should not (indirectly)
+ depend on plugins/the compiler.
+ -->
<dependency>
<groupId>org.scala-lang.plugins</groupId>
<artifactId>scala-continuations-library_@SCALA_BINARY_VERSION@</artifactId>
diff --git a/src/compiler/scala/reflect/macros/contexts/Names.scala b/src/compiler/scala/reflect/macros/contexts/Names.scala
index 299af40b94..5a5bb428b5 100644
--- a/src/compiler/scala/reflect/macros/contexts/Names.scala
+++ b/src/compiler/scala/reflect/macros/contexts/Names.scala
@@ -33,8 +33,9 @@ trait Names {
//
// TODO: hopefully SI-7823 will provide an ultimate answer to this problem.
// In the meanwhile I will also keep open the original issue: SI-6879 "c.freshName is broken".
+ val prefix = if (name.endsWith("$")) name else name + "$" // SI-8425
val sortOfUniqueSuffix = freshNameCreator.newName(nme.FRESH_SUFFIX)
- name + "$" + sortOfUniqueSuffix
+ prefix + sortOfUniqueSuffix
}
def freshName[NameType <: Name](name: NameType): NameType =
diff --git a/src/compiler/scala/reflect/macros/runtime/JavaReflectionRuntimes.scala b/src/compiler/scala/reflect/macros/runtime/JavaReflectionRuntimes.scala
index ecdd48db22..be114efbc0 100644
--- a/src/compiler/scala/reflect/macros/runtime/JavaReflectionRuntimes.scala
+++ b/src/compiler/scala/reflect/macros/runtime/JavaReflectionRuntimes.scala
@@ -14,7 +14,7 @@ trait JavaReflectionRuntimes {
def resolveJavaReflectionRuntime(classLoader: ClassLoader): MacroRuntime = {
val implClass = Class.forName(className, true, classLoader)
- val implMeths = implClass.getDeclaredMethods.find(_.getName == methName)
+ val implMeths = implClass.getMethods.find(_.getName == methName)
// relies on the fact that macro impls cannot be overloaded
// so every methName can resolve to at maximum one method
val implMeth = implMeths getOrElse { throw new NoSuchMethodException(s"$className.$methName") }
diff --git a/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala b/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala
index d439bb5603..9715fdaf00 100644
--- a/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala
@@ -359,6 +359,14 @@ trait ContextErrors {
//setError(sel)
}
+ def SelectWithUnderlyingError(sel: Tree, err: AbsTypeError) = {
+ // if there's no position, this is likely the result of a MissingRequirementError
+ // use the position of the selection we failed to type check to report the original message
+ if (err.errPos == NoPosition) issueNormalTypeError(sel, err.errMsg)
+ else issueTypeError(err)
+ setError(sel)
+ }
+
//typedNew
def IsAbstractError(tree: Tree, sym: Symbol) = {
issueNormalTypeError(tree, sym + " is abstract; cannot be instantiated")
diff --git a/src/compiler/scala/tools/nsc/typechecker/Contexts.scala b/src/compiler/scala/tools/nsc/typechecker/Contexts.scala
index 994a2a4f4f..8e1ceffecd 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Contexts.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Contexts.scala
@@ -103,7 +103,7 @@ trait Contexts { self: Analyzer =>
// there must be a scala.xml package when xml literals were parsed in this unit
if (unit.hasXml && ScalaXmlPackage == NoSymbol)
- unit.error(unit.firstXmlPos, "To compile XML syntax, the scala.xml package must be on the classpath.\nPlease see https://github.com/scala/scala/wiki/Scala-2.11#xml.")
+ unit.error(unit.firstXmlPos, "To compile XML syntax, the scala.xml package must be on the classpath.\nPlease see http://docs.scala-lang.org/overviews/core/scala-2.11.html#scala-xml.")
// scala-xml needs `scala.xml.TopScope` to be in scope globally as `$scope`
// We detect `scala-xml` by looking for `scala.xml.TopScope` and
@@ -544,6 +544,8 @@ trait Contexts { self: Analyzer =>
if (checking) onTreeCheckerError(pos, msg) else unit.error(pos, msg)
@inline private def issueCommon(err: AbsTypeError)(pf: PartialFunction[AbsTypeError, Unit]) {
+ // TODO: are errors allowed to have pos == NoPosition??
+ // if not, Jason suggests doing: val pos = err.errPos.orElse( { devWarning("Que?"); context.tree.pos })
if (settings.Yissuedebug) {
log("issue error: " + err.errMsg)
(new Exception).printStackTrace()
diff --git a/src/compiler/scala/tools/nsc/typechecker/Implicits.scala b/src/compiler/scala/tools/nsc/typechecker/Implicits.scala
index c8ac3622e2..d87090fa46 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Implicits.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Implicits.scala
@@ -82,7 +82,7 @@ trait Implicits {
// `implicitSearchContext.undetparams`, *not* in `context.undetparams`
// Here, we copy them up to parent context (analogously to the way the errors are copied above),
// and then filter out any which *were* inferred and are part of the substitutor in the implicit search result.
- context.undetparams = ((context.undetparams ++ implicitSearchContext.undetparams) filterNot result.subst.from.contains).distinct
+ context.undetparams = ((context.undetparams ++ result.undetparams) filterNot result.subst.from.contains).distinct
if (Statistics.canEnable) Statistics.stopTimer(implicitNanos, start)
if (Statistics.canEnable) Statistics.stopCounter(rawTypeImpl, rawTypeStart)
@@ -162,8 +162,9 @@ trait Implicits {
* @param tree The tree representing the implicit
* @param subst A substituter that represents the undetermined type parameters
* that were instantiated by the winning implicit.
+ * @param undetparams undeterminted type parameters
*/
- class SearchResult(val tree: Tree, val subst: TreeTypeSubstituter) {
+ class SearchResult(val tree: Tree, val subst: TreeTypeSubstituter, val undetparams: List[Symbol]) {
override def toString = "SearchResult(%s, %s)".format(tree,
if (subst.isEmpty) "" else subst)
@@ -173,16 +174,16 @@ trait Implicits {
final def isSuccess = !isFailure
}
- lazy val SearchFailure = new SearchResult(EmptyTree, EmptyTreeTypeSubstituter) {
+ lazy val SearchFailure = new SearchResult(EmptyTree, EmptyTreeTypeSubstituter, Nil) {
override def isFailure = true
}
- lazy val DivergentSearchFailure = new SearchResult(EmptyTree, EmptyTreeTypeSubstituter) {
+ lazy val DivergentSearchFailure = new SearchResult(EmptyTree, EmptyTreeTypeSubstituter, Nil) {
override def isFailure = true
override def isDivergent = true
}
- lazy val AmbiguousSearchFailure = new SearchResult(EmptyTree, EmptyTreeTypeSubstituter) {
+ lazy val AmbiguousSearchFailure = new SearchResult(EmptyTree, EmptyTreeTypeSubstituter, Nil) {
override def isFailure = true
override def isAmbiguousFailure = true
}
@@ -719,7 +720,7 @@ trait Implicits {
case Some(err) =>
fail("typing TypeApply reported errors for the implicit tree: " + err.errMsg)
case None =>
- val result = new SearchResult(unsuppressMacroExpansion(itree3), subst)
+ val result = new SearchResult(unsuppressMacroExpansion(itree3), subst, context.undetparams)
if (Statistics.canEnable) Statistics.incCounter(foundImplicits)
typingLog("success", s"inferred value of type $ptInstantiated is $result")
result
@@ -832,19 +833,41 @@ trait Implicits {
* so that if there is a best candidate it can still be selected.
*/
object DivergentImplicitRecovery {
- // symbol of the implicit that caused the divergence.
- // Initially null, will be saved on first diverging expansion.
- private var implicitSym: Symbol = _
- private var countdown: Int = 1
-
- def sym: Symbol = implicitSym
- def apply(search: SearchResult, i: ImplicitInfo): SearchResult =
- if (search.isDivergent && countdown > 0) {
- countdown -= 1
- implicitSym = i.sym
- log(s"discarding divergent implicit $implicitSym during implicit search")
+ private var divergentError: Option[DivergentImplicitTypeError] = None
+
+ private def saveDivergent(err: DivergentImplicitTypeError) {
+ if (divergentError.isEmpty) divergentError = Some(err)
+ }
+
+ def issueSavedDivergentError() {
+ divergentError foreach (err => context.issue(err))
+ }
+
+ def apply(search: SearchResult, i: ImplicitInfo, errors: Seq[AbsTypeError]): SearchResult = {
+ // A divergent error from a nested implicit search will be found in `errors`. Stash that
+ // aside to be re-issued if this implicit search fails.
+ errors.collectFirst { case err: DivergentImplicitTypeError => err } foreach saveDivergent
+
+ if (search.isDivergent && divergentError.isEmpty) {
+ // Divergence triggered by `i` at this level of the implicit serach. We haven't
+ // seen divergence so far, we won't issue this error just yet, and instead temporarily
+ // treat `i` as a failed candidate.
+ saveDivergent(DivergentImplicitTypeError(tree, pt, i.sym))
+ log(s"discarding divergent implicit ${i.sym} during implicit search")
SearchFailure
- } else search
+ } else {
+ if (search.isFailure) {
+ // We don't want errors that occur during checking implicit info
+ // to influence the check of further infos, but we should retain divergent implicit errors
+ // (except for the one we already squirreled away)
+ val saved = divergentError.getOrElse(null)
+ context.reportBuffer.retainErrors {
+ case err: DivergentImplicitTypeError => err ne saved
+ }
+ }
+ search
+ }
+ }
}
/** Sorted list of eligible implicits.
@@ -868,31 +891,33 @@ trait Implicits {
* - if it matches, forget about all others it improves upon
*/
@tailrec private def rankImplicits(pending: Infos, acc: Infos): Infos = pending match {
- case Nil => acc
- case i :: is =>
- DivergentImplicitRecovery(typedImplicit(i, ptChecked = true, isLocalToCallsite), i) match {
- case sr if sr.isDivergent =>
- Nil
- case sr if sr.isFailure =>
- // We don't want errors that occur during checking implicit info
- // to influence the check of further infos.
- context.reportBuffer.retainErrors {
- case err: DivergentImplicitTypeError => true
+ case Nil => acc
+ case firstPending :: otherPending =>
+ def firstPendingImproves(alt: ImplicitInfo) =
+ firstPending == alt || (
+ try improves(firstPending, alt)
+ catch {
+ case e: CyclicReference =>
+ debugwarn(s"Discarding $firstPending during implicit search due to cyclic reference.")
+ true
}
- rankImplicits(is, acc)
- case newBest =>
- best = newBest
- val newPending = undoLog undo {
- is filterNot (alt => alt == i || {
- try improves(i, alt)
- catch {
- case e: CyclicReference =>
- debugwarn(s"Discarding $i during implicit search due to cyclic reference")
- true
- }
- })
+ )
+
+ val typedFirstPending = typedImplicit(firstPending, ptChecked = true, isLocalToCallsite)
+
+ // Pass the errors to `DivergentImplicitRecovery` so that it can note
+ // the first `DivergentImplicitTypeError` that is being propagated
+ // from a nested implicit search; this one will be
+ // re-issued if this level of the search fails.
+ DivergentImplicitRecovery(typedFirstPending, firstPending, context.errors) match {
+ case sr if sr.isDivergent => Nil
+ case sr if sr.isFailure => rankImplicits(otherPending, acc)
+ case newBest =>
+ best = newBest // firstPending is our new best, since we already pruned last time around:
+ val pendingImprovingBest = undoLog undo {
+ otherPending filterNot firstPendingImproves
}
- rankImplicits(newPending, i :: acc)
+ rankImplicits(pendingImprovingBest, firstPending :: acc)
}
}
@@ -920,12 +945,9 @@ trait Implicits {
}
if (best.isFailure) {
- /* If there is no winner, and we witnessed and caught divergence,
- * now we can throw it for the error message.
- */
- if (DivergentImplicitRecovery.sym != null) {
- DivergingImplicitExpansionError(tree, pt, DivergentImplicitRecovery.sym)(context)
- }
+ // If there is no winner, and we witnessed and recorded a divergence error,
+ // our recovery attempt has failed, so we must now issue it.
+ DivergentImplicitRecovery.issueSavedDivergentError()
if (invalidImplicits.nonEmpty)
setAddendum(pos, () =>
@@ -1126,7 +1148,7 @@ trait Implicits {
val tree1 = typedPos(pos.focus)(arg)
context.firstError match {
case Some(err) => processMacroExpansionError(err.errPos, err.errMsg)
- case None => new SearchResult(tree1, EmptyTreeTypeSubstituter)
+ case None => new SearchResult(tree1, EmptyTreeTypeSubstituter, Nil)
}
} catch {
case ex: TypeError =>
@@ -1196,7 +1218,7 @@ trait Implicits {
def findSubManifest(tp: Type) = findManifest(tp, if (full) FullManifestClass else OptManifestClass)
def mot(tp0: Type, from: List[Symbol], to: List[Type]): SearchResult = {
implicit def wrapResult(tree: Tree): SearchResult =
- if (tree == EmptyTree) SearchFailure else new SearchResult(tree, if (from.isEmpty) EmptyTreeTypeSubstituter else new TreeTypeSubstituter(from, to))
+ if (tree == EmptyTree) SearchFailure else new SearchResult(tree, if (from.isEmpty) EmptyTreeTypeSubstituter else new TreeTypeSubstituter(from, to), Nil)
val tp1 = tp0.dealias
tp1 match {
@@ -1284,7 +1306,7 @@ trait Implicits {
}
def wrapResult(tree: Tree): SearchResult =
- if (tree == EmptyTree) SearchFailure else new SearchResult(tree, EmptyTreeTypeSubstituter)
+ if (tree == EmptyTree) SearchFailure else new SearchResult(tree, EmptyTreeTypeSubstituter, Nil)
/** Materializes implicits of predefined types (currently, manifests and tags).
* Will be replaced by implicit macros once we fix them.
diff --git a/src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala b/src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala
index 87da565142..9b9e641cad 100644
--- a/src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala
@@ -346,12 +346,14 @@ abstract class SuperAccessors extends transform.Transform with transform.TypingT
* performance hit for the compiler as a whole.
*/
override def atOwner[A](tree: Tree, owner: Symbol)(trans: => A): A = {
+ val savedValid = validCurrentOwner
if (owner.isClass) validCurrentOwner = true
val savedLocalTyper = localTyper
localTyper = localTyper.atOwner(tree, if (owner.isModule) owner.moduleClass else owner)
typers = typers updated (owner, localTyper)
val result = super.atOwner(tree, owner)(trans)
localTyper = savedLocalTyper
+ validCurrentOwner = savedValid
typers -= owner
result
}
diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
index 9f3f257529..e3901be546 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
@@ -1041,11 +1041,11 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper
if (tree.tpe <:< AnyTpe) pt.dealias match {
case TypeRef(_, UnitClass, _) => // (12)
if (settings.warnValueDiscard)
- context.unit.warning(tree.pos, "discarded non-Unit value")
+ context.warning(tree.pos, "discarded non-Unit value")
return typedPos(tree.pos, mode, pt)(Block(List(tree), Literal(Constant(()))))
case TypeRef(_, sym, _) if isNumericValueClass(sym) && isNumericSubType(tree.tpe, pt) =>
if (settings.warnNumericWiden)
- context.unit.warning(tree.pos, "implicit numeric widening")
+ context.warning(tree.pos, "implicit numeric widening")
return typedPos(tree.pos, mode, pt)(Select(tree, "to" + sym.name))
case _ =>
}
@@ -4670,8 +4670,8 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper
case SilentTypeError(err: AccessTypeError) =>
(tree1, Some(err))
case SilentTypeError(err) =>
- context issue err
- return setError(tree)
+ SelectWithUnderlyingError(tree, err)
+ return tree
case SilentResultValue(treeAndPre) =>
(stabilize(treeAndPre._1, treeAndPre._2, mode, pt), None)
}
@@ -5109,7 +5109,7 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper
def isPlausible(m: Symbol) = m.alternatives exists (m => requiresNoArgs(m.info))
def maybeWarn(s: String): Unit = {
- def warn(message: String) = context.unit.warning(lit.pos, s"$message Did you forget the interpolator?")
+ def warn(message: String) = context.warning(lit.pos, s"$message Did you forget the interpolator?")
def suspiciousSym(name: TermName) = context.lookupSymbol(name, _ => true).symbol
def suspiciousExpr = InterpolatorCodeRegex findFirstIn s
def suspiciousIdents = InterpolatorIdentRegex findAllIn s map (s => suspiciousSym(s drop 1))
diff --git a/src/compiler/scala/tools/reflect/quasiquotes/Holes.scala b/src/compiler/scala/tools/reflect/quasiquotes/Holes.scala
index 8376fca4ad..68cc728eb3 100644
--- a/src/compiler/scala/tools/reflect/quasiquotes/Holes.scala
+++ b/src/compiler/scala/tools/reflect/quasiquotes/Holes.scala
@@ -43,13 +43,13 @@ trait Holes { self: Quasiquotes =>
tpe <:< NothingClass.tpe || tpe <:< NullClass.tpe
private def extractIterableTParam(tpe: Type) =
IterableTParam.asSeenFrom(tpe, IterableClass)
- private def stripIterable(tpe: Type, limit: Option[Rank] = None): (Rank, Type) =
- if (limit.map { _ == NoDot }.getOrElse { false }) (NoDot, tpe)
+ private def stripIterable(tpe: Type, limit: Rank = DotDotDot): (Rank, Type) =
+ if (limit == NoDot) (NoDot, tpe)
else if (tpe != null && !isIterableType(tpe)) (NoDot, tpe)
else if (isBottomType(tpe)) (NoDot, tpe)
else {
val targ = extractIterableTParam(tpe)
- val (rank, innerTpe) = stripIterable(targ, limit.map { _.pred })
+ val (rank, innerTpe) = stripIterable(targ, limit.pred)
(rank.succ, innerTpe)
}
private def iterableTypeFromRank(n: Rank, tpe: Type): Type = {
@@ -76,10 +76,12 @@ trait Holes { self: Quasiquotes =>
class ApplyHole(annotatedRank: Rank, unquotee: Tree) extends Hole {
val (strippedTpe, tpe): (Type, Type) = {
- val (strippedRank, strippedTpe) = stripIterable(unquotee.tpe, limit = Some(annotatedRank))
+ val (strippedRank, strippedTpe) = stripIterable(unquotee.tpe, limit = annotatedRank)
if (isBottomType(strippedTpe)) cantSplice()
- else if (isNativeType(strippedTpe)) (strippedTpe, iterableTypeFromRank(annotatedRank, strippedTpe))
- else if (isLiftableType(strippedTpe)) (strippedTpe, iterableTypeFromRank(annotatedRank, treeType))
+ else if (isNativeType(strippedTpe)) {
+ if (strippedRank != NoDot && !(strippedTpe <:< treeType) && !isLiftableType(strippedTpe)) cantSplice()
+ else (strippedTpe, iterableTypeFromRank(annotatedRank, strippedTpe))
+ } else if (isLiftableType(strippedTpe)) (strippedTpe, iterableTypeFromRank(annotatedRank, treeType))
else cantSplice()
}
@@ -191,7 +193,7 @@ trait Holes { self: Quasiquotes =>
val (iterableRank, _) = stripIterable(tpe)
if (iterableRank.value < rank.value)
c.abort(pat.pos, s"Can't extract $tpe with $rank, consider using $iterableRank")
- val (_, strippedTpe) = stripIterable(tpe, limit = Some(rank))
+ val (_, strippedTpe) = stripIterable(tpe, limit = rank)
if (strippedTpe <:< treeType) treeNoUnlift
else
unlifters.spawn(strippedTpe, rank).map {
diff --git a/src/compiler/scala/tools/reflect/quasiquotes/Reifiers.scala b/src/compiler/scala/tools/reflect/quasiquotes/Reifiers.scala
index 1b8b0686e8..95113d5b00 100644
--- a/src/compiler/scala/tools/reflect/quasiquotes/Reifiers.scala
+++ b/src/compiler/scala/tools/reflect/quasiquotes/Reifiers.scala
@@ -193,8 +193,6 @@ trait Reifiers { self: Quasiquotes =>
reifyBuildCall(nme.SyntacticAppliedType, tpt, targs)
case SyntacticFunction(args, body) =>
reifyBuildCall(nme.SyntacticFunction, args, body)
- case SyntacticIdent(name, isBackquoted) =>
- reifyBuildCall(nme.SyntacticIdent, name, isBackquoted)
case SyntacticEmptyTypeTree() =>
reifyBuildCall(nme.SyntacticEmptyTypeTree)
case SyntacticImport(expr, selectors) =>
@@ -203,6 +201,20 @@ trait Reifiers { self: Quasiquotes =>
reifyBuildCall(nme.SyntacticPartialFunction, cases)
case SyntacticMatch(scrutinee, cases) =>
reifyBuildCall(nme.SyntacticMatch, scrutinee, cases)
+ case SyntacticTermIdent(name, isBackquoted) =>
+ reifyBuildCall(nme.SyntacticTermIdent, name, isBackquoted)
+ case SyntacticTypeIdent(name) =>
+ reifyBuildCall(nme.SyntacticTypeIdent, name)
+ case SyntacticCompoundType(parents, defns) =>
+ reifyBuildCall(nme.SyntacticCompoundType, parents, defns)
+ case SyntacticSingletonType(ref) =>
+ reifyBuildCall(nme.SyntacticSingletonType, ref)
+ case SyntacticTypeProjection(qual, name) =>
+ reifyBuildCall(nme.SyntacticTypeProjection, qual, name)
+ case SyntacticAnnotatedType(tpt, annot) =>
+ reifyBuildCall(nme.SyntacticAnnotatedType, tpt, annot)
+ case SyntacticExistentialType(tpt, where) =>
+ reifyBuildCall(nme.SyntacticExistentialType, tpt, where)
case Q(tree) if fillListHole.isDefinedAt(tree) =>
mirrorBuildCall(nme.SyntacticBlock, fillListHole(tree))
case Q(other) =>
diff --git a/src/library/scala/collection/Iterator.scala b/src/library/scala/collection/Iterator.scala
index 01a0aa3b51..1b496383a3 100644
--- a/src/library/scala/collection/Iterator.scala
+++ b/src/library/scala/collection/Iterator.scala
@@ -165,11 +165,11 @@ object Iterator {
/** Avoid stack overflows when applying ++ to lots of iterators by
* flattening the unevaluated iterators out into a vector of closures.
*/
- private[scala] final class ConcatIterator[+A](initial: Vector[() => Iterator[A]]) extends Iterator[A] {
- // current set to null when all iterators are exhausted
- private[this] var current: Iterator[A] = Iterator.empty
+ private[scala] final class ConcatIterator[+A](private[this] var current: Iterator[A], initial: Vector[() => Iterator[A]]) extends Iterator[A] {
+ @deprecated def this(initial: Vector[() => Iterator[A]]) = this(Iterator.empty, initial) // for binary compatibility
private[this] var queue: Vector[() => Iterator[A]] = initial
// Advance current to the next non-empty iterator
+ // current is set to null when all iterators are exhausted
private[this] def advance(): Boolean = {
if (queue.isEmpty) {
current = null
@@ -185,7 +185,7 @@ object Iterator {
def next() = if (hasNext) current.next else Iterator.empty.next
override def ++[B >: A](that: => GenTraversableOnce[B]): Iterator[B] =
- new ConcatIterator(queue :+ (() => that.toIterator))
+ new ConcatIterator(current, queue :+ (() => that.toIterator))
}
private[scala] final class JoinIterator[+A](lhs: Iterator[A], that: => GenTraversableOnce[A]) extends Iterator[A] {
@@ -194,7 +194,7 @@ object Iterator {
def next = if (lhs.hasNext) lhs.next else rhs.next
override def ++[B >: A](that: => GenTraversableOnce[B]) =
- new ConcatIterator(Vector(() => this, () => that.toIterator))
+ new ConcatIterator(this, Vector(() => that.toIterator))
}
}
diff --git a/src/library/scala/collection/generic/Sorted.scala b/src/library/scala/collection/generic/Sorted.scala
index ab0d443a03..a0b0e1318b 100644
--- a/src/library/scala/collection/generic/Sorted.scala
+++ b/src/library/scala/collection/generic/Sorted.scala
@@ -62,7 +62,8 @@ trait Sorted[K, +This <: Sorted[K, This]] {
/** Creates a ranged projection of this collection with both a lower-bound
* and an upper-bound.
*
- * @param from The upper-bound (exclusive) of the ranged projection.
+ * @param from The lower-bound (inclusive) of the ranged projection.
+ * @param until The upper-bound (exclusive) of the ranged projection.
*/
def range(from: K, until: K): This = rangeImpl(Some(from), Some(until))
diff --git a/src/reflect/scala/reflect/api/Internals.scala b/src/reflect/scala/reflect/api/Internals.scala
index 9faba7efd7..577cd09295 100644
--- a/src/reflect/scala/reflect/api/Internals.scala
+++ b/src/reflect/scala/reflect/api/Internals.scala
@@ -765,7 +765,7 @@ trait Internals { self: Universe =>
val SyntacticPartialFunction: SyntacticPartialFunctionExtractor
trait SyntacticPartialFunctionExtractor {
def apply(cases: List[Tree]): Match
- def unapply(tree: Match): Option[List[CaseDef]]
+ def unapply(tree: Tree): Option[List[CaseDef]]
}
val SyntacticMatch: SyntacticMatchExtractor
@@ -780,10 +780,16 @@ trait Internals { self: Universe =>
def unapply(tree: Try): Option[(Tree, List[CaseDef], Tree)]
}
- val SyntacticIdent: SyntacticIdentExtractor
- trait SyntacticIdentExtractor {
- def apply(name: Name, isBackquoted: Boolean = false): Ident
- def unapply(tree: Ident): Option[(Name, Boolean)]
+ val SyntacticTermIdent: SyntacticTermIdentExtractor
+ trait SyntacticTermIdentExtractor {
+ def apply(name: TermName, isBackquoted: Boolean = false): Ident
+ def unapply(id: Ident): Option[(TermName, Boolean)]
+ }
+
+ val SyntacticTypeIdent: SyntacticTypeIdentExtractor
+ trait SyntacticTypeIdentExtractor {
+ def apply(name: TypeName): Ident
+ def unapply(tree: Tree): Option[TypeName]
}
val SyntacticImport: SyntacticImportExtractor
@@ -803,6 +809,36 @@ trait Internals { self: Universe =>
def apply(qual: Tree, name: TermName): Select
def unapply(tree: Tree): Option[(Tree, TermName)]
}
+
+ val SyntacticCompoundType: SyntacticCompoundTypeExtractor
+ trait SyntacticCompoundTypeExtractor {
+ def apply(parents: List[Tree], defns: List[Tree]): CompoundTypeTree
+ def unapply(tree: Tree): Option[(List[Tree], List[Tree])]
+ }
+
+ val SyntacticSingletonType: SyntacitcSingletonTypeExtractor
+ trait SyntacitcSingletonTypeExtractor {
+ def apply(tree: Tree): SingletonTypeTree
+ def unapply(tree: Tree): Option[Tree]
+ }
+
+ val SyntacticTypeProjection: SyntacticTypeProjectionExtractor
+ trait SyntacticTypeProjectionExtractor {
+ def apply(qual: Tree, name: TypeName): SelectFromTypeTree
+ def unapply(tree: Tree): Option[(Tree, TypeName)]
+ }
+
+ val SyntacticAnnotatedType: SyntacticAnnotatedTypeExtractor
+ trait SyntacticAnnotatedTypeExtractor {
+ def apply(tpt: Tree, annot: Tree): Annotated
+ def unapply(tree: Tree): Option[(Tree, Tree)]
+ }
+
+ val SyntacticExistentialType: SyntacticExistentialTypeExtractor
+ trait SyntacticExistentialTypeExtractor {
+ def apply(tpt: Tree, where: List[Tree]): ExistentialTypeTree
+ def unapply(tree: Tree): Option[(Tree, List[MemberDef])]
+ }
}
@deprecated("Use `internal.reificationSupport` instead", "2.11.0")
diff --git a/src/reflect/scala/reflect/api/Liftables.scala b/src/reflect/scala/reflect/api/Liftables.scala
index ec9d85b69e..673dbce6f5 100644
--- a/src/reflect/scala/reflect/api/Liftables.scala
+++ b/src/reflect/scala/reflect/api/Liftables.scala
@@ -6,7 +6,7 @@ trait Liftables { self: Universe =>
/** A type class that defines a representation of `T` as a `Tree`.
*
- * @see [[http://docs.scala-lang.org/overviews/macros/quasiquotes.html#lifting]]
+ * @see [[http://docs.scala-lang.org/overviews/quasiquotes/lifting.html]]
*/
trait Liftable[T] {
def apply(value: T): Tree
@@ -32,7 +32,7 @@ trait Liftables { self: Universe =>
* lifted: universe.Tree = O
* }}}
*
- * @see [[http://docs.scala-lang.org/overviews/macros/quasiquotes.html#lifting]]
+ * @see [[http://docs.scala-lang.org/overviews/quasiquotes/lifting.html]]
*/
def apply[T](f: T => Tree): Liftable[T] =
new Liftable[T] { def apply(value: T): Tree = f(value) }
@@ -40,7 +40,7 @@ trait Liftables { self: Universe =>
/** A type class that defines a way to extract instance of `T` from a `Tree`.
*
- * @see [[http://docs.scala-lang.org/overviews/macros/quasiquotes.html#unlifting]]
+ * @see [[http://docs.scala-lang.org/overviews/quasiquotes/unlifting.html]]
*/
trait Unliftable[T] {
def unapply(tree: Tree): Option[T]
@@ -66,7 +66,7 @@ trait Liftables { self: Universe =>
* scala> val q"${_: O.type}" = q"$Oref"
* }}}
*
- * @see [[http://docs.scala-lang.org/overviews/macros/quasiquotes.html#unlifting]]
+ * @see [[http://docs.scala-lang.org/overviews/quasiquotes/unlifting.html]]
*/
def apply[T](pf: PartialFunction[Tree, T]): Unliftable[T] = new Unliftable[T] {
def unapply(value: Tree): Option[T] = pf.lift(value)
diff --git a/src/reflect/scala/reflect/api/Mirror.scala b/src/reflect/scala/reflect/api/Mirror.scala
index da3afd89ff..318fdb369a 100644
--- a/src/reflect/scala/reflect/api/Mirror.scala
+++ b/src/reflect/scala/reflect/api/Mirror.scala
@@ -118,4 +118,22 @@ abstract class Mirror[U <: Universe with Singleton] {
* @group Mirror
*/
def staticPackage(fullName: String): U#ModuleSymbol
+
+ /**
+ * Shortcut for `implicitly[WeakTypeTag[T]].tpe`
+ * @group TypeTags
+ */
+ def weakTypeOf[T: universe.WeakTypeTag]: U#Type = universe.weakTypeTag[T].in(this).tpe
+
+ /**
+ * Shortcut for `implicitly[TypeTag[T]].tpe`
+ * @group TypeTags
+ */
+ def typeOf[T: universe.TypeTag]: U#Type = universe.typeTag[T].in(this).tpe
+
+ /**
+ * Type symbol of `x` as derived from a type tag.
+ * @group TypeTags
+ */
+ def symbolOf[T: universe.WeakTypeTag]: U#TypeSymbol
}
diff --git a/src/reflect/scala/reflect/api/Quasiquotes.scala b/src/reflect/scala/reflect/api/Quasiquotes.scala
index 0065926e3b..e905aa4153 100644
--- a/src/reflect/scala/reflect/api/Quasiquotes.scala
+++ b/src/reflect/scala/reflect/api/Quasiquotes.scala
@@ -7,7 +7,7 @@ trait Quasiquotes { self: Universe =>
* that are also known as quasiquotes. With their help you can easily manipulate
* Scala reflection ASTs.
*
- * @see [[http://docs.scala-lang.org/overviews/macros/quasiquotes.html]]
+ * @see [[http://docs.scala-lang.org/overviews/quasiquotes/intro.html]]
*/
implicit class Quasiquote(ctx: StringContext) {
protected trait api {
diff --git a/src/reflect/scala/reflect/api/StandardLiftables.scala b/src/reflect/scala/reflect/api/StandardLiftables.scala
index af11de46ce..66ac62cc9e 100644
--- a/src/reflect/scala/reflect/api/StandardLiftables.scala
+++ b/src/reflect/scala/reflect/api/StandardLiftables.scala
@@ -27,6 +27,7 @@ trait StandardLiftables { self: Universe =>
callScala(stdnme.Symbol)(Literal(Constant(v.name)) :: Nil)
}
+ implicit def liftTree[T <: Tree]: Liftable[T] = Liftable { identity }
implicit def liftName[T <: Name]: Liftable[T] = Liftable { name => Ident(name) }
implicit def liftExpr[T <: Expr[_]]: Liftable[T] = Liftable { expr => expr.tree }
implicit def liftType[T <: Type]: Liftable[T] = Liftable { tpe => TypeTree(tpe) }
diff --git a/src/reflect/scala/reflect/internal/Definitions.scala b/src/reflect/scala/reflect/internal/Definitions.scala
index 25d78f4e6f..bf560a21e5 100644
--- a/src/reflect/scala/reflect/internal/Definitions.scala
+++ b/src/reflect/scala/reflect/internal/Definitions.scala
@@ -490,8 +490,10 @@ trait Definitions extends api.StandardDefinitions {
lazy val TypeCreatorClass = getClassIfDefined("scala.reflect.api.TypeCreator") // defined in scala-reflect.jar, so we need to be careful
lazy val TreeCreatorClass = getClassIfDefined("scala.reflect.api.TreeCreator") // defined in scala-reflect.jar, so we need to be careful
- lazy val BlackboxContextClass = getClassIfDefined("scala.reflect.macros.blackbox.Context") // defined in scala-reflect.jar, so we need to be careful
- lazy val WhiteboxContextClass = getClassIfDefined("scala.reflect.macros.whitebox.Context") // defined in scala-reflect.jar, so we need to be careful
+ private def Context_210 = if (settings.isScala211) NoSymbol else getClassIfDefined("scala.reflect.macros.Context") // needed under -Xsource:2.10
+ lazy val BlackboxContextClass = getClassIfDefined("scala.reflect.macros.blackbox.Context").orElse(Context_210) // defined in scala-reflect.jar, so we need to be careful
+
+ lazy val WhiteboxContextClass = getClassIfDefined("scala.reflect.macros.whitebox.Context").orElse(Context_210) // defined in scala-reflect.jar, so we need to be careful
def MacroContextPrefix = BlackboxContextClass.map(sym => getMemberMethod(sym, nme.prefix))
def MacroContextPrefixType = BlackboxContextClass.map(sym => getTypeMember(sym, tpnme.PrefixType))
def MacroContextUniverse = BlackboxContextClass.map(sym => getMemberMethod(sym, nme.universe))
diff --git a/src/reflect/scala/reflect/internal/Mirrors.scala b/src/reflect/scala/reflect/internal/Mirrors.scala
index 7065a8cd6d..4a35e024de 100644
--- a/src/reflect/scala/reflect/internal/Mirrors.scala
+++ b/src/reflect/scala/reflect/internal/Mirrors.scala
@@ -30,6 +30,8 @@ trait Mirrors extends api.Mirrors {
val EmptyPackageClass: ClassSymbol
val EmptyPackage: ModuleSymbol
+ def symbolOf[T: universe.WeakTypeTag]: universe.TypeSymbol = universe.weakTypeTag[T].in(this).tpe.typeSymbolDirect.asType
+
def findMemberFromRoot(fullName: Name): Symbol = {
val segs = nme.segments(fullName.toString, fullName.isTermName)
if (segs.isEmpty) NoSymbol
diff --git a/src/reflect/scala/reflect/internal/ReificationSupport.scala b/src/reflect/scala/reflect/internal/ReificationSupport.scala
index 9a130337b4..ad8a2594dd 100644
--- a/src/reflect/scala/reflect/internal/ReificationSupport.scala
+++ b/src/reflect/scala/reflect/internal/ReificationSupport.scala
@@ -6,7 +6,7 @@ import Flags._
import util._
trait ReificationSupport { self: SymbolTable =>
- import definitions.{TupleClass, FunctionClass, ScalaPackage, UnitClass}
+ import definitions._
import internal._
class ReificationSupportImpl extends ReificationSupportApi {
@@ -227,9 +227,9 @@ trait ReificationSupport { self: SymbolTable =>
else throw new IllegalArgumentException(s"can't create applied type from non-type $tree")
def unapply(tree: Tree): Option[(Tree, List[Tree])] = tree match {
- case AppliedTypeTree(tpe, targs) => Some((tpe, targs))
- case _ if tree.isType => Some((tree, Nil))
- case _ => None
+ case MaybeTypeTreeOriginal(AppliedTypeTree(tpe, targs)) => Some((tpe, targs))
+ case _ if tree.isType => Some((tree, Nil))
+ case _ => None
}
}
@@ -241,10 +241,15 @@ trait ReificationSupport { self: SymbolTable =>
case UnApply(treeInfo.Unapplied(Select(fun, nme.unapply)), pats) =>
Some((fun, pats :: Nil))
case treeInfo.Applied(fun, targs, argss) =>
- val callee =
- if (fun.isTerm) SyntacticTypeApplied(fun, targs)
- else SyntacticAppliedType(fun, targs)
- Some((callee, argss))
+ fun match {
+ case Select(_: New, nme.CONSTRUCTOR) =>
+ Some((tree, Nil))
+ case _ =>
+ val callee =
+ if (fun.isTerm) SyntacticTypeApplied(fun, targs)
+ else SyntacticAppliedType(fun, targs)
+ Some((callee, argss))
+ }
}
}
@@ -510,7 +515,9 @@ trait ReificationSupport { self: SymbolTable =>
gen.mkNew(parents, mkSelfType(selfType), earlyDefs ::: body, NoPosition, NoPosition)
def unapply(tree: Tree): Option[(List[Tree], List[Tree], ValDef, List[Tree])] = tree match {
- case SyntacticApplied(Select(New(SyntacticAppliedType(ident, targs)), nme.CONSTRUCTOR), argss) =>
+ case treeInfo.Applied(Select(New(SyntacticAppliedType(ident, targs)), nme.CONSTRUCTOR), Nil, List(Nil)) =>
+ Some((Nil, SyntacticAppliedType(ident, targs) :: Nil, noSelfType, Nil))
+ case treeInfo.Applied(Select(New(SyntacticAppliedType(ident, targs)), nme.CONSTRUCTOR), Nil, argss) =>
Some((Nil, SyntacticApplied(SyntacticAppliedType(ident, targs), argss) :: Nil, noSelfType, Nil))
case SyntacticBlock(SyntacticClassDef(_, tpnme.ANON_CLASS_NAME, Nil, _, ListOfNil, earlyDefs, parents, selfType, body) ::
Apply(Select(New(Ident(tpnme.ANON_CLASS_NAME)), nme.CONSTRUCTOR), Nil) :: Nil) =>
@@ -523,11 +530,21 @@ trait ReificationSupport { self: SymbolTable =>
object SyntacticDefDef extends SyntacticDefDefExtractor {
def apply(mods: Modifiers, name: TermName, tparams: List[Tree],
vparamss: List[List[Tree]], tpt: Tree, rhs: Tree): DefDef = {
+ val tparams0 = mkTparams(tparams)
val vparamss0 = mkParam(vparamss, PARAM)
- DefDef(mods, name, mkTparams(tparams), vparamss0, tpt, rhs)
+ val rhs0 = {
+ if (name != nme.CONSTRUCTOR) rhs
+ else rhs match {
+ case Block(_, _) => rhs
+ case _ => Block(List(rhs), gen.mkSyntheticUnit)
+ }
+ }
+ DefDef(mods, name, tparams0, vparamss0, tpt, rhs0)
}
def unapply(tree: Tree): Option[(Modifiers, TermName, List[TypeDef], List[List[ValDef]], Tree, Tree)] = tree match {
+ case DefDef(mods, nme.CONSTRUCTOR, tparams, vparamss, tpt, Block(List(expr), Literal(Constant(())))) =>
+ Some((mods, nme.CONSTRUCTOR, tparams, vparamss, tpt, expr))
case DefDef(mods, name, tparams, vparamss, tpt, rhs) =>
Some((mods, name, tparams, vparamss, tpt, rhs))
case _ => None
@@ -829,10 +846,10 @@ trait ReificationSupport { self: SymbolTable =>
// drop potential @scala.unchecked annotation
protected object MaybeUnchecked {
def unapply(tree: Tree): Some[Tree] = tree match {
- case Annotated(SyntacticNew(Nil, Apply(ScalaDot(tpnme.unchecked), Nil) :: Nil, noSelfType, Nil), annottee) =>
+ case Annotated(SyntacticNew(Nil, ScalaDot(tpnme.unchecked) :: Nil, noSelfType, Nil), annottee) =>
Some(annottee)
case Typed(annottee, MaybeTypeTreeOriginal(
- Annotated(SyntacticNew(Nil, Apply(ScalaDot(tpnme.unchecked), Nil) :: Nil, noSelfType, Nil), _))) =>
+ Annotated(SyntacticNew(Nil, ScalaDot(tpnme.unchecked) :: Nil, noSelfType, Nil), _))) =>
Some(annottee)
case annottee => Some(annottee)
}
@@ -852,9 +869,25 @@ trait ReificationSupport { self: SymbolTable =>
object SyntacticPartialFunction extends SyntacticPartialFunctionExtractor {
def apply(cases: List[Tree]): Match = Match(EmptyTree, mkCases(cases))
- def unapply(tree: Match): Option[List[CaseDef]] = tree match {
+ def unapply(tree: Tree): Option[List[CaseDef]] = tree match {
case Match(EmptyTree, cases) => Some(cases)
- case _ => None
+ case Typed(
+ Block(
+ List(ClassDef(clsMods, tpnme.ANON_FUN_NAME, Nil, Template(
+ List(abspf: TypeTree, ser: TypeTree), noSelfType, List(
+ DefDef(_, nme.CONSTRUCTOR, _, _, _, _),
+ DefDef(_, nme.applyOrElse, _, _, _,
+ Match(_, cases :+
+ CaseDef(Bind(nme.DEFAULT_CASE, Ident(nme.WILDCARD)), _, _))),
+ DefDef(_, nme.isDefinedAt, _, _, _, _))))),
+ Apply(Select(New(Ident(tpnme.ANON_FUN_NAME)), termNames.CONSTRUCTOR), List())),
+ pf: TypeTree)
+ if pf.tpe != null && pf.tpe.typeSymbol.eq(PartialFunctionClass) &&
+ abspf.tpe != null && abspf.tpe.typeSymbol.eq(AbstractPartialFunctionClass) &&
+ ser.tpe != null && ser.tpe.typeSymbol.eq(SerializableClass) &&
+ clsMods.hasFlag(FINAL) && clsMods.hasFlag(SYNTHETIC) =>
+ Some(cases)
+ case _ => None
}
}
@@ -875,13 +908,24 @@ trait ReificationSupport { self: SymbolTable =>
def unapply(tree: Try): Option[(Tree, List[CaseDef], Tree)] = Try.unapply(tree)
}
- object SyntacticIdent extends SyntacticIdentExtractor {
- def apply(name: Name, isBackquoted: Boolean) = {
+ object SyntacticTermIdent extends SyntacticTermIdentExtractor {
+ def apply(name: TermName, isBackquoted: Boolean): Ident = {
val id = self.Ident(name)
if (isBackquoted) id updateAttachment BackquotedIdentifierAttachment
id
}
- def unapply(tree: Ident): Some[(Name, Boolean)] = Some((tree.name, tree.hasAttachment[BackquotedIdentifierAttachment.type]))
+ def unapply(id: Ident): Option[(TermName, Boolean)] = id.name match {
+ case name: TermName => Some((name, id.hasAttachment[BackquotedIdentifierAttachment.type]))
+ case _ => None
+ }
+ }
+
+ object SyntacticTypeIdent extends SyntacticTypeIdentExtractor {
+ def apply(name: TypeName): Ident = self.Ident(name)
+ def unapply(tree: Tree): Option[TypeName] = tree match {
+ case MaybeTypeTreeOriginal(Ident(name: TypeName)) => Some(name)
+ case _ => None
+ }
}
/** Facade over Imports and ImportSelectors that lets to structurally
@@ -1027,8 +1071,8 @@ trait ReificationSupport { self: SymbolTable =>
object SyntacticSelectType extends SyntacticSelectTypeExtractor {
def apply(qual: Tree, name: TypeName): Select = Select(qual, name)
def unapply(tree: Tree): Option[(Tree, TypeName)] = tree match {
- case Select(qual, name: TypeName) => Some((qual, name))
- case _ => None
+ case MaybeTypeTreeOriginal(Select(qual, name: TypeName)) => Some((qual, name))
+ case _ => None
}
}
@@ -1039,6 +1083,63 @@ trait ReificationSupport { self: SymbolTable =>
case _ => None
}
}
+
+ object SyntacticCompoundType extends SyntacticCompoundTypeExtractor {
+ def apply(parents: List[Tree], defns: List[Tree]) =
+ CompoundTypeTree(Template(gen.mkParents(NoMods, parents), noSelfType, defns))
+ def unapply(tree: Tree): Option[(List[Tree], List[Tree])] = tree match {
+ case MaybeTypeTreeOriginal(CompoundTypeTree(Template(parents, _, defns))) =>
+ Some((parents, defns))
+ case _ =>
+ None
+ }
+ }
+
+ object SyntacticSingletonType extends SyntacitcSingletonTypeExtractor {
+ def apply(ref: Tree): SingletonTypeTree = SingletonTypeTree(ref)
+ def unapply(tree: Tree): Option[Tree] = tree match {
+ case MaybeTypeTreeOriginal(SingletonTypeTree(ref)) =>
+ Some(ref)
+ case _ =>
+ None
+ }
+ }
+
+ object SyntacticTypeProjection extends SyntacticTypeProjectionExtractor {
+ def apply(qual: Tree, name: TypeName): SelectFromTypeTree =
+ SelectFromTypeTree(qual, name)
+ def unapply(tree: Tree): Option[(Tree, TypeName)] = tree match {
+ case MaybeTypeTreeOriginal(SelectFromTypeTree(qual, name)) =>
+ Some((qual, name))
+ case _ =>
+ None
+ }
+ }
+
+ object SyntacticAnnotatedType extends SyntacticAnnotatedTypeExtractor {
+ def apply(tpt: Tree, annot: Tree): Annotated =
+ Annotated(annot, tpt)
+ def unapply(tree: Tree): Option[(Tree, Tree)] = tree match {
+ case MaybeTypeTreeOriginal(Annotated(annot, tpt)) =>
+ Some((tpt, annot))
+ case _ =>
+ None
+ }
+ }
+
+ object SyntacticExistentialType extends SyntacticExistentialTypeExtractor {
+ def apply(tpt: Tree, where: List[Tree]): ExistentialTypeTree =
+ ExistentialTypeTree(tpt, where.map {
+ case md: MemberDef => md
+ case tree => throw new IllegalArgumentException("$tree is not legal forSome definition")
+ })
+ def unapply(tree: Tree): Option[(Tree, List[MemberDef])] = tree match {
+ case MaybeTypeTreeOriginal(ExistentialTypeTree(tpt, where)) =>
+ Some((tpt, where))
+ case _ =>
+ None
+ }
+ }
}
val build = new ReificationSupportImpl
diff --git a/src/reflect/scala/reflect/internal/StdNames.scala b/src/reflect/scala/reflect/internal/StdNames.scala
index 10959ff41f..6848c357c5 100644
--- a/src/reflect/scala/reflect/internal/StdNames.scala
+++ b/src/reflect/scala/reflect/internal/StdNames.scala
@@ -612,37 +612,6 @@ trait StdNames {
val SelectFromTypeTree: NameType = "SelectFromTypeTree"
val SingleType: NameType = "SingleType"
val SuperType: NameType = "SuperType"
- val SyntacticApplied: NameType = "SyntacticApplied"
- val SyntacticAppliedType: NameType = "SyntacticAppliedType"
- val SyntacticAssign: NameType = "SyntacticAssign"
- val SyntacticBlock: NameType = "SyntacticBlock"
- val SyntacticClassDef: NameType = "SyntacticClassDef"
- val SyntacticDefDef: NameType = "SyntacticDefDef"
- val SyntacticEmptyTypeTree: NameType = "SyntacticEmptyTypeTree"
- val SyntacticFilter: NameType = "SyntacticFilter"
- val SyntacticFor: NameType = "SyntacticFor"
- val SyntacticForYield: NameType = "SyntacticForYield"
- val SyntacticFunction: NameType = "SyntacticFunction"
- val SyntacticFunctionType: NameType = "SyntacticFunctionType"
- val SyntacticIdent: NameType = "SyntacticIdent"
- val SyntacticImport: NameType = "SyntacticImport"
- val SyntacticMatch: NameType = "SyntacticMatch"
- val SyntacticNew: NameType = "SyntacticNew"
- val SyntacticObjectDef: NameType = "SyntacticObjectDef"
- val SyntacticPackageObjectDef: NameType = "SyntacticPackageObjectDef"
- val SyntacticPartialFunction: NameType = "SyntacticPartialFunction"
- val SyntacticPatDef: NameType = "SyntacticPatDef"
- val SyntacticSelectType: NameType = "SyntacticSelectType"
- val SyntacticSelectTerm: NameType = "SyntacticSelectTerm"
- val SyntacticTraitDef: NameType = "SyntacticTraitDef"
- val SyntacticTry: NameType = "SyntacticTry"
- val SyntacticTuple: NameType = "SyntacticTuple"
- val SyntacticTupleType: NameType = "SyntacticTupleType"
- val SyntacticTypeApplied: NameType = "SyntacticTypeApplied"
- val SyntacticValDef: NameType = "SyntacticValDef"
- val SyntacticValEq: NameType = "SyntacticValEq"
- val SyntacticValFrom: NameType = "SyntacticValFrom"
- val SyntacticVarDef: NameType = "SyntacticVarDef"
val This: NameType = "This"
val ThisType: NameType = "ThisType"
val Tuple2: NameType = "Tuple2"
@@ -810,11 +779,50 @@ trait StdNames {
val zero: NameType = "zero"
// quasiquote interpolators:
- val q: NameType = "q"
- val tq: NameType = "tq"
- val cq: NameType = "cq"
- val pq: NameType = "pq"
- val fq: NameType = "fq"
+ val q: NameType = "q"
+ val tq: NameType = "tq"
+ val cq: NameType = "cq"
+ val pq: NameType = "pq"
+ val fq: NameType = "fq"
+
+ // quasiquote's syntactic combinators
+ val SyntacticAnnotatedType: NameType = "SyntacticAnnotatedType"
+ val SyntacticApplied: NameType = "SyntacticApplied"
+ val SyntacticAppliedType: NameType = "SyntacticAppliedType"
+ val SyntacticAssign: NameType = "SyntacticAssign"
+ val SyntacticBlock: NameType = "SyntacticBlock"
+ val SyntacticClassDef: NameType = "SyntacticClassDef"
+ val SyntacticCompoundType: NameType = "SyntacticCompoundType"
+ val SyntacticDefDef: NameType = "SyntacticDefDef"
+ val SyntacticEmptyTypeTree: NameType = "SyntacticEmptyTypeTree"
+ val SyntacticExistentialType: NameType = "SyntacticExistentialType"
+ val SyntacticFilter: NameType = "SyntacticFilter"
+ val SyntacticFor: NameType = "SyntacticFor"
+ val SyntacticForYield: NameType = "SyntacticForYield"
+ val SyntacticFunction: NameType = "SyntacticFunction"
+ val SyntacticFunctionType: NameType = "SyntacticFunctionType"
+ val SyntacticImport: NameType = "SyntacticImport"
+ val SyntacticMatch: NameType = "SyntacticMatch"
+ val SyntacticNew: NameType = "SyntacticNew"
+ val SyntacticObjectDef: NameType = "SyntacticObjectDef"
+ val SyntacticPackageObjectDef: NameType = "SyntacticPackageObjectDef"
+ val SyntacticPartialFunction: NameType = "SyntacticPartialFunction"
+ val SyntacticPatDef: NameType = "SyntacticPatDef"
+ val SyntacticSelectTerm: NameType = "SyntacticSelectTerm"
+ val SyntacticSelectType: NameType = "SyntacticSelectType"
+ val SyntacticSingletonType: NameType = "SyntacticSingletonType"
+ val SyntacticTermIdent: NameType = "SyntacticTermIdent"
+ val SyntacticTraitDef: NameType = "SyntacticTraitDef"
+ val SyntacticTry: NameType = "SyntacticTry"
+ val SyntacticTuple: NameType = "SyntacticTuple"
+ val SyntacticTupleType: NameType = "SyntacticTupleType"
+ val SyntacticTypeApplied: NameType = "SyntacticTypeApplied"
+ val SyntacticTypeIdent: NameType = "SyntacticTypeIdent"
+ val SyntacticTypeProjection: NameType = "SyntacticTypeProjection"
+ val SyntacticValDef: NameType = "SyntacticValDef"
+ val SyntacticValEq: NameType = "SyntacticValEq"
+ val SyntacticValFrom: NameType = "SyntacticValFrom"
+ val SyntacticVarDef: NameType = "SyntacticVarDef"
// unencoded operators
object raw {
diff --git a/src/reflect/scala/reflect/internal/pickling/UnPickler.scala b/src/reflect/scala/reflect/internal/pickling/UnPickler.scala
index 42f794736a..64a1a44722 100644
--- a/src/reflect/scala/reflect/internal/pickling/UnPickler.scala
+++ b/src/reflect/scala/reflect/internal/pickling/UnPickler.scala
@@ -229,6 +229,20 @@ abstract class UnPickler {
NoSymbol
}
+ def moduleAdvice(missing: String): String = {
+ val module =
+ if (missing.startsWith("scala.xml")) Some(("org.scala-lang.modules", "scala-xml"))
+ else if (missing.startsWith("scala.util.parsing")) Some(("org.scala-lang.modules", "scala-parser-combinators"))
+ else if (missing.startsWith("scala.swing")) Some(("org.scala-lang.modules", "scala-swing"))
+ else if (missing.startsWith("scala.util.continuations")) Some(("org.scala-lang.plugins", "scala-continuations-library"))
+ else None
+
+ (module map { case (group, art) =>
+ s"""\n(NOTE: It looks like the $art module is missing; try adding a dependency on "$group" : "$art".
+ | See http://docs.scala-lang.org/overviews/core/scala-2.11.html for more information.)""".stripMargin
+ } getOrElse "")
+ }
+
// (1) Try name.
fromName(name) orElse {
// (2) Try with expanded name. Can happen if references to private
@@ -240,11 +254,12 @@ abstract class UnPickler {
// (4) Call the mirror's "missing" hook.
adjust(mirrorThatLoaded(owner).missingHook(owner, name)) orElse {
// (5) Create a stub symbol to defer hard failure a little longer.
+ val fullName = s"${owner.fullName}.$name"
val missingMessage =
- s"""|bad symbolic reference. A signature in $filename refers to ${name.longString}
- |in ${owner.kindString} ${owner.fullName} which is not available.
- |It may be completely missing from the current classpath, or the version on
- |the classpath might be incompatible with the version used when compiling $filename.""".stripMargin
+ s"""|bad symbolic reference to $fullName encountered in class file '$filename'.
+ |Cannot access ${name.longString} in ${owner.kindString} ${owner.fullName}. The current classpath may be
+ |missing a definition for $fullName, or $filename may have been compiled against a version that's
+ |incompatible with the one found on the current classpath.${moduleAdvice(fullName)}""".stripMargin
owner.newStubSymbol(name, missingMessage)
}
}