diff options
author | Eugene Burmako <xeno.by@gmail.com> | 2012-09-10 20:00:22 +0200 |
---|---|---|
committer | Eugene Burmako <xeno.by@gmail.com> | 2012-09-14 13:29:47 +0200 |
commit | 00d7cd2d5300524aeb885d8d51b2123aa0b44f6e (patch) | |
tree | 10e384ad9a6665abc606f2a1c0e1024fa11e5709 | |
parent | 6d5a92b3f1c5bfb32230e5902d6dd494c9cd3a0a (diff) | |
download | scala-00d7cd2d5300524aeb885d8d51b2123aa0b44f6e.tar.gz scala-00d7cd2d5300524aeb885d8d51b2123aa0b44f6e.tar.bz2 scala-00d7cd2d5300524aeb885d8d51b2123aa0b44f6e.zip |
improvements for reification of free symbols
1) Free symbols no longer carry signatures in their constructors.
Previously to reify a free symbol (i.e. to generate a ValDef that creates it)
one had to reify sym.info first. However reification of sym.info might lead to
unexpected side effects, including stack overflows, if reification of sym.info
recursively required reifying sym itself.
Now it's not a problem. First we reify a "header" of a free symbol
by emitting something like:
val free$Foo1 = build.newFreeTerm("Foo", Foo.this, NoFlags)`
Afterwards, when doing code generation for the reification symbol table, we
populate free symbols by inserting calls to `build.setTypeSignature($sym.info)`
This techniques transforms recursion into memoized iteration, because even if
reifying sym.info indirectly requires reification of sym itself, we remember
that we already reified sym and simply return things like Ident(free$Foo1).
2) Unfortunately I haven't been able to get rid of recursion completely.
Since some symbols (e.g. local classes) aren't pickled, we need to recreate
them during reification (this is necessary e.g. to reify RefinedTypes).
Reifier uses a special function, named `reifySymDef`, for that purpose.
Here's an example of how it works:
val symdef$_1 = build.newNestedSymbol(free$U1, newTypeName("_"),
NoPosition, DEFERRED | PARAM, false);
`reifySymDef` expands into a call to `newNestedSymbol`, which requires an owner
This essentially turns `reifySymDef` into a recursion of `reifySymDef` calls,
so that the entire owner chain get reified.
This is an implementation strategy that was employed in the first revision
of the reifier written by Martin, and personally I have no clue whether it's
really necessary to reify the parents. I leave this as a future work.
3) When working with free symbols, it's necessary to attach free symbols
to their reification. This is required in obscure nested reification scenarios,
when a symbol that was free for an inner reifee is no longer free for an outer
reifee. In that case we need to remove that free symbol from the symbol table
of the inner reification.
Back then we didn't have tree attachments, so I had to introduce a phantom
"value" parameter for `newFreeType` to keep track of the original symbols for
free types. Now when we have attachments, this is no longer necessary and
allowed me to clean up the code.
18 files changed, 117 insertions, 125 deletions
diff --git a/src/compiler/scala/reflect/reify/codegen/GenSymbols.scala b/src/compiler/scala/reflect/reify/codegen/GenSymbols.scala index 5a474b11fb..be138c7bfa 100644 --- a/src/compiler/scala/reflect/reify/codegen/GenSymbols.scala +++ b/src/compiler/scala/reflect/reify/codegen/GenSymbols.scala @@ -90,48 +90,60 @@ trait GenSymbols { } } else { // todo. make sure that free methods and free local defs work correctly - if (sym.isTerm) reifyFreeTerm(sym, Ident(sym)) - else reifyFreeType(sym, Ident(sym)) + if (sym.isExistential) reifySymDef(sym) + else if (sym.isTerm) reifyFreeTerm(Ident(sym)) + else reifyFreeType(Ident(sym)) } } - def reifyFreeTerm(sym: Symbol, value: Tree): Tree = - reifyIntoSymtab(sym) { + def reifyFreeTerm(binding: Tree): Tree = + reifyIntoSymtab(binding.symbol) { sym => if (reifyDebug) println("Free term" + (if (sym.isCapturedVariable) " (captured)" else "") + ": " + sym + "(" + sym.accurateKindString + ")") - var name = newTermName(nme.REIFY_FREE_PREFIX + sym.name) - if (sym.isType) name = name.append(nme.REIFY_FREE_THIS_SUFFIX) + val name = newTermName(nme.REIFY_FREE_PREFIX + sym.name + (if (sym.isType) nme.REIFY_FREE_THIS_SUFFIX else "")) if (sym.isCapturedVariable) { - assert(value.isInstanceOf[Ident], showRaw(value)) - val capturedTpe = capturedVariableType(sym) - val capturedValue = referenceCapturedVariable(sym) - (name, mirrorBuildCall(nme.newFreeTerm, reify(sym.name.toString), reify(capturedTpe), capturedValue, mirrorBuildCall(nme.flagsFromBits, reify(sym.flags)), reify(origin(sym)))) + assert(binding.isInstanceOf[Ident], showRaw(binding)) + val capturedBinding = referenceCapturedVariable(sym) + Reification(name, capturedBinding, mirrorBuildCall(nme.newFreeTerm, reify(sym.name.toString), capturedBinding, mirrorBuildCall(nme.flagsFromBits, reify(sym.flags)), reify(origin(sym)))) } else { - (name, mirrorBuildCall(nme.newFreeTerm, reify(sym.name.toString), reify(sym.tpe), value, mirrorBuildCall(nme.flagsFromBits, reify(sym.flags)), reify(origin(sym)))) + Reification(name, binding, mirrorBuildCall(nme.newFreeTerm, reify(sym.name.toString), binding, mirrorBuildCall(nme.flagsFromBits, reify(sym.flags)), reify(origin(sym)))) } } - def reifyFreeType(sym: Symbol, value: Tree): Tree = - reifyIntoSymtab(sym) { + def reifyFreeType(binding: Tree): Tree = + reifyIntoSymtab(binding.symbol) { sym => if (reifyDebug) println("Free type: %s (%s)".format(sym, sym.accurateKindString)) - var name = newTermName(nme.REIFY_FREE_PREFIX + sym.name) - val phantomTypeTag = Apply(TypeApply(Select(Ident(nme.UNIVERSE_SHORT), nme.TypeTag), List(value)), List(Literal(Constant(null)), Literal(Constant(null)))) - (name, mirrorBuildCall(nme.newFreeType, reify(sym.name.toString), reify(sym.info), phantomTypeTag, mirrorBuildCall(nme.flagsFromBits, reify(sym.flags)), reify(origin(sym)))) + val name = newTermName(nme.REIFY_FREE_PREFIX + sym.name) + Reification(name, binding, mirrorBuildCall(nme.newFreeType, reify(sym.name.toString), mirrorBuildCall(nme.flagsFromBits, reify(sym.flags)), reify(origin(sym)))) } def reifySymDef(sym: Symbol): Tree = - reifyIntoSymtab(sym) { + reifyIntoSymtab(sym) { sym => 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.REIFY_SYMDEF_PREFIX + sym.name) - (name, mirrorBuildCall(nme.newNestedSymbol, reify(sym.owner), reify(sym.name), reify(sym.pos), mirrorBuildCall(nme.flagsFromBits, reify(sym.flags)), reify(sym.isClass))) + val name = newTermName(nme.REIFY_SYMDEF_PREFIX + sym.name) + def reifiedOwner = if (sym.owner.isLocatable) reify(sym.owner) else reifySymDef(sym.owner) + Reification(name, Ident(sym), mirrorBuildCall(nme.newNestedSymbol, reifiedOwner, reify(sym.name), reify(sym.pos), mirrorBuildCall(nme.flagsFromBits, reify(sym.flags)), reify(sym.isClass))) } - private def reifyIntoSymtab(sym: Symbol)(reificode: => (TermName, Tree)): Tree ={ + case class Reification(name: Name, binding: Tree, tree: Tree) + + private def reifyIntoSymtab(sym: Symbol)(reificode: Symbol => Reification): Tree = { def fromSymtab = symtab symRef sym if (fromSymtab == EmptyTree) { - val reification = reificode - state.symtab += (sym, reification._1, reification._2) + // reification is lazy, so that we can carefully choose where to evaluate it + // and we choose this place to be exactly here: + // + // reasons: + // 1) reification happens at maximum once per symbol to prevent repeated reifications + // 2) reification happens before putting the symbol itself into the symbol table to ensure correct initialization order: + // for example, if reification of symbol A refers to reification of symbol B + // (this might happen when we're doing `reifySymDef`, which expands into `newNestedSymbol`, which needs `sym.owner`) + // then we have to put reification-B into the symbol table before reification-A + // so that subsequent code generation that traverses the symbol table in the first-added first-codegenned order + // produces valid Scala code (with vals in a block depending only on lexically preceding vals) + val reification = reificode(sym) + import reification.{name, binding} + val tree = reification.tree addAttachment ReifyBindingAttachment(binding) + state.symtab += (sym, name, tree) } fromSymtab } diff --git a/src/compiler/scala/reflect/reify/codegen/GenTrees.scala b/src/compiler/scala/reflect/reify/codegen/GenTrees.scala index f48df8df65..bdcc7383b0 100644 --- a/src/compiler/scala/reflect/reify/codegen/GenTrees.scala +++ b/src/compiler/scala/reflect/reify/codegen/GenTrees.scala @@ -124,7 +124,7 @@ trait GenTrees { val sym = tree.symbol if (reifyDebug) println("This for %s, reified as freeVar".format(sym)) if (reifyDebug) println("Free: " + sym) - mirrorBuildCall(nme.Ident, reifyFreeTerm(sym, This(sym))) + mirrorBuildCall(nme.Ident, reifyFreeTerm(This(sym))) case tree @ This(_) if !tree.symbol.isLocalToReifee => if (reifyDebug) println("This for %s, reified as This".format(tree.symbol)) mirrorBuildCall(nme.This, reify(tree.symbol)) diff --git a/src/compiler/scala/reflect/reify/utils/Extractors.scala b/src/compiler/scala/reflect/reify/utils/Extractors.scala index cd8d2b60dc..3f3f08cf2b 100644 --- a/src/compiler/scala/reflect/reify/utils/Extractors.scala +++ b/src/compiler/scala/reflect/reify/utils/Extractors.scala @@ -176,12 +176,11 @@ trait Extractors { List( _, _, - binding, Apply(Select(Select(uref2 @ Ident(_), build2), flagsFromBits), List(Literal(Constant(flags: Long)))), Literal(Constant(origin: String))))) if uref1.name == nme.UNIVERSE_SHORT && build1 == nme.build && newFreeTerm == nme.newFreeTerm && uref2.name == nme.UNIVERSE_SHORT && build2 == nme.build && flagsFromBits == nme.flagsFromBits => - Some(uref1, name, binding, flags, origin) + Some(uref1, name, reifyBinding(tree), flags, origin) case _ => None } @@ -194,22 +193,11 @@ trait Extractors { Select(Select(uref1 @ Ident(_), build1), newFreeType), List( _, - _, - value, Apply(Select(Select(uref2 @ Ident(_), build2), flagsFromBits), List(Literal(Constant(flags: Long)))), Literal(Constant(origin: String))))) if uref1.name == nme.UNIVERSE_SHORT && build1 == nme.build && newFreeType == nme.newFreeType && uref2.name == nme.UNIVERSE_SHORT && build2 == nme.build && flagsFromBits == nme.flagsFromBits => - value match { - case Apply(TypeApply(Select(Select(uref3 @ Ident(_), typeTag), apply), List(binding)), List(Literal(Constant(null)), _)) - if uref3.name == nme.UNIVERSE_SHORT && typeTag == nme.TypeTag && apply == nme.apply => - Some(uref1, name, binding, flags, origin) - case Apply(TypeApply(Select(uref3 @ Ident(_), typeTag), List(binding)), List(Literal(Constant(null)), _)) - if uref3.name == nme.UNIVERSE_SHORT && typeTag == nme.TypeTag => - Some(uref1, name, binding, flags, origin) - case _ => - throw new Error("unsupported free type def: %s%n%s".format(value, showRaw(value))) - } + Some(uref1, name, reifyBinding(tree), flags, origin) case _ => None } diff --git a/src/compiler/scala/reflect/reify/utils/StdAttachments.scala b/src/compiler/scala/reflect/reify/utils/StdAttachments.scala index abbed814e0..0b9cf58c89 100644 --- a/src/compiler/scala/reflect/reify/utils/StdAttachments.scala +++ b/src/compiler/scala/reflect/reify/utils/StdAttachments.scala @@ -6,7 +6,13 @@ trait StdAttachments { import global._ - case class ReifyBindingAttachment(binding: Symbol) + case class ReifyBindingAttachment(binding: Tree) - case class ReifyAliasAttachment(binding: Symbol, alias: TermName) + def reifyBinding(tree: Tree): Tree = + tree.attachments.get[ReifyBindingAttachment] match { + case Some(ReifyBindingAttachment(binding)) => binding + case other => Ident(NoSymbol) + } + + case class ReifyAliasAttachment(sym: Symbol, alias: TermName) }
\ No newline at end of file diff --git a/src/compiler/scala/reflect/reify/utils/SymbolTables.scala b/src/compiler/scala/reflect/reify/utils/SymbolTables.scala index 3892c86dd3..30ec6e8d52 100644 --- a/src/compiler/scala/reflect/reify/utils/SymbolTables.scala +++ b/src/compiler/scala/reflect/reify/utils/SymbolTables.scala @@ -45,28 +45,27 @@ trait SymbolTables { def symRef(sym: Symbol): Tree = symtab.get(sym) match { - case Some(FreeDef(_, name, _, _, _)) => Ident(name) addAttachment ReifyBindingAttachment(sym) - case Some(SymDef(_, name, _, _)) => Ident(name) addAttachment ReifyBindingAttachment(sym) + case Some(FreeDef(_, name, binding, _, _)) => Ident(name) addAttachment binding + case Some(SymDef(_, name, _, _)) => Ident(name) addAttachment ReifyBindingAttachment(Ident(sym)) case None => EmptyTree } def +(sym: Symbol, name: TermName, reification: Tree): SymbolTable = add(sym, name, reification) - def +(sym: Symbol, name: TermName): SymbolTable = add(sym, name) def +(symDef: Tree): SymbolTable = add(symDef) def ++(symDefs: TraversableOnce[Tree]): SymbolTable = (this /: symDefs)((symtab, symDef) => symtab.add(symDef)) def ++(symtab: SymbolTable): SymbolTable = { val updated = this ++ symtab.symtab.values; new SymbolTable(updated.symtab, updated.aliases ++ symtab.aliases) } def -(sym: Symbol): SymbolTable = remove(sym) def -(name: TermName): SymbolTable = remove(name) - def -(symDef: Tree): SymbolTable = remove(binding(symDef)) + def -(symDef: Tree): SymbolTable = remove(reifyBinding(symDef).symbol) def --(syms: GenTraversableOnce[Symbol]): SymbolTable = (this /: syms)((symtab, sym) => symtab.remove(sym)) def --(names: Iterable[TermName]): SymbolTable = (this /: names)((symtab, name) => symtab.remove(name)) - def --(symDefs: TraversableOnce[Tree]): SymbolTable = this -- (symDefs map (binding(_))) + def --(symDefs: TraversableOnce[Tree]): SymbolTable = this -- (symDefs map (reifyBinding(_))) def --(symtab: SymbolTable): SymbolTable = { val updated = this -- symtab.symtab.values; new SymbolTable(updated.symtab, updated.aliases diff symtab.aliases) } def filterSyms(p: Symbol => Boolean): SymbolTable = this -- (syms filterNot p) def filterAliases(p: (Symbol, TermName) => Boolean): SymbolTable = this -- (aliases filterNot (tuple => p(tuple._1, tuple._2)) map (_._2)) private def add(symDef: Tree): SymbolTable = { - val sym = binding(symDef) + val sym = reifyBinding(symDef).symbol assert(sym != NoSymbol, showRaw(symDef)) val name = symDef match { case FreeDef(_, name, _, _, _) => name @@ -85,7 +84,8 @@ trait SymbolTables { val fresh = typer.context.unit.fresh newTermName(fresh.newName(name)) } - add(ValDef(NoMods, freshName(name0), TypeTree(), reification) addAttachment ReifyBindingAttachment(sym)) + val bindingAttachment = reification.attachments.get[ReifyBindingAttachment].get + add(ValDef(NoMods, freshName(name0), TypeTree(), reification) addAttachment bindingAttachment) } private def add(sym: Symbol, name: TermName): SymbolTable = { @@ -115,12 +115,6 @@ trait SymbolTables { new SymbolTable(newSymtab, newAliases) } - private def binding(tree: Tree): Symbol = - tree.attachments.get[ReifyBindingAttachment] match { - case Some(ReifyBindingAttachment(binding)) => binding - case other => NoSymbol - } - private val cache = mutable.Map[SymbolTable, List[Tree]]() def encode: List[Tree] = cache.getOrElseUpdate(this, SymbolTable.encode(this)) map (_.duplicate) @@ -147,7 +141,7 @@ trait SymbolTables { def apply(encoded: List[Tree]): SymbolTable = { var result = new SymbolTable(original = Some(encoded)) encoded foreach (entry => (entry.attachments.get[ReifyBindingAttachment], entry.attachments.get[ReifyAliasAttachment]) match { - case (Some(ReifyBindingAttachment(sym)), _) => result += entry + case (Some(ReifyBindingAttachment(_)), _) => result += entry case (_, Some(ReifyAliasAttachment(sym, alias))) => result = new SymbolTable(result.symtab, result.aliases :+ (sym, alias)) case _ => // do nothing, this is boilerplate that can easily be recreated by subsequent `result.encode` }) @@ -169,30 +163,26 @@ trait SymbolTables { def fillInSymbol(sym: Symbol): Tree = { if (reifyDebug) println("Filling in: %s (%s)".format(sym, sym.accurateKindString)) - val isFree = currtab.symName(sym) startsWith nme.REIFY_FREE_PREFIX - if (isFree) { - if (sym.annotations.isEmpty) EmptyTree - else Apply(Select(currtab.symRef(sym), nme.setAnnotations), List(reifier.reify(sym.annotations))) - } else { - // SI-6204 don't reify signatures for incomplete symbols, because this might lead to cyclic reference errors - val signature = - if (sym.isInitialized) { - if (sym.isCapturedVariable) capturedVariableType(sym) - else sym.info - } else NoType - val rset = reifier.mirrorBuildCall(nme.setTypeSignature, currtab.symRef(sym), reifier.reify(signature)) - // `Symbol.annotations` doesn't initialize the symbol, so we don't need to do anything special here - // also since we call `sym.info` a few lines above, by now the symbol will be initialized (if possible) - // so the annotations will be filled in and will be waiting to be reified (unless symbol initialization is prohibited as described above) - if (sym.annotations.isEmpty) rset - else reifier.mirrorBuildCall(nme.setAnnotations, rset, reifier.mkList(sym.annotations map reifier.reifyAnnotationInfo)) - } + val isFreeTerm = FreeTermDef.unapply(currtab.symDef(sym)).isDefined + // SI-6204 don't reify signatures for incomplete symbols, because this might lead to cyclic reference errors + val signature = + if (sym.isInitialized) { + if (sym.isCapturedVariable) capturedVariableType(sym) + else if (isFreeTerm) sym.tpe + else sym.info + } else NoType + val rset = reifier.mirrorBuildCall(nme.setTypeSignature, currtab.symRef(sym), reifier.reify(signature)) + // `Symbol.annotations` doesn't initialize the symbol, so we don't need to do anything special here + // also since we call `sym.info` a few lines above, by now the symbol will be initialized (if possible) + // so the annotations will be filled in and will be waiting to be reified (unless symbol initialization is prohibited as described above) + if (sym.annotations.isEmpty) rset + else reifier.mirrorBuildCall(nme.setAnnotations, rset, reifier.mkList(sym.annotations map reifier.reifyAnnotationInfo)) } // `fillInSymbol` might add symbols to `symtab`, that's why this is done iteratively var progress = 0 while (progress < cumulativeSymtab.length) { - val sym = currtab.binding(cumulativeSymtab(progress)) + val sym = reifyBinding(cumulativeSymtab(progress)).symbol if (sym != NoSymbol) { val symtabProgress = currtab.symtab.size val aliasesProgress = currtab.aliases.length @@ -207,7 +197,7 @@ trait SymbolTables { val withAliases = cumulativeSymtab flatMap (entry => { val result = mutable.ListBuffer[Tree]() result += entry - val sym = currtab.binding(entry) + val sym = reifyBinding(entry).symbol if (sym != NoSymbol) result ++= cumulativeAliases.distinct filter (alias => alias._1 == sym && alias._2 != currtab.symName(sym)) map (alias => { val canonicalName = currtab.symName(sym) diff --git a/src/library/scala/reflect/base/Base.scala b/src/library/scala/reflect/base/Base.scala index 2448dd53e4..6f90d598f9 100644 --- a/src/library/scala/reflect/base/Base.scala +++ b/src/library/scala/reflect/base/Base.scala @@ -36,10 +36,10 @@ class Base extends Universe { self => def newClassSymbol(name: TypeName, pos: Position = NoPosition, flags: FlagSet = NoFlags): ClassSymbol = new ClassSymbol(this, name, flags) - def newFreeTermSymbol(name: TermName, info: Type, value: => Any, flags: FlagSet = NoFlags, origin: String = null) = + def newFreeTermSymbol(name: TermName, value: => Any, flags: FlagSet = NoFlags, origin: String = null) = new FreeTermSymbol(this, name, flags) - def newFreeTypeSymbol(name: TypeName, info: Type, value: => Any, flags: FlagSet = NoFlags, origin: String = null) = + def newFreeTypeSymbol(name: TypeName, flags: FlagSet = NoFlags, origin: String = null) = new FreeTypeSymbol(this, name, flags) private def kindString: String = @@ -311,10 +311,10 @@ class Base extends Universe { self => else new TypeSymbol(owner, name.toTypeName, flags) else new TermSymbol(owner, name.toTermName, flags) - def newFreeTerm(name: String, info: Type, value: => Any, flags: Long = 0L, origin: String = null): FreeTermSymbol = + def newFreeTerm(name: String, value: => Any, flags: Long = 0L, origin: String = null): FreeTermSymbol = new FreeTermSymbol(rootMirror.RootClass, newTermName(name), flags) - def newFreeType(name: String, info: Type, value: => Any, flags: Long = 0L, origin: String = null): FreeTypeSymbol = + def newFreeType(name: String, flags: Long = 0L, origin: String = null): FreeTypeSymbol = new FreeTypeSymbol(rootMirror.RootClass, newTypeName(name), flags) def setTypeSignature[S <: Symbol](sym: S, tpe: Type): S = sym diff --git a/src/library/scala/reflect/base/BuildUtils.scala b/src/library/scala/reflect/base/BuildUtils.scala index 28d2528af9..c4231dd515 100644 --- a/src/library/scala/reflect/base/BuildUtils.scala +++ b/src/library/scala/reflect/base/BuildUtils.scala @@ -29,24 +29,18 @@ trait BuildUtils { self: Universe => /** Create a fresh free term symbol. * @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, flags: FlagSet = NoFlags, origin: String = null): FreeTermSymbol + def newFreeTerm(name: String, value: => Any, flags: FlagSet = NoFlags, origin: String = null): FreeTermSymbol /** Create a fresh free 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, flags: FlagSet = NoFlags, origin: String = null): FreeTypeSymbol + def newFreeType(name: String, flags: FlagSet = NoFlags, origin: String = null): FreeTypeSymbol /** Set symbol's type signature to given type. * @return the symbol itself diff --git a/src/reflect/scala/reflect/internal/BuildUtils.scala b/src/reflect/scala/reflect/internal/BuildUtils.scala index b9d489628e..f7371f4180 100644 --- a/src/reflect/scala/reflect/internal/BuildUtils.scala +++ b/src/reflect/scala/reflect/internal/BuildUtils.scala @@ -30,11 +30,11 @@ trait BuildUtils extends base.BuildUtils { self: SymbolTable => else MissingRequirementError.notFound("overloaded method %s #%d in %s".format(name, index, owner.fullName)) } - def newFreeTerm(name: String, info: Type, value: => Any, flags: Long = 0L, origin: String = null): FreeTermSymbol = - newFreeTermSymbol(newTermName(name), info, value, flags, origin) + def newFreeTerm(name: String, value: => Any, flags: Long = 0L, origin: String = null): FreeTermSymbol = + newFreeTermSymbol(newTermName(name), value, flags, origin) - def newFreeType(name: String, info: Type, value: => Any, flags: Long = 0L, origin: String = null): FreeTypeSymbol = - newFreeTypeSymbol(newTypeName(name), info, value, flags, origin) + def newFreeType(name: String, flags: Long = 0L, origin: String = null): FreeTypeSymbol = + newFreeTypeSymbol(newTypeName(name), flags, origin) def newNestedSymbol(owner: Symbol, name: Name, pos: Position, flags: Long, isClass: Boolean): Symbol = owner.newNestedSymbol(name, pos, flags, isClass) diff --git a/src/reflect/scala/reflect/internal/Importers.scala b/src/reflect/scala/reflect/internal/Importers.scala index 4b3eb0cdc4..87058df732 100644 --- a/src/reflect/scala/reflect/internal/Importers.scala +++ b/src/reflect/scala/reflect/internal/Importers.scala @@ -72,9 +72,9 @@ trait Importers extends api.Importers { self: SymbolTable => case x: from.ModuleSymbol => linkReferenced(myowner.newModuleSymbol(myname, mypos, myflags), x, importSymbol) case x: from.FreeTermSymbol => - newFreeTermSymbol(importName(x.name).toTermName, importType(x.info), x.value, x.flags, x.origin) + newFreeTermSymbol(importName(x.name).toTermName, x.value, x.flags, x.origin) setInfo importType(x.info) case x: from.FreeTypeSymbol => - newFreeTypeSymbol(importName(x.name).toTypeName, importType(x.info), x.value, x.flags, x.origin) + newFreeTypeSymbol(importName(x.name).toTypeName, x.flags, x.origin) case x: from.TermSymbol => linkReferenced(myowner.newValue(myname, mypos, myflags), x, importSymbol) case x: from.TypeSkolem => diff --git a/src/reflect/scala/reflect/internal/Symbols.scala b/src/reflect/scala/reflect/internal/Symbols.scala index b1e81de037..430cf58a54 100644 --- a/src/reflect/scala/reflect/internal/Symbols.scala +++ b/src/reflect/scala/reflect/internal/Symbols.scala @@ -48,13 +48,13 @@ trait Symbols extends api.Symbols { self: SymbolTable => /** Create a new free term. Its owner is NoSymbol. */ - def newFreeTermSymbol(name: TermName, info: Type, value: => Any, flags: Long = 0L, origin: String): FreeTermSymbol = - new FreeTermSymbol(name, value, origin) initFlags flags setInfo info + def newFreeTermSymbol(name: TermName, value: => Any, flags: Long = 0L, origin: String): FreeTermSymbol = + new FreeTermSymbol(name, value, origin) initFlags flags /** Create a new free type. Its owner is NoSymbol. */ - def newFreeTypeSymbol(name: TypeName, info: Type, value: => Any, flags: Long = 0L, origin: String): FreeTypeSymbol = - new FreeTypeSymbol(name, value, origin) initFlags flags setInfo info + def newFreeTypeSymbol(name: TypeName, flags: Long = 0L, origin: String): FreeTypeSymbol = + new FreeTypeSymbol(name, origin) initFlags flags /** The original owner of a class. Used by the backend to generate * EnclosingMethod attributes. @@ -3080,9 +3080,7 @@ trait Symbols extends api.Symbols { self: SymbolTable => } implicit val FreeTermSymbolTag = ClassTag[FreeTermSymbol](classOf[FreeTermSymbol]) - class FreeTypeSymbol(name0: TypeName, value0: => Any, val origin: String) extends TypeSkolem(NoSymbol, NoPosition, name0, NoSymbol) with FreeSymbol with FreeTypeSymbolApi { - def value = value0 - } + class FreeTypeSymbol(name0: TypeName, val origin: String) extends TypeSkolem(NoSymbol, NoPosition, name0, NoSymbol) with FreeSymbol with FreeTypeSymbolApi implicit val FreeTypeSymbolTag = ClassTag[FreeTypeSymbol](classOf[FreeTypeSymbol]) /** An object representing a missing symbol */ diff --git a/src/reflect/scala/reflect/runtime/SynchronizedSymbols.scala b/src/reflect/scala/reflect/runtime/SynchronizedSymbols.scala index 40346cad79..7705610efb 100644 --- a/src/reflect/scala/reflect/runtime/SynchronizedSymbols.scala +++ b/src/reflect/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 newFreeTermSymbol(name: TermName, info: Type, value: => Any, flags: Long = 0L, origin: String = null): FreeTermSymbol = - new FreeTermSymbol(name, value, origin) with SynchronizedTermSymbol initFlags flags setInfo info + override def newFreeTermSymbol(name: TermName, value: => Any, flags: Long = 0L, origin: String = null): FreeTermSymbol = + new FreeTermSymbol(name, value, origin) with SynchronizedTermSymbol initFlags flags - override def newFreeTypeSymbol(name: TypeName, info: Type, value: => Any, flags: Long = 0L, origin: String = null): FreeTypeSymbol = - new FreeTypeSymbol(name, value, origin) with SynchronizedTypeSymbol initFlags flags setInfo info + override def newFreeTypeSymbol(name: TypeName, flags: Long = 0L, origin: String = null): FreeTypeSymbol = + new FreeTypeSymbol(name, origin) with SynchronizedTypeSymbol initFlags flags override protected def makeNoSymbol: NoSymbol = new NoSymbol with SynchronizedSymbol diff --git a/test/files/run/existentials3-new.check b/test/files/run/existentials3-new.check index a036d92a24..2550f4dae0 100644 --- a/test/files/run/existentials3-new.check +++ b/test/files/run/existentials3-new.check @@ -1,24 +1,24 @@ -Bar.type, t=TypeRef, s= <: scala.runtime.AbstractFunction0[Bar] with Serializable{case def unapply(x$0: Bar): Boolean} with Singleton
-Bar, t=TypeRef, s= <: Test.ToS with Product with Serializable{def copy(): Bar}
+Bar.type, t=TypeRef, s=type Bar.type
+Bar, t=TypeRef, s=type Bar
Test.ToS, t=RefinedType, s=f3
Test.ToS, t=RefinedType, s=f4
Test.ToS, t=RefinedType, s=f5
() => Test.ToS, t=TypeRef, s=class Function0
() => Test.ToS, t=TypeRef, s=class Function0
-$anon, t=TypeRef, s= <: B with Test.ToS
-$anon, t=TypeRef, s= <: B with A with Test.ToS
+$anon, t=TypeRef, s=type $anon
+$anon, t=TypeRef, s=type $anon
List[java.lang.Object{type T1}#T1], t=TypeRef, s=class List
List[Seq[Int]], t=TypeRef, s=class List
List[Seq[U forSome { type U <: Int }]], t=TypeRef, s=class List
-Bar.type, t=TypeRef, s= <: scala.runtime.AbstractFunction0[Bar] with Serializable{case def unapply(x$0: Bar): Boolean} with Singleton
-Bar, t=TypeRef, s= <: Test.ToS with Product with Serializable{def copy(): Bar}
+Bar.type, t=TypeRef, s=type Bar.type
+Bar, t=TypeRef, s=type Bar
Test.ToS, t=RefinedType, s=g3
Test.ToS, t=RefinedType, s=g4
Test.ToS, t=RefinedType, s=g5
() => Test.ToS, t=TypeRef, s=class Function0
() => Test.ToS, t=TypeRef, s=class Function0
-$anon, t=TypeRef, s= <: B with Test.ToS
-$anon, t=TypeRef, s= <: B with A with Test.ToS
+$anon, t=TypeRef, s=type $anon
+$anon, t=TypeRef, s=type $anon
List[java.lang.Object{type T1}#T1], t=TypeRef, s=class List
List[Seq[Int]], t=TypeRef, s=class List
List[Seq[U forSome { type U <: Int }]], t=TypeRef, s=class List
diff --git a/test/files/run/existentials3-new.scala b/test/files/run/existentials3-new.scala index 16735eab4f..31ddc8cc9e 100644 --- a/test/files/run/existentials3-new.scala +++ b/test/files/run/existentials3-new.scala @@ -42,27 +42,27 @@ object Test { // tags do work for f10/g10 def main(args: Array[String]): Unit = { - m(f1) - m(f2) + m2(f1) + m2(f2) m(f3) m(f4) m(f5) m(f6) m(f7) - m(f8) - m(f9) + m2(f8) + m2(f9) m2(f10) m(f11) m(f12) - m(g1) - m(g2) + m2(g1) + m2(g2) m(g3) m(g4) m(g5) m(g6) m(g7) - m(g8) - m(g9) + m2(g8) + m2(g9) m2(g10) m(g11) m(g12) diff --git a/test/files/run/macro-typecheck-macrosdisabled/Impls_Macros_1.scala b/test/files/run/macro-typecheck-macrosdisabled/Impls_Macros_1.scala index b2f6f7d50e..f693ad78cc 100644 --- a/test/files/run/macro-typecheck-macrosdisabled/Impls_Macros_1.scala +++ b/test/files/run/macro-typecheck-macrosdisabled/Impls_Macros_1.scala @@ -18,7 +18,8 @@ object Macros { val rupkg = c.mirror.staticModule("scala.reflect.runtime.package") val rusym = build.selectTerm(rupkg, "universe") val NullaryMethodType(rutpe) = rusym.typeSignature - val ru = build.newFreeTerm("ru", rutpe, scala.reflect.runtime.universe) + val ru = build.newFreeTerm("ru", scala.reflect.runtime.universe) + build.setTypeSignature(ru, rutpe) val tree2 = Apply(Select(Ident(ru), newTermName("reify")), List(Literal(Constant(2)))) val ttree2 = c.typeCheck(tree2, withMacrosDisabled = true) diff --git a/test/files/run/macro-typecheck-macrosdisabled2/Impls_Macros_1.scala b/test/files/run/macro-typecheck-macrosdisabled2/Impls_Macros_1.scala index 948c047351..1dbf5a1a87 100644 --- a/test/files/run/macro-typecheck-macrosdisabled2/Impls_Macros_1.scala +++ b/test/files/run/macro-typecheck-macrosdisabled2/Impls_Macros_1.scala @@ -18,7 +18,8 @@ object Macros { val rupkg = c.mirror.staticModule("scala.reflect.runtime.package") val rusym = build.selectTerm(rupkg, "universe") val NullaryMethodType(rutpe) = rusym.typeSignature - val ru = build.newFreeTerm("ru", rutpe, scala.reflect.runtime.universe) + val ru = build.newFreeTerm("ru", scala.reflect.runtime.universe) + build.setTypeSignature(ru, rutpe) val tree2 = Apply(Select(Ident(ru), newTermName("reify")), List(Apply(Select(Ident(newTermName("scala")), newTermName("Array")), List(Literal(Constant(2)))))) val ttree2 = c.typeCheck(tree2, withMacrosDisabled = true) diff --git a/test/files/run/t1195-new.scala b/test/files/run/t1195-new.scala index 4edfb5073f..690c6213cf 100644 --- a/test/files/run/t1195-new.scala +++ b/test/files/run/t1195-new.scala @@ -9,7 +9,7 @@ object Test { val g1 = g() val h1 = h() - def m[T: TypeTag](x: T) = println(typeOf[T] + ", underlying = " + typeOf[T].typeSymbol.typeSignature) + def m[T: AbsTypeTag](x: T) = println(absTypeOf[T] + ", underlying = " + absTypeOf[T].typeSymbol.typeSignature) def main(args: Array[String]): Unit = { m(f) diff --git a/test/files/run/toolbox_typecheck_macrosdisabled.scala b/test/files/run/toolbox_typecheck_macrosdisabled.scala index 01a418d42e..51eb63f294 100644 --- a/test/files/run/toolbox_typecheck_macrosdisabled.scala +++ b/test/files/run/toolbox_typecheck_macrosdisabled.scala @@ -12,7 +12,8 @@ object Test extends App { val rupkg = cm.staticModule("scala.reflect.runtime.package") val rusym = build.selectTerm(rupkg, "universe") val NullaryMethodType(rutpe) = rusym.typeSignature - val ru = build.newFreeTerm("ru", rutpe, scala.reflect.runtime.universe) + val ru = build.newFreeTerm("ru", scala.reflect.runtime.universe) + build.setTypeSignature(ru, rutpe) val tree1 = Apply(Select(Ident(ru), newTermName("reify")), List(Literal(Constant(2)))) val ttree1 = toolbox.typeCheck(tree1, withMacrosDisabled = false) diff --git a/test/files/run/toolbox_typecheck_macrosdisabled2.scala b/test/files/run/toolbox_typecheck_macrosdisabled2.scala index 462dc9fa91..74fd09d9fd 100644 --- a/test/files/run/toolbox_typecheck_macrosdisabled2.scala +++ b/test/files/run/toolbox_typecheck_macrosdisabled2.scala @@ -12,7 +12,8 @@ object Test extends App { val rupkg = cm.staticModule("scala.reflect.runtime.package") val rusym = build.selectTerm(rupkg, "universe") val NullaryMethodType(rutpe) = rusym.typeSignature - val ru = build.newFreeTerm("ru", rutpe, scala.reflect.runtime.universe) + val ru = build.newFreeTerm("ru", scala.reflect.runtime.universe) + build.setTypeSignature(ru, rutpe) val tree1 = Apply(Select(Ident(ru), newTermName("reify")), List(Apply(Select(Ident(newTermName("scala")), newTermName("Array")), List(Literal(Constant(2)))))) val ttree1 = toolbox.typeCheck(tree1, withMacrosDisabled = false) |