summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGrzegorz Kossakowski <grzegorz.kossakowski@gmail.com>2012-09-19 04:07:48 -0700
committerGrzegorz Kossakowski <grzegorz.kossakowski@gmail.com>2012-09-19 04:07:48 -0700
commitb9fd3f713d4c0122c1411315ad25049d117df57c (patch)
tree9d0ce1d9c26365e02822ffbe1888b1b5ea58e377
parenteb49e8176f334eebc77072cc9334c7f1875b09a2 (diff)
parent08e5fd23e73bd2bcccc5f380c0a197d3bb900c02 (diff)
downloadscala-b9fd3f713d4c0122c1411315ad25049d117df57c.tar.gz
scala-b9fd3f713d4c0122c1411315ad25049d117df57c.tar.bz2
scala-b9fd3f713d4c0122c1411315ad25049d117df57c.zip
Merge pull request #1343 from namin/dynamic-sig
Fixes SI-6354: improved error messages for Dynamic signature mismatches.
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala7
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Typers.scala17
-rw-r--r--test/files/neg/applydynamic_sip.check50
-rw-r--r--test/files/neg/applydynamic_sip.flags1
-rw-r--r--test/files/neg/applydynamic_sip.scala25
5 files changed, 95 insertions, 5 deletions
diff --git a/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala b/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala
index 144cc841b4..e34988af1a 100644
--- a/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala
@@ -515,9 +515,16 @@ trait ContextErrors {
def ApplyWithoutArgsError(tree: Tree, fun: Tree) =
NormalTypeError(tree, fun.tpe+" does not take parameters")
+ // Dynamic
def DynamicVarArgUnsupported(tree: Tree, name: String) =
issueNormalTypeError(tree, name+ " does not support passing a vararg parameter")
+ def DynamicRewriteError(tree: Tree, err: AbsTypeError) = {
+ issueTypeError(PosAndMsgTypeError(err.errPos, err.errMsg +
+ s"\nerror after rewriting to $tree\npossible cause: maybe a wrong Dynamic method signature?"))
+ setError(tree)
+ }
+
//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 089245e124..b374ff53a5 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
@@ -3806,7 +3806,8 @@ trait Typers extends Modes with Adaptations with Tags {
case AssignOrNamedArg(Ident(name), rhs) => gen.mkTuple(List(CODE.LIT(name.toString), rhs))
case _ => gen.mkTuple(List(CODE.LIT(""), arg))
}
- typed(treeCopy.Apply(orig, fun, args map argToBinding), mode, pt)
+ val t = treeCopy.Apply(orig, fun, args map argToBinding)
+ wrapErrors(t, _.typed(t, mode, pt))
}
/** Translate selection that does not typecheck according to the normal rules into a selectDynamic/applyDynamic.
@@ -3874,6 +3875,13 @@ trait Typers extends Modes with Adaptations with Tags {
atPos(qual.pos)(Apply(tappSel, List(Literal(Constant(name.decode)))))
}
}
+
+ def wrapErrors(tree: Tree, typeTree: Typer => Tree): Tree = {
+ silent(typeTree) match {
+ case SilentResultValue(r) => r
+ case SilentTypeError(err) => DynamicRewriteError(tree, err)
+ }
+ }
}
@inline final def deindentTyping() = context.typingIndentLevel -= 2
@@ -4067,7 +4075,8 @@ trait Typers extends Modes with Adaptations with Tags {
}
else if(dyna.isDynamicallyUpdatable(lhs1)) {
val rhs1 = typed(rhs, EXPRmode | BYVALmode, WildcardType)
- typed1(Apply(lhs1, List(rhs1)), mode, pt)
+ val t = Apply(lhs1, List(rhs1))
+ dyna.wrapErrors(t, _.typed1(t, mode, pt))
}
else fail()
}
@@ -4535,7 +4544,9 @@ trait Typers extends Modes with Adaptations with Tags {
* @return ...
*/
def typedSelect(tree: Tree, qual: Tree, name: Name): Tree = {
- def asDynamicCall = dyna.mkInvoke(context.tree, tree, qual, name) map (typed1(_, mode, pt))
+ def asDynamicCall = dyna.mkInvoke(context.tree, tree, qual, name) map { t =>
+ dyna.wrapErrors(t, (_.typed1(t, mode, pt)))
+ }
val sym = tree.symbol orElse member(qual, name) orElse {
// symbol not found? --> try to convert implicitly to a type that does have the required
diff --git a/test/files/neg/applydynamic_sip.check b/test/files/neg/applydynamic_sip.check
index 8845f68a52..dcf97b29fc 100644
--- a/test/files/neg/applydynamic_sip.check
+++ b/test/files/neg/applydynamic_sip.check
@@ -7,4 +7,52 @@ applydynamic_sip.scala:8: error: applyDynamicNamed does not support passing a va
applydynamic_sip.scala:9: error: applyDynamicNamed does not support passing a vararg parameter
qual.sel(arg, arg2 = "a2", a2: _*)
^
-three errors found
+applydynamic_sip.scala:18: error: type mismatch;
+ found : String("sel")
+ required: Int
+error after rewriting to Test.this.bad1.selectDynamic("sel")
+possible cause: maybe a wrong Dynamic method signature?
+ bad1.sel
+ ^
+applydynamic_sip.scala:19: error: type mismatch;
+ found : String("sel")
+ required: Int
+error after rewriting to Test.this.bad1.applyDynamic("sel")
+possible cause: maybe a wrong Dynamic method signature?
+ bad1.sel(1)
+ ^
+applydynamic_sip.scala:20: error: type mismatch;
+ found : String("sel")
+ required: Int
+error after rewriting to Test.this.bad1.applyDynamicNamed("sel")
+possible cause: maybe a wrong Dynamic method signature?
+ bad1.sel(a = 1)
+ ^
+applydynamic_sip.scala:21: error: type mismatch;
+ found : String("sel")
+ required: Int
+error after rewriting to Test.this.bad1.updateDynamic("sel")
+possible cause: maybe a wrong Dynamic method signature?
+ bad1.sel = 1
+ ^
+applydynamic_sip.scala:29: error: Int does not take parameters
+error after rewriting to Test.this.bad2.selectDynamic("sel")
+possible cause: maybe a wrong Dynamic method signature?
+ bad2.sel
+ ^
+applydynamic_sip.scala:30: error: Int does not take parameters
+error after rewriting to Test.this.bad2.applyDynamic("sel")
+possible cause: maybe a wrong Dynamic method signature?
+ bad2.sel(1)
+ ^
+applydynamic_sip.scala:31: error: Int does not take parameters
+error after rewriting to Test.this.bad2.applyDynamicNamed("sel")
+possible cause: maybe a wrong Dynamic method signature?
+ bad2.sel(a = 1)
+ ^
+applydynamic_sip.scala:32: error: Int does not take parameters
+error after rewriting to Test.this.bad2.updateDynamic("sel")
+possible cause: maybe a wrong Dynamic method signature?
+ bad2.sel = 1
+ ^
+11 errors found
diff --git a/test/files/neg/applydynamic_sip.flags b/test/files/neg/applydynamic_sip.flags
new file mode 100644
index 0000000000..1141f97507
--- /dev/null
+++ b/test/files/neg/applydynamic_sip.flags
@@ -0,0 +1 @@
+-language:dynamics
diff --git a/test/files/neg/applydynamic_sip.scala b/test/files/neg/applydynamic_sip.scala
index 362461577b..ee4432ebe6 100644
--- a/test/files/neg/applydynamic_sip.scala
+++ b/test/files/neg/applydynamic_sip.scala
@@ -7,4 +7,27 @@ object Test extends App {
qual.sel(a, a2: _*)
qual.sel(arg = a, a2: _*)
qual.sel(arg, arg2 = "a2", a2: _*)
-} \ No newline at end of file
+
+ val bad1 = new Dynamic {
+ def selectDynamic(n: Int) = n
+ def applyDynamic(n: Int) = n
+ def applyDynamicNamed(n: Int) = n
+ def updateDynamic(n: Int) = n
+
+ }
+ bad1.sel
+ bad1.sel(1)
+ bad1.sel(a = 1)
+ bad1.sel = 1
+
+ val bad2 = new Dynamic {
+ def selectDynamic = 1
+ def applyDynamic = 1
+ def applyDynamicNamed = 1
+ def updateDynamic = 1
+ }
+ bad2.sel
+ bad2.sel(1)
+ bad2.sel(a = 1)
+ bad2.sel = 1
+}