diff options
-rw-r--r-- | src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala | 3 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/typechecker/Typers.scala | 18 | ||||
-rw-r--r-- | test/files/neg/applydynamic_sip.check | 10 | ||||
-rw-r--r-- | test/files/neg/applydynamic_sip.scala | 10 | ||||
-rw-r--r-- | test/files/run/applydynamic_sip.scala | 4 |
5 files changed, 38 insertions, 7 deletions
diff --git a/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala b/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala index edc69be827..38fbcf4ef4 100644 --- a/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala +++ b/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala @@ -504,6 +504,9 @@ trait ContextErrors { def ApplyWithoutArgsError(tree: Tree, fun: Tree) = NormalTypeError(tree, fun.tpe+" does not take parameters") + def DynamicVarArgUnsupported(tree: Tree, name: String) = + issueNormalTypeError(tree, name+ " does not support passing a vararg parameter") + //checkClassType def TypeNotAStablePrefixError(tpt: Tree, pre: Type) = { issueNormalTypeError(tpt, "type "+pre+" is not a stable prefix") diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala index 305e30aeee..0da118403d 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala @@ -3517,15 +3517,23 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser { case t => (t, Nil) } + @inline def hasNamedArg(as: List[Tree]) = as collectFirst {case AssignOrNamedArg(lhs, rhs) =>} nonEmpty + // note: context.tree includes at most one Apply node // thus, we can't use it to detect we're going to receive named args in expressions such as: // qual.sel(a)(a2, arg2 = "a2") val oper = outer match { - case Apply(`tree`, as) => if (as collectFirst {case AssignOrNamedArg(lhs, rhs) =>} nonEmpty) - nme.applyDynamicNamed - else nme.applyDynamic - case Assign(`tree`, _) => nme.updateDynamic - case _ => nme.selectDynamic + case Apply(`tree`, as) => + val oper = + if (hasNamedArg(as)) nme.applyDynamicNamed + else nme.applyDynamic + // not supported: foo.bar(a1,..., an: _*) + if (treeInfo.isWildcardStarArgList(as)) { + DynamicVarArgUnsupported(tree, oper) + return Some(setError(tree)) + } else oper + case Assign(`tree`, _) => nme.updateDynamic + case _ => nme.selectDynamic } val dynSel = Select(qual, oper) diff --git a/test/files/neg/applydynamic_sip.check b/test/files/neg/applydynamic_sip.check new file mode 100644 index 0000000000..8845f68a52 --- /dev/null +++ b/test/files/neg/applydynamic_sip.check @@ -0,0 +1,10 @@ +applydynamic_sip.scala:7: error: applyDynamic does not support passing a vararg parameter + qual.sel(a, a2: _*) + ^ +applydynamic_sip.scala:8: error: applyDynamicNamed does not support passing a vararg parameter + qual.sel(arg = a, a2: _*) + ^ +applydynamic_sip.scala:9: error: applyDynamicNamed does not support passing a vararg parameter + qual.sel(arg, arg2 = "a2", a2: _*) + ^ +three errors found diff --git a/test/files/neg/applydynamic_sip.scala b/test/files/neg/applydynamic_sip.scala new file mode 100644 index 0000000000..362461577b --- /dev/null +++ b/test/files/neg/applydynamic_sip.scala @@ -0,0 +1,10 @@ +object Test extends App { + val qual: Dynamic = ??? + val expr = "expr" + val a = "a" + val a2 = "a2" + + qual.sel(a, a2: _*) + qual.sel(arg = a, a2: _*) + qual.sel(arg, arg2 = "a2", a2: _*) +}
\ No newline at end of file diff --git a/test/files/run/applydynamic_sip.scala b/test/files/run/applydynamic_sip.scala index 7150517530..57cb4349f7 100644 --- a/test/files/run/applydynamic_sip.scala +++ b/test/files/run/applydynamic_sip.scala @@ -29,9 +29,9 @@ object Test extends App { qual.sel[T](a) qual.sel[T](a)(a2) - // If qual.sel is followed by a potential type argument list [Ts] + // If qual.sel is followed by a potential type argument list [Ts] // and a non-empty named argument list (x1 = arg1, …, xn = argn) where some name prefixes xi = might be missing: - // qual.applyDynamicNamed(“sel”)(xs1 -> arg1, …, xsn -> argn) + // qual.applyDynamicNamed(“sel”)(xs1 -> arg1, …, xsn -> argn) qual.sel(arg = a) qual.sel[T](arg = a) qual.sel(a, arg2 = "a2") |