diff options
author | Martin Odersky <odersky@gmail.com> | 2016-09-15 12:08:42 +0200 |
---|---|---|
committer | Martin Odersky <odersky@gmail.com> | 2016-10-02 16:12:28 +0200 |
commit | b5132e87afe1a98467369d2f91ba4483a6a88ea4 (patch) | |
tree | f8fca34ccef6c3b9ff5d9d7f971f30aabd84a2e1 /src/dotty/tools/dotc/typer/Typer.scala | |
parent | 84bc770bb7bcac2fe09a13c62c24aac1e3fda582 (diff) | |
download | dotty-b5132e87afe1a98467369d2f91ba4483a6a88ea4.tar.gz dotty-b5132e87afe1a98467369d2f91ba4483a6a88ea4.tar.bz2 dotty-b5132e87afe1a98467369d2f91ba4483a6a88ea4.zip |
Change owner as necessary when typing a TypedSplice
When typing an untpd.TypedSplice it could be that the owner
at the time the tree is originally typed is different from the owner
at the time the tree is unwrapped. In that case the owner needs
to be changed.
Problem was noticed in Course-2002-02 after changing Closure to
be a pure expression. This means that TypedSplices containing
closures are no longer lifted out from containing closures
during eta expansion, and the owner chain got corrupted.
Diffstat (limited to 'src/dotty/tools/dotc/typer/Typer.scala')
-rw-r--r-- | src/dotty/tools/dotc/typer/Typer.scala | 19 |
1 files changed, 16 insertions, 3 deletions
diff --git a/src/dotty/tools/dotc/typer/Typer.scala b/src/dotty/tools/dotc/typer/Typer.scala index 85102841e..18b609f8d 100644 --- a/src/dotty/tools/dotc/typer/Typer.scala +++ b/src/dotty/tools/dotc/typer/Typer.scala @@ -513,8 +513,8 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit val rawUpdate: untpd.Tree = untpd.Select(untpd.TypedSplice(fn), nme.update) val wrappedUpdate = if (targs.isEmpty) rawUpdate - else untpd.TypeApply(rawUpdate, targs map untpd.TypedSplice) - val appliedUpdate = cpy.Apply(fn)(wrappedUpdate, (args map untpd.TypedSplice) :+ tree.rhs) + else untpd.TypeApply(rawUpdate, targs map (untpd.TypedSplice(_))) + val appliedUpdate = cpy.Apply(fn)(wrappedUpdate, (args map (untpd.TypedSplice(_))) :+ tree.rhs) typed(appliedUpdate, pt) case lhs => val lhsCore = typedUnadapted(lhs, AssignProto) @@ -1357,6 +1357,19 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit } } + def typedTypedSplice(tree: untpd.TypedSplice)(implicit ctx: Context): Tree = + tree.tree match { + case tree1: TypeTree => tree1 // no change owner necessary here ... + case tree1: Ident => tree1 // ... or here + case tree1 => + if (ctx.owner ne tree.owner) { + println(i"changing owner of $tree1 from ${tree.owner} to ${ctx.owner}") + tree1.changeOwner(tree.owner, ctx.owner) + } + else tree1 + } + + def typedAsFunction(tree: untpd.PostfixOp, pt: Type)(implicit ctx: Context): Tree = { val untpd.PostfixOp(qual, nme.WILDCARD) = tree val pt1 = if (defn.isFunctionType(pt)) pt else AnyFunctionProto @@ -1456,7 +1469,7 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit case tree: untpd.Alternative => typedAlternative(tree, pt) case tree: untpd.PackageDef => typedPackageDef(tree) case tree: untpd.Annotated => typedAnnotated(tree, pt) - case tree: untpd.TypedSplice => tree.tree + case tree: untpd.TypedSplice => typedTypedSplice(tree) case tree: untpd.UnApply => typedUnApply(tree, pt) case tree @ untpd.PostfixOp(qual, nme.WILDCARD) => typedAsFunction(tree, pt) case untpd.EmptyTree => tpd.EmptyTree |