summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/compiler/scala/reflect/internal/Definitions.scala6
-rw-r--r--src/compiler/scala/reflect/internal/SymbolTable.scala13
-rw-r--r--src/compiler/scala/reflect/internal/TreeInfo.scala2
-rw-r--r--src/compiler/scala/reflect/internal/Types.scala7
-rw-r--r--src/compiler/scala/reflect/internal/util/Collections.scala25
-rw-r--r--src/compiler/scala/reflect/reify/codegen/Types.scala2
-rw-r--r--src/compiler/scala/reflect/reify/phases/Reify.scala66
-rw-r--r--src/compiler/scala/tools/nsc/backend/icode/GenICode.scala2
-rw-r--r--src/compiler/scala/tools/nsc/interpreter/IMain.scala10
-rw-r--r--src/compiler/scala/tools/nsc/interpreter/Power.scala3
-rw-r--r--src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala2
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala5
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Implicits.scala2
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Macros.scala35
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/PatMatVirtualiser.scala6
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/TreeCheckers.scala2
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Typers.scala24
-rw-r--r--src/library/scala/reflect/makro/Reifiers.scala2
18 files changed, 134 insertions, 80 deletions
diff --git a/src/compiler/scala/reflect/internal/Definitions.scala b/src/compiler/scala/reflect/internal/Definitions.scala
index 6cb935edad..d89e852124 100644
--- a/src/compiler/scala/reflect/internal/Definitions.scala
+++ b/src/compiler/scala/reflect/internal/Definitions.scala
@@ -103,7 +103,7 @@ trait Definitions extends reflect.api.StandardDefinitions {
getMemberMethod(valueClassCompanion(className.toTermName).moduleClass, methodName)
private def classesMap[T](f: Name => T) = symbolsMap(ScalaValueClassesNoUnit, f)
- private def symbolsMap[T](syms: List[Symbol], f: Name => T): Map[Symbol, T] = syms zip (syms map (x => f(x.name))) toMap
+ private def symbolsMap[T](syms: List[Symbol], f: Name => T): Map[Symbol, T] = mapFrom(syms)(x => f(x.name))
private def symbolsMapFilt[T](syms: List[Symbol], p: Name => Boolean, f: Name => T) = symbolsMap(syms filter (x => p(x.name)), f)
private def boxedName(name: Name) = sn.Boxed(name.toTypeName)
@@ -493,8 +493,8 @@ trait Definitions extends reflect.api.StandardDefinitions {
lazy val NoManifest = getRequiredModule("scala.reflect.NoManifest")
lazy val ExprClass = getMember(getRequiredClass("scala.reflect.api.Exprs"), tpnme.Expr)
- def ExprTree = getMemberClass(ExprClass, nme.tree)
- def ExprTpe = getMemberClass(ExprClass, nme.tpe)
+ def ExprTree = getMember(ExprClass, nme.tree)
+ def ExprTpe = getMember(ExprClass, nme.tpe)
def ExprEval = getMember(ExprClass, nme.eval)
def ExprValue = getMember(ExprClass, nme.value)
lazy val ExprModule = getMember(getRequiredClass("scala.reflect.api.Exprs"), nme.Expr)
diff --git a/src/compiler/scala/reflect/internal/SymbolTable.scala b/src/compiler/scala/reflect/internal/SymbolTable.scala
index 7d9dd282cf..9158c2a4d4 100644
--- a/src/compiler/scala/reflect/internal/SymbolTable.scala
+++ b/src/compiler/scala/reflect/internal/SymbolTable.scala
@@ -76,6 +76,19 @@ abstract class SymbolTable extends api.Universe
result
}
+ // For too long have we suffered in order to sort NAMES.
+ // I'm pretty sure there's a reasonable default for that.
+ // Notice challenge created by Ordering's invariance.
+ implicit def lowPriorityNameOrdering[T <: Names#Name]: Ordering[T] =
+ SimpleNameOrdering.asInstanceOf[Ordering[T]]
+
+ private object SimpleNameOrdering extends Ordering[Names#Name] {
+ def compare(n1: Names#Name, n2: Names#Name) = (
+ if (n1 eq n2) 0
+ else n1.toString compareTo n2.toString
+ )
+ }
+
/** Dump each symbol to stdout after shutdown.
*/
final val traceSymbolActivity = sys.props contains "scalac.debug.syms"
diff --git a/src/compiler/scala/reflect/internal/TreeInfo.scala b/src/compiler/scala/reflect/internal/TreeInfo.scala
index 48dfe8bcfc..f4878139e9 100644
--- a/src/compiler/scala/reflect/internal/TreeInfo.scala
+++ b/src/compiler/scala/reflect/internal/TreeInfo.scala
@@ -602,7 +602,7 @@ abstract class TreeInfo {
object ReifiedTree {
def unapply(tree: Tree): Option[(Tree, List[Tree], Tree, Tree)] = tree match {
- case reifee @ Block((mrDef @ ValDef(_, _, _, _)) :: symbolTable, Apply(Apply(_, List(tree)), List(Apply(_, List(tpe))))) if mrDef.name == nme.MIRROR_SHORT =>
+ case reifee @ Block((mrDef @ ValDef(_, _, _, _)) :: symbolTable, Apply(Apply(_, List(tree)), List(Apply(_, tpe :: _)))) if mrDef.name == nme.MIRROR_SHORT =>
Some(reifee, symbolTable, tree, tpe)
case _ =>
None
diff --git a/src/compiler/scala/reflect/internal/Types.scala b/src/compiler/scala/reflect/internal/Types.scala
index 815a5c0710..2fe7dfda17 100644
--- a/src/compiler/scala/reflect/internal/Types.scala
+++ b/src/compiler/scala/reflect/internal/Types.scala
@@ -1509,7 +1509,8 @@ trait Types extends api.Types { self: SymbolTable =>
case tv: TypeVar => tvs += tv
case _ =>
}
- val varToParamMap: Map[Type, Symbol] = tvs map (tv => tv -> tv.origin.typeSymbol.cloneSymbol) toMap
+ val varToParamMap: Map[Type, Symbol] =
+ mapFrom[TypeVar, Type, Symbol](tvs.toList)(_.origin.typeSymbol.cloneSymbol)
val paramToVarMap = varToParamMap map (_.swap)
val varToParam = new TypeMap {
def apply(tp: Type) = varToParamMap get tp match {
@@ -3473,7 +3474,7 @@ trait Types extends api.Types { self: SymbolTable =>
case TypeRef(pre, sym, _) if sameLength(sym.typeParams, args) =>
val eparams = typeParamsToExistentials(sym)
val bounds = args map (TypeBounds upper _)
- (eparams, bounds).zipped foreach (_ setInfo _)
+ foreach2(eparams, bounds)(_ setInfo _)
newExistentialType(eparams, typeRef(pre, sym, eparams map (_.tpe)))
case _ =>
@@ -3655,7 +3656,7 @@ trait Types extends api.Types { self: SymbolTable =>
else owner.newValueParameter(name.toTermName)
paramStack = newParams :: paramStack
try {
- (newParams, ptypes).zipped foreach ((p, t) => p setInfo this(t))
+ foreach2(newParams, ptypes)((p, t) => p setInfo this(t))
val restpe1 = this(restpe)
if (isType) PolyType(newParams, restpe1)
else MethodType(newParams, restpe1)
diff --git a/src/compiler/scala/reflect/internal/util/Collections.scala b/src/compiler/scala/reflect/internal/util/Collections.scala
index 9e4ae1ca00..2e119f8ccc 100644
--- a/src/compiler/scala/reflect/internal/util/Collections.scala
+++ b/src/compiler/scala/reflect/internal/util/Collections.scala
@@ -70,6 +70,27 @@ trait Collections {
lb.toList
}
+ final def flatCollect[A, B](elems: List[A])(pf: PartialFunction[A, Traversable[B]]): List[B] = {
+ val lb = new ListBuffer[B]
+ for (x <- elems ; if pf isDefinedAt x)
+ lb ++= pf(x)
+
+ lb.toList
+ }
+
+ final def distinctBy[A, B](xs: List[A])(f: A => B): List[A] = {
+ val buf = new ListBuffer[A]
+ val seen = mutable.Set[B]()
+ xs foreach { x =>
+ val y = f(x)
+ if (!seen(y)) {
+ buf += x
+ seen += y
+ }
+ }
+ buf.toList
+ }
+
@tailrec final def flattensToEmpty(xss: Seq[Seq[_]]): Boolean = {
xss.isEmpty || xss.head.isEmpty && flattensToEmpty(xss.tail)
}
@@ -89,6 +110,10 @@ trait Collections {
xs find p getOrElse orElse
}
+ final def mapFrom[A, A1 >: A, B](xs: List[A])(f: A => B): Map[A1, B] = {
+ Map[A1, B](xs map (x => (x, f(x))): _*)
+ }
+
final def mapWithIndex[A, B](xs: List[A])(f: (A, Int) => B): List[B] = {
val lb = new ListBuffer[B]
var index = 0
diff --git a/src/compiler/scala/reflect/reify/codegen/Types.scala b/src/compiler/scala/reflect/reify/codegen/Types.scala
index 841ec61e60..8fa24c5b00 100644
--- a/src/compiler/scala/reflect/reify/codegen/Types.scala
+++ b/src/compiler/scala/reflect/reify/codegen/Types.scala
@@ -84,7 +84,7 @@ trait Types {
def spliceType(tpe: Type): Tree = {
// [Eugene] it seems that depending on the context the very same symbol can be either a spliceable tparam or a quantified existential. very weird!
- val quantified = currents collect { case ExistentialType(quantified, _) => quantified } flatMap identity
+ val quantified = currentQuantified
if (tpe.isSpliceable && !(quantified contains tpe.typeSymbol)) {
if (reifyDebug) println("splicing " + tpe)
diff --git a/src/compiler/scala/reflect/reify/phases/Reify.scala b/src/compiler/scala/reflect/reify/phases/Reify.scala
index a1ff486ed7..e03ff5832c 100644
--- a/src/compiler/scala/reflect/reify/phases/Reify.scala
+++ b/src/compiler/scala/reflect/reify/phases/Reify.scala
@@ -19,37 +19,47 @@ trait Reify extends Symbols
import definitions._
import treeInfo._
+ // `reify` looked so nice, I wanted to push the last bit of orthogonal
+ // logic out of it so you can see the improvement. There is no cost to
+ // wrapper methods of this form because the inliner will eliminate them,
+ // but they are very good at separating concerns like pushing/popping
+ // a stack, and they are great for composition and reuse.
+ //
+ // Also, please avoid public vars whenever possible.
+ private object reifyStack {
+ var currents: List[Any] = reifee :: Nil
+
+ @inline final def push[T](reifee: Any)(body: => T): T = {
+ currents ::= reifee
+ try body
+ finally currents = currents.tail
+ }
+ }
+ def currentQuantified = flatCollect(reifyStack.currents)({ case ExistentialType(quantified, _) => quantified })
+ def current = reifyStack.currents.head
+
/**
* Reifies any supported value.
* For internal use only, use ``reified'' instead.
*/
- var currents: List[Any] = reifee :: Nil
- def current = currents.head
- def reify(reifee: Any): Tree = {
- currents = reifee :: currents
- try {
- reifee match {
- // before adding some case here, in global scope, please, consider
- // whether it can be localized like reifyAnnotationInfo or reifyScope
- // this will help reification stay as sane as possible
- case sym: Symbol => reifySymRef(sym)
- case tpe: Type => reifyType(tpe)
- case name: Name => reifyName(name)
- case tree: Tree => reifyTree(tree)
- // disabled because this is a very special case that I plan to remove later
- // why do I dislike annotations? see comments to `reifyAnnotationInfo`
+ def reify(reifee: Any): Tree = reifyStack.push(reifee)(reifee match {
+ // before adding some case here, in global scope, please, consider
+ // whether it can be localized like reifyAnnotationInfo or reifyScope
+ // this will help reification stay as sane as possible
+ case sym: Symbol => reifySymRef(sym)
+ case tpe: Type => reifyType(tpe)
+ case name: Name => reifyName(name)
+ case tree: Tree => reifyTree(tree)
+ // disabled because this is a very special case that I plan to remove later
+ // why do I dislike annotations? see comments to `reifyAnnotationInfo`
// case ann: AnnotationInfo => reifyAnnotationInfo(ann)
- case pos: Position => reifyPosition(pos)
- case mods: mirror.Modifiers => reifyModifiers(mods)
- case xs: List[_] => reifyList(xs)
- case s: String => Literal(Constant(s))
- case v if isAnyVal(v) => Literal(Constant(v))
- case null => Literal(Constant(null))
- case _ =>
- throw new Error("reifee %s of type %s is not supported".format(reifee, reifee.getClass))
- }
- } finally {
- currents = currents.tail
- }
- }
+ case pos: Position => reifyPosition(pos)
+ case mods: mirror.Modifiers => reifyModifiers(mods)
+ case xs: List[_] => reifyList(xs)
+ case s: String => Literal(Constant(s))
+ case v if isAnyVal(v) => Literal(Constant(v))
+ case null => Literal(Constant(null))
+ case _ =>
+ throw new Error("reifee %s of type %s is not supported".format(reifee, reifee.getClass))
+ })
} \ No newline at end of file
diff --git a/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala b/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala
index ff58de5f12..5e5b09405c 100644
--- a/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala
+++ b/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala
@@ -2225,7 +2225,7 @@ abstract class GenICode extends SubComponent {
* jumps to the given basic block.
*/
def patch(code: Code) {
- val map = toPatch map (i => (i -> patch(i))) toMap;
+ val map = mapFrom(toPatch)(patch)
code.blocks foreach (_ subst map)
}
diff --git a/src/compiler/scala/tools/nsc/interpreter/IMain.scala b/src/compiler/scala/tools/nsc/interpreter/IMain.scala
index 3d77344091..a9c2ce0d09 100644
--- a/src/compiler/scala/tools/nsc/interpreter/IMain.scala
+++ b/src/compiler/scala/tools/nsc/interpreter/IMain.scala
@@ -369,7 +369,7 @@ class IMain(initialSettings: Settings, protected val out: JPrintWriter) extends
def flatName(id: String) = optFlatName(id) getOrElse id
def optFlatName(id: String) = requestForIdent(id) map (_ fullFlatName id)
- def allDefinedNames = definedNameMap.keys.toList sortBy (_.toString)
+ def allDefinedNames = definedNameMap.keys.toList.sorted
def pathToType(id: String): String = pathToName(newTypeName(id))
def pathToTerm(id: String): String = pathToName(newTermName(id))
def pathToName(name: Name): String = {
@@ -1007,9 +1007,8 @@ class IMain(initialSettings: Settings, protected val out: JPrintWriter) extends
def lookupTypeOf(name: Name) = typeOf.getOrElse(name, typeOf(global.encode(name.toString)))
def simpleNameOfType(name: TypeName) = (compilerTypeOf get name) map (_.typeSymbol.simpleName)
- private def typeMap[T](f: Type => T): Map[Name, T] = {
- termNames ++ typeNames map (x => x -> f(cleanMemberDecl(resultSymbol, x))) toMap
- }
+ private def typeMap[T](f: Type => T) =
+ mapFrom[Name, Name, T](termNames ++ typeNames)(x => f(cleanMemberDecl(resultSymbol, x)))
/** Types of variables defined by this request. */
lazy val compilerTypeOf = typeMap[Type](x => x) withDefaultValue NoType
@@ -1024,8 +1023,7 @@ class IMain(initialSettings: Settings, protected val out: JPrintWriter) extends
typeNames.map(x => x -> compilerTypeOf(x).typeSymbol)
).toMap[Name, Symbol] withDefaultValue NoSymbol
- lazy val typesOfDefinedTerms: Map[Name, Type] =
- termNames map (x => x -> applyToResultMember(x, _.tpe)) toMap
+ lazy val typesOfDefinedTerms = mapFrom[Name, Name, Type](termNames)(x => applyToResultMember(x, _.tpe))
/** load and run the code using reflection */
def loadAndRun: (String, Boolean) = {
diff --git a/src/compiler/scala/tools/nsc/interpreter/Power.scala b/src/compiler/scala/tools/nsc/interpreter/Power.scala
index 01ace0e984..659caad1e1 100644
--- a/src/compiler/scala/tools/nsc/interpreter/Power.scala
+++ b/src/compiler/scala/tools/nsc/interpreter/Power.scala
@@ -231,7 +231,7 @@ class Power[ReplValsImpl <: ReplVals : TypeTag](val intp: IMain, replVals: ReplV
def shortClass = erasure.getName split "[$.]" last
def baseClasses = tpe.baseClasses
- def baseClassDecls = baseClasses map (x => (x, x.info.decls.toList.sortBy(_.name.toString))) toMap
+ def baseClassDecls = mapFrom(baseClasses)(_.info.decls.toList.sortBy(_.name))
def ancestors = baseClasses drop 1
def ancestorDeclares(name: String) = ancestors filter (_.info member newTermName(name) ne NoSymbol)
def baseTypes = tpe.baseTypeSeq.toList
@@ -362,7 +362,6 @@ class Power[ReplValsImpl <: ReplVals : TypeTag](val intp: IMain, replVals: ReplV
else if (s1 isLess s2) -1
else 1
}
- implicit lazy val powerNameOrdering: Ordering[Name] = Ordering[String] on (_.toString)
implicit lazy val powerSymbolOrdering: Ordering[Symbol] = Ordering[Name] on (_.name)
implicit lazy val powerTypeOrdering: Ordering[Type] = Ordering[Symbol] on (_.typeSymbol)
diff --git a/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala b/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala
index ff671088ac..1fb7fac184 100644
--- a/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala
+++ b/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala
@@ -820,7 +820,7 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers {
// concise printing of type env
private def pp(env: TypeEnv): String = {
- env.toList.sortBy(_._1.name.toString) map {
+ env.toList.sortBy(_._1.name) map {
case (k, v) =>
val vsym = v.typeSymbol
if (k == vsym) "" + k.name
diff --git a/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala b/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala
index c13be0e39d..2d1369b11d 100644
--- a/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala
@@ -343,6 +343,11 @@ trait ContextErrors {
issueNormalTypeError(tree, "macros cannot be eta-expanded")
setError(tree)
}
+
+ def MacroPartialApplicationError(tree: Tree) = {
+ issueNormalTypeError(tree, "macros cannot be partially applied")
+ setError(tree)
+ }
//typedReturn
def ReturnOutsideOfDefError(tree: Tree) = {
diff --git a/src/compiler/scala/tools/nsc/typechecker/Implicits.scala b/src/compiler/scala/tools/nsc/typechecker/Implicits.scala
index 1612253dd6..0d7ef71193 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Implicits.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Implicits.scala
@@ -831,7 +831,7 @@ trait Implicits {
/** Returns all eligible ImplicitInfos and their SearchResults in a map.
*/
- def findAll() = (eligible map (info => (info, typedImplicit(info, false)))).toMap
+ def findAll() = mapFrom(eligible)(typedImplicit(_, false))
/** Returns the SearchResult of the best match.
*/
diff --git a/src/compiler/scala/tools/nsc/typechecker/Macros.scala b/src/compiler/scala/tools/nsc/typechecker/Macros.scala
index 5d4cd0be77..ef9bae700e 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Macros.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Macros.scala
@@ -388,6 +388,7 @@ trait Macros { self: Analyzer =>
compatibilityError("types incompatible for parameter "+aparam.name+": corresponding is not a vararg parameter")
if (!hasErrors) {
var atpe = aparam.tpe.substSym(flatactparams, flatreqparams).instantiateTypeParams(tparams, tvars)
+ atpe = atpe.dealias // SI-5706
// strip the { type PrefixType = ... } refinement off the Context or otherwise we get compatibility errors
atpe = atpe match {
case RefinedType(List(tpe), Scope(sym)) if tpe == MacroContextClass.tpe && sym.allOverriddenSymbols.contains(MacroContextPrefixType) => tpe
@@ -855,7 +856,7 @@ trait Macros { self: Analyzer =>
val numParamLists = paramss_without_evidences.length
val numArgLists = argss.length
if (numParamLists != numArgLists) {
- typer.context.error(expandee.pos, "macros cannot be partially applied")
+ typer.TyperErrorGen.MacroPartialApplicationError(expandee)
return None
}
@@ -953,6 +954,11 @@ trait Macros { self: Analyzer =>
* the expandee with an error marker set if there has been an error
*/
def macroExpand(typer: Typer, expandee: Tree, mode: Int = EXPRmode, pt: Type = WildcardType): Tree = {
+ def fail(what: String, tree: Tree): Tree = {
+ val err = typer.context.errBuffer.head
+ this.fail(typer, tree, "failed to perform %s: %s at %s".format(what, err.errMsg, err.errPos))
+ return expandee
+ }
val start = startTimer(macroExpandNanos)
incCounter(macroExpandCount)
try {
@@ -979,15 +985,9 @@ trait Macros { self: Analyzer =>
case _ => ;
}
- def fail(what: String): Tree = {
- val err = typer.context.errBuffer.head
- this.fail(typer, expanded, "failed to perform %s: %s at %s".format(what, err.errMsg, err.errPos))
- return expandee
- }
-
if (macroDebug) println("typechecking1 against %s: %s".format(expectedTpe, expanded))
var typechecked = typer.context.withImplicitsEnabled(typer.typed(expanded, EXPRmode, expectedTpe))
- if (typer.context.hasErrors) fail("typecheck1")
+ if (typer.context.hasErrors) fail("typecheck1", expanded)
if (macroDebug) {
println("typechecked1:")
println(typechecked)
@@ -996,7 +996,7 @@ trait Macros { self: Analyzer =>
if (macroDebug) println("typechecking2 against %s: %s".format(pt, expanded))
typechecked = typer.context.withImplicitsEnabled(typer.typed(typechecked, EXPRmode, pt))
- if (typer.context.hasErrors) fail("typecheck2")
+ if (typer.context.hasErrors) fail("typecheck2", expanded)
if (macroDebug) {
println("typechecked2:")
println(typechecked)
@@ -1009,13 +1009,16 @@ trait Macros { self: Analyzer =>
}
case Delay(expandee) =>
// need to save the context to preserve enclosures
- val args = macroArgs(typer, expandee)
- assert(args.isDefined, expandee)
- val context = args.get.head.asInstanceOf[MacroContext]
- var result = expandee withAttachment MacroAttachment(delayed = true, context = Some(context))
- // adapting here would be premature, we must wait until undetparams are inferred
-// result = typer.adapt(result, mode, pt)
- result
+ macroArgs(typer, expandee) match {
+ case Some((context: MacroContext) :: _) =>
+ // adapting here would be premature, we must wait until undetparams are inferred
+ expandee withAttachment MacroAttachment(delayed = true, context = Some(context))
+ case _ =>
+ // !!! The correct place to issue an error needs to be clarified.
+ // I have the else condition here only as a fallback.
+ if (expandee.isErroneous) expandee
+ else fail("macros cannot be partially applied", expandee)
+ }
case Fallback(fallback) =>
typer.context.withImplicitsEnabled(typer.typed(fallback, EXPRmode, pt))
case Other(result) =>
diff --git a/src/compiler/scala/tools/nsc/typechecker/PatMatVirtualiser.scala b/src/compiler/scala/tools/nsc/typechecker/PatMatVirtualiser.scala
index 96d92e0609..e5dc8e9ca9 100644
--- a/src/compiler/scala/tools/nsc/typechecker/PatMatVirtualiser.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/PatMatVirtualiser.scala
@@ -46,7 +46,7 @@ trait PatMatVirtualiser extends ast.TreeDSL { self: Analyzer =>
val outer = newTermName("<outer>")
val runOrElse = newTermName("runOrElse")
val zero = newTermName("zero")
- val _match = newTermName("__match") // don't call it __match, since that will trigger virtual pattern matching...
+ val _match = newTermName("__match") // don't call the val __match, since that will trigger virtual pattern matching...
def counted(str: String, i: Int) = newTermName(str+i)
}
@@ -1067,7 +1067,7 @@ class Foo(x: Other) { x._1 } // no error in this order
// assert(owner ne null); assert(owner ne NoSymbol)
def freshSym(pos: Position, tp: Type = NoType, prefix: String = "x") =
- NoSymbol.newTermSymbol(freshName(prefix), pos) setInfo /*repackExistential*/(tp)
+ NoSymbol.newTermSymbol(freshName(prefix), pos) setInfo tp
// codegen relevant to the structure of the translation (how extractors are combined)
trait AbsCodegen {
@@ -1141,7 +1141,7 @@ class Foo(x: Other) { x._1 } // no error in this order
val matchStrategy: Tree
def inMatchMonad(tp: Type): Type = appliedType(oneSig, List(tp)).finalResultType
- def pureType(tp: Type): Type = appliedType(oneSig, List(tp)).paramTypes.head
+ def pureType(tp: Type): Type = appliedType(oneSig, List(tp)).paramTypes.headOption getOrElse NoType // fail gracefully (otherwise we get crashes)
protected def matchMonadSym = oneSig.finalResultType.typeSymbol
import CODE._
diff --git a/src/compiler/scala/tools/nsc/typechecker/TreeCheckers.scala b/src/compiler/scala/tools/nsc/typechecker/TreeCheckers.scala
index 4319dd10c7..a6a8d6009f 100644
--- a/src/compiler/scala/tools/nsc/typechecker/TreeCheckers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/TreeCheckers.scala
@@ -57,7 +57,7 @@ abstract class TreeCheckers extends Analyzer {
def prev = maps.init.last._2
def latest = maps.last._2
- def sortedNewSyms = newSyms.toList.distinct sortBy (_.name.toString)
+ def sortedNewSyms = newSyms.toList.distinct sortBy (_.name)
def inPrev(sym: Symbol) = {
(maps.size >= 2) && (prev contains sym)
diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
index 1414424a0b..934a7567d5 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
@@ -83,6 +83,9 @@ trait Typers extends Modes with Adaptations with Taggings with PatMatVirtualiser
private def isPastTyper = phase.id > currentRun.typerPhase.id
+ // don't translate matches in presentation compiler: it loses vital symbols that are needed to do hyperlinking
+ @inline private def doMatchTranslation = !forInteractive && opt.virtPatmat && (phase.id < currentRun.uncurryPhase.id)
+
abstract class Typer(context0: Context) extends TyperDiagnostics with Adaptation with Tagging with TyperContextErrors {
import context0.unit
import typeDebug.{ ptTree, ptBlock, ptLine }
@@ -2436,7 +2439,7 @@ trait Typers extends Modes with Adaptations with Taggings with PatMatVirtualiser
fun.body match {
// later phase indicates scaladoc is calling (where shit is messed up, I tell you)
// -- so fall back to old patmat, which is more forgiving
- case Match(sel, cases) if opt.virtPatmat && (phase.id < currentRun.uncurryPhase.id) =>
+ case Match(sel, cases) if doMatchTranslation =>
// go to outer context -- must discard the context that was created for the Function since we're discarding the function
// thus, its symbol, which serves as the current context.owner, is not the right owner
// you won't know you're using the wrong owner until lambda lift crashes (unless you know better than to use the wrong owner)
@@ -3289,14 +3292,12 @@ trait Typers extends Modes with Adaptations with Taggings with PatMatVirtualiser
case tp => tp
}
- (hidden map { s =>
- // Hanging onto lower bound in case anything interesting
- // happens with it.
- (s, s.existentialBound match {
- case TypeBounds(lo, hi) => TypeBounds(lo, hiBound(s))
- case _ => hiBound(s)
- })
- }).toMap
+ // Hanging onto lower bound in case anything interesting
+ // happens with it.
+ mapFrom(hidden)(s => s.existentialBound match {
+ case TypeBounds(lo, hi) => TypeBounds(lo, hiBound(s))
+ case _ => hiBound(s)
+ })
}
/** Given a set `rawSyms` of term- and type-symbols, and a type
@@ -3830,7 +3831,7 @@ trait Typers extends Modes with Adaptations with Taggings with PatMatVirtualiser
}
def typedTranslatedMatch(tree: Tree, selector: Tree, cases: List[CaseDef]): Tree = {
- if (opt.virtPatmat && (phase.id < currentRun.uncurryPhase.id)) {
+ if (doMatchTranslation) {
if (selector ne EmptyTree) {
val (selector1, selectorTp, casesAdapted, ownType, doTranslation) = typedMatch(selector, cases, mode, pt)
typed(translatedMatch(selector1, selectorTp, casesAdapted, ownType, doTranslation), mode, pt)
@@ -4734,9 +4735,8 @@ trait Typers extends Modes with Adaptations with Taggings with PatMatVirtualiser
catches1 = catches1 map (adaptCase(_, mode, owntype))
}
- if((phase.id < currentRun.uncurryPhase.id) && opt.virtPatmat) {
+ if (doMatchTranslation)
catches1 = (MatchTranslator(this)).translateTry(catches1, owntype, tree.pos)
- }
treeCopy.Try(tree, block1, catches1, finalizer1) setType owntype
diff --git a/src/library/scala/reflect/makro/Reifiers.scala b/src/library/scala/reflect/makro/Reifiers.scala
index ae6669946c..b1de8d9957 100644
--- a/src/library/scala/reflect/makro/Reifiers.scala
+++ b/src/library/scala/reflect/makro/Reifiers.scala
@@ -74,4 +74,4 @@ trait Reifiers {
case class ReificationError(var pos: reflect.api.Position, val msg: String) extends Throwable(msg)
-case class UnexpectedReificationError(val pos: reflect.api.Position, val msg: String, val cause: Throwable = null) extends Throwable(msg) \ No newline at end of file
+case class UnexpectedReificationError(val pos: reflect.api.Position, val msg: String, val cause: Throwable = null) extends Throwable(msg, cause) \ No newline at end of file