summaryrefslogtreecommitdiff
path: root/src/compiler/scala/tools
diff options
context:
space:
mode:
authorJason Zaugg <jzaugg@gmail.com>2016-11-18 16:04:49 +1000
committerJason Zaugg <jzaugg@gmail.com>2016-11-18 18:17:30 +1000
commit944db65d63e12ae4e0135999cdc8b9f2695f4102 (patch)
tree0076ec04446f6eefc3c18dc0f079d6bd84761e68 /src/compiler/scala/tools
parent73678d4dafe250f0b38df2e953787af26b1a4ee3 (diff)
downloadscala-944db65d63e12ae4e0135999cdc8b9f2695f4102.tar.gz
scala-944db65d63e12ae4e0135999cdc8b9f2695f4102.tar.bz2
scala-944db65d63e12ae4e0135999cdc8b9f2695f4102.zip
SI-10066 Fix crash in erroneous code with implicits, dynamic
The compiler support in the typechecker for `scala.Dynamic` is very particular about the `Context` in which it is typechecked. It looks at the `tree` in the enclosing context to find the expression immediately enclosing the dynamic selection. See the logic in `dyna::mkInvoke` for the details. This commit substitutes the result of `resetAttrs` into the tree of the typer context before continuing with typechecking.
Diffstat (limited to 'src/compiler/scala/tools')
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Typers.scala23
1 files changed, 18 insertions, 5 deletions
diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
index cca6f280e3..192917d4aa 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
@@ -863,11 +863,24 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper
case _ =>
}
debuglog(s"fallback on implicits: ${tree}/$resetTree")
- val tree1 = typed(resetTree, mode)
- // Q: `typed` already calls `pluginsTyped` and `adapt`. the only difference here is that
- // we pass `EmptyTree` as the `original`. intended? added in 2009 (53d98e7d42) by martin.
- tree1 setType pluginsTyped(tree1.tpe, this, tree1, mode, pt)
- if (tree1.isEmpty) tree1 else adapt(tree1, mode, pt, EmptyTree)
+ // SO-10066 Need to patch the enclosing tree in the context to make translation of Dynamic
+ // work during fallback typechecking below.
+ val resetContext: Context = {
+ object substResetForOriginal extends Transformer {
+ override def transform(tree: Tree): Tree = {
+ if (tree eq original) resetTree
+ else super.transform(tree)
+ }
+ }
+ context.make(substResetForOriginal.transform(context.tree))
+ }
+ typerWithLocalContext(resetContext) { typer1 =>
+ val tree1 = typer1.typed(resetTree, mode)
+ // Q: `typed` already calls `pluginsTyped` and `adapt`. the only difference here is that
+ // we pass `EmptyTree` as the `original`. intended? added in 2009 (53d98e7d42) by martin.
+ tree1 setType pluginsTyped(tree1.tpe, typer1, tree1, mode, pt)
+ if (tree1.isEmpty) tree1 else typer1.adapt(tree1, mode, pt, EmptyTree)
+ }
}
)
else