summaryrefslogtreecommitdiff
path: root/src/compiler/scala/tools
diff options
context:
space:
mode:
authorJason Zaugg <jzaugg@gmail.com>2013-10-29 16:04:17 +0100
committerJason Zaugg <jzaugg@gmail.com>2013-11-08 08:25:18 +0100
commita5127a8392fd2a0bce9b3ced302b4ebe1a80bc65 (patch)
tree4d52b8ed7dd8fcfb10d4bef41198ffe6ecc7cfe6 /src/compiler/scala/tools
parent3dba9932fcc79ce0ea6f7c9282320c14c95d133f (diff)
downloadscala-a5127a8392fd2a0bce9b3ced302b4ebe1a80bc65.tar.gz
scala-a5127a8392fd2a0bce9b3ced302b4ebe1a80bc65.tar.bz2
scala-a5127a8392fd2a0bce9b3ced302b4ebe1a80bc65.zip
SI-7678 Don't cache member symbols of TypeTags in Definitions.
It we can only safely use vals in Definitions for top-level symbols. Otherwise, when the IDE switches to loading the symbol from source, we can hold on to a stale symbol, which in turn impedes implicit materialization of TypeTags. This commit moves (most) of the accessors for member symbols into RunDefinitions, and changes calling code accordingly. This is a win for presentation compiler correctness, and might even shave of a few cycles. In a few cases, I have had to leave a `def` to a member symbol in Definitions so we can get to it from the SymbolTable cake, which doesn't see RunDefinitions. The macro FastTrack facility now correctly recreates the mapping from Symbol to macro implementation each run, using a new facility in perRunCaches to create a run-indexed cache. The enclosed test recreates the situation reported in the ticket, in which TypeTags.scala is loaded from source.
Diffstat (limited to 'src/compiler/scala/tools')
-rw-r--r--src/compiler/scala/tools/nsc/backend/icode/GenICode.scala4
-rw-r--r--src/compiler/scala/tools/nsc/backend/jvm/BCodeBodyBuilder.scala4
-rw-r--r--src/compiler/scala/tools/nsc/backend/jvm/BCodeTypes.scala4
-rw-r--r--src/compiler/scala/tools/nsc/transform/CleanUp.scala11
-rw-r--r--src/compiler/scala/tools/nsc/transform/Constructors.scala1
-rw-r--r--src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala1
-rw-r--r--src/compiler/scala/tools/nsc/transform/TypeAdaptingTransformer.scala8
-rw-r--r--src/compiler/scala/tools/nsc/transform/patmat/MatchCodeGen.scala2
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Adaptations.scala2
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Implicits.scala2
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Macros.scala9
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/RefChecks.scala2
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Tags.scala3
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Typers.scala6
-rw-r--r--src/compiler/scala/tools/reflect/FastTrack.scala25
15 files changed, 53 insertions, 31 deletions
diff --git a/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala b/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala
index a80fee876e..d44e7a9312 100644
--- a/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala
+++ b/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala
@@ -702,7 +702,7 @@ abstract class GenICode extends SubComponent {
}
genLoadApply3
- case Apply(fun @ _, List(expr)) if (definitions.isBox(fun.symbol)) =>
+ case Apply(fun @ _, List(expr)) if currentRun.runDefinitions.isBox(fun.symbol) =>
def genLoadApply4 = {
debuglog("BOX : " + fun.symbol.fullName)
val ctx1 = genLoad(expr, ctx, toTypeKind(expr.tpe))
@@ -721,7 +721,7 @@ abstract class GenICode extends SubComponent {
}
genLoadApply4
- case Apply(fun @ _, List(expr)) if (definitions.isUnbox(fun.symbol)) =>
+ case Apply(fun @ _, List(expr)) if (currentRun.runDefinitions.isUnbox(fun.symbol)) =>
debuglog("UNBOX : " + fun.symbol.fullName)
val ctx1 = genLoad(expr, ctx, toTypeKind(expr.tpe))
val boxType = toTypeKind(fun.symbol.owner.linkedClassOfClass.tpe)
diff --git a/src/compiler/scala/tools/nsc/backend/jvm/BCodeBodyBuilder.scala b/src/compiler/scala/tools/nsc/backend/jvm/BCodeBodyBuilder.scala
index 3bacc26a3a..c166b0bb7e 100644
--- a/src/compiler/scala/tools/nsc/backend/jvm/BCodeBodyBuilder.scala
+++ b/src/compiler/scala/tools/nsc/backend/jvm/BCodeBodyBuilder.scala
@@ -623,14 +623,14 @@ abstract class BCodeBodyBuilder extends BCodeSkelBuilder {
abort(s"Cannot instantiate $tpt of kind: $generatedType")
}
- case Apply(fun @ _, List(expr)) if definitions.isBox(fun.symbol) =>
+ case Apply(fun @ _, List(expr)) if currentRun.runDefinitions.isBox(fun.symbol) =>
val nativeKind = tpeTK(expr)
genLoad(expr, nativeKind)
val MethodNameAndType(mname, mdesc) = asmBoxTo(nativeKind)
bc.invokestatic(BoxesRunTime.getInternalName, mname, mdesc)
generatedType = boxResultType(fun.symbol) // was toTypeKind(fun.symbol.tpe.resultType)
- case Apply(fun @ _, List(expr)) if definitions.isUnbox(fun.symbol) =>
+ case Apply(fun @ _, List(expr)) if currentRun.runDefinitions.isUnbox(fun.symbol) =>
genLoad(expr)
val boxType = unboxResultType(fun.symbol) // was toTypeKind(fun.symbol.owner.linkedClassOfClass.tpe)
generatedType = boxType
diff --git a/src/compiler/scala/tools/nsc/backend/jvm/BCodeTypes.scala b/src/compiler/scala/tools/nsc/backend/jvm/BCodeTypes.scala
index 39fea9a486..916d118b6e 100644
--- a/src/compiler/scala/tools/nsc/backend/jvm/BCodeTypes.scala
+++ b/src/compiler/scala/tools/nsc/backend/jvm/BCodeTypes.scala
@@ -90,11 +90,11 @@ abstract class BCodeTypes extends BCodeIdiomatic {
)
boxResultType =
- for(Pair(csym, msym) <- definitions.boxMethod)
+ for(Pair(csym, msym) <- currentRun.runDefinitions.boxMethod)
yield (msym -> classLiteral(primitiveTypeMap(csym)))
unboxResultType =
- for(Pair(csym, msym) <- definitions.unboxMethod)
+ for(Pair(csym, msym) <- currentRun.runDefinitions.unboxMethod)
yield (msym -> primitiveTypeMap(csym))
// boxed classes are looked up in the `exemplars` map by jvmWiseLUB().
diff --git a/src/compiler/scala/tools/nsc/transform/CleanUp.scala b/src/compiler/scala/tools/nsc/transform/CleanUp.scala
index 0135190256..3ecce8d7b1 100644
--- a/src/compiler/scala/tools/nsc/transform/CleanUp.scala
+++ b/src/compiler/scala/tools/nsc/transform/CleanUp.scala
@@ -168,7 +168,7 @@ abstract class CleanUp extends Transform with ast.TreeDSL {
def methodSymRHS = ((REF(forReceiverSym) DOT Class_getMethod)(LIT(method), REF(reflParamsCacheSym)))
def cacheRHS = ((REF(methodCache) DOT methodCache_add)(REF(forReceiverSym), REF(methodSym)))
BLOCK(
- REF(methodSym) === (REF(ensureAccessibleMethod) APPLY (methodSymRHS)),
+ REF(methodSym) === (REF(currentRun.runDefinitions.ensureAccessibleMethod) APPLY (methodSymRHS)),
REF(reflPolyCacheSym) === gen.mkSoftRef(cacheRHS),
Return(REF(methodSym))
)
@@ -181,11 +181,11 @@ abstract class CleanUp extends Transform with ast.TreeDSL {
def testForName(name: Name): Tree => Tree = t => (
if (nme.CommonOpNames(name))
- gen.mkMethodCall(Boxes_isNumberOrBool, t :: Nil)
+ gen.mkMethodCall(currentRun.runDefinitions.Boxes_isNumberOrBool, t :: Nil)
else if (nme.BooleanOpNames(name))
t IS_OBJ BoxedBooleanClass.tpe
else
- gen.mkMethodCall(Boxes_isNumber, t :: Nil)
+ gen.mkMethodCall(currentRun.runDefinitions.Boxes_isNumber, t :: Nil)
)
/* The Tree => Tree function in the return is necessary to prevent the original qual
@@ -219,6 +219,9 @@ abstract class CleanUp extends Transform with ast.TreeDSL {
/* ### CALLING THE APPLY ### */
def callAsReflective(paramTypes: List[Type], resType: Type): Tree = {
+ val runDefinitions = currentRun.runDefinitions
+ import runDefinitions._
+
gen.evalOnce(qual, currentOwner, unit) { qual1 =>
/* Some info about the type of the method being called. */
val methSym = ad.symbol
@@ -518,7 +521,7 @@ abstract class CleanUp extends Transform with ast.TreeDSL {
//
// See SI-6611; we must *only* do this for literal vararg arrays.
case Apply(appMeth, List(Apply(wrapRefArrayMeth, List(arg @ StripCast(ArrayValue(_, _)))), _))
- if wrapRefArrayMeth.symbol == Predef_wrapRefArray && appMeth.symbol == ArrayModule_genericApply =>
+ if wrapRefArrayMeth.symbol == currentRun.runDefinitions.Predef_wrapRefArray && appMeth.symbol == ArrayModule_genericApply =>
super.transform(arg)
case Apply(appMeth, List(elem0, Apply(wrapArrayMeth, List(rest @ ArrayValue(elemtpt, _)))))
if wrapArrayMeth.symbol == Predef_wrapArray(elemtpt.tpe) && appMeth.symbol == ArrayModule_apply(elemtpt.tpe) =>
diff --git a/src/compiler/scala/tools/nsc/transform/Constructors.scala b/src/compiler/scala/tools/nsc/transform/Constructors.scala
index 2ec7e97ac5..b97b1e3527 100644
--- a/src/compiler/scala/tools/nsc/transform/Constructors.scala
+++ b/src/compiler/scala/tools/nsc/transform/Constructors.scala
@@ -362,6 +362,7 @@ abstract class Constructors extends Transform with ast.TreeDSL {
* be an error to pass it to array_update(.., .., Object).
*/
def rewriteArrayUpdate(tree: Tree): Tree = {
+ val arrayUpdateMethod = currentRun.runDefinitions.arrayUpdateMethod
val adapter = new Transformer {
override def transform(t: Tree): Tree = t match {
case Apply(fun @ Select(receiver, method), List(xs, idx, v)) if fun.symbol == arrayUpdateMethod =>
diff --git a/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala b/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala
index 4cf3bef939..1723c69180 100644
--- a/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala
+++ b/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala
@@ -101,6 +101,7 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers {
private val concreteSpecMethods = perRunCaches.newWeakSet[Symbol]()
private def specializedOn(sym: Symbol): List[Symbol] = {
+ val GroupOfSpecializable = currentRun.runDefinitions.GroupOfSpecializable
sym getAnnotation SpecializedClass match {
case Some(AnnotationInfo(_, Nil, _)) => specializableTypes.map(_.typeSymbol)
case Some(ann @ AnnotationInfo(_, args, _)) => {
diff --git a/src/compiler/scala/tools/nsc/transform/TypeAdaptingTransformer.scala b/src/compiler/scala/tools/nsc/transform/TypeAdaptingTransformer.scala
index 41b8461c46..f83b6f857e 100644
--- a/src/compiler/scala/tools/nsc/transform/TypeAdaptingTransformer.scala
+++ b/src/compiler/scala/tools/nsc/transform/TypeAdaptingTransformer.scala
@@ -25,7 +25,7 @@ trait TypeAdaptingTransformer {
}
private def isSafelyRemovableUnbox(fn: Tree, arg: Tree): Boolean = {
- isUnbox(fn.symbol) && {
+ currentRun.runDefinitions.isUnbox(fn.symbol) && {
val cls = arg.tpe.typeSymbol
(cls == definitions.NullClass) || isBoxedValueClass(cls)
}
@@ -75,7 +75,7 @@ trait TypeAdaptingTransformer {
log(s"boxing an unbox: ${tree.symbol} -> ${arg.tpe}")
arg
case _ =>
- (REF(boxMethod(x)) APPLY tree) setPos (tree.pos) setType ObjectTpe
+ (REF(currentRun.runDefinitions.boxMethod(x)) APPLY tree) setPos (tree.pos) setType ObjectTpe
}
}
}
@@ -123,7 +123,7 @@ trait TypeAdaptingTransformer {
case x =>
assert(x != ArrayClass)
// don't `setType pt` the Apply tree, as the Apply's fun won't be typechecked if the Apply tree already has a type
- Apply(unboxMethod(pt.typeSymbol), tree)
+ Apply(currentRun.runDefinitions.unboxMethod(pt.typeSymbol), tree)
}
}
typer.typedPos(tree.pos)(tree1)
@@ -184,4 +184,4 @@ trait TypeAdaptingTransformer {
cast(tree, pt)
}
}
-} \ No newline at end of file
+}
diff --git a/src/compiler/scala/tools/nsc/transform/patmat/MatchCodeGen.scala b/src/compiler/scala/tools/nsc/transform/patmat/MatchCodeGen.scala
index c8dbbb02bb..06b39b035a 100644
--- a/src/compiler/scala/tools/nsc/transform/patmat/MatchCodeGen.scala
+++ b/src/compiler/scala/tools/nsc/transform/patmat/MatchCodeGen.scala
@@ -72,7 +72,7 @@ trait MatchCodeGen extends Interface {
// for name-based matching, but this was an expedient route for the basics.
def drop(tgt: Tree)(n: Int): Tree = {
def callDirect = fn(tgt, nme.drop, LIT(n))
- def callRuntime = Apply(REF(traversableDropMethod), tgt :: LIT(n) :: Nil)
+ def callRuntime = Apply(REF(currentRun.runDefinitions.traversableDropMethod), tgt :: LIT(n) :: Nil)
def needsRuntime = (tgt.tpe ne null) && (typeOfMemberNamedDrop(tgt.tpe) == NoType)
if (needsRuntime) callRuntime else callDirect
diff --git a/src/compiler/scala/tools/nsc/typechecker/Adaptations.scala b/src/compiler/scala/tools/nsc/typechecker/Adaptations.scala
index 567d5d0ecd..0b5b0759b2 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Adaptations.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Adaptations.scala
@@ -24,6 +24,8 @@ trait Adaptations {
trait Adaptation {
self: Typer =>
+ import runDefinitions._
+
def checkValidAdaptation(t: Tree, args: List[Tree]): Boolean = {
def applyArg = t match {
case Apply(_, arg :: Nil) => arg
diff --git a/src/compiler/scala/tools/nsc/typechecker/Implicits.scala b/src/compiler/scala/tools/nsc/typechecker/Implicits.scala
index dc60631421..b1a48f7478 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Implicits.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Implicits.scala
@@ -338,7 +338,7 @@ trait Implicits {
val wildPt = approximate(pt)
private val runDefintions = currentRun.runDefinitions
- import runDefintions.{ TagMaterializers, TagSymbols, Predef_conforms, PartialManifestClass, ManifestSymbols }
+ import runDefintions._
def undet_s = if (undetParams.isEmpty) "" else undetParams.mkString(" inferring ", ", ", "")
def tree_s = typeDebug ptTree tree
diff --git a/src/compiler/scala/tools/nsc/typechecker/Macros.scala b/src/compiler/scala/tools/nsc/typechecker/Macros.scala
index d1045757a5..02fb70f3e5 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Macros.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Macros.scala
@@ -104,7 +104,10 @@ trait Macros extends FastTrack with MacroRuntimes with Traces with Helpers {
targs: List[Tree]) {
// Was this binding derived from a `def ... = macro ???` definition?
- def is_??? = className == Predef_???.owner.javaClassName && methName == Predef_???.name.encoded
+ def is_??? = {
+ val Predef_??? = currentRun.runDefinitions.Predef_???
+ className == Predef_???.owner.javaClassName && methName == Predef_???.name.encoded
+ }
}
/** Macro def -> macro impl bindings are serialized into a `macroImpl` annotation
@@ -146,6 +149,8 @@ trait Macros extends FastTrack with MacroRuntimes with Traces with Helpers {
}
def pickle(macroImplRef: Tree): Tree = {
+ val runDefinitions = currentRun.runDefinitions
+ import runDefinitions._
val MacroImplReference(isBundle, owner, macroImpl, targs) = macroImplRef
// todo. refactor when fixing SI-5498
@@ -311,7 +316,7 @@ trait Macros extends FastTrack with MacroRuntimes with Traces with Helpers {
def fail() = { if (macroDef != null) macroDef setFlag IS_ERROR; macroDdef setType ErrorType; EmptyTree }
def success(macroImplRef: Tree) = { bindMacroImpl(macroDef, macroImplRef); macroImplRef }
- if (!typer.checkFeature(macroDdef.pos, MacrosFeature, immediate = true)) {
+ if (!typer.checkFeature(macroDdef.pos, currentRun.runDefinitions.MacrosFeature, immediate = true)) {
macroLogVerbose("typecheck terminated unexpectedly: language.experimental.macros feature is not enabled")
fail()
} else {
diff --git a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala
index 36f889f8a4..84531608e0 100644
--- a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala
@@ -945,7 +945,7 @@ abstract class RefChecks extends InfoTransform with scala.reflect.internal.trans
}
def checkImplicitViewOptionApply(pos: Position, fn: Tree, args: List[Tree]): Unit = if (settings.lint) (fn, args) match {
- case (tap@TypeApply(fun, targs), List(view: ApplyImplicitView)) if fun.symbol == Option_apply =>
+ case (tap@TypeApply(fun, targs), List(view: ApplyImplicitView)) if fun.symbol == currentRun.runDefinitions.Option_apply =>
unit.warning(pos, s"Suspicious application of an implicit view (${view.fun}) in the argument to Option.apply.") // SI-6567
case _ =>
}
diff --git a/src/compiler/scala/tools/nsc/typechecker/Tags.scala b/src/compiler/scala/tools/nsc/typechecker/Tags.scala
index 32a66aa4dd..90ec3a89b8 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Tags.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Tags.scala
@@ -10,6 +10,9 @@ trait Tags {
trait Tag {
self: Typer =>
+ private val runDefinitions = currentRun.runDefinitions
+ import runDefinitions._
+
private def resolveTag(pos: Position, taggedTp: Type, allowMaterialization: Boolean) = enteringTyper {
def wrapper (tree: => Tree): Tree = if (allowMaterialization) (context.withMacrosEnabled[Tree](tree)) else (context.withMacrosDisabled[Tree](tree))
wrapper(inferImplicit(
diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
index c385e7533a..a9bb81c691 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
@@ -115,6 +115,8 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper
import context0.unit
import typeDebug.{ ptTree, ptBlock, ptLine, inGreen, inRed }
import TyperErrorGen._
+ val runDefinitions = currentRun.runDefinitions
+ import runDefinitions._
val infer = new Inferencer(context0) {
// See SI-3281 re undoLog
@@ -3847,7 +3849,7 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper
if (sameLength(tparams, args)) {
val targs = args map (_.tpe)
checkBounds(tree, NoPrefix, NoSymbol, tparams, targs, "")
- if (fun.symbol == Predef_classOf)
+ if (isPredefClassOf(fun.symbol))
typedClassOf(tree, args.head, noGen = true)
else {
if (!isPastTyper && fun.symbol == Any_isInstanceOf && targs.nonEmpty) {
@@ -4807,7 +4809,7 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper
typed1(This(sym.owner) setPos tree.pos, mode, pt)
// Inferring classOf type parameter from expected type. Otherwise an
// actual call to the stubbed classOf method is generated, returning null.
- else if (isPredefMemberNamed(sym, nme.classOf) && pt.typeSymbol == ClassClass && pt.typeArgs.nonEmpty)
+ else if (isPredefClassOf(sym) && pt.typeSymbol == ClassClass && pt.typeArgs.nonEmpty)
typedClassOf(tree, TypeTree(pt.typeArgs.head))
else {
val pre1 = if (sym.isTopLevel) sym.owner.thisType else if (qual == EmptyTree) NoPrefix else qual.tpe
diff --git a/src/compiler/scala/tools/reflect/FastTrack.scala b/src/compiler/scala/tools/reflect/FastTrack.scala
index ad1d4c896b..dd92e14602 100644
--- a/src/compiler/scala/tools/reflect/FastTrack.scala
+++ b/src/compiler/scala/tools/reflect/FastTrack.scala
@@ -37,14 +37,19 @@ trait FastTrack {
}
/** A map from a set of pre-established macro symbols to their implementations. */
- lazy val fastTrack = Map[Symbol, FastTrackEntry](
- make( materializeClassTag) { case Applied(_, ttag :: Nil, _) => _.materializeClassTag(ttag.tpe) },
- make( materializeWeakTypeTag) { case Applied(_, ttag :: Nil, (u :: _) :: _) => _.materializeTypeTag(u, EmptyTree, ttag.tpe, concrete = false) },
- make( materializeTypeTag) { case Applied(_, ttag :: Nil, (u :: _) :: _) => _.materializeTypeTag(u, EmptyTree, ttag.tpe, concrete = true) },
- make( ApiUniverseReify) { case Applied(_, ttag :: Nil, (expr :: _) :: _) => c => c.materializeExpr(c.prefix.tree, EmptyTree, expr) },
- make( StringContext_f) { case Applied(Select(Apply(_, ps), _), _, args) => c => c.macro_StringInterpolation_f(ps, args.flatten, c.expandee.pos) },
- make(ReflectRuntimeCurrentMirror) { case _ => c => currentMirror(c).tree },
- make( QuasiquoteClass_api_apply) { case _ => _.expandQuasiquote },
- make(QuasiquoteClass_api_unapply) { case _ => _.expandQuasiquote }
- )
+ def fastTrack: Map[Symbol, FastTrackEntry] = fastTrackCache()
+ private val fastTrackCache = perRunCaches.newGeneric[Map[Symbol, FastTrackEntry]] {
+ val runDefinitions = currentRun.runDefinitions
+ import runDefinitions._
+ Map[Symbol, FastTrackEntry](
+ make( materializeClassTag) { case Applied(_, ttag :: Nil, _) => _.materializeClassTag(ttag.tpe) },
+ make( materializeWeakTypeTag) { case Applied(_, ttag :: Nil, (u :: _) :: _) => _.materializeTypeTag(u, EmptyTree, ttag.tpe, concrete = false) },
+ make( materializeTypeTag) { case Applied(_, ttag :: Nil, (u :: _) :: _) => _.materializeTypeTag(u, EmptyTree, ttag.tpe, concrete = true) },
+ make( ApiUniverseReify) { case Applied(_, ttag :: Nil, (expr :: _) :: _) => c => c.materializeExpr(c.prefix.tree, EmptyTree, expr) },
+ make( StringContext_f) { case Applied(Select(Apply(_, ps), _), _, args) => c => c.macro_StringInterpolation_f(ps, args.flatten, c.expandee.pos) },
+ make(ReflectRuntimeCurrentMirror) { case _ => c => currentMirror(c).tree },
+ make( QuasiquoteClass_api_apply) { case _ => _.expandQuasiquote },
+ make(QuasiquoteClass_api_unapply) { case _ => _.expandQuasiquote }
+ )
+ }
}