diff options
-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 |