summaryrefslogtreecommitdiff
path: root/src/compiler/scala/tools/nsc/typechecker/Typers.scala
diff options
context:
space:
mode:
authorEugene Burmako <xeno.by@gmail.com>2013-06-27 17:10:47 +0200
committerEugene Burmako <xeno.by@gmail.com>2013-07-09 15:09:38 +0200
commite72ae708ed39ad006ef7dbbb85e116a8e6704663 (patch)
treeefe31be83f23f421a00b95c1c39e681ae2a3715b /src/compiler/scala/tools/nsc/typechecker/Typers.scala
parent55decf733eb361c235ef1bd9039e5c6226202a96 (diff)
downloadscala-e72ae708ed39ad006ef7dbbb85e116a8e6704663.tar.gz
scala-e72ae708ed39ad006ef7dbbb85e116a8e6704663.tar.bz2
scala-e72ae708ed39ad006ef7dbbb85e116a8e6704663.zip
SI-7617 typedAssign no longer expands lhs
This makes sure that setter and updateDynamic macros work as intended rather than in some cases expanding incorrectly or prematurely. Setter invocations are desugared from assignments of values to getters. If a typecheck of an assignment's lhs yields an invocation of a getter, then the assignment is rewritten into an invocation of a setter. However if a getter is a macro, then it just expands, destroying the prerequisite for desugaring. Therefore we need to disable expansion for the typecheck of an lhs. Similar thing happens to updateDynamic that first desugars a getter invocation into q"$target.updateDynamic($fieldName)" and then expects typedAssign to rewrite the corresponding Assign node into an additional application of a partially applied updateDynamic to a rhs. Here we also need to disable the typecheck of an lhs, because macros cannot be partially applied.
Diffstat (limited to 'src/compiler/scala/tools/nsc/typechecker/Typers.scala')
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Typers.scala5
1 files changed, 4 insertions, 1 deletions
diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
index ecbab41db3..07968afbec 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
@@ -4057,6 +4057,7 @@ trait Typers extends Modes with Adaptations with Tags {
findSelection(cxTree) match {
case Some((opName, treeInfo.Applied(_, targs, _))) =>
val fun = gen.mkTypeApply(Select(qual, opName), targs)
+ if (opName == nme.updateDynamic) suppressMacroExpansion(fun) // SI-7617
atPos(qual.pos)(Apply(fun, Literal(Constant(name.decode)) :: Nil))
case _ =>
setError(tree)
@@ -4229,7 +4230,9 @@ trait Typers extends Modes with Adaptations with Tags {
}
def typedAssign(lhs: Tree, rhs: Tree): Tree = {
- val lhs1 = typed(lhs, EXPRmode | LHSmode, WildcardType)
+ // see SI-7617 for an explanation of why macro expansion is suppressed
+ def typedLhs(lhs: Tree) = typed(lhs, EXPRmode | LHSmode, WildcardType)
+ val lhs1 = unsuppressMacroExpansion(typedLhs(suppressMacroExpansion(lhs)))
val varsym = lhs1.symbol
// see #2494 for double error message example