aboutsummaryrefslogtreecommitdiff
path: root/src/dotty/tools/dotc/ast/TreeTypeMap.scala
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2014-10-19 16:57:14 +0200
committerMartin Odersky <odersky@gmail.com>2014-10-26 16:24:01 +0100
commit1a81244b68e58bde6a3d03551f1d92f15c3ff719 (patch)
tree30055185c94c52ac8e78b894af162f818c95f8e2 /src/dotty/tools/dotc/ast/TreeTypeMap.scala
parent0f3a903bebdac5eeaa84b2f8fdd0298bd15468f2 (diff)
downloaddotty-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.
Diffstat (limited to 'src/dotty/tools/dotc/ast/TreeTypeMap.scala')
-rw-r--r--src/dotty/tools/dotc/ast/TreeTypeMap.scala44
1 files changed, 16 insertions, 28 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)
+ }
}