summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/StdAttachments.scala14
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Typers.scala6
-rw-r--r--test/files/neg/t6920.check6
-rw-r--r--test/files/neg/t6920.scala10
-rw-r--r--test/files/neg/t8006.check6
-rw-r--r--test/files/neg/t8006.scala8
6 files changed, 47 insertions, 3 deletions
diff --git a/src/compiler/scala/tools/nsc/typechecker/StdAttachments.scala b/src/compiler/scala/tools/nsc/typechecker/StdAttachments.scala
index 86bf846f1c..14f47a00fd 100644
--- a/src/compiler/scala/tools/nsc/typechecker/StdAttachments.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/StdAttachments.scala
@@ -151,4 +151,18 @@ trait StdAttachments {
* because someone has put MacroImplRefAttachment on it.
*/
def isMacroImplRef(tree: Tree): Boolean = tree.attachments.get[MacroImplRefAttachment.type].isDefined
+
+ /** Since mkInvoke, the applyDynamic/selectDynamic/etc desugarer, is disconnected
+ * from typedNamedApply, the applyDynamicNamed argument rewriter, the latter
+ * doesn’t know whether it needs to apply the rewriting because the application
+ * has just been desugared or it needs to hold on because it’s already performed
+ * a desugaring on this tree. This has led to SI-8006.
+ *
+ * This attachment solves the problem by providing a means of communication
+ * between the two Dynamic desugarers, which solves the aforementioned issue.
+ */
+ case object DynamicRewriteAttachment
+ def markDynamicRewrite(tree: Tree): Tree = tree.updateAttachment(DynamicRewriteAttachment)
+ def unmarkDynamicRewrite(tree: Tree): Tree = tree.removeAttachment[DynamicRewriteAttachment.type]
+ def isDynamicRewrite(tree: Tree): Boolean = tree.attachments.get[DynamicRewriteAttachment.type].isDefined
}
diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
index 7ff9e854b1..910da77ca8 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
@@ -3369,7 +3369,7 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper
(args exists isNamedArg) || // uses a named argument
isNamedApplyBlock(fun)) { // fun was transformed to a named apply block =>
// integrate this application into the block
- if (dyna.isApplyDynamicNamed(fun)) dyna.typedNamedApply(tree, fun, args, mode, pt)
+ if (dyna.isApplyDynamicNamed(fun) && isDynamicRewrite(fun)) dyna.typedNamedApply(tree, fun, args, mode, pt)
else tryNamesDefaults
} else {
val tparams = context.extractUndetparams()
@@ -3927,7 +3927,7 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper
gen.mkTuple(List(CODE.LIT(""), arg))
}
- val t = treeCopy.Apply(orig, fun, args map argToBinding)
+ val t = treeCopy.Apply(orig, unmarkDynamicRewrite(fun), args map argToBinding)
wrapErrors(t, _.typed(t, mode, pt))
}
@@ -3992,7 +3992,7 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper
val nameStringLit = atPos(treeSelection.pos.withStart(treeSelection.pos.point).makeTransparent) {
Literal(Constant(name.decode))
}
- atPos(qual.pos)(Apply(fun, List(nameStringLit)))
+ markDynamicRewrite(atPos(qual.pos)(Apply(fun, List(nameStringLit))))
case _ =>
setError(tree)
}
diff --git a/test/files/neg/t6920.check b/test/files/neg/t6920.check
new file mode 100644
index 0000000000..ee4eafb83e
--- /dev/null
+++ b/test/files/neg/t6920.check
@@ -0,0 +1,6 @@
+t6920.scala:9: error: too many arguments for method applyDynamicNamed: (values: Seq[(String, Any)])String
+error after rewriting to CompilerError.this.test.applyDynamicNamed("crushTheCompiler")(scala.Tuple2("a", 1), scala.Tuple2("b", 2))
+possible cause: maybe a wrong Dynamic method signature?
+ test.crushTheCompiler(a = 1, b = 2)
+ ^
+one error found
diff --git a/test/files/neg/t6920.scala b/test/files/neg/t6920.scala
new file mode 100644
index 0000000000..b79d641698
--- /dev/null
+++ b/test/files/neg/t6920.scala
@@ -0,0 +1,10 @@
+import scala.language.dynamics
+
+class DynTest extends Dynamic {
+ def applyDynamicNamed(name: String)(values: Seq[(String, Any)]) = "test"
+}
+
+class CompilerError {
+ val test = new DynTest
+ test.crushTheCompiler(a = 1, b = 2)
+} \ No newline at end of file
diff --git a/test/files/neg/t8006.check b/test/files/neg/t8006.check
new file mode 100644
index 0000000000..fbac26e3ad
--- /dev/null
+++ b/test/files/neg/t8006.check
@@ -0,0 +1,6 @@
+t8006.scala:3: error: too many arguments for method applyDynamicNamed: (value: (String, Any))String
+error after rewriting to X.this.d.applyDynamicNamed("meth")(scala.Tuple2("value1", 10), scala.Tuple2("value2", 100))
+possible cause: maybe a wrong Dynamic method signature?
+ d.meth(value1 = 10, value2 = 100) // two arguments here, but only one is allowed
+ ^
+one error found
diff --git a/test/files/neg/t8006.scala b/test/files/neg/t8006.scala
new file mode 100644
index 0000000000..b2f71c1587
--- /dev/null
+++ b/test/files/neg/t8006.scala
@@ -0,0 +1,8 @@
+object X {
+ val d = new D
+ d.meth(value1 = 10, value2 = 100) // two arguments here, but only one is allowed
+}
+import language.dynamics
+class D extends Dynamic {
+ def applyDynamicNamed(name: String)(value: (String, Any)) = name
+} \ No newline at end of file