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