diff options
author | Martin Odersky <odersky@gmail.com> | 2014-10-19 16:57:14 +0200 |
---|---|---|
committer | Martin Odersky <odersky@gmail.com> | 2014-10-26 16:24:01 +0100 |
commit | 1a81244b68e58bde6a3d03551f1d92f15c3ff719 (patch) | |
tree | 30055185c94c52ac8e78b894af162f818c95f8e2 | |
parent | 0f3a903bebdac5eeaa84b2f8fdd0298bd15468f2 (diff) | |
download | dotty-1a81244b68e58bde6a3d03551f1d92f15c3ff719.tar.gz dotty-1a81244b68e58bde6a3d03551f1d92f15c3ff719.tar.bz2 dotty-1a81244b68e58bde6a3d03551f1d92f15c3ff719.zip |
Fix to TreeTypeMap
Now handles the case where a class symbol itself is not changed by the map,
but one of its declarations is. In this case we need to back out, and create
new symbols for the class and all other symbols that are defined in the same scope as
the class.
-rw-r--r-- | src/dotty/tools/dotc/ast/TreeTypeMap.scala | 44 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/Symbols.scala | 6 |
2 files changed, 19 insertions, 31 deletions
diff --git a/src/dotty/tools/dotc/ast/TreeTypeMap.scala b/src/dotty/tools/dotc/ast/TreeTypeMap.scala index 22428edb6..32c89c94f 100644 --- a/src/dotty/tools/dotc/ast/TreeTypeMap.scala +++ b/src/dotty/tools/dotc/ast/TreeTypeMap.scala @@ -79,25 +79,13 @@ final class TreeTypeMap( override def transform(tree: tpd.Tree)(implicit ctx: Context): tpd.Tree = treeMap(tree) match { case impl @ Template(constr, parents, self, body) => - if (oldOwners contains impl.symbol.owner) { - val tmap = withMappedSyms(localSyms(impl :: self :: Nil)) - cpy.Template(impl)( + val tmap = withMappedSyms(localSyms(impl :: self :: Nil)) + cpy.Template(impl)( constr = tmap.transformSub(constr), parents = parents mapconserve transform, self = tmap.transformSub(self), body = body mapconserve tmap.transform ).withType(tmap.mapType(impl.tpe)) - } - else { - val tmap = withMappedSyms(impl.symbol :: impl.constr.symbol :: Nil) - val parents1 = parents mapconserve transform - val (_, constr1 :: self1 :: Nil) = transformDefs(constr :: self :: Nil) - val body1 = tmap.transformStats(body) - updateDecls(constr :: body, constr1 :: body1) - cpy.Template(impl)( - constr1.asInstanceOf[DefDef], parents1, self1.asInstanceOf[ValDef], body1) - .withType(tmap.mapType(impl.tpe)) - } case tree1 => tree1.withType(mapType(tree1.tpe)) match { case id: Ident if tpd.needsSelect(id.tpe) => @@ -171,24 +159,24 @@ final class TreeTypeMap( * and return a treemap that contains the substitution * between original and mapped symbols. */ - def withMappedSyms(syms: List[Symbol]): TreeTypeMap = - withMappedSyms(syms, ctx.mapSymbols(syms, this)) + def withMappedSyms(syms: List[Symbol], mapAlways: Boolean = false): TreeTypeMap = + withMappedSyms(syms, ctx.mapSymbols(syms, this, mapAlways)) /** The tree map with the substitution between originals `syms` * and mapped symbols `mapped`. Also goes into mapped classes * and substitutes their declarations. */ - def withMappedSyms(syms: List[Symbol], mapped: List[Symbol]): TreeTypeMap = - if (mapped eq syms) this - else { - val substMap = withSubstitution(syms, mapped) - val mappedClasses = mapped.filter(_.isClass) - (substMap /: mappedClasses) { (tmap, cls) => - val origDcls = cls.decls.toList - val mappedDcls = ctx.mapSymbols(origDcls, tmap) - val tmap1 = tmap.withMappedSyms(origDcls, mappedDcls) - (origDcls, mappedDcls).zipped.foreach(cls.asClass.replace) - tmap1 - } + def withMappedSyms(syms: List[Symbol], mapped: List[Symbol]): TreeTypeMap = { + val symsChanged = syms ne mapped + val substMap = withSubstitution(syms, mapped) + val fullMap = (substMap /: mapped.filter(_.isClass)) { (tmap, cls) => + val origDcls = cls.decls.toList + val mappedDcls = ctx.mapSymbols(origDcls, tmap) + val tmap1 = tmap.withMappedSyms(origDcls, mappedDcls) + if (symsChanged) (origDcls, mappedDcls).zipped.foreach(cls.asClass.replace) + tmap1 } + if (symsChanged || (fullMap eq substMap)) fullMap + else withMappedSyms(syms, mapAlways = true) + } } diff --git a/src/dotty/tools/dotc/core/Symbols.scala b/src/dotty/tools/dotc/core/Symbols.scala index cedc0adc8..83fb2c134 100644 --- a/src/dotty/tools/dotc/core/Symbols.scala +++ b/src/dotty/tools/dotc/core/Symbols.scala @@ -267,10 +267,10 @@ trait Symbols { this: Context => * Cross symbol references are brought over from originals to copies. * Do not copy any symbols if all attributes of all symbols stay the same. */ - def mapSymbols(originals: List[Symbol], ttmap: TreeTypeMap): List[Symbol] = - if (originals forall (sym => + def mapSymbols(originals: List[Symbol], ttmap: TreeTypeMap, mapAlways: Boolean = false): List[Symbol] = + if (originals.forall(sym => (ttmap.mapType(sym.info) eq sym.info) && - !(ttmap.oldOwners contains sym.owner))) + !(ttmap.oldOwners contains sym.owner)) && !mapAlways) originals else { val copies: List[Symbol] = for (original <- originals) yield |