aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/dotty/tools/dotc/ast/TreeTypeMap.scala44
-rw-r--r--src/dotty/tools/dotc/core/Symbols.scala6
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