diff options
Diffstat (limited to 'src')
32 files changed, 415 insertions, 161 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/ant/templates/tool-unix.tmpl b/src/compiler/scala/tools/ant/templates/tool-unix.tmpl index d6dc167dd8..f58223a39e 100644..100755 --- a/src/compiler/scala/tools/ant/templates/tool-unix.tmpl +++ b/src/compiler/scala/tools/ant/templates/tool-unix.tmpl @@ -156,7 +156,7 @@ while [[ $# -gt 0 ]]; do java_args=("${java_args[@@]}" "$1") scala_args=("${scala_args[@@]}" "$1") # respect user-supplied -Dscala.usejavacp - case "$1" in -Dscala.usejavacp) OVERRIDE_USEJAVACP="";; esac + case "$1" in -Dscala.usejavacp*) OVERRIDE_USEJAVACP="";; esac shift ;; -J*) diff --git a/src/compiler/scala/tools/ant/templates/tool-windows.tmpl b/src/compiler/scala/tools/ant/templates/tool-windows.tmpl index 9a2deb4da6..cf0e003f10 100644 --- a/src/compiler/scala/tools/ant/templates/tool-windows.tmpl +++ b/src/compiler/scala/tools/ant/templates/tool-windows.tmpl @@ -49,7 +49,8 @@ if "%_TEST_PARAM:~0,2%"=="-J" ( ) if "%_TEST_PARAM:~0,2%"=="-D" ( - if "%_TEST_PARAM%"=="-Dscala.usejavacp" ( + rem Only match beginning of the -D option. The relevant bit is 17 chars long. + if "%_TEST_PARAM:~0,17%"=="-Dscala.usejavacp" ( set _OVERRIDE_USEJAVACP= ) rem test if this was double-quoted property "-Dprop=42" diff --git a/src/compiler/scala/tools/nsc/Global.scala b/src/compiler/scala/tools/nsc/Global.scala index c5d0c8506a..35eab94333 100644 --- a/src/compiler/scala/tools/nsc/Global.scala +++ b/src/compiler/scala/tools/nsc/Global.scala @@ -236,6 +236,7 @@ class Global(var currentSettings: Settings, var reporter: Reporter) override def inform(msg: String) = inform(NoPosition, msg) override def globalError(msg: String) = globalError(NoPosition, msg) override def warning(msg: String) = warning(NoPosition, msg) + override def deprecationWarning(pos: Position, msg: String) = currentUnit.deprecationWarning(pos, msg) def globalError(pos: Position, msg: String) = reporter.error(pos, msg) def warning(pos: Position, msg: String) = if (settings.fatalWarnings) globalError(pos, msg) else reporter.warning(pos, msg) @@ -1236,7 +1237,7 @@ class Global(var currentSettings: Settings, var reporter: Reporter) } private val unitbuf = new SyncedCompilationBuffer - + val compiledFiles = new mutable.HashSet[String] /** A map from compiled top-level symbols to their source files */ @@ -1491,7 +1492,7 @@ class Global(var currentSettings: Settings, var reporter: Reporter) made to the underlying structure. */ def units: Iterator[CompilationUnit] = unitbuf.iterator - + def registerPickle(sym: Symbol): Unit = () /** does this run compile given class, module, or case factory? */ 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 133e80788b..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 @@ -433,8 +433,10 @@ trait Contexts { self: Analyzer => case _ => false } val isImport = tree match { - case _: Import => true - case _ => false + // The guard is for SI-8403. It prevents adding imports again in the context created by + // `Namer#createInnerNamer` + case _: Import if tree != this.tree => true + case _ => false } val sameOwner = owner == this.owner val prefixInChild = @@ -542,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/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/FormatInterpolator.scala b/src/compiler/scala/tools/reflect/FormatInterpolator.scala index 0258002850..e0f9bb6044 100644 --- a/src/compiler/scala/tools/reflect/FormatInterpolator.scala +++ b/src/compiler/scala/tools/reflect/FormatInterpolator.scala @@ -93,7 +93,8 @@ abstract class FormatInterpolator { case '\n' => "\\n" case '\f' => "\\f" case '\r' => "\\r" - case '\"' => "\\u0022" // $" in future + case '\"' => "${'\"'}" /* avoid lint warn */ + + " or a triple-quoted literal \"\"\"with embedded \" or \\u0022\"\"\"" // $" in future case '\'' => "'" case '\\' => """\\""" case x => "\\u%04x" format x 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/GenTraversableOnce.scala b/src/library/scala/collection/GenTraversableOnce.scala index 01d179aeb6..0cd91409cf 100644 --- a/src/library/scala/collection/GenTraversableOnce.scala +++ b/src/library/scala/collection/GenTraversableOnce.scala @@ -506,7 +506,6 @@ trait GenTraversableOnce[+A] extends Any { def toIndexedSeq: immutable.IndexedSeq[A] /** Converts this $coll to a stream. - * $willNotTerminateInf * @return a stream containing all elements of this $coll. */ def toStream: Stream[A] 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/Printers.scala b/src/reflect/scala/reflect/internal/Printers.scala index 680c19e426..fcc377ba32 100644 --- a/src/reflect/scala/reflect/internal/Printers.scala +++ b/src/reflect/scala/reflect/internal/Printers.scala @@ -567,8 +567,8 @@ trait Printers extends api.Printers { self: SymbolTable => override protected val commentsRequired = true - protected def needsParentheses(parent: Tree)(insideIf: Boolean = true, insideMatch: Boolean = true, - insideTry: Boolean = true, insideAnnotated: Boolean = true, insideBlock: Boolean = true, insideLabelDef: Boolean = true) = { + protected def needsParentheses(parent: Tree)(insideIf: Boolean = true, insideMatch: Boolean = true, insideTry: Boolean = true, + insideAnnotated: Boolean = true, insideBlock: Boolean = true, insideLabelDef: Boolean = true, insideAssign: Boolean = true) = { parent match { case _: If => insideIf case _: Match => insideMatch @@ -576,6 +576,7 @@ trait Printers extends api.Printers { self: SymbolTable => case _: Annotated => insideAnnotated case _: Block => insideBlock case _: LabelDef => insideLabelDef + case _: Assign => insideAssign case _ => false } } 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/SymbolTable.scala b/src/reflect/scala/reflect/internal/SymbolTable.scala index e50c65c9ca..c76dedbff4 100644 --- a/src/reflect/scala/reflect/internal/SymbolTable.scala +++ b/src/reflect/scala/reflect/internal/SymbolTable.scala @@ -51,6 +51,7 @@ abstract class SymbolTable extends macros.Universe val gen = new InternalTreeGen { val global: SymbolTable.this.type = SymbolTable.this } def log(msg: => AnyRef): Unit + def deprecationWarning(pos: Position, msg: String): Unit = warning(msg) def warning(msg: String): Unit = Console.err.println(msg) def inform(msg: String): Unit = Console.err.println(msg) def globalError(msg: String): Unit = abort(msg) diff --git a/src/reflect/scala/reflect/internal/Symbols.scala b/src/reflect/scala/reflect/internal/Symbols.scala index 595d638c28..2ce54d2259 100644 --- a/src/reflect/scala/reflect/internal/Symbols.scala +++ b/src/reflect/scala/reflect/internal/Symbols.scala @@ -2343,7 +2343,11 @@ trait Symbols extends api.Symbols { self: SymbolTable => def localName: TermName = name.localName /** The setter of this value or getter definition, or NoSymbol if none exists */ + @deprecated("Use `setterIn` instead", "2.11.0") final def setter(base: Symbol, hasExpandedName: Boolean = needsExpandedSetterName): Symbol = + setterIn(base, hasExpandedName) + + final def setterIn(base: Symbol, hasExpandedName: Boolean = needsExpandedSetterName): Symbol = base.info decl setterNameInBase(base, hasExpandedName) filter (_.hasAccessorFlag) def needsExpandedSetterName = ( diff --git a/src/reflect/scala/reflect/internal/Variances.scala b/src/reflect/scala/reflect/internal/Variances.scala index 3bcfed7d34..cfe2ad8b87 100644 --- a/src/reflect/scala/reflect/internal/Variances.scala +++ b/src/reflect/scala/reflect/internal/Variances.scala @@ -75,7 +75,14 @@ trait Variances { def nextVariance(sym: Symbol, v: Variance): Variance = ( if (shouldFlip(sym, tvar)) v.flip else if (isLocalOnly(sym)) Bivariant - else if (sym.isAliasType) Invariant + else if (sym.isAliasType) ( + // Unsound pre-2.11 behavior preserved under -Xsource:2.10 + if (settings.isScala211 || sym.isOverridingSymbol) Invariant + else { + deprecationWarning(sym.pos, s"Construct depends on unsound variance analysis and will not compile in scala 2.11 and beyond") + Bivariant + } + ) else v ) def loop(sym: Symbol, v: Variance): Variance = ( 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) } } diff --git a/src/scaladoc/scala/tools/nsc/doc/ScaladocAnalyzer.scala b/src/scaladoc/scala/tools/nsc/doc/ScaladocAnalyzer.scala index 212f94c531..e5c64c6f45 100644 --- a/src/scaladoc/scala/tools/nsc/doc/ScaladocAnalyzer.scala +++ b/src/scaladoc/scala/tools/nsc/doc/ScaladocAnalyzer.scala @@ -37,7 +37,7 @@ trait ScaladocAnalyzer extends Analyzer { comment.defineVariables(sym) val typer1 = newTyper(context.makeNewScope(docDef, context.owner)) for (useCase <- comment.useCases) { - typer1.silent(_ => typer1 defineUseCases useCase) match { + typer1.silent(_.asInstanceOf[ScaladocTyper].defineUseCases(useCase)) match { case SilentTypeError(err) => unit.warning(useCase.pos, err.errMsg) case _ => |