summaryrefslogtreecommitdiff
path: root/src/compiler/scala/reflect/reify
diff options
context:
space:
mode:
Diffstat (limited to 'src/compiler/scala/reflect/reify')
-rw-r--r--src/compiler/scala/reflect/reify/codegen/AnnotationInfos.scala56
-rw-r--r--src/compiler/scala/reflect/reify/codegen/Symbols.scala114
-rw-r--r--src/compiler/scala/reflect/reify/codegen/Trees.scala20
-rw-r--r--src/compiler/scala/reflect/reify/codegen/Types.scala141
-rw-r--r--src/compiler/scala/reflect/reify/phases/Metalevels.scala2
-rw-r--r--src/compiler/scala/reflect/reify/phases/Reify.scala4
6 files changed, 209 insertions, 128 deletions
diff --git a/src/compiler/scala/reflect/reify/codegen/AnnotationInfos.scala b/src/compiler/scala/reflect/reify/codegen/AnnotationInfos.scala
new file mode 100644
index 0000000000..1d218317dc
--- /dev/null
+++ b/src/compiler/scala/reflect/reify/codegen/AnnotationInfos.scala
@@ -0,0 +1,56 @@
+package scala.reflect.reify
+package codegen
+
+trait AnnotationInfos {
+ self: Reifier =>
+
+ import mirror._
+ import definitions._
+ import treeInfo._
+
+ // usually annotations are reified as their originals from Modifiers
+ // however, when reifying free and tough types, we're forced to reify annotation infos as is
+ // why is that bad? take a look inside
+ def reifyAnnotationInfo(ann: AnnotationInfo): Tree = {
+ val reifiedArgs = ann.args map { arg =>
+ val saved1 = reifyTreeSymbols
+ val saved2 = reifyTreeTypes
+
+ try {
+ // one more quirk of reifying annotations
+ //
+ // when reifying AnnotatedTypes we need to reify all the types and symbols of inner ASTs
+ // that's because a lot of logic expects post-typer trees to have non-null tpes
+ //
+ // Q: reified trees are pre-typer, so there's shouldn't be a problem.
+ // reflective typechecker will fill in missing symbols and types, right?
+ // A: actually, no. annotation ASTs live inside AnnotatedTypes,
+ // and insides of the types is the place where typechecker doesn't look.
+ reifyTreeSymbols = true
+ reifyTreeTypes = true
+
+ // todo. every AnnotationInfo is an island, entire of itself
+ // no regular Traverser or Transformer can reach it
+ // hence we need to run its contents through the entire reification pipeline
+ // e.g. to apply reshaping or to check metalevels
+ reify(arg)
+ } finally {
+ reifyTreeSymbols = saved1
+ reifyTreeTypes = saved2
+ }
+ }
+
+ def reifyClassfileAnnotArg(arg: ClassfileAnnotArg): Tree = arg match {
+ case LiteralAnnotArg(const) =>
+ mirrorFactoryCall(nme.LiteralAnnotArg, reifyProduct(const))
+ case ArrayAnnotArg(args) =>
+ mirrorFactoryCall(nme.ArrayAnnotArg, scalaFactoryCall(nme.Array, args map reifyClassfileAnnotArg: _*))
+ case NestedAnnotArg(ann) =>
+ mirrorFactoryCall(nme.NestedAnnotArg, reifyAnnotationInfo(ann))
+ }
+
+ // if you reify originals of anns, you get SO when trying to reify AnnotatedTypes, so screw it - after all, it's not that important
+ val reifiedAssocs = ann.assocs map (assoc => scalaFactoryCall(nme.Tuple2, reify(assoc._1), reifyClassfileAnnotArg(assoc._2)))
+ mirrorFactoryCall(nme.AnnotationInfo, reify(ann.atp), mkList(reifiedArgs), mkList(reifiedAssocs))
+ }
+} \ No newline at end of file
diff --git a/src/compiler/scala/reflect/reify/codegen/Symbols.scala b/src/compiler/scala/reflect/reify/codegen/Symbols.scala
index 3328f5e402..2fc0002838 100644
--- a/src/compiler/scala/reflect/reify/codegen/Symbols.scala
+++ b/src/compiler/scala/reflect/reify/codegen/Symbols.scala
@@ -46,13 +46,8 @@ trait Symbols {
}
} else {
// todo. make sure that free methods and free local defs work correctly
- if (sym.isTerm) {
- if (reifyDebug) println("Free term" + (if (sym.isCapturedVariable) " (captured)" else "") + ": " + sym)
- reifyFreeTerm(sym, Ident(sym))
- } else {
- if (reifyDebug) println("Free type: " + sym)
- reifyFreeType(sym, Ident(sym))
- }
+ if (sym.isTerm) reifyFreeTerm(sym, Ident(sym))
+ else reifyFreeType(sym, Ident(sym))
}
}
@@ -61,13 +56,16 @@ trait Symbols {
case Some(reified) =>
reified
case None =>
+ if (reifyDebug) println("Free term" + (if (sym.isCapturedVariable) " (captured)" else "") + ": " + sym + "(" + sym.accurateKindString + ")")
+ var name = newTermName(nme.MIRROR_FREE_PREFIX + sym.name)
+ if (sym.isType) name = name.append(nme.MIRROR_FREE_THIS_SUFFIX)
if (sym.isCapturedVariable) {
assert(value.isInstanceOf[Ident], showRaw(value))
val capturedTpe = capturedVariableType(sym)
val capturedValue = referenceCapturedVariable(sym)
- locallyReify(sym, mirrorCall(nme.newFreeTerm, reify(sym.name.toString), reify(capturedTpe), capturedValue, reify(origin(sym))))
+ locallyReify(sym, name, mirrorCall(nme.newFreeTerm, reify(sym.name.toString), reify(capturedTpe), capturedValue, reify(origin(sym))))
} else {
- locallyReify(sym, mirrorCall(nme.newFreeTerm, reify(sym.name.toString), reify(sym.tpe), value, reify(origin(sym))))
+ locallyReify(sym, name, mirrorCall(nme.newFreeTerm, reify(sym.name.toString), reify(sym.tpe), value, reify(origin(sym))))
}
}
@@ -76,36 +74,104 @@ trait Symbols {
case Some(reified) =>
reified
case None =>
+ if (reifyDebug) println("Free type: %s (%s)".format(sym, sym.accurateKindString))
+ var name = newTermName(nme.MIRROR_FREE_PREFIX + sym.name)
val phantomTypeTag = Apply(TypeApply(Select(Ident(nme.MIRROR_SHORT), nme.TypeTag), List(value)), List(Literal(Constant(null))))
// todo. implement info reification for free types: type bounds, HK-arity, whatever else that can be useful
- locallyReify(sym, mirrorCall(nme.newFreeType, reify(sym.name.toString), reify(sym.info), phantomTypeTag, reify(origin(sym))))
+ locallyReify(sym, name, mirrorCall(nme.newFreeType, reify(sym.name.toString), reify(sym.info), phantomTypeTag, reify(origin(sym))))
+ }
+
+ def reifySymDef(sym: Symbol): Tree =
+ locallyReified get sym match {
+ case Some(reified) =>
+ reified
+ case None =>
+ if (reifyDebug) println("Sym def: %s (%s)".format(sym, sym.accurateKindString))
+ assert(!sym.isLocatable, sym) // if this assertion fires, then tough type reification needs to be rethought
+ sym.owner.ownersIterator find (!_.isLocatable) foreach reifySymDef
+ var name = newTermName(nme.MIRROR_SYMDEF_PREFIX + sym.name)
+ locallyReify(sym, name, Apply(Select(reify(sym.owner), nme.newNestedSymbol), List(reify(sym.name), reify(sym.pos), reify(sym.flags), reify(sym.isClass))))
}
+ // todo. very brittle abstraction, needs encapsulation
import scala.collection.mutable._
- private val localReifications = ArrayBuffer[ValDef]()
+ private val localReifications = ArrayBuffer[Tree]()
private val locallyReified = Map[Symbol, Tree]()
- def symbolTable: List[ValDef] = localReifications.toList
- def symbolTable_=(newSymbolTable: List[ValDef]): Unit = {
+ private var filledIn = false
+ def symbolTable: List[Tree] = { fillInSymbolTable(); localReifications.toList }
+ def symbolTable_=(newSymbolTable: List[Tree]): Unit = {
localReifications.clear()
locallyReified.clear()
+ filledIn = false
newSymbolTable foreach {
- case freedef @ FreeDef(_, name, binding, _) =>
- if (!(locallyReified contains binding.symbol)) {
- localReifications += freedef
- locallyReified(binding.symbol) = Ident(name)
+ case entry =>
+ val att = entry.attachment
+ att match {
+ case sym: Symbol =>
+ // don't duplicate reified symbols when merging inlined reifee
+ if (!(locallyReified contains sym)) {
+ val ValDef(_, name, _, _) = entry
+ localReifications += entry
+ locallyReified(sym) = Ident(name)
+ }
+ case other =>
+ // do nothing => symbol table fill-ins will be repopulated later
}
}
}
- private def locallyReify(sym: Symbol, reificode: => Tree): Tree = {
+ private def localName(name0: TermName): TermName = {
+ var name = name0.toString
+ name = name.replace(".type", "$type")
+ name = name.replace(" ", "$")
+ val fresh = typer.context.unit.fresh
+ newTermName(fresh.newName(name))
+ }
+
+ private def locallyReify(sym: Symbol, name0: TermName, reificode: => Tree): Tree = {
val reified = reificode
- val Apply(Select(_, flavor), _) = reified
- // [Eugene] name clashes are impossible, right?
- var name = newTermName(nme.MIRROR_FREE_PREFIX + sym.name)
- if (flavor == nme.newFreeTerm && sym.isType) name = name.append(nme.MIRROR_FREE_THIS_SUFFIX);
- // todo. also reify annotations for free vars
- localReifications += ValDef(NoMods, name, TypeTree(), reified)
+ val name = localName(name0)
+ // todo. tried to declare a private class here to carry an attachment, but it's path-dependent
+ // so got troubles with exchanging free variables between nested and enclosing quasiquotes
+ // attaching just Symbol isn't good either, so we need to think of a principled solution
+ val local = ValDef(NoMods, name, TypeTree(), reified) setAttachment sym
+ localReifications += local
+ filledIn = false
locallyReified(sym) = Ident(name)
locallyReified(sym)
}
+
+ /** Sets type signatures and annotations for locally reified symbols */
+ private def fillInSymbolTable() = {
+ if (!filledIn) {
+ val fillIns = new ArrayBuffer[Tree]
+ var i = 0
+ while (i < localReifications.length) {
+ // fillInSymbol might create new locallyReified symbols, that's why this is done iteratively
+ val reified = localReifications(i)
+ reified.attachment match {
+ case sym: Symbol => fillIns += fillInSymbol(sym)
+ case other => // do nothing
+ }
+ i += 1
+ }
+
+ filledIn = true
+ localReifications ++= fillIns.toList
+ }
+ }
+
+ /** Generate code to add type and annotation info to a reified symbol */
+ private def fillInSymbol(sym: Symbol): Tree = {
+ if (reifyDebug) println("Filling in: %s (%s)".format(sym, sym.accurateKindString))
+ val isFree = locallyReified(sym) match { case Ident(name) => name startsWith nme.MIRROR_FREE_PREFIX }
+ if (isFree) {
+ if (sym.annotations.isEmpty) EmptyTree
+ else Apply(Select(locallyReified(sym), nme.setAnnotations), List(reify(sym.annotations)))
+ } else {
+ val rset = Apply(Select(locallyReified(sym), nme.setTypeSignature), List(reifyType(sym.info)))
+ if (sym.annotations.isEmpty) rset
+ else Apply(Select(rset, nme.setAnnotations), List(reify(sym.annotations)))
+ }
+ }
} \ No newline at end of file
diff --git a/src/compiler/scala/reflect/reify/codegen/Trees.scala b/src/compiler/scala/reflect/reify/codegen/Trees.scala
index 22f42aea49..5ad53c0009 100644
--- a/src/compiler/scala/reflect/reify/codegen/Trees.scala
+++ b/src/compiler/scala/reflect/reify/codegen/Trees.scala
@@ -8,6 +8,11 @@ trait Trees {
import definitions._
import treeInfo._
+ // unfortunately, these are necessary to reify AnnotatedTypes
+ // I'd gladly got rid of them, but I don't fancy making a metaprogramming API that doesn't work with annotated types
+ var reifyTreeSymbols = false
+ var reifyTreeTypes = false
+
/**
* Reify a tree.
* For internal use only, use ``reified'' instead.
@@ -59,6 +64,17 @@ trait Trees {
reifyProduct(tree)
}
+ // usually we don't reify symbols/types, because they can be re-inferred during subsequent reflective compilation
+ // however, reification of AnnotatedTypes is special. see ``reifyType'' to find out why.
+ if (reifyTreeSymbols && tree.hasSymbol) {
+ if (reifyDebug) println("reifying symbol %s for tree %s".format(tree.symbol, tree))
+ rtree = Apply(Select(rtree, nme.setSymbol), List(reifySymRef(tree.symbol)))
+ }
+ if (reifyTreeTypes && tree.tpe != null) {
+ if (reifyDebug) println("reifying type %s for tree %s".format(tree.tpe, tree))
+ rtree = Apply(Select(rtree, nme.setType), List(reifyType(tree.tpe)))
+ }
+
rtree
}
@@ -82,7 +98,7 @@ trait Trees {
case InlinedTreeSplice(_, inlinedSymbolTable, tree, _) =>
if (reifyDebug) println("inlining the splicee")
// all free vars local to the enclosing reifee should've already been inlined by ``Metalevels''
- inlinedSymbolTable foreach { case freedef @ FreeDef(_, _, binding, _) => assert(!binding.symbol.isLocalToReifee, freedef) }
+ inlinedSymbolTable collect { case freedef @ FreeDef(_, _, binding, _) if binding.symbol.isLocalToReifee => assert(false, freedef) }
symbolTable ++= inlinedSymbolTable
tree
case tree =>
@@ -152,7 +168,7 @@ trait Trees {
val tpe = tpe0.dealias
if (reifyDebug) println("reifying bound type %s (underlying type is %s, dealiased is %s)".format(sym0, tpe0, tpe))
- if (eligibleForSplicing(tpe)) {
+ if (tpe.isSpliceable) {
val spliced = spliceType(tpe)
if (spliced == EmptyTree) {
if (reifyDebug) println("splicing failed: reify as is")
diff --git a/src/compiler/scala/reflect/reify/codegen/Types.scala b/src/compiler/scala/reflect/reify/codegen/Types.scala
index 9bc113e8a4..948728088e 100644
--- a/src/compiler/scala/reflect/reify/codegen/Types.scala
+++ b/src/compiler/scala/reflect/reify/codegen/Types.scala
@@ -55,11 +55,9 @@ trait Types {
case tpe @ NullaryMethodType(restpe) =>
reifyProduct(tpe)
case tpe @ AnnotatedType(anns, underlying, selfsym) =>
-// reifyAnnotatedType(tpe)
- CannotReifyType(tpe)
+ reifyAnnotatedType(tpe)
case _ =>
-// reifyToughType(tpe)
- CannotReifyType(tpe)
+ reifyToughType(tpe)
}
}
@@ -70,13 +68,6 @@ trait Types {
var maybeConcrete = true
var definitelyConcrete = true
- def eligibleForSplicing(tpe: Type): Boolean = {
- // [Eugene] is this comprehensive?
- // the only thingies that we want to splice are: 1) type parameters, 2) type members
- // this check seems to cover them all, right?
- tpe.isInstanceOf[TypeRef] && tpe.typeSymbol.isAbstractType
- }
-
private type SpliceCacheKey = (Symbol, Symbol)
private lazy val spliceCache: collection.mutable.Map[SpliceCacheKey, Tree] = {
val cache = analyzer.perRunMacroCache.getOrElseUpdate(MacroContextReify, collection.mutable.Map[Any, Any]())
@@ -84,7 +75,7 @@ trait Types {
}
def spliceType(tpe: Type): Tree = {
- if (eligibleForSplicing(tpe)) {
+ if (tpe.isSpliceable) {
if (reifyDebug) println("splicing " + tpe)
if (spliceTypesEnabled) {
@@ -113,7 +104,7 @@ trait Types {
splice match {
case InlinedTypeSplice(_, inlinedSymbolTable, tpe) =>
// all free vars local to the enclosing reifee should've already been inlined by ``Metalevels''
- inlinedSymbolTable foreach { case freedef @ FreeDef(_, _, binding, _) => assert(!binding.symbol.isLocalToReifee, freedef) }
+ inlinedSymbolTable collect { case freedef @ FreeDef(_, _, binding, _) if binding.symbol.isLocalToReifee => assert(false, freedef) }
symbolTable ++= inlinedSymbolTable
reifyTrace("inlined the splicee: ")(tpe)
case tpe =>
@@ -134,93 +125,39 @@ trait Types {
EmptyTree
}
- // yet another thingie disabled for simplicity
- // in principle, we could retain and reify AnnotatedTypes
- // but that'd require reifying every type and symbol inside ann.args
- // however, since we've given up on tough types for the moment, the former would be problematic
-// private def reifyAnnotatedType(tpe: AnnotatedType): Tree = {
-// // ``Reshaper'' transforms annotation infos from symbols back into Modifier.annotations, which are trees
-// // so the only place on Earth that can lead to reification of AnnotationInfos is the Ay Tee Land
-// // therefore this function is as local as possible, don't move it out of this scope
-// def reifyAnnotationInfo(ann: AnnotationInfo): Tree = {
-// val reifiedArgs = ann.args map { arg =>
-// val saved1 = reifyTreeSymbols
-// val saved2 = reifyTreeTypes
-//
-// try {
-// // one more quirk of reifying annotations
-// //
-// // when reifying AnnotatedTypes we need to reify all the types and symbols of inner ASTs
-// // that's because a lot of logic expects post-typer trees to have non-null tpes
-// //
-// // Q: reified trees are pre-typer, so there's shouldn't be a problem.
-// // reflective typechecker will fill in missing symbols and types, right?
-// // A: actually, no. annotation ASTs live inside AnnotatedTypes,
-// // and insides of the types is the place where typechecker doesn't look.
-// reifyTreeSymbols = true
-// reifyTreeTypes = true
-//
-// // todo. every AnnotationInfo is an island, entire of itself
-// // no regular Traverser or Transformer can reach it
-// // hence we need to run its contents through the entire reification pipeline
-// // e.g. to apply reshaping or to check metalevels
-// reify(arg)
-// } finally {
-// reifyTreeSymbols = saved1
-// reifyTreeTypes = saved2
-// }
-// }
-//
-// def reifyClassfileAnnotArg(arg: ClassfileAnnotArg): Tree = arg match {
-// case LiteralAnnotArg(const) =>
-// mirrorFactoryCall(nme.LiteralAnnotArg, reifyProduct(const))
-// case ArrayAnnotArg(args) =>
-// mirrorFactoryCall(nme.ArrayAnnotArg, scalaFactoryCall(nme.Array, args map reifyClassfileAnnotArg: _*))
-// case NestedAnnotArg(ann) =>
-// mirrorFactoryCall(nme.NestedAnnotArg, reifyAnnotationInfo(ann))
-// }
-//
-// // if you reify originals of anns, you get SO when trying to reify AnnotatedTypes, so screw it - after all, it's not that important
-// val reifiedAssocs = ann.assocs map (assoc => scalaFactoryCall(nme.Tuple2, reify(assoc._1), reifyClassfileAnnotArg(assoc._2)))
-// mirrorFactoryCall(nme.AnnotationInfo, reify(ann.atp), mkList(reifiedArgs), mkList(reifiedAssocs))
-// }
-//
-// val AnnotatedType(anns, underlying, selfsym) = tpe
-// mirrorFactoryCall(nme.AnnotatedType, mkList(anns map reifyAnnotationInfo), reify(underlying), reify(selfsym))
-// }
-
- // previous solution to reifying tough types involved creating dummy symbols (see ``registerReifiableSymbol'' calls below)
- // however such symbols lost all the connections with their origins and became almost useless, except for typechecking
- // hence this approach was replaced by less powerful, but more principled one based on ``reifyFreeType''
- // it's possible that later on we will revise and revive ``reifyToughType'', but for now it's disabled under an implementation restriction
-// /** Reify a tough type, i.e. the one that leads to creation of auxiliary symbols */
-// // This is the uncharted territory in the reifier
-// private def reifyToughType(tpe: Type): Tree = {
-// if (reifyDebug) println("tough type: %s (%s)".format(tpe, tpe.kind))
-//
-// def reifyScope(scope: Scope): Tree = {
-// scope foreach registerReifiableSymbol
-// mirrorCall(nme.newScopeWith, scope.toList map reify: _*)
-// }
-//
-// tpe match {
-// case tpe @ RefinedType(parents, decls) =>
-// registerReifiableSymbol(tpe.typeSymbol)
-// mirrorFactoryCall(tpe, reify(parents), reifyScope(decls), reify(tpe.typeSymbol))
-// case tpe @ ExistentialType(tparams, underlying) =>
-// tparams foreach registerReifiableSymbol
-// mirrorFactoryCall(tpe, reify(tparams), reify(underlying))
-// case tpe @ ClassInfoType(parents, decls, clazz) =>
-// registerReifiableSymbol(clazz)
-// mirrorFactoryCall(tpe, reify(parents), reifyScope(decls), reify(tpe.typeSymbol))
-// case tpe @ MethodType(params, restpe) =>
-// params foreach registerReifiableSymbol
-// mirrorFactoryCall(tpe, reify(params), reify(restpe))
-// case tpe @ PolyType(tparams, underlying) =>
-// tparams foreach registerReifiableSymbol
-// mirrorFactoryCall(tpe, reify(tparams), reify(underlying))
-// case _ =>
-// throw new Error("internal error: %s (%s) is not supported".format(tpe, tpe.kind))
-// }
-// }
+ /** Reify an annotated type, i.e. the one that makes us deal with AnnotationInfos */
+ private def reifyAnnotatedType(tpe: AnnotatedType): Tree = {
+ val AnnotatedType(anns, underlying, selfsym) = tpe
+ mirrorFactoryCall(nme.AnnotatedType, mkList(anns map reifyAnnotationInfo), reify(underlying), reify(selfsym))
+ }
+
+ /** Reify a tough type, i.e. the one that leads to creation of auxiliary symbols */
+ private def reifyToughType(tpe: Type): Tree = {
+ if (reifyDebug) println("tough type: %s (%s)".format(tpe, tpe.kind))
+
+ def reifyScope(scope: Scope): Tree = {
+ scope foreach reifySymDef
+ mirrorCall(nme.newScopeWith, scope.toList map reify: _*)
+ }
+
+ tpe match {
+ case tpe @ RefinedType(parents, decls) =>
+ reifySymDef(tpe.typeSymbol)
+ mirrorFactoryCall(tpe, reify(parents), reifyScope(decls), reify(tpe.typeSymbol))
+ case tpe @ ExistentialType(tparams, underlying) =>
+ tparams foreach reifySymDef
+ mirrorFactoryCall(tpe, reify(tparams), reify(underlying))
+ case tpe @ ClassInfoType(parents, decls, clazz) =>
+ reifySymDef(clazz)
+ mirrorFactoryCall(tpe, reify(parents), reifyScope(decls), reify(tpe.typeSymbol))
+ case tpe @ MethodType(params, restpe) =>
+ params foreach reifySymDef
+ mirrorFactoryCall(tpe, reify(params), reify(restpe))
+ case tpe @ PolyType(tparams, underlying) =>
+ tparams foreach reifySymDef
+ mirrorFactoryCall(tpe, reify(tparams), reify(underlying))
+ case _ =>
+ throw new Error("internal error: %s (%s) is not supported".format(tpe, tpe.kind))
+ }
+ }
} \ No newline at end of file
diff --git a/src/compiler/scala/reflect/reify/phases/Metalevels.scala b/src/compiler/scala/reflect/reify/phases/Metalevels.scala
index a329a1043d..bb0b8ac138 100644
--- a/src/compiler/scala/reflect/reify/phases/Metalevels.scala
+++ b/src/compiler/scala/reflect/reify/phases/Metalevels.scala
@@ -134,6 +134,8 @@ trait Metalevels {
// FreeRef(_, _) check won't work, because metalevels of symbol table and body are different, hence, freerefs in symbol table look different from freerefs in body
// todo. also perform garbage collection on local symbols
// so that local symbols used only in type signatures of free vars get removed
+ // todo. same goes for auxiliary symbol defs reified to support tough types
+ // some of them need to be rebuilt, some of them need to be removed, because they're no longer necessary
case FreeRef(mr, name) if freedefsToInline contains name =>
if (reifyDebug) println("inlineable free ref: %s in %s".format(name, showRaw(tree)))
val freedef @ FreeDef(_, _, binding, _) = freedefsToInline(name)
diff --git a/src/compiler/scala/reflect/reify/phases/Reify.scala b/src/compiler/scala/reflect/reify/phases/Reify.scala
index f6d6423605..02a96987ed 100644
--- a/src/compiler/scala/reflect/reify/phases/Reify.scala
+++ b/src/compiler/scala/reflect/reify/phases/Reify.scala
@@ -9,6 +9,7 @@ trait Reify extends Symbols
with Types
with Names
with Trees
+ with AnnotationInfos
with Positions
with Util {
@@ -30,6 +31,9 @@ trait Reify extends Symbols
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)