diff options
-rw-r--r-- | src/dotty/tools/dotc/ast/TreeTypeMap.scala | 51 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/Symbols.scala | 2 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/Types.scala | 2 |
3 files changed, 42 insertions, 13 deletions
diff --git a/src/dotty/tools/dotc/ast/TreeTypeMap.scala b/src/dotty/tools/dotc/ast/TreeTypeMap.scala index 33be848c1..22428edb6 100644 --- a/src/dotty/tools/dotc/ast/TreeTypeMap.scala +++ b/src/dotty/tools/dotc/ast/TreeTypeMap.scala @@ -79,14 +79,25 @@ final class TreeTypeMap( override def transform(tree: tpd.Tree)(implicit ctx: Context): tpd.Tree = treeMap(tree) match { case impl @ Template(constr, parents, self, body) => - 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)) + if (oldOwners contains impl.symbol.owner) { + 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) => @@ -160,8 +171,24 @@ final class TreeTypeMap( * and return a treemap that contains the substitution * between original and mapped symbols. */ - def withMappedSyms(syms: List[Symbol]): TreeTypeMap = { - val mapped = ctx.mapSymbols(syms, this) - withSubstitution(syms, mapped) - } + def withMappedSyms(syms: List[Symbol]): TreeTypeMap = + withMappedSyms(syms, ctx.mapSymbols(syms, this)) + + /** 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 + } + } } diff --git a/src/dotty/tools/dotc/core/Symbols.scala b/src/dotty/tools/dotc/core/Symbols.scala index 0174f75cf..cedc0adc8 100644 --- a/src/dotty/tools/dotc/core/Symbols.scala +++ b/src/dotty/tools/dotc/core/Symbols.scala @@ -267,7 +267,7 @@ 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) = + def mapSymbols(originals: List[Symbol], ttmap: TreeTypeMap): List[Symbol] = if (originals forall (sym => (ttmap.mapType(sym.info) eq sym.info) && !(ttmap.oldOwners contains sym.owner))) diff --git a/src/dotty/tools/dotc/core/Types.scala b/src/dotty/tools/dotc/core/Types.scala index d93e4eb09..33ce71ad3 100644 --- a/src/dotty/tools/dotc/core/Types.scala +++ b/src/dotty/tools/dotc/core/Types.scala @@ -116,6 +116,8 @@ object Types { tp.tp1.derivesFrom(cls) || tp.tp2.derivesFrom(cls) case tp: OrType => tp.tp1.derivesFrom(cls) && tp.tp2.derivesFrom(cls) + case tp: JavaArrayType => + cls == defn.ObjectClass case _ => false } |