Skip to content

Commit 01f2475

Browse files
committed
Make typed tree copiers selectively retype nodes.
Those nodes that had so far a propagateType method defined on them are automatically retyped on copying. No more manual interventions are needed.
1 parent 3ce9d15 commit 01f2475

File tree

3 files changed

+102
-15
lines changed

3 files changed

+102
-15
lines changed

src/dotty/tools/dotc/ast/Trees.scala

Lines changed: 19 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -912,6 +912,13 @@ object Trees {
912912

913913
val cpy: TreeCopier
914914

915+
/** A class for copying trees. The copy methods avid creating a new tree
916+
* If all arguments stay the same.
917+
918+
* Note: Some of the copy methods take a context.
919+
* These are exactly those methods that are overridden in TypedTreeCopier
920+
* so that they selectively retype themselves. Retyping needs a context.
921+
*/
915922
abstract class TreeCopier {
916923

917924
def postProcess(tree: Tree, copied: untpd.Tree): copied.ThisTree[T]
@@ -926,7 +933,7 @@ object Trees {
926933
case tree: Ident if (name == tree.name) => tree
927934
case _ => finalize(tree, untpd.Ident(name))
928935
}
929-
def Select(tree: Tree)(qualifier: Tree, name: Name): Select = tree match {
936+
def Select(tree: Tree)(qualifier: Tree, name: Name)(implicit ctx: Context): Select = tree match {
930937
case tree: SelectWithSig =>
931938
if ((qualifier eq tree.qualifier) && (name == tree.name)) tree
932939
else finalize(tree, new SelectWithSig(qualifier, name, tree.sig))
@@ -957,7 +964,7 @@ object Trees {
957964
case tree: New if (tpt eq tree.tpt) => tree
958965
case _ => finalize(tree, untpd.New(tpt))
959966
}
960-
def Pair(tree: Tree)(left: Tree, right: Tree): Pair = tree match {
967+
def Pair(tree: Tree)(left: Tree, right: Tree)(implicit ctx: Context): Pair = tree match {
961968
case tree: Pair if (left eq tree.left) && (right eq tree.right) => tree
962969
case _ => finalize(tree, untpd.Pair(left, right))
963970
}
@@ -973,39 +980,39 @@ object Trees {
973980
case tree: Assign if (lhs eq tree.lhs) && (rhs eq tree.rhs) => tree
974981
case _ => finalize(tree, untpd.Assign(lhs, rhs))
975982
}
976-
def Block(tree: Tree)(stats: List[Tree], expr: Tree): Block = tree match {
983+
def Block(tree: Tree)(stats: List[Tree], expr: Tree)(implicit ctx: Context): Block = tree match {
977984
case tree: Block if (stats eq tree.stats) && (expr eq tree.expr) => tree
978985
case _ => finalize(tree, untpd.Block(stats, expr))
979986
}
980-
def If(tree: Tree)(cond: Tree, thenp: Tree, elsep: Tree): If = tree match {
987+
def If(tree: Tree)(cond: Tree, thenp: Tree, elsep: Tree)(implicit ctx: Context): If = tree match {
981988
case tree: If if (cond eq tree.cond) && (thenp eq tree.thenp) && (elsep eq tree.elsep) => tree
982989
case _ => finalize(tree, untpd.If(cond, thenp, elsep))
983990
}
984991
def Closure(tree: Tree)(env: List[Tree], meth: Tree, tpt: Tree): Closure = tree match {
985992
case tree: Closure if (env eq tree.env) && (meth eq tree.meth) && (tpt eq tree.tpt) => tree
986993
case _ => finalize(tree, untpd.Closure(env, meth, tpt))
987994
}
988-
def Match(tree: Tree)(selector: Tree, cases: List[CaseDef]): Match = tree match {
995+
def Match(tree: Tree)(selector: Tree, cases: List[CaseDef])(implicit ctx: Context): Match = tree match {
989996
case tree: Match if (selector eq tree.selector) && (cases eq tree.cases) => tree
990997
case _ => finalize(tree, untpd.Match(selector, cases))
991998
}
992-
def CaseDef(tree: Tree)(pat: Tree, guard: Tree, body: Tree): CaseDef = tree match {
999+
def CaseDef(tree: Tree)(pat: Tree, guard: Tree, body: Tree)(implicit ctx: Context): CaseDef = tree match {
9931000
case tree: CaseDef if (pat eq tree.pat) && (guard eq tree.guard) && (body eq tree.body) => tree
9941001
case _ => finalize(tree, untpd.CaseDef(pat, guard, body))
9951002
}
9961003
def Return(tree: Tree)(expr: Tree, from: Tree): Return = tree match {
9971004
case tree: Return if (expr eq tree.expr) && (from eq tree.from) => tree
9981005
case _ => finalize(tree, untpd.Return(expr, from))
9991006
}
1000-
def Try(tree: Tree)(expr: Tree, handler: Tree, finalizer: Tree): Try = tree match {
1007+
def Try(tree: Tree)(expr: Tree, handler: Tree, finalizer: Tree)(implicit ctx: Context): Try = tree match {
10011008
case tree: Try if (expr eq tree.expr) && (handler eq tree.handler) && (finalizer eq tree.finalizer) => tree
10021009
case _ => finalize(tree, untpd.Try(expr, handler, finalizer))
10031010
}
10041011
def Throw(tree: Tree)(expr: Tree): Throw = tree match {
10051012
case tree: Throw if (expr eq tree.expr) => tree
10061013
case _ => finalize(tree, untpd.Throw(expr))
10071014
}
1008-
def SeqLiteral(tree: Tree)(elems: List[Tree]): SeqLiteral = tree match {
1015+
def SeqLiteral(tree: Tree)(elems: List[Tree])(implicit ctx: Context): SeqLiteral = tree match {
10091016
case tree: JavaSeqLiteral =>
10101017
if (elems eq tree.elems) tree
10111018
else finalize(tree, new JavaSeqLiteral(elems))
@@ -1084,7 +1091,7 @@ object Trees {
10841091
case tree: PackageDef if (pid eq tree.pid) && (stats eq tree.stats) => tree
10851092
case _ => finalize(tree, untpd.PackageDef(pid, stats))
10861093
}
1087-
def Annotated(tree: Tree)(annot: Tree, arg: Tree): Annotated = tree match {
1094+
def Annotated(tree: Tree)(annot: Tree, arg: Tree)(implicit ctx: Context): Annotated = tree match {
10881095
case tree: Annotated if (annot eq tree.annot) && (arg eq tree.arg) => tree
10891096
case _ => finalize(tree, untpd.Annotated(annot, arg))
10901097
}
@@ -1095,15 +1102,13 @@ object Trees {
10951102

10961103
// Copier methods with default arguments; these demand that the original tree
10971104
// is of the same class as the copy. We only include trees with more than 2 elements here.
1098-
def If(tree: If)(cond: Tree = tree.cond, thenp: Tree = tree.thenp, elsep: Tree = tree.elsep): If =
1105+
def If(tree: If)(cond: Tree = tree.cond, thenp: Tree = tree.thenp, elsep: Tree = tree.elsep)(implicit ctx: Context): If =
10991106
If(tree: Tree)(cond, thenp, elsep)
11001107
def Closure(tree: Closure)(env: List[Tree] = tree.env, meth: Tree = tree.meth, tpt: Tree = tree.tpt): Closure =
11011108
Closure(tree: Tree)(env, meth, tpt)
1102-
def Match(tree: Match)(selector: Tree = tree.selector, cases: List[CaseDef] = tree.cases): Match =
1103-
Match(tree: Tree)(selector, cases)
1104-
def CaseDef(tree: CaseDef)(pat: Tree = tree.pat, guard: Tree = tree.guard, body: Tree = tree.body): CaseDef =
1109+
def CaseDef(tree: CaseDef)(pat: Tree = tree.pat, guard: Tree = tree.guard, body: Tree = tree.body)(implicit ctx: Context): CaseDef =
11051110
CaseDef(tree: Tree)(pat, guard, body)
1106-
def Try(tree: Try)(expr: Tree = tree.expr, handler: Tree = tree.handler, finalizer: Tree = tree.finalizer): Try =
1111+
def Try(tree: Try)(expr: Tree = tree.expr, handler: Tree = tree.handler, finalizer: Tree = tree.finalizer)(implicit ctx: Context): Try =
11071112
Try(tree: Tree)(expr, handler, finalizer)
11081113
def UnApply(tree: UnApply)(fun: Tree = tree.fun, implicits: List[Tree] = tree.implicits, patterns: List[Tree] = tree.patterns): UnApply =
11091114
UnApply(tree: Tree)(fun, implicits, patterns)

src/dotty/tools/dotc/ast/tpd.scala

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -336,6 +336,88 @@ object tpd extends Trees.Instance[Type] with TypedTreeInfo {
336336
class TypedTreeCopier extends TreeCopier {
337337
def postProcess(tree: Tree, copied: untpd.Tree): copied.ThisTree[Type] =
338338
copied.withTypeUnchecked(tree.tpe)
339+
340+
override def Pair(tree: Tree)(left: Tree, right: Tree)(implicit ctx: Context): Pair = {
341+
val tree1 = untpd.cpy.Pair(tree)(left, right)
342+
tree match {
343+
case tree: Pair if (left.tpe eq tree.left.tpe) && (right.tpe eq tree.right.tpe) => tree1.withTypeUnchecked(tree.tpe)
344+
case _ => ta.assignType(tree1, left, right)
345+
}
346+
}
347+
348+
override def Block(tree: Tree)(stats: List[Tree], expr: Tree)(implicit ctx: Context): Block = {
349+
val tree1 = untpd.cpy.Block(tree)(stats, expr)
350+
tree match {
351+
case tree: Block if (expr.tpe eq tree.expr.tpe) => tree1.withTypeUnchecked(tree.tpe)
352+
case _ => ta.assignType(tree1, stats, expr)
353+
}
354+
}
355+
356+
override def If(tree: Tree)(cond: Tree, thenp: Tree, elsep: Tree)(implicit ctx: Context): If = {
357+
val tree1 = untpd.cpy.If(tree)(cond, thenp, elsep)
358+
tree match {
359+
case tree: If if (thenp.tpe eq tree.thenp.tpe) && (elsep.tpe eq tree.elsep.tpe) => tree1.withTypeUnchecked(tree.tpe)
360+
case _ => ta.assignType(tree1, thenp, elsep)
361+
}
362+
}
363+
364+
override def Match(tree: Tree)(selector: Tree, cases: List[CaseDef])(implicit ctx: Context): Match = {
365+
val tree1 = untpd.cpy.Match(tree)(selector, cases)
366+
tree match {
367+
case tree: Match if sameTypes(cases, tree.cases) => tree1.withTypeUnchecked(tree.tpe)
368+
case _ => ta.assignType(tree1, cases)
369+
}
370+
}
371+
372+
override def CaseDef(tree: Tree)(pat: Tree, guard: Tree, body: Tree)(implicit ctx: Context): CaseDef = {
373+
val tree1 = untpd.cpy.CaseDef(tree)(pat, guard, body)
374+
tree match {
375+
case tree: CaseDef if (body.tpe eq tree.body.tpe) => tree1.withTypeUnchecked(tree.tpe)
376+
case _ => ta.assignType(tree1, body)
377+
}
378+
}
379+
380+
override def Try(tree: Tree)(expr: Tree, handler: Tree, finalizer: Tree)(implicit ctx: Context): Try = {
381+
val tree1 = untpd.cpy.Try(tree)(expr, handler, finalizer)
382+
tree match {
383+
case tree: Try if (expr.tpe eq tree.expr.tpe) && (handler.tpe eq tree.handler.tpe) => tree1.withTypeUnchecked(tree.tpe)
384+
case _ => ta.assignType(tree1, expr, handler)
385+
}
386+
}
387+
388+
override def SeqLiteral(tree: Tree)(elems: List[Tree])(implicit ctx: Context): SeqLiteral = {
389+
val tree1 = untpd.cpy.SeqLiteral(tree)(elems)
390+
tree match {
391+
case tree: SeqLiteral if sameTypes(elems, tree.elems) => tree1.withTypeUnchecked(tree.tpe)
392+
case _ => ta.assignType(tree1, elems)
393+
}
394+
}
395+
396+
override def Annotated(tree: Tree)(annot: Tree, arg: Tree)(implicit ctx: Context): Annotated = {
397+
val tree1 = untpd.cpy.Annotated(tree)(annot, arg)
398+
tree match {
399+
case tree: Annotated if (arg.tpe eq tree.arg.tpe) && (annot eq tree.annot) => tree1.withTypeUnchecked(tree.tpe)
400+
case _ => ta.assignType(tree1, annot, arg)
401+
}
402+
}
403+
404+
override def Select(tree: Tree)(qualifier: Tree, name: Name)(implicit ctx: Context): Select = {
405+
val tree1 = untpd.cpy.Select(tree)(qualifier, name)
406+
tree match {
407+
case tree: Select if (qualifier.tpe eq tree.qualifier.tpe) => tree1.withTypeUnchecked(tree.tpe)
408+
case _ => tree.tpe match {
409+
case tpe: NamedType => tree1.withType(tpe.derivedSelect(qualifier.tpe))
410+
case _ => tree1.withTypeUnchecked(tree.tpe)
411+
}
412+
}
413+
}
414+
415+
override def If(tree: If)(cond: Tree = tree.cond, thenp: Tree = tree.thenp, elsep: Tree = tree.elsep)(implicit ctx: Context): If =
416+
If(tree: Tree)(cond, thenp, elsep)
417+
override def CaseDef(tree: CaseDef)(pat: Tree = tree.pat, guard: Tree = tree.guard, body: Tree = tree.body)(implicit ctx: Context): CaseDef =
418+
CaseDef(tree: Tree)(pat, guard, body)
419+
override def Try(tree: Try)(expr: Tree = tree.expr, handler: Tree = tree.handler, finalizer: Tree = tree.finalizer)(implicit ctx: Context): Try =
420+
Try(tree: Tree)(expr, handler, finalizer)
339421
}
340422

341423
implicit class TreeOps[ThisTree <: tpd.Tree](val tree: ThisTree) extends AnyVal {

src/dotty/tools/dotc/transform/SuperAccessors.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -215,7 +215,7 @@ class SuperAccessors extends MacroTransform with IdentityDenotTransformer { this
215215
ctx.debuglog("Adding protected accessor for " + tree)
216216
transform(makeAccessor(sel, targs))
217217
}
218-
else if (goToSuper) super.transform(tree)
218+
else if (goToSuper) super.transform(tree)(ctx.withPhase(thisTransformer.next))
219219
else tree
220220

221221
try tree match {

0 commit comments

Comments
 (0)