summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEugene Burmako <xeno.by@gmail.com>2012-04-14 21:11:37 +0200
committerEugene Burmako <xeno.by@gmail.com>2012-04-14 21:11:37 +0200
commit5e4c47f33b8e25feb59ab4599231b1b8d3150de8 (patch)
treeff2ded10d14c5a6e859ac216e60244029a17a505
parent3a2901da406f2478b5634b0636e56de9c4cd676d (diff)
downloadscala-5e4c47f33b8e25feb59ab4599231b1b8d3150de8.tar.gz
scala-5e4c47f33b8e25feb59ab4599231b1b8d3150de8.tar.bz2
scala-5e4c47f33b8e25feb59ab4599231b1b8d3150de8.zip
implements reification of tough types
-rw-r--r--src/compiler/scala/reflect/internal/StdNames.scala1
-rw-r--r--src/compiler/scala/reflect/internal/Symbols.scala4
-rw-r--r--src/compiler/scala/reflect/internal/TreeInfo.scala16
-rw-r--r--src/compiler/scala/reflect/internal/Types.scala33
-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
-rw-r--r--src/compiler/scala/tools/nsc/util/Position.scala10
-rw-r--r--src/library/scala/reflect/api/Attachment.scala10
-rw-r--r--src/library/scala/reflect/api/StandardNames.scala1
-rwxr-xr-xsrc/library/scala/reflect/api/Symbols.scala5
-rw-r--r--src/library/scala/reflect/api/Trees.scala18
-rw-r--r--src/library/scala/reflect/api/TypeTags.scala7
-rwxr-xr-xsrc/library/scala/reflect/api/Types.scala4
-rw-r--r--test/files/jvm/manifests.check56
-rw-r--r--test/files/jvm/manifests.check.temporarily.disabled55
-rw-r--r--test/files/jvm/manifests.scala (renamed from test/files/jvm/manifests.scala.temporarily.disabled)9
-rw-r--r--test/files/neg/t3507.check4
-rw-r--r--test/files/pos/implicits.scala (renamed from test/files/pos/implicits.scala.temporarily.disabled)0
-rw-r--r--test/files/pos/manifest1.scala (renamed from test/files/pos/manifest1.scala.temporarily.disabled)0
-rw-r--r--test/files/run/existentials3.check24
-rw-r--r--test/files/run/existentials3.check.temporarily.disabled22
-rw-r--r--test/files/run/existentials3.scala (renamed from test/files/run/existentials3.scala.temporarily.disabled)20
-rw-r--r--test/files/run/t1195.check6
-rw-r--r--test/files/run/t1195.check.temporarily.disabled6
-rw-r--r--test/files/run/t1195.scala (renamed from test/files/run/t1195.scala.temporarily.disabled)4
-rw-r--r--test/files/run/t3507.check1
-rw-r--r--test/files/run/t3507.scala (renamed from test/files/neg/t3507.scala)6
-rw-r--r--test/files/run/t4110.check2
-rw-r--r--test/files/run/t4110.check.temporarily.disabled2
-rw-r--r--test/files/run/t4110.scala (renamed from test/files/run/t4110.scala.temporarily.disabled)0
-rw-r--r--test/files/run/treePrint.check (renamed from test/files/run/treePrint.check.temporarily.disabled)0
-rw-r--r--test/files/run/treePrint.scala (renamed from test/files/run/treePrint.scala.temporarily.disabled)11
36 files changed, 415 insertions, 259 deletions
diff --git a/src/compiler/scala/reflect/internal/StdNames.scala b/src/compiler/scala/reflect/internal/StdNames.scala
index ac2cf178bf..bf468affe6 100644
--- a/src/compiler/scala/reflect/internal/StdNames.scala
+++ b/src/compiler/scala/reflect/internal/StdNames.scala
@@ -206,6 +206,7 @@ trait StdNames extends NameManglers { self: SymbolTable =>
val MIRROR_FREE_PREFIX: NameType = "free$"
val MIRROR_FREE_THIS_SUFFIX: NameType = "$this"
val MIRROR_FREE_VALUE_SUFFIX: NameType = "$value"
+ val MIRROR_SYMDEF_PREFIX: NameType = "symdef$"
val MIXIN_CONSTRUCTOR: NameType = "$init$"
val MODULE_INSTANCE_FIELD: NameType = NameTransformer.MODULE_INSTANCE_NAME // "MODULE$"
val OUTER: NameType = "$outer"
diff --git a/src/compiler/scala/reflect/internal/Symbols.scala b/src/compiler/scala/reflect/internal/Symbols.scala
index 3bb57cea04..c9947c3c09 100644
--- a/src/compiler/scala/reflect/internal/Symbols.scala
+++ b/src/compiler/scala/reflect/internal/Symbols.scala
@@ -64,6 +64,7 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
this: Symbol =>
def kind: String = kindString
+ def isExistential: Boolean = this.isExistentiallyBound
def newNestedSymbol(name: Name, pos: Position, newFlags: Long, isClass: Boolean): Symbol = name match {
case n: TermName => newTermSymbol(n, pos, newFlags)
@@ -897,8 +898,10 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
if (!owner.isLocatable) return false
if (owner.isTerm) return false
+ if (isLocalDummy) return false
if (isType && isNonClassType) return false
+ if (isRefinementClass) return false
return true
}
@@ -2965,7 +2968,6 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
override def isFreeTerm = true
}
- // [Eugene] the NoSymbol origin works for type parameters. what about existential free types?
class FreeType(name0: TypeName, value0: => Any, val origin: String) extends TypeSkolem(NoSymbol, NoPosition, name0, NoSymbol) {
def value = value0
override def isFreeType = true
diff --git a/src/compiler/scala/reflect/internal/TreeInfo.scala b/src/compiler/scala/reflect/internal/TreeInfo.scala
index a8cca1625f..039c8e557a 100644
--- a/src/compiler/scala/reflect/internal/TreeInfo.scala
+++ b/src/compiler/scala/reflect/internal/TreeInfo.scala
@@ -590,7 +590,7 @@ abstract class TreeInfo {
}
object Reified {
- def unapply(tree: Tree): Option[(Tree, List[ValDef], Tree)] = tree match {
+ def unapply(tree: Tree): Option[(Tree, List[Tree], Tree)] = tree match {
case ReifiedTree(reifee, symbolTable, reified, _) =>
Some(reifee, symbolTable, reified)
case ReifiedType(reifee, symbolTable, reified) =>
@@ -601,16 +601,16 @@ abstract class TreeInfo {
}
object ReifiedTree {
- def unapply(tree: Tree): Option[(Tree, List[ValDef], Tree, Tree)] = tree match {
+ def unapply(tree: Tree): Option[(Tree, List[Tree], Tree, Tree)] = tree match {
case reifee @ Block((mrDef @ ValDef(_, _, _, _)) :: symbolTable, Apply(Apply(_, List(tree)), List(Apply(_, List(tpe))))) if mrDef.name == nme.MIRROR_SHORT =>
- Some(reifee, symbolTable map (_.asInstanceOf[ValDef]), tree, tpe)
+ Some(reifee, symbolTable, tree, tpe)
case _ =>
None
}
}
object InlineableTreeSplice {
- def unapply(tree: Tree): Option[(Tree, List[ValDef], Tree, Tree, Symbol)] = tree match {
+ def unapply(tree: Tree): Option[(Tree, List[Tree], Tree, Tree, Symbol)] = tree match {
case select @ Select(ReifiedTree(splicee, symbolTable, tree, tpe), _) if select.symbol == ExprEval || select.symbol == ExprValue =>
Some(splicee, symbolTable, tree, tpe, select.symbol)
case _ =>
@@ -619,7 +619,7 @@ abstract class TreeInfo {
}
object InlinedTreeSplice {
- def unapply(tree: Tree): Option[(Tree, List[ValDef], Tree, Tree)] = tree match {
+ def unapply(tree: Tree): Option[(Tree, List[Tree], Tree, Tree)] = tree match {
case Select(ReifiedTree(splicee, symbolTable, tree, tpe), name) if name == ExprTree.name =>
Some(splicee, symbolTable, tree, tpe)
case _ =>
@@ -628,16 +628,16 @@ abstract class TreeInfo {
}
object ReifiedType {
- def unapply(tree: Tree): Option[(Tree, List[ValDef], Tree)] = tree match {
+ 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 =>
- Some(reifee, symbolTable map (_.asInstanceOf[ValDef]), tpe)
+ Some(reifee, symbolTable, tpe)
case _ =>
None
}
}
object InlinedTypeSplice {
- def unapply(tree: Tree): Option[(Tree, List[ValDef], Tree)] = tree match {
+ def unapply(tree: Tree): Option[(Tree, List[Tree], Tree)] = tree match {
case Select(ReifiedType(splicee, symbolTable, tpe), name) if name == TypeTagTpe.name =>
Some(splicee, symbolTable, tpe)
case _ =>
diff --git a/src/compiler/scala/reflect/internal/Types.scala b/src/compiler/scala/reflect/internal/Types.scala
index 3efbe4b4df..d7c90d597c 100644
--- a/src/compiler/scala/reflect/internal/Types.scala
+++ b/src/compiler/scala/reflect/internal/Types.scala
@@ -266,6 +266,35 @@ trait Types extends api.Types { self: SymbolTable =>
def typeArguments = typeArgs
def erasure = transformedType(this)
def substituteTypes(from: List[Symbol], to: List[Type]): Type = subst(from, to)
+
+ // [Eugene] to be discussed and refactored
+ def isConcrete = {
+ def notConcreteSym(sym: Symbol) =
+ sym.isAbstractType && !sym.isExistential
+
+ def notConcreteTpe(tpe: Type): Boolean = tpe match {
+ case ThisType(_) => false
+ case SuperType(_, _) => false
+ case SingleType(pre, sym) => notConcreteSym(sym)
+ case ConstantType(_) => false
+ case TypeRef(_, sym, _) => notConcreteSym(sym)
+ case RefinedType(_, _) => false
+ case ExistentialType(_, _) => false
+ case AnnotatedType(_, tp, _) => notConcreteTpe(tp)
+ case _ => true
+ }
+
+ !notConcreteTpe(this)
+ }
+
+ // [Eugene] is this comprehensive?
+ // the only thingies that we want to splice are: 1) type parameters, 2) type members
+ // the thingies that we don't want to splice are: 1) concrete types (obviously), 2) existential skolems
+ // this check seems to cover them all, right?
+ // todo. after we discuss this, move the check to subclasses
+ def isSpliceable = {
+ this.isInstanceOf[TypeRef] && typeSymbol.isAbstractType && !typeSymbol.isExistential
+ }
}
/** The base class for all types */
@@ -2147,7 +2176,7 @@ trait Types extends api.Types { self: SymbolTable =>
sym.isPackageClass
|| pre.isGround && args.forall(_.isGround)
)
-
+
def etaExpand: Type = {
// must initialise symbol, see test/files/pos/ticket0137.scala
val tpars = initializedTypeParams
@@ -2763,7 +2792,7 @@ trait Types extends api.Types { self: SymbolTable =>
zippedArgs map { case (p, a) => p.name + "=" + a } mkString (origin + "[", ", ", "]")
)
}
-
+
trait UntouchableTypeVar extends TypeVar {
override def untouchable = true
override def isGround = true
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)
diff --git a/src/compiler/scala/tools/nsc/util/Position.scala b/src/compiler/scala/tools/nsc/util/Position.scala
index 573f7bc7b2..208cd5703a 100644
--- a/src/compiler/scala/tools/nsc/util/Position.scala
+++ b/src/compiler/scala/tools/nsc/util/Position.scala
@@ -40,7 +40,15 @@ trait Position extends scala.reflect.api.Position with scala.reflect.api.Attachm
/** A bit weird method that is necessary to safely update positions without destroying custom attachments */
// necessary for conformance with Attachment
- def withPos(pos: scala.reflect.api.Position) = pos
+ def withPos(newPos: scala.reflect.api.Position): scala.reflect.api.Attachment = newPos
+
+ /** Exposes itself as payload of Attachment */
+ // necessary for conformance with Attachment
+ def payload: Position = this
+
+ /** A bit weird method that is necessary to safely update positions without destroying custom attachments */
+ // necessary for conformance with Attachment
+ def withPayload(newPos: Any): scala.reflect.api.Attachment = newPos.asInstanceOf[Position]
/** Java file corresponding to the source file of this position.
*/
diff --git a/src/library/scala/reflect/api/Attachment.scala b/src/library/scala/reflect/api/Attachment.scala
index dfd362ebe0..9fa5ceb0fb 100644
--- a/src/library/scala/reflect/api/Attachment.scala
+++ b/src/library/scala/reflect/api/Attachment.scala
@@ -7,10 +7,18 @@ package api
* Attachments have to carry positions, because we don't want to introduce even a single additional field in Tree
* imposing an unnecessary memory tax because of something that will not be used in most cases.
*/
+// [Eugene] with the introduction of `attach` and `payload[T]` users don't need to create custom attachments anymore
+// however, we cannot move attachments to scala.reflect.internal, because they are used in Trees, which are implemented completely in scala.reflect.api
trait Attachment {
/** Gets the underlying position */
def pos: Position
/** Creates a copy of this attachment with its position updated */
- def withPos(pos: Position): Attachment
+ def withPos(newPos: Position): Attachment
+
+ /** Gets the underlying payload */
+ def payload: Any
+
+ /** Creates a copy of this attachment with its payload updated */
+ def withPayload(newPayload: Any): Attachment
}
diff --git a/src/library/scala/reflect/api/StandardNames.scala b/src/library/scala/reflect/api/StandardNames.scala
index d2110ede75..d39d44dd86 100644
--- a/src/library/scala/reflect/api/StandardNames.scala
+++ b/src/library/scala/reflect/api/StandardNames.scala
@@ -44,6 +44,7 @@ trait StandardNames { self: Universe =>
val MIRROR_FREE_PREFIX: TermName
val MIRROR_FREE_THIS_SUFFIX: TermName
val MIRROR_FREE_VALUE_SUFFIX: TermName
+ val MIRROR_SYMDEF_PREFIX: TermName
val MIXIN_CONSTRUCTOR: TermName
val MODULE_INSTANCE_FIELD: TermName
val OUTER: TermName
diff --git a/src/library/scala/reflect/api/Symbols.scala b/src/library/scala/reflect/api/Symbols.scala
index a154e5f7a0..e47bc7216e 100755
--- a/src/library/scala/reflect/api/Symbols.scala
+++ b/src/library/scala/reflect/api/Symbols.scala
@@ -173,6 +173,11 @@ trait Symbols { self: Universe =>
*/
def isSkolem : Boolean
+ /** Does this symbol represent an existentially bound type?
+ * If yes, `isType` is also guaranteed to be true.
+ */
+ def isExistential : Boolean
+
/** Does this symbol represent a free type captured by reification?
*/
// needed for ones who wish to inspect reified trees
diff --git a/src/library/scala/reflect/api/Trees.scala b/src/library/scala/reflect/api/Trees.scala
index 6ddb2ea673..5ef73cba0c 100644
--- a/src/library/scala/reflect/api/Trees.scala
+++ b/src/library/scala/reflect/api/Trees.scala
@@ -85,10 +85,18 @@ trait Trees { self: Universe =>
def pos_=(pos: Position): Unit = rawatt = (rawatt withPos pos) // the "withPos" part is crucial to robustness
def setPos(newpos: Position): this.type = { pos = newpos; this }
- private[this] var rawatt: Attachment = NoPosition
- def attachment: Attachment = rawatt
- def attachment_=(att: Attachment): Unit = rawatt = att
- def setAttachment(att: Attachment): this.type = { rawatt = att; this }
+ private var rawatt: Attachment = NoPosition
+ private case class NontrivialAttachment(pos: api.Position, payload: Any) extends Attachment {
+ def withPos(newPos: api.Position) = copy(pos = newPos, payload = payload)
+ def withPayload(newPayload: Any) = copy(pos = pos, payload = newPayload)
+ }
+ // todo. annotate T with ClassTag and make pattern matcher use it
+ // todo. support multiple attachments, and remove the assignment. only leave attach/detach
+// def attachment[T]: T = rawatt.payload.asInstanceOf[T]
+// def attachmentOpt[T]: Option[T] = try { Some(rawatt.payload.asInstanceOf[T]) } catch { case _: Throwable => None }
+ def attachment: Any = rawatt.payload
+ def attachment_=(att: Any): Unit = rawatt = NontrivialAttachment(pos, att)
+ def setAttachment(att: Any): this.type = { attachment = att; this }
private[this] var rawtpe: Type = _
@@ -238,7 +246,7 @@ trait Trees { self: Universe =>
duplicateTree(this).asInstanceOf[this.type]
private[scala] def copyAttrs(tree: Tree): this.type = {
- attachment = tree.attachment
+ rawatt = tree.rawatt
tpe = tree.tpe
if (hasSymbol) symbol = tree.symbol
this
diff --git a/src/library/scala/reflect/api/TypeTags.scala b/src/library/scala/reflect/api/TypeTags.scala
index 4ffabe1c36..59a7c87f44 100644
--- a/src/library/scala/reflect/api/TypeTags.scala
+++ b/src/library/scala/reflect/api/TypeTags.scala
@@ -61,9 +61,8 @@ trait TypeTags { self: Universe =>
// assert(tpe != null)
def sym = tpe.typeSymbol
-
- def isConcrete = !isNotConcrete
- def isNotConcrete = tpe exists (_.typeSymbol.isAbstractType)
+ def isConcrete = tpe.isConcrete
+ def notConcrete = !isConcrete
def toConcrete: ConcreteTypeTag[T] = ConcreteTypeTag[T](tpe)
override def toString = {
@@ -124,7 +123,7 @@ trait TypeTags { self: Universe =>
// it's unsafe to use assert here, because we might run into deadlocks with Predef
// also see comments in ClassTags.scala
//assert(isConcrete, tpe)
- if (isNotConcrete) throw new Error("%s (%s) is not concrete and cannot be used to construct a concrete type tag".format(tpe, tpe.kind))
+ if (notConcrete) throw new Error("%s (%s) is not concrete and cannot be used to construct a concrete type tag".format(tpe, tpe.kind))
override def productPrefix = "ConcreteTypeTag"
}
diff --git a/src/library/scala/reflect/api/Types.scala b/src/library/scala/reflect/api/Types.scala
index 12aad453b1..5e1c1af2fe 100755
--- a/src/library/scala/reflect/api/Types.scala
+++ b/src/library/scala/reflect/api/Types.scala
@@ -57,6 +57,10 @@ trait Types { self: Universe =>
*/
def isHigherKinded: Boolean // !!! This should be called "isTypeConstructor", no?
+ /** Does this type refer to abstract types or is an abstract type?
+ */
+ def isConcrete: Boolean
+
/**
* Expands type aliases and converts higher-kinded TypeRefs to PolyTypes.
* Functions on types are also implemented as PolyTypes.
diff --git a/test/files/jvm/manifests.check b/test/files/jvm/manifests.check
new file mode 100644
index 0000000000..be8ec2bb5b
--- /dev/null
+++ b/test/files/jvm/manifests.check
@@ -0,0 +1,56 @@
+x=(), m=ConcreteTypeTag[Unit], k=TypeRef, s=class Unit
+x=true, m=ConcreteTypeTag[Boolean], k=TypeRef, s=class Boolean
+x=a, m=ConcreteTypeTag[Char], k=TypeRef, s=class Char
+x=1, m=ConcreteTypeTag[Int], k=TypeRef, s=class Int
+x=abc, m=ConcreteTypeTag[String], k=TypeRef, s=class String
+x='abc, m=ConcreteTypeTag[Symbol], k=TypeRef, s=class Symbol
+
+x=List(()), m=ConcreteTypeTag[List[Unit]], k=TypeRef, s=class List
+x=List(true), m=ConcreteTypeTag[List[Boolean]], k=TypeRef, s=class List
+x=List(1), m=ConcreteTypeTag[List[Int]], k=TypeRef, s=class List
+x=List(abc), m=ConcreteTypeTag[List[String]], k=TypeRef, s=class List
+x=List('abc), m=ConcreteTypeTag[List[Symbol]], k=TypeRef, s=class List
+
+x=[Z, m=ConcreteTypeTag[Array[Boolean]], k=TypeRef, s=class Array
+x=[C, m=ConcreteTypeTag[Array[Char]], k=TypeRef, s=class Array
+x=[I, m=ConcreteTypeTag[Array[Int]], k=TypeRef, s=class Array
+x=[Ljava.lang.String;, m=ConcreteTypeTag[Array[String]], k=TypeRef, s=class Array
+x=[Lscala.Symbol;, m=ConcreteTypeTag[Array[Symbol]], k=TypeRef, s=class Array
+
+x=((),()), m=ConcreteTypeTag[(Unit, Unit)], k=TypeRef, s=class Tuple2
+x=(true,false), m=ConcreteTypeTag[(Boolean, Boolean)], k=TypeRef, s=class Tuple2
+x=(1,2), m=ConcreteTypeTag[(Int, Int)], k=TypeRef, s=class Tuple2
+x=(abc,xyz), m=ConcreteTypeTag[(String, String)], k=TypeRef, s=class Tuple2
+x=('abc,'xyz), m=ConcreteTypeTag[(Symbol, Symbol)], k=TypeRef, s=class Tuple2
+
+
+x=Foo, m=ConcreteTypeTag[Foo[Int]], k=TypeRef, s=class Foo
+x=Foo, m=ConcreteTypeTag[Foo[List[Int]]], k=TypeRef, s=class Foo
+x=Foo, m=ConcreteTypeTag[Foo[Foo[Int]]], k=TypeRef, s=class Foo
+x=Foo, m=ConcreteTypeTag[Foo[List[Foo[Int]]]], k=TypeRef, s=class Foo
+
+x=Test1$$anon$1, m=ConcreteTypeTag[Bar[String]], k=RefinedType, s=<local Test1>
+x=Test1$$anon$2, m=ConcreteTypeTag[Bar[String]], k=RefinedType, s=<local Test1>
+
+()=()
+true=true
+a=a
+1=1
+'abc='abc
+
+List(())=List(())
+List(true)=List(true)
+List('abc)=List('abc)
+
+Array()=Array()
+Array(true)=Array(true)
+Array(a)=Array(a)
+Array(1)=Array(1)
+
+((),())=((),())
+(true,false)=(true,false)
+
+List(List(1), List(2))=List(List(1), List(2))
+
+Array(Array(1), Array(2))=Array(Array(1), Array(2))
+
diff --git a/test/files/jvm/manifests.check.temporarily.disabled b/test/files/jvm/manifests.check.temporarily.disabled
deleted file mode 100644
index 54f504b929..0000000000
--- a/test/files/jvm/manifests.check.temporarily.disabled
+++ /dev/null
@@ -1,55 +0,0 @@
-x=(), m=Unit
-x=true, m=Boolean
-x=a, m=Char
-x=1, m=Int
-x=abc, m=java.lang.String
-x='abc, m=scala.Symbol
-
-x=List(()), m=scala.collection.immutable.List[Unit]
-x=List(true), m=scala.collection.immutable.List[Boolean]
-x=List(1), m=scala.collection.immutable.List[Int]
-x=List(abc), m=scala.collection.immutable.List[java.lang.String]
-x=List('abc), m=scala.collection.immutable.List[scala.Symbol]
-
-x=[Z, m=Array[Boolean]
-x=[C, m=Array[Char]
-x=[I, m=Array[Int]
-x=[Ljava.lang.String;, m=Array[java.lang.String]
-x=[Lscala.Symbol;, m=Array[scala.Symbol]
-
-x=((),()), m=scala.Tuple2[Unit, Unit]
-x=(true,false), m=scala.Tuple2[Boolean, Boolean]
-x=(1,2), m=scala.Tuple2[Int, Int]
-x=(abc,xyz), m=scala.Tuple2[java.lang.String, java.lang.String]
-x=('abc,'xyz), m=scala.Tuple2[scala.Symbol, scala.Symbol]
-
-
-x=Foo, m=Foo[Int]
-x=Foo, m=Foo[scala.collection.immutable.List[Int]]
-x=Foo, m=Foo[Foo[Int]]
-x=Foo, m=Foo[scala.collection.immutable.List[Foo[Int]]]
-
-x=Test1$$anon$1, m=Object with Bar[java.lang.String]
-
-()=()
-true=true
-a=a
-1=1
-'abc='abc
-
-List(())=List(())
-List(true)=List(true)
-List('abc)=List('abc)
-
-Array()=Array()
-Array(true)=Array(true)
-Array(a)=Array(a)
-Array(1)=Array(1)
-
-((),())=((),())
-(true,false)=(true,false)
-
-List(List(1), List(2))=List(List(1), List(2))
-
-Array(Array(1), Array(2))=Array(Array(1), Array(2))
-
diff --git a/test/files/jvm/manifests.scala.temporarily.disabled b/test/files/jvm/manifests.scala
index 241966fd9d..935427f5d4 100644
--- a/test/files/jvm/manifests.scala.temporarily.disabled
+++ b/test/files/jvm/manifests.scala
@@ -50,7 +50,8 @@ object Test1 extends TestUtil {
print(new Foo(List(new Foo(2))))
println()
- print(new Bar[String] { def f = "abc" })
+ print(new Bar[String] { def f = "abc" });
+ {print(new Bar[String] { def f = "abc" })}
println()
}
@@ -102,8 +103,10 @@ trait TestUtil {
}
import scala.reflect._
def print[T](x: T)(implicit m: Manifest[T]) {
- val m1: Manifest[T] = read(write(m))
+ // manifests are no longer serializable
+// val m1: Manifest[T] = read(write(m))
+ val m1: Manifest[T] = m
val x1 = x.toString.replaceAll("@[0-9a-z]+$", "")
- println("x="+x1+", m="+m1)
+ println("x="+x1+", m="+m1+", k="+m1.tpe.kind+", s="+m1.sym.toString)
}
}
diff --git a/test/files/neg/t3507.check b/test/files/neg/t3507.check
deleted file mode 100644
index 71bf295039..0000000000
--- a/test/files/neg/t3507.check
+++ /dev/null
@@ -1,4 +0,0 @@
-t3507.scala:13: error: No ConcreteTypeTag available for _1.b.c.type
- mani/*[object _1.b.c]*/(c) // kaboom in manifestOfType / TreeGen.mkAttributedQualifier
- ^
-one error found
diff --git a/test/files/pos/implicits.scala.temporarily.disabled b/test/files/pos/implicits.scala
index 2c01dd0ba8..2c01dd0ba8 100644
--- a/test/files/pos/implicits.scala.temporarily.disabled
+++ b/test/files/pos/implicits.scala
diff --git a/test/files/pos/manifest1.scala.temporarily.disabled b/test/files/pos/manifest1.scala
index 8901aa7437..8901aa7437 100644
--- a/test/files/pos/manifest1.scala.temporarily.disabled
+++ b/test/files/pos/manifest1.scala
diff --git a/test/files/run/existentials3.check b/test/files/run/existentials3.check
new file mode 100644
index 0000000000..8227d77909
--- /dev/null
+++ b/test/files/run/existentials3.check
@@ -0,0 +1,24 @@
+ConcreteTypeTag[Bar.type], t=TypeRef, s= <: scala.runtime.AbstractFunction0[Bar] with Serializable{case def unapply(x$0: Bar): Boolean} with Singleton
+ConcreteTypeTag[Bar], t=TypeRef, s= <: Test.ToS with Product with Serializable{def copy(): Bar}
+ConcreteTypeTag[Test.ToS], t=RefinedType, s=f3
+ConcreteTypeTag[Test.ToS], t=RefinedType, s=f4
+ConcreteTypeTag[Test.ToS], t=RefinedType, s=f5
+ConcreteTypeTag[() => Test.ToS], t=TypeRef, s=class Function0
+ConcreteTypeTag[() => Test.ToS], t=TypeRef, s=class Function0
+ConcreteTypeTag[$anon], t=TypeRef, s= <: B with Test.ToS
+ConcreteTypeTag[$anon], t=TypeRef, s= <: B with A with Test.ToS
+ConcreteTypeTag[List[Object{type T1}#T1]], t=TypeRef, s=class List
+ConcreteTypeTag[List[Seq[Int]]], t=TypeRef, s=class List
+ConcreteTypeTag[List[Seq[U forSome { type U <: Int }]]], t=TypeRef, s=class List
+ConcreteTypeTag[Bar.type], t=TypeRef, s= <: scala.runtime.AbstractFunction0[Bar] with Serializable{case def unapply(x$0: Bar): Boolean} with Singleton
+ConcreteTypeTag[Bar], t=TypeRef, s= <: Test.ToS with Product with Serializable{def copy(): Bar}
+ConcreteTypeTag[Test.ToS], t=RefinedType, s=g3
+ConcreteTypeTag[Test.ToS], t=RefinedType, s=g4
+ConcreteTypeTag[Test.ToS], t=RefinedType, s=g5
+ConcreteTypeTag[() => Test.ToS], t=TypeRef, s=class Function0
+ConcreteTypeTag[() => Test.ToS], t=TypeRef, s=class Function0
+ConcreteTypeTag[$anon], t=TypeRef, s= <: B with Test.ToS
+ConcreteTypeTag[$anon], t=TypeRef, s= <: B with A with Test.ToS
+ConcreteTypeTag[List[Object{type T1}#T1]], t=TypeRef, s=class List
+ConcreteTypeTag[List[Seq[Int]]], t=TypeRef, s=class List
+ConcreteTypeTag[List[Seq[U forSome { type U <: Int }]]], t=TypeRef, s=class List
diff --git a/test/files/run/existentials3.check.temporarily.disabled b/test/files/run/existentials3.check.temporarily.disabled
deleted file mode 100644
index 36a458dacc..0000000000
--- a/test/files/run/existentials3.check.temporarily.disabled
+++ /dev/null
@@ -1,22 +0,0 @@
-_ <: scala.runtime.AbstractFunction0[_ <: Object with Test$ToS with scala.Product with scala.Serializable] with scala.Serializable with java.lang.Object
-_ <: Object with Test$ToS with scala.Product with scala.Serializable
-Object with Test$ToS
-Object with Test$ToS
-Object with Test$ToS
-scala.Function0[Object with Test$ToS]
-scala.Function0[Object with Test$ToS]
-_ <: Object with _ <: Object with Object with Test$ToS
-_ <: Object with _ <: Object with _ <: Object with Test$ToS
-scala.collection.immutable.List[Object with scala.collection.Seq[Int]]
-scala.collection.immutable.List[Object with scala.collection.Seq[_ <: Int]]
-_ <: scala.runtime.AbstractFunction0[_ <: Object with Test$ToS with scala.Product with scala.Serializable] with scala.Serializable with java.lang.Object
-_ <: Object with Test$ToS with scala.Product with scala.Serializable
-Object with Test$ToS
-Object with Test$ToS
-Object with Test$ToS
-scala.Function0[Object with Test$ToS]
-scala.Function0[Object with Test$ToS]
-_ <: Object with _ <: Object with Object with Test$ToS
-_ <: Object with _ <: Object with _ <: Object with Test$ToS
-scala.collection.immutable.List[Object with scala.collection.Seq[Int]]
-scala.collection.immutable.List[Object with scala.collection.Seq[_ <: Int]]
diff --git a/test/files/run/existentials3.scala.temporarily.disabled b/test/files/run/existentials3.scala
index bb80d366cc..d6d5612687 100644
--- a/test/files/run/existentials3.scala.temporarily.disabled
+++ b/test/files/run/existentials3.scala
@@ -11,11 +11,11 @@ object Test {
def f8 = { trait A ; trait B extends A ; class C extends B with ToS; new C { } }
def f9 = { trait A ; trait B ; class C extends B with A with ToS; new C { } }
-
+
def f10 = { class A { type T1 } ; List[A#T1]() }
def f11 = { abstract class A extends Seq[Int] ; List[A]() }
def f12 = { abstract class A extends Seq[U forSome { type U <: Int }] ; List[A]() }
-
+
val g1 = { case class Bar() extends ToS; Bar }
val g2 = { case class Bar() extends ToS; Bar() }
val g3 = { class Bar() extends ToS; object Bar extends ToS; Bar }
@@ -30,10 +30,16 @@ object Test {
val g10 = { class A { type T1 } ; List[A#T1]() }
val g11 = { abstract class A extends Seq[Int] ; List[A]() }
val g12 = { abstract class A extends Seq[U forSome { type U <: Int }] ; List[A]() }
-
- def m[T: Manifest](x: T) = println(manifest[T])
-
+
+ def printTag(t: TypeTag[_]) = {
+ val s = if (t.sym.isFreeType) t.sym.typeSignature.toString else t.sym.toString
+ println("%s, t=%s, s=%s".format(t, t.tpe.kind, s))
+ }
+ def m[T: ConcreteTypeTag](x: T) = printTag(concreteTypeTag[T])
+ def m2[T: TypeTag](x: T) = printTag(typeTag[T])
+
// manifests don't work for f10/g10
+ // oh, they do now :)
def main(args: Array[String]): Unit = {
m(f1)
m(f2)
@@ -44,7 +50,7 @@ object Test {
m(f7)
m(f8)
m(f9)
- // m(f10)
+ m2(f10)
m(f11)
m(f12)
m(g1)
@@ -56,7 +62,7 @@ object Test {
m(g7)
m(g8)
m(g9)
- // m(g10)
+ m2(g10)
m(g11)
m(g12)
}
diff --git a/test/files/run/t1195.check b/test/files/run/t1195.check
new file mode 100644
index 0000000000..554e3fd03d
--- /dev/null
+++ b/test/files/run/t1195.check
@@ -0,0 +1,6 @@
+ConcreteTypeTag[Bar.type], underlying = <: scala.runtime.AbstractFunction1[Int,Bar] with Serializable{case def unapply(x$0: Bar): Option[Int]} with Singleton
+ConcreteTypeTag[Bar], underlying = <: Product with Serializable{val x: Int; def copy(x: Int): Bar; def copy$default$1: Int; def _1: Int}
+ConcreteTypeTag[Product with Serializable], underlying = Product with Serializable
+ConcreteTypeTag[Bar.type], underlying = <: scala.runtime.AbstractFunction1[Int,Bar] with Serializable{case def unapply(x$0: Bar): Option[Int]} with Singleton
+ConcreteTypeTag[Bar], underlying = <: Product with Serializable{val x: Int; def copy(x: Int): Bar; def copy$default$1: Int; def _1: Int}
+ConcreteTypeTag[Product with Serializable], underlying = Product with Serializable
diff --git a/test/files/run/t1195.check.temporarily.disabled b/test/files/run/t1195.check.temporarily.disabled
deleted file mode 100644
index d023bc91f7..0000000000
--- a/test/files/run/t1195.check.temporarily.disabled
+++ /dev/null
@@ -1,6 +0,0 @@
-_ <: scala.runtime.AbstractFunction1[Int, _ <: Object with scala.Product with scala.Serializable] with scala.Serializable with java.lang.Object
-_ <: Object with scala.Product with scala.Serializable
-Object with scala.Product with scala.Serializable
-_ <: scala.runtime.AbstractFunction1[Int, _ <: Object with scala.Product with scala.Serializable] with scala.Serializable with java.lang.Object
-_ <: Object with scala.Product with scala.Serializable
-Object with scala.Product with scala.Serializable
diff --git a/test/files/run/t1195.scala.temporarily.disabled b/test/files/run/t1195.scala
index 81ef5bdb0e..93b1dcbd07 100644
--- a/test/files/run/t1195.scala.temporarily.disabled
+++ b/test/files/run/t1195.scala
@@ -6,8 +6,8 @@ object Test {
val f1 = f()
val g1 = g()
val h1 = h()
-
- def m[T: Manifest](x: T) = println(manifest[T])
+
+ def m[T: Manifest](x: T) = println(manifest[T] + ", underlying = " + manifest[T].sym.typeSignature)
def main(args: Array[String]): Unit = {
m(f)
diff --git a/test/files/run/t3507.check b/test/files/run/t3507.check
new file mode 100644
index 0000000000..50ab029592
--- /dev/null
+++ b/test/files/run/t3507.check
@@ -0,0 +1 @@
+ConcreteTypeTag[_1.type#b.c.type]
diff --git a/test/files/neg/t3507.scala b/test/files/run/t3507.scala
index 32688d3934..3cdd40a881 100644
--- a/test/files/neg/t3507.scala
+++ b/test/files/run/t3507.scala
@@ -5,11 +5,11 @@ class A {
def m = b.c
}
-object Test {
+object Test extends App {
var a: A = new A // mutable
val c /*: object _1.b.c forSome { val _1: A } */ = a.m // widening using existential
-
- def mani[T: Manifest](x: T) = ()
+
+ def mani[T: Manifest](x: T) = println(manifest[T])
mani/*[object _1.b.c]*/(c) // kaboom in manifestOfType / TreeGen.mkAttributedQualifier
// --> _1 is not in scope here
} \ No newline at end of file
diff --git a/test/files/run/t4110.check b/test/files/run/t4110.check
new file mode 100644
index 0000000000..28f220e1fe
--- /dev/null
+++ b/test/files/run/t4110.check
@@ -0,0 +1,2 @@
+ConcreteTypeTag[Test.A with Test.B]
+ConcreteTypeTag[Test.A with Test.B]
diff --git a/test/files/run/t4110.check.temporarily.disabled b/test/files/run/t4110.check.temporarily.disabled
deleted file mode 100644
index 8b005989de..0000000000
--- a/test/files/run/t4110.check.temporarily.disabled
+++ /dev/null
@@ -1,2 +0,0 @@
-Object with Test$A with Test$B
-Object with Test$A with Test$B
diff --git a/test/files/run/t4110.scala.temporarily.disabled b/test/files/run/t4110.scala
index 4bd377b73e..4bd377b73e 100644
--- a/test/files/run/t4110.scala.temporarily.disabled
+++ b/test/files/run/t4110.scala
diff --git a/test/files/run/treePrint.check.temporarily.disabled b/test/files/run/treePrint.check
index 3360815ac1..3360815ac1 100644
--- a/test/files/run/treePrint.check.temporarily.disabled
+++ b/test/files/run/treePrint.check
diff --git a/test/files/run/treePrint.scala.temporarily.disabled b/test/files/run/treePrint.scala
index e0332a705f..4a80e2824d 100644
--- a/test/files/run/treePrint.scala.temporarily.disabled
+++ b/test/files/run/treePrint.scala
@@ -4,7 +4,7 @@ object Test {
import scala.tools.nsc._
import interpreter._
import java.io.{ OutputStream, BufferedReader, StringReader, PrintWriter, Writer, OutputStreamWriter}
-
+
val code = """
def foo = {
var q: Boolean = false
@@ -22,11 +22,11 @@ object Test {
else 20
}
else 30
-
+
(x == 5) || !q || true
}
- """
-
+ """
+
class NullOutputStream extends OutputStream { def write(b: Int) { } }
def main(args: Array[String]) {
@@ -35,7 +35,8 @@ object Test {
settings.Ycompacttrees.value = true
val intp = new IMain(settings, new PrintWriter(new NullOutputStream))
- val power = new Power(intp, new ReplVals { })
+ val vals = new ReplVals { }
+ val power = new Power(intp, vals)
intp.interpret("""def initialize = "Have to interpret something or we get errors." """)
power trees code foreach println
}