summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorEugene Burmako <xeno.by@gmail.com>2012-04-16 11:52:25 +0200
committerEugene Burmako <xeno.by@gmail.com>2012-04-17 21:27:40 +0200
commite408aa9ccaba736d0f85b7afecd288c3873d05bb (patch)
treeb115dd0261cfe4f8a2f741d1cb4afd1412886e48 /src
parent17fa0b13480c7dd9796885e32ec562e162253350 (diff)
downloadscala-e408aa9ccaba736d0f85b7afecd288c3873d05bb.tar.gz
scala-e408aa9ccaba736d0f85b7afecd288c3873d05bb.tar.bz2
scala-e408aa9ccaba736d0f85b7afecd288c3873d05bb.zip
adds erasures to concrete type tags
Diffstat (limited to 'src')
-rw-r--r--src/compiler/scala/reflect/internal/Importers.scala4
-rw-r--r--src/compiler/scala/reflect/internal/StdNames.scala8
-rw-r--r--src/compiler/scala/reflect/internal/Symbols.scala8
-rw-r--r--src/compiler/scala/reflect/internal/TreeBuildUtil.scala8
-rw-r--r--src/compiler/scala/reflect/internal/TreeInfo.scala31
-rw-r--r--src/compiler/scala/reflect/internal/Types.scala2
-rw-r--r--src/compiler/scala/reflect/makro/runtime/Reifiers.scala41
-rw-r--r--src/compiler/scala/reflect/makro/runtime/Typers.scala8
-rw-r--r--src/compiler/scala/reflect/reify/Reifier.scala26
-rw-r--r--src/compiler/scala/reflect/reify/codegen/Symbols.scala10
-rw-r--r--src/compiler/scala/reflect/reify/codegen/Trees.scala35
-rw-r--r--src/compiler/scala/reflect/reify/codegen/Types.scala27
-rw-r--r--src/compiler/scala/reflect/reify/codegen/Util.scala2
-rw-r--r--src/compiler/scala/reflect/reify/phases/Metalevels.scala4
-rw-r--r--src/compiler/scala/reflect/reify/phases/Reify.scala47
-rw-r--r--src/compiler/scala/reflect/reify/phases/Reshape.scala6
-rw-r--r--src/compiler/scala/reflect/runtime/SynchronizedSymbols.scala8
-rw-r--r--src/compiler/scala/tools/nsc/ast/FreeVars.scala4
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Implicits.scala3
-rw-r--r--src/library/scala/reflect/ClassTag.scala4
-rw-r--r--src/library/scala/reflect/DynamicProxy.scala20
-rw-r--r--src/library/scala/reflect/TagMaterialization.scala49
-rwxr-xr-xsrc/library/scala/reflect/api/Symbols.scala10
-rw-r--r--src/library/scala/reflect/api/TreeBuildUtil.scala20
-rw-r--r--src/library/scala/reflect/api/TypeTags.scala43
-rwxr-xr-xsrc/library/scala/reflect/api/Types.scala14
-rw-r--r--src/library/scala/reflect/makro/Reifiers.scala4
-rw-r--r--src/library/scala/reflect/makro/internal/Utils.scala45
-rw-r--r--src/library/scala/reflect/package.scala2
29 files changed, 284 insertions, 209 deletions
diff --git a/src/compiler/scala/reflect/internal/Importers.scala b/src/compiler/scala/reflect/internal/Importers.scala
index ab5e19fca9..596d400628 100644
--- a/src/compiler/scala/reflect/internal/Importers.scala
+++ b/src/compiler/scala/reflect/internal/Importers.scala
@@ -71,9 +71,9 @@ trait Importers { self: SymbolTable =>
case x: from.ModuleSymbol =>
linkReferenced(myowner.newModuleSymbol(myname, mypos, myflags), x, importSymbol)
case x: from.FreeTerm =>
- newFreeTerm(importName(x.name).toTermName, importType(x.info), x.value, x.origin, myflags)
+ newFreeTermSymbol(importName(x.name).toTermName, importType(x.info), x.value, x.flags, x.origin)
case x: from.FreeType =>
- newFreeType(importName(x.name).toTypeName, importType(x.info), x.value, x.origin, myflags)
+ newFreeTypeSymbol(importName(x.name).toTypeName, importType(x.info), x.value, x.flags, x.origin)
case x: from.TermSymbol =>
linkReferenced(myowner.newValue(myname, mypos, myflags), x, importSymbol)
case x: from.TypeSkolem =>
diff --git a/src/compiler/scala/reflect/internal/StdNames.scala b/src/compiler/scala/reflect/internal/StdNames.scala
index bf468affe6..c5fe1ecb45 100644
--- a/src/compiler/scala/reflect/internal/StdNames.scala
+++ b/src/compiler/scala/reflect/internal/StdNames.scala
@@ -291,11 +291,14 @@ trait StdNames extends NameManglers { self: SymbolTable =>
val AnnotationInfo: NameType = "AnnotationInfo"
val Any: NameType = "Any"
val AnyVal: NameType = "AnyVal"
+ val AppliedTypeTree: NameType = "AppliedTypeTree"
val Apply: NameType = "Apply"
val ArrayAnnotArg: NameType = "ArrayAnnotArg"
+ val Constant: NameType = "Constant"
val ConstantType: NameType = "ConstantType"
val EmptyPackage: NameType = "EmptyPackage"
val EmptyPackageClass: NameType = "EmptyPackageClass"
+ val ExistentialTypeTree: NameType = "ExistentialTypeTree"
val Expr: NameType = "Expr"
val Ident: NameType = "Ident"
val Import: NameType = "Import"
@@ -404,13 +407,15 @@ trait StdNames extends NameManglers { self: SymbolTable =>
val name: NameType = "name"
val ne: NameType = "ne"
val newArray: NameType = "newArray"
+ val newFreeExistential: NameType = "newFreeExistential"
val newFreeTerm: NameType = "newFreeTerm"
val newFreeType: NameType = "newFreeType"
val newNestedSymbol: NameType = "newNestedSymbol"
val newScopeWith: NameType = "newScopeWith"
+ val next: NameType = "next"
val nmeNewTermName: NameType = "newTermName"
val nmeNewTypeName: NameType = "newTypeName"
- val next: NameType = "next"
+ val normalize: NameType = "normalize"
val notifyAll_ : NameType = "notifyAll"
val notify_ : NameType = "notify"
val null_ : NameType = "null"
@@ -465,6 +470,7 @@ trait StdNames extends NameManglers { self: SymbolTable =>
val view_ : NameType = "view"
val wait_ : NameType = "wait"
val withFilter: NameType = "withFilter"
+ val wrap: NameType = "wrap"
val zip: NameType = "zip"
val synthSwitch: NameType = "$synthSwitch"
diff --git a/src/compiler/scala/reflect/internal/Symbols.scala b/src/compiler/scala/reflect/internal/Symbols.scala
index 6eaae7f1ee..74e924add4 100644
--- a/src/compiler/scala/reflect/internal/Symbols.scala
+++ b/src/compiler/scala/reflect/internal/Symbols.scala
@@ -47,13 +47,13 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
/** Create a new free term. Its owner is NoSymbol.
*/
- def newFreeTerm(name: TermName, info: Type, value: => Any, origin: String, newFlags: Long = 0L): FreeTerm =
- new FreeTerm(name, value, origin) initFlags newFlags setInfo info
+ def newFreeTermSymbol(name: TermName, info: Type, value: => Any, flags: Long = 0L, origin: String): FreeTerm =
+ new FreeTerm(name, value, origin) initFlags flags setInfo info
/** Create a new free type. Its owner is NoSymbol.
*/
- def newFreeType(name: TypeName, info: Type, value: => Any, origin: String, newFlags: Long = 0L): FreeType =
- new FreeType(name, value, origin) initFlags newFlags setInfo info
+ def newFreeTypeSymbol(name: TypeName, info: Type, value: => Any, flags: Long = 0L, origin: String): FreeType =
+ new FreeType(name, value, origin) initFlags flags setInfo info
/** The original owner of a class. Used by the backend to generate
* EnclosingMethod attributes.
diff --git a/src/compiler/scala/reflect/internal/TreeBuildUtil.scala b/src/compiler/scala/reflect/internal/TreeBuildUtil.scala
index fbcd5043bc..d4d4652e91 100644
--- a/src/compiler/scala/reflect/internal/TreeBuildUtil.scala
+++ b/src/compiler/scala/reflect/internal/TreeBuildUtil.scala
@@ -1,6 +1,8 @@
package scala.reflect
package internal
+import Flags._
+
trait TreeBuildUtil extends api.TreeBuildUtil { self: SymbolTable =>
// ``staticClass'' and ``staticModule'' rely on ClassLoaders
@@ -51,9 +53,11 @@ trait TreeBuildUtil extends api.TreeBuildUtil { self: SymbolTable =>
try selectOverloadedMethod(owner, name, index)
catch { case _: MissingRequirementError => NoSymbol }
- def newFreeTerm(name: String, info: Type, value: => Any, origin: String) = newFreeTerm(newTermName(name), info, value, origin)
+ def newFreeTerm(name: String, info: Type, value: => Any, flags: Long = 0L, origin: String = null) = newFreeTermSymbol(newTermName(name), info, value, flags, origin)
+
+ def newFreeType(name: String, info: Type, value: => Any, flags: Long = 0L, origin: String = null) = newFreeTypeSymbol(newTypeName(name), info, value, (if (flags == 0L) PARAM else flags) | DEFERRED, origin)
- def newFreeType(name: String, info: Type, value: => Any, origin: String) = newFreeType(newTypeName(name), info, value, origin)
+ def newFreeExistential(name: String, info: Type, value: => Any, flags: Long = 0L, origin: String = null) = newFreeTypeSymbol(newTypeName(name), info, value, (if (flags == 0L) EXISTENTIAL else flags) | DEFERRED, origin)
def modifiersFromInternalFlags(flags: Long, privateWithin: Name, annotations: List[Tree]): Modifiers =
Modifiers(flags, privateWithin, annotations)
diff --git a/src/compiler/scala/reflect/internal/TreeInfo.scala b/src/compiler/scala/reflect/internal/TreeInfo.scala
index 039c8e557a..937b3ea5d6 100644
--- a/src/compiler/scala/reflect/internal/TreeInfo.scala
+++ b/src/compiler/scala/reflect/internal/TreeInfo.scala
@@ -629,7 +629,7 @@ abstract class TreeInfo {
object ReifiedType {
def unapply(tree: Tree): Option[(Tree, List[Tree], Tree)] = tree match {
- case reifee @ Block((mrDef @ ValDef(_, _, _, _)) :: symbolTable, Apply(_, List(tpe))) if mrDef.name == nme.MIRROR_SHORT =>
+ case reifee @ Block((mrDef @ ValDef(_, _, _, _)) :: symbolTable, Apply(_, tpe :: _)) if mrDef.name == nme.MIRROR_SHORT =>
Some(reifee, symbolTable, tpe)
case _ =>
None
@@ -646,11 +646,11 @@ abstract class TreeInfo {
}
object FreeDef {
- def unapply(tree: Tree): Option[(Tree, TermName, Tree, String)] = tree match {
- case FreeTermDef(mrRef, name, binding, origin) =>
- Some(mrRef, name, binding, origin)
- case FreeTypeDef(mrRef, name, binding, origin) =>
- Some(mrRef, name, binding, origin)
+ def unapply(tree: Tree): Option[(Tree, TermName, Tree, Long, String)] = tree match {
+ case FreeTermDef(mrRef, name, binding, flags, origin) =>
+ Some(mrRef, name, binding, flags, origin)
+ case FreeTypeDef(mrRef, name, binding, flags, origin) =>
+ Some(mrRef, name, binding, flags, origin)
case _ =>
None
}
@@ -659,28 +659,29 @@ abstract class TreeInfo {
object FreeTermDef {
lazy val newFreeTermMethod = getMember(getRequiredClass("scala.reflect.api.TreeBuildUtil"), nme.newFreeTerm)
- def unapply(tree: Tree): Option[(Tree, TermName, Tree, String)] = tree match {
- case ValDef(_, name, _, Apply(Select(mrRef @ Ident(_), newFreeTerm), List(_, _, binding, Literal(Constant(origin: String)))))
+ def unapply(tree: Tree): Option[(Tree, TermName, Tree, Long, String)] = tree match {
+ case ValDef(_, name, _, Apply(Select(mrRef @ Ident(_), newFreeTerm), List(_, _, binding, Literal(Constant(flags: Long)), Literal(Constant(origin: String)))))
if mrRef.name == nme.MIRROR_SHORT && newFreeTerm == newFreeTermMethod.name =>
- Some(mrRef, name, binding, origin)
+ Some(mrRef, name, binding, flags, origin)
case _ =>
None
}
}
object FreeTypeDef {
- lazy val newFreeTypeMethod = getMember(getRequiredClass("scala.reflect.api.TreeBuildUtil"), nme.newFreeType)
+ lazy val newFreeExistentialMethod = getMember(getRequiredClass("scala.reflect.api.TreeBuildUtil"), nme.newFreeType)
+ lazy val newFreeTypeMethod = getMember(getRequiredClass("scala.reflect.api.TreeBuildUtil"), nme.newFreeExistential)
- def unapply(tree: Tree): Option[(Tree, TermName, Tree, String)] = tree match {
- case ValDef(_, name, _, Apply(Select(mrRef1 @ Ident(_), newFreeType), List(_, _, value, Literal(Constant(origin: String)))))
- if mrRef1.name == nme.MIRROR_SHORT && newFreeType == newFreeTypeMethod.name =>
+ def unapply(tree: Tree): Option[(Tree, TermName, Tree, Long, String)] = tree match {
+ case ValDef(_, name, _, Apply(Select(mrRef1 @ Ident(_), newFreeType), List(_, _, value, Literal(Constant(flags: Long)), Literal(Constant(origin: String)))))
+ if mrRef1.name == nme.MIRROR_SHORT && (newFreeType == newFreeTypeMethod.name || newFreeType == newFreeExistentialMethod.name) =>
value match {
case Apply(TypeApply(Select(Select(mrRef2 @ Ident(_), typeTag), apply), List(binding)), List(Literal(Constant(null))))
if mrRef2.name == nme.MIRROR_SHORT && typeTag == nme.TypeTag && apply == nme.apply =>
- Some(mrRef1, name, binding, origin)
+ Some(mrRef1, name, binding, flags, origin)
case Apply(TypeApply(Select(mrRef2 @ Ident(_), typeTag), List(binding)), List(Literal(Constant(null))))
if mrRef2.name == nme.MIRROR_SHORT && typeTag == nme.TypeTag =>
- Some(mrRef1, name, binding, origin)
+ Some(mrRef1, name, binding, flags, origin)
case _ =>
throw new Error("unsupported free type def: " + showRaw(tree))
}
diff --git a/src/compiler/scala/reflect/internal/Types.scala b/src/compiler/scala/reflect/internal/Types.scala
index fc57a130d1..7115cafc33 100644
--- a/src/compiler/scala/reflect/internal/Types.scala
+++ b/src/compiler/scala/reflect/internal/Types.scala
@@ -277,7 +277,7 @@ trait Types extends api.Types { self: SymbolTable =>
case SuperType(_, _) => false
case SingleType(pre, sym) => notConcreteSym(sym)
case ConstantType(_) => false
- case TypeRef(_, sym, _) => notConcreteSym(sym)
+ case TypeRef(_, sym, args) => notConcreteSym(sym) || (args exists (arg => notConcreteTpe(arg)))
case RefinedType(_, _) => false
case ExistentialType(_, _) => false
case AnnotatedType(_, tp, _) => notConcreteTpe(tp)
diff --git a/src/compiler/scala/reflect/makro/runtime/Reifiers.scala b/src/compiler/scala/reflect/makro/runtime/Reifiers.scala
index 2488b06d6c..3586adc590 100644
--- a/src/compiler/scala/reflect/makro/runtime/Reifiers.scala
+++ b/src/compiler/scala/reflect/makro/runtime/Reifiers.scala
@@ -10,6 +10,7 @@ trait Reifiers {
self: Context =>
import mirror._
+ import definitions._
lazy val reflectMirrorPrefix: Tree = {
// [Eugene] how do I typecheck this without undergoing this tiresome (and, in general, incorrect) procedure?
@@ -24,6 +25,44 @@ trait Reifiers {
def reifyType(prefix: Tree, tpe: Type, dontSpliceAtTopLevel: Boolean = false, requireConcreteTypeTag: Boolean = false): Tree =
reifyTopLevel(prefix, tpe, dontSpliceAtTopLevel, requireConcreteTypeTag)
+ def reifyErasure(tpe: Type): Tree = {
+ val positionBearer = enclosingMacros.find(c => c.macroApplication.pos != NoPosition).map(_.macroApplication).getOrElse(EmptyTree).asInstanceOf[Tree]
+ val typetagInScope = callsiteTyper.context.withMacrosDisabled(callsiteTyper.resolveTypeTag(positionBearer, gen.mkAttributedRef(Reflect_mirror).tpe, tpe, full = true))
+ def typetagIsSynthetic(tree: Tree) = tree.isInstanceOf[Block] || (tree exists (sub => sub.symbol == TypeTagModule || sub.symbol == ConcreteTypeTagModule))
+ typetagInScope match {
+ case success if !success.isEmpty && !typetagIsSynthetic(success) =>
+ val factory = TypeApply(Select(Ident(ClassTagModule), nme.apply), List(TypeTree(tpe)))
+ Apply(factory, List(typetagInScope))
+ case _ =>
+ if (tpe.typeSymbol == ArrayClass) {
+ val componentTpe = tpe.typeArguments(0)
+ val componentTag = callsiteTyper.resolveClassTag(positionBearer, componentTpe)
+ Select(componentTag, nme.wrap)
+ } else {
+ // [Eugene] what's the intended behavior? there's no spec on ClassManifests
+ // for example, should we ban Array[T] or should we tag them with Array[AnyRef]?
+ // if its the latter, what should be the result of tagging Array[T] where T <: Int?
+ if (tpe.isSpliceable) throw new ReificationError(enclosingPosition, "tpe %s is an unresolved spliceable type".format(tpe))
+ // [Eugene] imho this logic should be moved into `erasure`
+ var erasure = tpe match {
+ case tpe if tpe.typeSymbol.isDerivedValueClass => tpe // [Eugene to Martin] is this correct?
+ case ConstantType(value) => tpe.widen.erasure
+ case _ => {
+ // [Eugene] magikz. needs review
+ var result = tpe.erasure.normalize // necessary to deal with erasures of HK types, typeConstructor won't work
+ result = result match {
+ case PolyType(undets, underlying) => existentialAbstraction(undets, underlying) // we don't want undets in the result
+ case _ => result
+ }
+ result
+ }
+ }
+ val factory = TypeApply(Select(Ident(ClassTagModule), nme.apply), List(TypeTree(tpe)))
+ Apply(factory, List(TypeApply(Select(Ident(PredefModule), nme.classOf), List(TypeTree(erasure)))))
+ }
+ }
+ }
+
def unreifyTree(tree: Tree): Tree =
Select(tree, definitions.ExprEval)
@@ -34,7 +73,7 @@ trait Reifiers {
try {
val result = reifier.reified
- logFreeVars(expandee.pos, result)
+ logFreeVars(enclosingPosition, result)
result
} catch {
case ex: reifier.ReificationError =>
diff --git a/src/compiler/scala/reflect/makro/runtime/Typers.scala b/src/compiler/scala/reflect/makro/runtime/Typers.scala
index 38e819746d..b32d4fb7b1 100644
--- a/src/compiler/scala/reflect/makro/runtime/Typers.scala
+++ b/src/compiler/scala/reflect/makro/runtime/Typers.scala
@@ -34,9 +34,9 @@ trait Typers {
def trace(msg: Any) = if (mirror.settings.Ymacrodebug.value) println(msg)
trace("inferring implicit value of type %s, macros = %s".format(pt, !withMacrosDisabled))
import mirror.analyzer.SearchResult
- val wrapper1 = if (!withMacrosDisabled) (callsiteTyper.context.withMacrosEnabled[SearchResult] _) else (callsiteTyper.context.withMacrosDisabled[SearchResult] _)
- def wrapper (inference: => SearchResult) = wrapper1(inference)
val context = callsiteTyper.context.makeImplicit(true)
+ val wrapper1 = if (!withMacrosDisabled) (context.withMacrosEnabled[SearchResult] _) else (context.withMacrosDisabled[SearchResult] _)
+ def wrapper (inference: => SearchResult) = wrapper1(inference)
wrapper(mirror.analyzer.inferImplicit(mirror.EmptyTree, pt, true, false, context, !silent, pos)) match {
case failure if failure.tree.isEmpty =>
trace("implicit search has failed. to find out the reason, turn on -Xlog-implicits")
@@ -51,11 +51,11 @@ trait Typers {
def trace(msg: Any) = if (mirror.settings.Ymacrodebug.value) println(msg)
trace("inferring implicit view from %s to %s for %s, macros = %s, reportAmbiguous = %s".format(from, to, tree, !withMacrosDisabled, reportAmbiguous))
import mirror.analyzer.SearchResult
- val wrapper1 = if (!withMacrosDisabled) (callsiteTyper.context.withMacrosEnabled[SearchResult] _) else (callsiteTyper.context.withMacrosDisabled[SearchResult] _)
+ val context = callsiteTyper.context.makeImplicit(reportAmbiguous)
+ val wrapper1 = if (!withMacrosDisabled) (context.withMacrosEnabled[SearchResult] _) else (context.withMacrosDisabled[SearchResult] _)
def wrapper (inference: => SearchResult) = wrapper1(inference)
val fun1 = mirror.definitions.FunctionClass(1)
val viewTpe = mirror.TypeRef(fun1.typeConstructor.prefix, fun1, List(from, to))
- val context = callsiteTyper.context.makeImplicit(reportAmbiguous)
wrapper(mirror.analyzer.inferImplicit(mirror.EmptyTree, viewTpe, reportAmbiguous, true, context, !silent, pos)) match {
case failure if failure.tree.isEmpty =>
trace("implicit search has failed. to find out the reason, turn on -Xlog-implicits")
diff --git a/src/compiler/scala/reflect/reify/Reifier.scala b/src/compiler/scala/reflect/reify/Reifier.scala
index 16c26734b2..c89ebf0d39 100644
--- a/src/compiler/scala/reflect/reify/Reifier.scala
+++ b/src/compiler/scala/reflect/reify/Reifier.scala
@@ -47,6 +47,15 @@ abstract class Reifier extends Phases
if (prefix exists (_.isErroneous)) CannotReifyErroneousPrefix(prefix)
if (prefix.tpe == null) CannotReifyUntypedPrefix(prefix)
+ def reifyErasure(tpe: Type): Tree = {
+ val result = typer.resolveClassTag(positionBearer, tpe)
+ if (result == EmptyTree) throw new Error("cannot reify erasure for %s: ".format(tpe))
+ result match {
+ case Apply(TypeApply(Select(_, _), _), List(clazz)) => clazz
+ case _ => Select(result, nme.erasure)
+ }
+ }
+
val rtree = reifee match {
case tree: Tree =>
reifyTrace("reifying = ")(if (opt.showTrees) "\n" + nodePrinters.nodeToString(tree).trim else tree.toString)
@@ -73,11 +82,11 @@ abstract class Reifier extends Phases
CannotReifyReifeeThatHasTypeLocalToReifee(tree)
val manifestedType = typer.packedType(tree, NoSymbol)
- val manifestedRtype = reifyType(manifestedType)
val tagModule = if (definitelyConcrete) ConcreteTypeTagModule else TypeTagModule
- var typeTagCtor = TypeApply(Select(Ident(nme.MIRROR_SHORT), tagModule.name), List(TypeTree(manifestedType)))
- var exprCtor = TypeApply(Select(Ident(nme.MIRROR_SHORT), ExprModule.name), List(TypeTree(manifestedType)))
- Apply(Apply(exprCtor, List(rtree)), List(Apply(typeTagCtor, List(manifestedRtype))))
+ val tagCtor = TypeApply(Select(Ident(nme.MIRROR_SHORT), tagModule.name), List(TypeTree(manifestedType)))
+ val exprCtor = TypeApply(Select(Ident(nme.MIRROR_SHORT), ExprModule.name), List(TypeTree(manifestedType)))
+ val tagArgs = if (definitelyConcrete) List(reify(manifestedType), reifyErasure(manifestedType)) else List(reify(manifestedType))
+ Apply(Apply(exprCtor, List(rtree)), List(Apply(tagCtor, tagArgs)))
case tpe: Type =>
reifyTrace("reifying = ")(tpe.toString)
@@ -85,9 +94,10 @@ abstract class Reifier extends Phases
val rtree = reify(tpe)
val manifestedType = tpe
- var tagModule = if (definitelyConcrete) ConcreteTypeTagModule else TypeTagModule
- var ctor = TypeApply(Select(Ident(nme.MIRROR_SHORT), tagModule.name), List(TypeTree(manifestedType)))
- Apply(ctor, List(rtree))
+ val tagModule = if (definitelyConcrete) ConcreteTypeTagModule else TypeTagModule
+ val ctor = TypeApply(Select(Ident(nme.MIRROR_SHORT), tagModule.name), List(TypeTree(manifestedType)))
+ val args = if (definitelyConcrete) List(rtree, reifyErasure(manifestedType)) else List(rtree)
+ Apply(ctor, args)
case _ =>
throw new Error("reifee %s of type %s is not supported".format(reifee, if (reifee == null) "null" else reifee.getClass.toString))
@@ -126,7 +136,7 @@ abstract class Reifier extends Phases
// 3) local freeterm inlining in Metalevels
// 4) trivial tree splice inlining in Reify (Trees.scala)
// 5) trivial type splice inlining in Reify (Types.scala)
- val freevarBindings = symbolTable collect { case freedef @ FreeDef(_, _, binding, _) => binding.symbol } toSet
+ val freevarBindings = symbolTable collect { case entry @ FreeDef(_, _, binding, _, _) => binding.symbol } toSet
val untyped = resetAllAttrs(wrapped, leaveAlone = {
case ValDef(_, mr, _, _) if mr == nme.MIRROR_SHORT => true
case tree if freevarBindings contains tree.symbol => true
diff --git a/src/compiler/scala/reflect/reify/codegen/Symbols.scala b/src/compiler/scala/reflect/reify/codegen/Symbols.scala
index 2fc0002838..0513f99366 100644
--- a/src/compiler/scala/reflect/reify/codegen/Symbols.scala
+++ b/src/compiler/scala/reflect/reify/codegen/Symbols.scala
@@ -63,9 +63,9 @@ trait Symbols {
assert(value.isInstanceOf[Ident], showRaw(value))
val capturedTpe = capturedVariableType(sym)
val capturedValue = referenceCapturedVariable(sym)
- locallyReify(sym, name, 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(sym.flags), reify(origin(sym))))
} else {
- locallyReify(sym, name, 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(sym.flags), reify(origin(sym))))
}
}
@@ -77,8 +77,8 @@ trait Symbols {
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, name, mirrorCall(nme.newFreeType, reify(sym.name.toString), reify(sym.info), phantomTypeTag, reify(origin(sym))))
+ val flavor = if (sym.isExistential) nme.newFreeExistential else nme.newFreeType
+ locallyReify(sym, name, mirrorCall(flavor, reify(sym.name.toString), reify(sym.info), phantomTypeTag, reify(sym.flags), reify(origin(sym))))
}
def reifySymDef(sym: Symbol): Tree =
@@ -169,7 +169,7 @@ trait Symbols {
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)))
+ val rset = Apply(Select(locallyReified(sym), nme.setTypeSignature), List(reify(sym.info)))
if (sym.annotations.isEmpty) rset
else Apply(Select(rset, nme.setAnnotations), List(reify(sym.annotations)))
}
diff --git a/src/compiler/scala/reflect/reify/codegen/Trees.scala b/src/compiler/scala/reflect/reify/codegen/Trees.scala
index 5ad53c0009..c9f5fc5b8d 100644
--- a/src/compiler/scala/reflect/reify/codegen/Trees.scala
+++ b/src/compiler/scala/reflect/reify/codegen/Trees.scala
@@ -7,6 +7,7 @@ trait Trees {
import mirror._
import definitions._
import treeInfo._
+ import scala.reflect.api.Modifier
// 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
@@ -46,7 +47,7 @@ trait Trees {
reifyMirrorObject(EmptyTree)
case mirror.emptyValDef =>
mirrorSelect(nme.emptyValDef)
- case FreeDef(_, _, _, _) =>
+ case FreeDef(_, _, _, _, _) =>
reifyNestedFreeDef(tree)
case FreeRef(_, _) =>
reifyNestedFreeRef(tree)
@@ -57,6 +58,28 @@ trait Trees {
case NestedExpr(_, _, _) =>
reifyNestedExpr(tree)
case Literal(const @ Constant(_)) =>
+ // [Eugene] was necessary when we reified erasures as normalized tycons
+ // now, when we do existentialAbstraction on normalizations, everything works great
+ // todo. find an explanation
+// if (const.tag == ClazzTag) {
+//// def preprocess(tpe: Type): Type = tpe.typeSymbol match {
+//// case ArrayClass => appliedType(ArrayClass, preprocess(tpe.typeArgs.head))
+//// case _ => tpe.typeConstructor
+//// }
+//// val tpe = preprocess(const.typeValue)
+// val tpe = const.typeValue
+// var reified = reify(tpe)
+// reified = mirrorCall(nme.Literal, mirrorCall(nme.Constant, reified))
+//// val skolems = ClassClass.typeParams map (_ => newTypeName(typer.context.unit.fresh.newName("_$")))
+//// var existential = mirrorCall(nme.AppliedTypeTree, mirrorCall(nme.TypeTree, reify(ClassClass.typeConstructor)), mkList(skolems map (skolem => mirrorCall(nme.Ident, reify(skolem)))))
+//// existential = mirrorCall(nme.ExistentialTypeTree, existential, reify(skolems map (skolem => TypeDef(Modifiers(Set(Modifier.deferred: Modifier)), skolem, Nil, TypeBoundsTree(Ident(NothingClass) setType NothingClass.tpe, Ident(AnyClass) setType AnyClass.tpe)))))
+//// reified = mirrorCall(nme.TypeApply, mirrorCall(nme.Select, reified, reify(nme.asInstanceOf_)), mkList(List(existential)))
+// // why is this required??
+//// reified = mirrorCall(nme.TypeApply, mirrorCall(nme.Select, reified, reify(nme.asInstanceOf_)), mkList(List(mirrorCall(nme.TypeTree, reify(appliedType(ClassClass.tpe, List(AnyClass.tpe)))))))
+// reified
+// } else {
+// mirrorCall(nme.Literal, reifyProduct(const))
+// }
mirrorCall(nme.Literal, reifyProduct(const))
case Import(expr, selectors) =>
mirrorCall(nme.Import, reify(expr), mkList(selectors map reifyProduct))
@@ -68,11 +91,11 @@ trait Trees {
// 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)))
+ rtree = Apply(Select(rtree, nme.setSymbol), List(reify(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 = Apply(Select(rtree, nme.setType), List(reify(tree.tpe)))
}
rtree
@@ -98,7 +121,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 collect { case freedef @ FreeDef(_, _, binding, _) if binding.symbol.isLocalToReifee => assert(false, freedef) }
+ inlinedSymbolTable collect { case freedef @ FreeDef(_, _, binding, _, _) if binding.symbol.isLocalToReifee => assert(false, freedef) }
symbolTable ++= inlinedSymbolTable
tree
case tree =>
@@ -172,7 +195,7 @@ trait Trees {
val spliced = spliceType(tpe)
if (spliced == EmptyTree) {
if (reifyDebug) println("splicing failed: reify as is")
- mirrorCall(nme.TypeTree, reifyType(tpe))
+ mirrorCall(nme.TypeTree, reify(tpe))
} else {
spliced match {
case TypeRefToFreeType(freeType) =>
@@ -189,7 +212,7 @@ trait Trees {
mirrorCall(nme.Ident, reify(sym))
} else {
if (reifyDebug) println("tpe is an alias, but not a locatable: reify as TypeTree(%s)".format(tpe))
- mirrorCall(nme.TypeTree, reifyType(tpe))
+ mirrorCall(nme.TypeTree, reify(tpe))
}
}
}
diff --git a/src/compiler/scala/reflect/reify/codegen/Types.scala b/src/compiler/scala/reflect/reify/codegen/Types.scala
index 948728088e..e2a2a69828 100644
--- a/src/compiler/scala/reflect/reify/codegen/Types.scala
+++ b/src/compiler/scala/reflect/reify/codegen/Types.scala
@@ -65,8 +65,16 @@ trait Types {
private var spliceTypesEnabled = !dontSpliceAtTopLevel
/** Keeps track of whether this reification contains abstract type parameters */
- var maybeConcrete = true
- var definitelyConcrete = true
+ private var _definitelyConcrete = true
+ def definitelyConcrete = _definitelyConcrete
+ def definitelyConcrete_=(value: Boolean) {
+ _definitelyConcrete = value
+ if (!value && requireConcreteTypeTag) {
+ assert(current.isInstanceOf[Type], current)
+ val offender = current.asInstanceOf[Type]
+ CannotReifyConcreteTypeTagHavingUnresolvedTypeParameters(offender)
+ }
+ }
private type SpliceCacheKey = (Symbol, Symbol)
private lazy val spliceCache: collection.mutable.Map[SpliceCacheKey, Tree] = {
@@ -75,7 +83,9 @@ trait Types {
}
def spliceType(tpe: Type): Tree = {
- if (tpe.isSpliceable) {
+ // [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
+ if (tpe.isSpliceable && !(quantified contains tpe.typeSymbol)) {
if (reifyDebug) println("splicing " + tpe)
if (spliceTypesEnabled) {
@@ -89,22 +99,18 @@ trait Types {
// if this fails, it might produce the dreaded "erroneous or inaccessible type" error
// to find out the whereabouts of the error run scalac with -Ydebug
if (reifyDebug) println("launching implicit search for %s.%s[%s]".format(prefix, tagClass.name, tpe))
- val positionBearer = mirror.analyzer.openMacros.find(c => c.macroApplication.pos != NoPosition).map(_.macroApplication).getOrElse(EmptyTree).asInstanceOf[Tree]
typer.resolveTypeTag(positionBearer, prefix.tpe, tpe, requireConcreteTypeTag) match {
case failure if failure.isEmpty =>
if (reifyDebug) println("implicit search was fruitless")
- definitelyConcrete &= false
- maybeConcrete &= false
EmptyTree
case success =>
if (reifyDebug) println("implicit search has produced a result: " + success)
- definitelyConcrete |= requireConcreteTypeTag
- maybeConcrete |= true
+ definitelyConcrete &= requireConcreteTypeTag
var splice = Select(success, nme.tpe)
splice match {
case InlinedTypeSplice(_, inlinedSymbolTable, tpe) =>
// all free vars local to the enclosing reifee should've already been inlined by ``Metalevels''
- inlinedSymbolTable collect { case freedef @ FreeDef(_, _, binding, _) if binding.symbol.isLocalToReifee => assert(false, freedef) }
+ inlinedSymbolTable collect { case freedef @ FreeDef(_, _, binding, _, _) if binding.symbol.isLocalToReifee => assert(false, freedef) }
symbolTable ++= inlinedSymbolTable
reifyTrace("inlined the splicee: ")(tpe)
case tpe =>
@@ -117,8 +123,7 @@ trait Types {
if (reifyDebug) println("splicing has been cancelled: spliceTypesEnabled = false")
}
- if (requireConcreteTypeTag)
- CannotReifyConcreteTypeTagHavingUnresolvedTypeParameters(tpe)
+ definitelyConcrete = false
}
spliceTypesEnabled = true
diff --git a/src/compiler/scala/reflect/reify/codegen/Util.scala b/src/compiler/scala/reflect/reify/codegen/Util.scala
index bb369a1adb..8d7cf39ff7 100644
--- a/src/compiler/scala/reflect/reify/codegen/Util.scala
+++ b/src/compiler/scala/reflect/reify/codegen/Util.scala
@@ -14,6 +14,8 @@ trait Util {
object reifiedNodePrinters extends { val global: mirror.type = mirror } with tools.nsc.ast.NodePrinters with NodePrinters
val reifiedNodeToString = reifiedNodePrinters.reifiedNodeToString
+ val positionBearer = mirror.analyzer.openMacros.find(c => c.macroApplication.pos != NoPosition).map(_.macroApplication).getOrElse(EmptyTree).asInstanceOf[Tree]
+
def reifyList(xs: List[Any]): Tree =
mkList(xs map reify)
diff --git a/src/compiler/scala/reflect/reify/phases/Metalevels.scala b/src/compiler/scala/reflect/reify/phases/Metalevels.scala
index bb0b8ac138..206f3b1118 100644
--- a/src/compiler/scala/reflect/reify/phases/Metalevels.scala
+++ b/src/compiler/scala/reflect/reify/phases/Metalevels.scala
@@ -115,7 +115,7 @@ trait Metalevels {
if (reifyDebug) println("entering inlineable splice: " + splicee)
val Block(mrDef :: symbolTable, expr) = splicee
// [Eugene] how to express the fact that a scrutinee is both of some type and matches an extractor?
- val freedefsToInline = symbolTable collect { case freedef @ FreeTermDef(_, _, binding, _) if binding.symbol.isLocalToReifee => freedef.asInstanceOf[ValDef] }
+ val freedefsToInline = symbolTable collect { case freedef @ FreeTermDef(_, _, binding, _, _) if binding.symbol.isLocalToReifee => freedef.asInstanceOf[ValDef] }
freedefsToInline foreach (vdef => this.freedefsToInline(vdef.name) = vdef)
val symbolTable1 = symbolTable diff freedefsToInline
val tree1 = Select(Block(mrDef :: symbolTable1, expr), flavor)
@@ -138,7 +138,7 @@ trait Metalevels {
// 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)
+ val freedef @ FreeDef(_, _, binding, _, _) = freedefsToInline(name)
if (reifyDebug) println("related definition: %s".format(showRaw(freedef)))
val inlined = reify(binding)
if (reifyDebug) println("verdict: inlined as %s".format(showRaw(inlined)))
diff --git a/src/compiler/scala/reflect/reify/phases/Reify.scala b/src/compiler/scala/reflect/reify/phases/Reify.scala
index 02a96987ed..a1ff486ed7 100644
--- a/src/compiler/scala/reflect/reify/phases/Reify.scala
+++ b/src/compiler/scala/reflect/reify/phases/Reify.scala
@@ -23,24 +23,33 @@ trait Reify extends Symbols
* Reifies any supported value.
* For internal use only, use ``reified'' instead.
*/
- def reify(reifee: Any): Tree = 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))
+ 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`
+// 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
+ }
}
} \ No newline at end of file
diff --git a/src/compiler/scala/reflect/reify/phases/Reshape.scala b/src/compiler/scala/reflect/reify/phases/Reshape.scala
index e700604612..4ab306a13f 100644
--- a/src/compiler/scala/reflect/reify/phases/Reshape.scala
+++ b/src/compiler/scala/reflect/reify/phases/Reshape.scala
@@ -78,12 +78,6 @@ trait Reshape {
if (reifyDebug) println("unapplying unapply: " + tree)
val fun1 = extractExtractor(fun)
Apply(fun1, args).copyAttrs(unapply)
- case Literal(const @ Constant(tpe: Type)) =>
- // todo. implement this
- ???
- case Literal(const @ Constant(sym: Symbol)) =>
- // todo. implement this
- ???
case _ =>
tree
}
diff --git a/src/compiler/scala/reflect/runtime/SynchronizedSymbols.scala b/src/compiler/scala/reflect/runtime/SynchronizedSymbols.scala
index 6fc5f7ed8a..4048e94d0f 100644
--- a/src/compiler/scala/reflect/runtime/SynchronizedSymbols.scala
+++ b/src/compiler/scala/reflect/runtime/SynchronizedSymbols.scala
@@ -14,11 +14,11 @@ trait SynchronizedSymbols extends internal.Symbols { self: SymbolTable =>
override def connectModuleToClass(m: ModuleSymbol, moduleClass: ClassSymbol): ModuleSymbol =
synchronized { super.connectModuleToClass(m, moduleClass) }
- override def newFreeTerm(name: TermName, info: Type, value: => Any, origin: String = null, newFlags: Long = 0L): FreeTerm =
- new FreeTerm(name, value, origin) with SynchronizedTermSymbol initFlags newFlags setInfo info
+ override def newFreeTermSymbol(name: TermName, info: Type, value: => Any, flags: Long = 0L, origin: String = null): FreeTerm =
+ new FreeTerm(name, value, origin) with SynchronizedTermSymbol initFlags flags setInfo info
- override def newFreeType(name: TypeName, info: Type, value: => Any, origin: String = null, newFlags: Long = 0L): FreeType =
- new FreeType(name, value, origin) with SynchronizedTypeSymbol initFlags newFlags setInfo info
+ override def newFreeTypeSymbol(name: TypeName, info: Type, value: => Any, flags: Long = 0L, origin: String = null): FreeType =
+ new FreeType(name, value, origin) with SynchronizedTypeSymbol initFlags flags setInfo info
override protected def makeNoSymbol: NoSymbol = new NoSymbol with SynchronizedSymbol
diff --git a/src/compiler/scala/tools/nsc/ast/FreeVars.scala b/src/compiler/scala/tools/nsc/ast/FreeVars.scala
index 1bf36e8bf2..a1983d1834 100644
--- a/src/compiler/scala/tools/nsc/ast/FreeVars.scala
+++ b/src/compiler/scala/tools/nsc/ast/FreeVars.scala
@@ -13,9 +13,9 @@ trait FreeVars extends reflect.internal.FreeVars { self: Global =>
case Reified(_, symbolTable, _) =>
// logging free vars only when they are untyped prevents avalanches of duplicate messages
symbolTable foreach {
- case FreeTermDef(_, _, binding, origin) if settings.logFreeTerms.value && binding.tpe == null =>
+ case FreeTermDef(_, _, binding, _, origin) if settings.logFreeTerms.value && binding.tpe == null =>
reporter.echo(position, "free term: %s %s".format(showRaw(binding), origin))
- case FreeTypeDef(_, _, binding, origin) if settings.logFreeTypes.value && binding.tpe == null =>
+ case FreeTypeDef(_, _, binding, _, origin) if settings.logFreeTypes.value && binding.tpe == null =>
reporter.echo(position, "free type: %s %s".format(showRaw(binding), origin))
case _ =>
// do nothing
diff --git a/src/compiler/scala/tools/nsc/typechecker/Implicits.scala b/src/compiler/scala/tools/nsc/typechecker/Implicits.scala
index 4fb9362ccc..30a79917c9 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Implicits.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Implicits.scala
@@ -1161,7 +1161,8 @@ trait Implicits {
// todo. migrate hardcoded materialization in Implicits to corresponding implicit macros
var materializer = atPos(pos.focus)(Apply(TypeApply(Ident(TagMaterializers(tagClass)), List(TypeTree(tp))), List(prefix)))
if (settings.XlogImplicits.value) println("materializing requested %s.%s[%s] using %s".format(pre, tagClass.name, tp, materializer))
- success(materializer)
+ if (context.macrosEnabled) success(materializer)
+ else failure(materializer, "macros are disabled")
}
/** The manifest corresponding to type `pt`, provided `pt` is an instance of Manifest.
diff --git a/src/library/scala/reflect/ClassTag.scala b/src/library/scala/reflect/ClassTag.scala
index 7138837f0d..fe8a16a484 100644
--- a/src/library/scala/reflect/ClassTag.scala
+++ b/src/library/scala/reflect/ClassTag.scala
@@ -117,6 +117,10 @@ object ClassTag {
case _ => apply[T](rm.typeToClass(tpe.erasure))
}
+ def apply[T](ttag: rm.ConcreteTypeTag[T]): ClassTag[T] =
+ if (ttag.erasure != null) ClassTag[T](ttag.erasure)
+ else ClassTag[T](ttag.tpe)
+
implicit def toDeprecatedClassManifestApis[T](ctag: ClassTag[T]): DeprecatedClassManifestApis[T] = new DeprecatedClassManifestApis[T](ctag)
}
diff --git a/src/library/scala/reflect/DynamicProxy.scala b/src/library/scala/reflect/DynamicProxy.scala
index ffd1e7a39f..02872977f5 100644
--- a/src/library/scala/reflect/DynamicProxy.scala
+++ b/src/library/scala/reflect/DynamicProxy.scala
@@ -2,13 +2,13 @@ package scala.reflect
/**
* A dynamic proxy which redirects method calls and attribute access to a given
* target object at runtime using reflection.
- *
+ *
* Usage example:
- *
+ *
* object x{ def hello = "hello world" }
* val d = new DynamicProxy{ val dynamicProxyTarget = x }
* assert( d.hello == "hello world" )
- *
+ *
* Not supported (yet):
* - implicit conversions and parameters
* - multiple arguments lists
@@ -26,7 +26,7 @@ trait DynamicProxy extends Dynamic{
object DynamicReflectBoxed{
implicit def box[@specialized T]( v:T ) = DynamicReflectBoxed( v.getClass, v )
}
-
+
def selectDynamic( method:String ) = {
val symbol = classToType( dynamicProxyTarget.getClass ).member( newTermName(method).encodedName )
invoke( dynamicProxyTarget, symbol )()
@@ -38,7 +38,7 @@ trait DynamicProxy extends Dynamic{
}
def applyDynamic( method:String )( args:DynamicReflectBoxed* ) : Any
- = applyDynamicNamed( method )( args.map( value => ("",value) ) :_* )
+ = applyDynamicNamed( method )( args.map( value => ("",value) ) :_* )
def applyDynamicNamed( method:String )( args:(String,DynamicReflectBoxed)* ) : Any = {
val class_ = dynamicProxyTarget.getClass
@@ -48,27 +48,27 @@ trait DynamicProxy extends Dynamic{
if(args.size == 0){
invoke( dynamicProxyTarget, symbol )()
} else {
- val call =
+ val call =
Apply(
Select(
TypeApply(
Select(
Select(
- Ident(newFreeTerm("__this", symbolForName("scala.reflect.DynamicProxy").asType, this, null))
+ Ident(newFreeTerm("__this", symbolForName("scala.reflect.DynamicProxy").asType, this))
, newTermName("dynamicProxyTarget")
- ),
+ ),
newTermName("asInstanceOf") )
, List(TypeTree().setType(classToType(class_)))
)
,newTermName(method).encodedName
)
,args.map{ case(name,box) =>
- val value = Ident(newFreeTerm("__arg"+({i+=1;i}.toString), classToType(box.class_), box.value, null))
+ val value = Ident(newFreeTerm("__arg"+({i+=1;i}.toString), classToType(box.class_), box.value))
if( name == "" ) value
else AssignOrNamedArg( Ident(name), value )
}.toList
)
toolbox.runExpr( call )
- }
+ }
}
}
diff --git a/src/library/scala/reflect/TagMaterialization.scala b/src/library/scala/reflect/TagMaterialization.scala
index aede00020f..a7237223f1 100644
--- a/src/library/scala/reflect/TagMaterialization.scala
+++ b/src/library/scala/reflect/TagMaterialization.scala
@@ -65,59 +65,22 @@ object TagMaterialization {
val ConcreteTypeTagClass = selectType(TypeTagsClass, "ConcreteTypeTag")
val ConcreteTypeTagModule = selectTerm(TypeTagsClass, "ConcreteTypeTag")
- def materializeClassTag(tpe: Type): Tree = {
- val prefix = gen.mkAttributedRef(Reflect_mirror) setType singleType(Reflect_mirror.owner.thisPrefix, Reflect_mirror)
- materializeClassTag(prefix, tpe)
- }
-
- def materializeClassTag(prefix: Tree, tpe: Type): Tree = {
- val typetagInScope = c.inferImplicitValue(appliedType(typeRef(prefix.tpe, ConcreteTypeTagClass, Nil), List(tpe)))
- def typetagIsSynthetic(tree: Tree) = tree.isInstanceOf[Block] || (tree exists (sub => sub.symbol == TypeTagModule || sub.symbol == ConcreteTypeTagModule))
- typetagInScope match {
- case success if !success.isEmpty && !typetagIsSynthetic(success) =>
- val factory = TypeApply(Select(Ident(ClassTagModule), newTermName("apply")), List(TypeTree(tpe)))
- Apply(factory, List(Select(typetagInScope, newTermName("tpe"))))
- case _ =>
- val result =
- tpe match {
- case coreTpe if coreTags contains coreTpe =>
- Select(Ident(ClassTagModule), coreTags(coreTpe))
- case _ =>
- if (tpe.typeSymbol == ArrayClass) {
- val componentTpe = tpe.typeArguments(0)
- val classtagInScope = c.inferImplicitValue(appliedType(typeRef(NoPrefix, ClassTagClass, Nil), List(componentTpe)))
- val componentTag = classtagInScope orElse materializeClassTag(prefix, componentTpe)
- Select(componentTag, newTermName("wrap"))
- } else {
- // [Eugene] what's the intended behavior? there's no spec on ClassManifests
- // for example, should we ban Array[T] or should we tag them with Array[AnyRef]?
- // if its the latter, what should be the result of tagging Array[T] where T <: Int?
- if (tpe.typeSymbol.isAbstractType) fail("tpe is an abstract type")
- val erasure =
- if (tpe.typeSymbol.isDerivedValueClass) tpe // [Eugene to Martin] is this correct?
- else tpe.erasure.normalize // necessary to deal with erasures of HK types
- val factory = TypeApply(Select(Ident(ClassTagModule), newTermName("apply")), List(TypeTree(tpe)))
- Apply(factory, List(TypeApply(Ident(newTermName("classOf")), List(TypeTree(erasure)))))
- }
- }
- try c.typeCheck(result)
- catch { case terr @ c.TypeError(pos, msg) => fail(terr) }
- }
- }
+ def materializeClassTag(tpe: Type): Tree =
+ materializeTag(c.reflectMirrorPrefix, tpe, ClassTagModule, c.reifyErasure(tpe))
def materializeTypeTag(tpe: Type, requireConcreteTypeTag: Boolean): Tree = {
def prefix: Tree = ??? // todo. needs to be synthesized from c.prefix
- materializeTypeTag(prefix, tpe, requireConcreteTypeTag)
+ val tagModule = if (requireConcreteTypeTag) ConcreteTypeTagModule else TypeTagModule
+ materializeTag(prefix, tpe, tagModule, c.reifyType(prefix, tpe, dontSpliceAtTopLevel = true, requireConcreteTypeTag = requireConcreteTypeTag))
}
- def materializeTypeTag(prefix: Tree, tpe: Type, requireConcreteTypeTag: Boolean): Tree = {
- val tagModule = if (requireConcreteTypeTag) ConcreteTypeTagModule else TypeTagModule
+ private def materializeTag(prefix: Tree, tpe: Type, tagModule: Symbol, materializer: => Tree): Tree = {
val result =
tpe match {
case coreTpe if coreTags contains coreTpe =>
Select(Select(prefix, tagModule.name), coreTags(coreTpe))
case _ =>
- try c.reifyType(prefix, tpe, dontSpliceAtTopLevel = true, requireConcreteTypeTag = requireConcreteTypeTag)
+ try materializer
catch {
case ex: Throwable =>
// [Eugene] cannot pattern match on an abstract type, so had to do this
diff --git a/src/library/scala/reflect/api/Symbols.scala b/src/library/scala/reflect/api/Symbols.scala
index e47bc7216e..d9293888d9 100755
--- a/src/library/scala/reflect/api/Symbols.scala
+++ b/src/library/scala/reflect/api/Symbols.scala
@@ -120,6 +120,11 @@ trait Symbols { self: Universe =>
*/
def isTerm : Boolean
+ /** Does this symbol represent a package?
+ * If yes, `isTerm` is also guaranteed to be true.
+ */
+ def isPackage : Boolean
+
/** Does this symbol represent the definition of method?
* If yes, `isTerm` is also guaranteed to be true.
*/
@@ -146,6 +151,11 @@ trait Symbols { self: Universe =>
*/
def isClass : Boolean
+ /** Does this symbol represent a package class?
+ * If yes, `isClass` is also guaranteed to be true.
+ */
+ def isPackageClass : Boolean
+
/** Does this symbol represent the definition of a primitive class?
* Namely, is it one of [[scala.Double]], [[scala.Float]], [[scala.Long]], [[scala.Int]], [[scala.Char]],
* [[scala.Short]], [[scala.Byte]], [[scala.Unit]] or [[scala.Boolean]]?
diff --git a/src/library/scala/reflect/api/TreeBuildUtil.scala b/src/library/scala/reflect/api/TreeBuildUtil.scala
index 32d7eefa5b..4f510337c2 100644
--- a/src/library/scala/reflect/api/TreeBuildUtil.scala
+++ b/src/library/scala/reflect/api/TreeBuildUtil.scala
@@ -62,20 +62,34 @@ trait TreeBuildUtil { self: Universe =>
* @param name the name of the free variable
* @param info the type signature of the free variable
* @param value the value of the free variable at runtime
+ * @param flags (optional) flags of the free variable
* @param origin debug information that tells where this symbol comes from
*/
- def newFreeTerm(name: String, info: Type, value: => Any, origin: String): Symbol
+ def newFreeTerm(name: String, info: Type, value: => Any, flags: Long = 0L, origin: String = null): Symbol
- /** Create a fresh free type symbol.
+ /** Create a fresh free non-existential type symbol.
* @param name the name of the free variable
* @param info the type signature of the free variable
* @param value a type tag that captures the value of the free variable
* is completely phantom, since the captured type cannot be propagated to the runtime
* if it could be, we wouldn't be creating a free type to begin with
* the only usage for it is preserving the captured symbol for compile-time analysis
+ * @param flags (optional) flags of the free variable
* @param origin debug information that tells where this symbol comes from
*/
- def newFreeType(name: String, info: Type, value: => Any, origin: String): Symbol
+ def newFreeType(name: String, info: Type, value: => Any, flags: Long = 0L, origin: String = null): Symbol
+
+ /** Create a fresh free existential type symbol.
+ * @param name the name of the free variable
+ * @param info the type signature of the free variable
+ * @param value a type tag that captures the value of the free variable
+ * is completely phantom, since the captured type cannot be propagated to the runtime
+ * if it could be, we wouldn't be creating a free type to begin with
+ * the only usage for it is preserving the captured symbol for compile-time analysis
+ * @param flags (optional) flags of the free variable
+ * @param origin (optional) debug information that tells where this symbol comes from
+ */
+ def newFreeExistential(name: String, info: Type, value: => Any, flags: Long = 0L, origin: String = null): Symbol
/** Create a Modiiers structure given internal flags, qualifier, annotations */
def modifiersFromInternalFlags(flags: Long, privateWithin: Name, annotations: List[Tree]): Modifiers
diff --git a/src/library/scala/reflect/api/TypeTags.scala b/src/library/scala/reflect/api/TypeTags.scala
index 59a7c87f44..85755cd2f2 100644
--- a/src/library/scala/reflect/api/TypeTags.scala
+++ b/src/library/scala/reflect/api/TypeTags.scala
@@ -7,6 +7,7 @@ package scala.reflect
package api
import scala.reflect.{ mirror => rm }
+import java.lang.{ Class => jClass }
import language.implicitConversions
/**
@@ -119,7 +120,7 @@ trait TypeTags { self: Universe =>
* @see [[scala.reflect.api.TypeTags]]
*/
@annotation.implicitNotFound(msg = "No ConcreteTypeTag available for ${T}")
- class ConcreteTypeTag[T](tpe: Type) extends TypeTag[T](tpe) {
+ abstract class ConcreteTypeTag[T](tpe: Type, val erasure: jClass[_]) extends TypeTag[T](tpe) {
// it's unsafe to use assert here, because we might run into deadlocks with Predef
// also see comments in ClassTags.scala
//assert(isConcrete, tpe)
@@ -128,24 +129,24 @@ trait TypeTags { self: Universe =>
}
object ConcreteTypeTag {
- val Byte : ConcreteTypeTag[scala.Byte] = new ConcreteTypeTag[scala.Byte](ByteTpe) { private def readResolve() = ConcreteTypeTag.Byte }
- val Short : ConcreteTypeTag[scala.Short] = new ConcreteTypeTag[scala.Short](ShortTpe) { private def readResolve() = ConcreteTypeTag.Short }
- val Char : ConcreteTypeTag[scala.Char] = new ConcreteTypeTag[scala.Char](CharTpe) { private def readResolve() = ConcreteTypeTag.Char }
- val Int : ConcreteTypeTag[scala.Int] = new ConcreteTypeTag[scala.Int](IntTpe) { private def readResolve() = ConcreteTypeTag.Int }
- val Long : ConcreteTypeTag[scala.Long] = new ConcreteTypeTag[scala.Long](LongTpe) { private def readResolve() = ConcreteTypeTag.Long }
- val Float : ConcreteTypeTag[scala.Float] = new ConcreteTypeTag[scala.Float](FloatTpe) { private def readResolve() = ConcreteTypeTag.Float }
- val Double : ConcreteTypeTag[scala.Double] = new ConcreteTypeTag[scala.Double](DoubleTpe) { private def readResolve() = ConcreteTypeTag.Double }
- val Boolean : ConcreteTypeTag[scala.Boolean] = new ConcreteTypeTag[scala.Boolean](BooleanTpe) { private def readResolve() = ConcreteTypeTag.Boolean }
- val Unit : ConcreteTypeTag[scala.Unit] = new ConcreteTypeTag[scala.Unit](UnitTpe) { private def readResolve() = ConcreteTypeTag.Unit }
- val Any : ConcreteTypeTag[scala.Any] = new ConcreteTypeTag[scala.Any](AnyTpe) { private def readResolve() = ConcreteTypeTag.Any }
- val Object : ConcreteTypeTag[java.lang.Object] = new ConcreteTypeTag[java.lang.Object](ObjectTpe) { private def readResolve() = ConcreteTypeTag.Object }
- val AnyVal : ConcreteTypeTag[scala.AnyVal] = new ConcreteTypeTag[scala.AnyVal](AnyValTpe) { private def readResolve() = ConcreteTypeTag.AnyVal }
- val AnyRef : ConcreteTypeTag[scala.AnyRef] = new ConcreteTypeTag[scala.AnyRef](AnyRefTpe) { private def readResolve() = ConcreteTypeTag.AnyRef }
- val Nothing : ConcreteTypeTag[scala.Nothing] = new ConcreteTypeTag[scala.Nothing](NothingTpe) { private def readResolve() = ConcreteTypeTag.Nothing }
- val Null : ConcreteTypeTag[scala.Null] = new ConcreteTypeTag[scala.Null](NullTpe) { private def readResolve() = ConcreteTypeTag.Null }
- val String : ConcreteTypeTag[java.lang.String] = new ConcreteTypeTag[java.lang.String](StringTpe) { private def readResolve() = ConcreteTypeTag.String }
-
- def apply[T](tpe: Type): ConcreteTypeTag[T] =
+ val Byte : ConcreteTypeTag[scala.Byte] = new ConcreteTypeTag[scala.Byte](ByteTpe, ClassTag.Byte.erasure) { private def readResolve() = ConcreteTypeTag.Byte }
+ val Short : ConcreteTypeTag[scala.Short] = new ConcreteTypeTag[scala.Short](ShortTpe, ClassTag.Short.erasure) { private def readResolve() = ConcreteTypeTag.Short }
+ val Char : ConcreteTypeTag[scala.Char] = new ConcreteTypeTag[scala.Char](CharTpe, ClassTag.Char.erasure) { private def readResolve() = ConcreteTypeTag.Char }
+ val Int : ConcreteTypeTag[scala.Int] = new ConcreteTypeTag[scala.Int](IntTpe, ClassTag.Int.erasure) { private def readResolve() = ConcreteTypeTag.Int }
+ val Long : ConcreteTypeTag[scala.Long] = new ConcreteTypeTag[scala.Long](LongTpe, ClassTag.Long.erasure) { private def readResolve() = ConcreteTypeTag.Long }
+ val Float : ConcreteTypeTag[scala.Float] = new ConcreteTypeTag[scala.Float](FloatTpe, ClassTag.Float.erasure) { private def readResolve() = ConcreteTypeTag.Float }
+ val Double : ConcreteTypeTag[scala.Double] = new ConcreteTypeTag[scala.Double](DoubleTpe, ClassTag.Double.erasure) { private def readResolve() = ConcreteTypeTag.Double }
+ val Boolean : ConcreteTypeTag[scala.Boolean] = new ConcreteTypeTag[scala.Boolean](BooleanTpe, ClassTag.Boolean.erasure) { private def readResolve() = ConcreteTypeTag.Boolean }
+ val Unit : ConcreteTypeTag[scala.Unit] = new ConcreteTypeTag[scala.Unit](UnitTpe, ClassTag.Unit.erasure) { private def readResolve() = ConcreteTypeTag.Unit }
+ val Any : ConcreteTypeTag[scala.Any] = new ConcreteTypeTag[scala.Any](AnyTpe, ClassTag.Any.erasure) { private def readResolve() = ConcreteTypeTag.Any }
+ val Object : ConcreteTypeTag[java.lang.Object] = new ConcreteTypeTag[java.lang.Object](ObjectTpe, ClassTag.Object.erasure) { private def readResolve() = ConcreteTypeTag.Object }
+ val AnyVal : ConcreteTypeTag[scala.AnyVal] = new ConcreteTypeTag[scala.AnyVal](AnyValTpe, ClassTag.AnyVal.erasure) { private def readResolve() = ConcreteTypeTag.AnyVal }
+ val AnyRef : ConcreteTypeTag[scala.AnyRef] = new ConcreteTypeTag[scala.AnyRef](AnyRefTpe, ClassTag.AnyRef.erasure) { private def readResolve() = ConcreteTypeTag.AnyRef }
+ val Nothing : ConcreteTypeTag[scala.Nothing] = new ConcreteTypeTag[scala.Nothing](NothingTpe, ClassTag.Nothing.erasure) { private def readResolve() = ConcreteTypeTag.Nothing }
+ val Null : ConcreteTypeTag[scala.Null] = new ConcreteTypeTag[scala.Null](NullTpe, ClassTag.Null.erasure) { private def readResolve() = ConcreteTypeTag.Null }
+ val String : ConcreteTypeTag[java.lang.String] = new ConcreteTypeTag[java.lang.String](StringTpe, ClassTag.String.erasure) { private def readResolve() = ConcreteTypeTag.String }
+
+ def apply[T](tpe: Type, erasure: jClass[_] = null): ConcreteTypeTag[T] =
tpe match {
case ByteTpe => ConcreteTypeTag.Byte.asInstanceOf[ConcreteTypeTag[T]]
case ShortTpe => ConcreteTypeTag.Short.asInstanceOf[ConcreteTypeTag[T]]
@@ -163,12 +164,12 @@ trait TypeTags { self: Universe =>
case NothingTpe => ConcreteTypeTag.Nothing.asInstanceOf[ConcreteTypeTag[T]]
case NullTpe => ConcreteTypeTag.Null.asInstanceOf[ConcreteTypeTag[T]]
case StringTpe => ConcreteTypeTag.String.asInstanceOf[ConcreteTypeTag[T]]
- case _ => new ConcreteTypeTag[T](tpe) {}
+ case _ => new ConcreteTypeTag[T](tpe, erasure) {}
}
def unapply[T](ttag: TypeTag[T]): Option[Type] = if (ttag.isConcrete) Some(ttag.tpe) else None
- implicit def toClassTag[T](ttag: rm.ConcreteTypeTag[T]): ClassTag[T] = ClassTag[T](rm.typeToClass(ttag.tpe.erasure))
+ implicit def toClassTag[T](ttag: rm.ConcreteTypeTag[T]): ClassTag[T] = ClassTag[T](ttag)
implicit def toDeprecatedManifestApis[T](ttag: rm.ConcreteTypeTag[T]): DeprecatedManifestApis[T] = new DeprecatedManifestApis[T](ttag)
diff --git a/src/library/scala/reflect/api/Types.scala b/src/library/scala/reflect/api/Types.scala
index 5e1c1af2fe..4cb5609166 100755
--- a/src/library/scala/reflect/api/Types.scala
+++ b/src/library/scala/reflect/api/Types.scala
@@ -53,14 +53,26 @@ trait Types { self: Universe =>
*/
def typeArguments: List[Type]
+ /** For a (potentially wrapped) poly type, its type parameters,
+ * the empty list for all other types */
+ def typeParams: List[Symbol]
+
/** Is this type a type constructor that is missing its type arguments?
*/
def isHigherKinded: Boolean // !!! This should be called "isTypeConstructor", no?
- /** Does this type refer to abstract types or is an abstract type?
+ /** Returns the corresponding type constructor (e.g. List for List[T] or List[String])
+ */
+ def typeConstructor: Type
+
+ /** Does this type refer to spliceable types or is a spliceable type?
*/
def isConcrete: Boolean
+ /** Is this type an abstract type that needs to be resolved?
+ */
+ def isSpliceable: Boolean
+
/**
* Expands type aliases and converts higher-kinded TypeRefs to PolyTypes.
* Functions on types are also implemented as PolyTypes.
diff --git a/src/library/scala/reflect/makro/Reifiers.scala b/src/library/scala/reflect/makro/Reifiers.scala
index d690df6aee..b9e82e0387 100644
--- a/src/library/scala/reflect/makro/Reifiers.scala
+++ b/src/library/scala/reflect/makro/Reifiers.scala
@@ -48,6 +48,10 @@ trait Reifiers {
*/
def reifyType(prefix: Tree, tpe: Type, dontSpliceAtTopLevel: Boolean = false, requireConcreteTypeTag: Boolean = false): Tree
+ /** Given a type, generate a tree that when compiled and executed produces the erasure of the original type.
+ */
+ def reifyErasure(tpe: Type): Tree
+
/** Undoes reification of a tree.
*
* This reversion doesn't simply restore the original tree (that would lose the context of reification),
diff --git a/src/library/scala/reflect/makro/internal/Utils.scala b/src/library/scala/reflect/makro/internal/Utils.scala
index db658fd637..604bba10b6 100644
--- a/src/library/scala/reflect/makro/internal/Utils.scala
+++ b/src/library/scala/reflect/makro/internal/Utils.scala
@@ -55,49 +55,22 @@ package internal {
NothingClass.asType -> newTermName("Nothing"),
NullClass.asType -> newTermName("Null"))
- def materializeClassTag(prefix: Tree, tpe: Type): Tree = {
- val typetagInScope = c.inferImplicitValue(appliedType(typeRef(prefix.tpe, ConcreteTypeTagClass, Nil), List(tpe)))
- def typetagIsSynthetic(tree: Tree) = tree.isInstanceOf[Block] || (tree exists (sub => sub.symbol == TypeTagModule || sub.symbol == ConcreteTypeTagModule))
- typetagInScope match {
- case success if !success.isEmpty && !typetagIsSynthetic(success) =>
- val factory = TypeApply(Select(Ident(ClassTagModule), newTermName("apply")), List(TypeTree(tpe)))
- Apply(factory, List(Select(typetagInScope, newTermName("tpe"))))
- case _ =>
- val result =
- tpe match {
- case coreTpe if coreTags contains coreTpe =>
- Select(Ident(ClassTagModule), coreTags(coreTpe))
- case _ =>
- if (tpe.typeSymbol == ArrayClass) {
- val componentTpe = tpe.typeArguments(0)
- val classtagInScope = c.inferImplicitValue(appliedType(typeRef(NoPrefix, ClassTagClass, Nil), List(componentTpe)))
- val componentTag = classtagInScope orElse materializeClassTag(prefix, componentTpe)
- Select(componentTag, newTermName("wrap"))
- } else {
- // [Eugene] what's the intended behavior? there's no spec on ClassManifests
- // for example, should we ban Array[T] or should we tag them with Array[AnyRef]?
- // if its the latter, what should be the result of tagging Array[T] where T <: Int?
- if (tpe.typeSymbol.isAbstractType) fail("tpe is an abstract type")
- val erasure =
- if (tpe.typeSymbol.isDerivedValueClass) tpe // [Eugene to Martin] is this correct?
- else tpe.erasure.normalize // necessary to deal with erasures of HK types
- val factory = TypeApply(Select(Ident(ClassTagModule), newTermName("apply")), List(TypeTree(tpe)))
- Apply(factory, List(TypeApply(Ident(newTermName("classOf")), List(TypeTree(erasure)))))
- }
- }
- try c.typeCheck(result)
- catch { case terr @ c.TypeError(pos, msg) => fail(terr) }
- }
- }
+ def materializeClassTag(prefix: Tree, tpe: Type): Tree =
+ materializeTag(prefix, tpe, ClassTagModule, c.reifyErasure(tpe))
def materializeTypeTag(prefix: Tree, tpe: Type, requireConcreteTypeTag: Boolean): Tree = {
val tagModule = if (requireConcreteTypeTag) ConcreteTypeTagModule else TypeTagModule
+ materializeTag(prefix, tpe, tagModule, c.reifyType(prefix, tpe, dontSpliceAtTopLevel = true, requireConcreteTypeTag = requireConcreteTypeTag))
+ }
+
+ private def materializeTag(prefix: Tree, tpe: Type, tagModule: Symbol, materializer: => Tree): Tree = {
val result =
tpe match {
case coreTpe if coreTags contains coreTpe =>
- Select(Select(prefix, tagModule.name), coreTags(coreTpe))
+ val ref = if (tagModule.owner.isPackageClass) Ident(tagModule) else Select(prefix, tagModule.name)
+ Select(ref, coreTags(coreTpe))
case _ =>
- try c.reifyType(prefix, tpe, dontSpliceAtTopLevel = true, requireConcreteTypeTag = requireConcreteTypeTag)
+ try materializer
catch {
case ex: Throwable =>
// [Eugene] cannot pattern match on an abstract type, so had to do this
diff --git a/src/library/scala/reflect/package.scala b/src/library/scala/reflect/package.scala
index 6d50a96dfd..93fd0bb711 100644
--- a/src/library/scala/reflect/package.scala
+++ b/src/library/scala/reflect/package.scala
@@ -64,7 +64,7 @@ package object reflect {
@deprecated("Use `@scala.reflect.ConcreteTypeTag` instead", "2.10.0")
lazy val Manifest = ConcreteTypeTag
@deprecated("NoManifest is no longer supported, and using it may lead to incorrect results, Use `@scala.reflect.TypeTag` instead", "2.10.0")
- object NoManifest extends OptManifest[Nothing](scala.reflect.mirror.definitions.NothingClass.asType) with Serializable
+ object NoManifest extends OptManifest[Nothing](scala.reflect.mirror.TypeTag.Nothing.tpe)
// ClassTag class is defined separately from the mirror
type TypeTag[T] = scala.reflect.mirror.TypeTag[T]