summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Phillips <paulp@improving.org>2011-08-16 16:53:16 +0000
committerPaul Phillips <paulp@improving.org>2011-08-16 16:53:16 +0000
commitd8359a20a088a4724431ce9c7dd93869c2ad23cb (patch)
treedaecc28fd7443c37bfe13cffd1d77dd96b409756
parent20859263f2a2cf85464b333b9842bb31c020ee5e (diff)
downloadscala-d8359a20a088a4724431ce9c7dd93869c2ad23cb.tar.gz
scala-d8359a20a088a4724431ce9c7dd93869c2ad23cb.tar.bz2
scala-d8359a20a088a4724431ce9c7dd93869c2ad23cb.zip
Improved the error message given when a concret...
Improved the error message given when a concrete method implementation doesn't match the abstract one. No review.
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/RefChecks.scala17
-rw-r--r--test/files/neg/abstract-concrete-methods.check5
-rw-r--r--test/files/neg/abstract-concrete-methods.scala10
3 files changed, 29 insertions, 3 deletions
diff --git a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala
index 9f957af136..10918ecffa 100644
--- a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala
@@ -533,19 +533,30 @@ abstract class RefChecks extends InfoTransform with reflect.internal.transform.R
mismatches match {
// Only one mismatched parameter: say something useful.
case (pa, pc) :: Nil =>
- val addendum =
- if (pa.typeSymbol == pc.typeSymbol) {
+ val abstractSym = pa.typeSymbol
+ val concreteSym = pc.typeSymbol
+ def subclassMsg(c1: Symbol, c2: Symbol) = (
+ ": %s is a subclass of %s, but method parameter types must match exactly.".format(
+ c1.fullLocationString, c2.fullLocationString)
+ )
+ val addendum = (
+ if (abstractSym == concreteSym) {
// TODO: what is the optimal way to test for a raw type at this point?
// Compilation has already failed so we shouldn't have to worry overmuch
// about forcing types.
- if (underlying.isJavaDefined && pa.typeArgs.isEmpty && pa.typeSymbol.typeParams.nonEmpty)
+ if (underlying.isJavaDefined && pa.typeArgs.isEmpty && abstractSym.typeParams.nonEmpty)
". To implement a raw type, use %s[_]".format(pa)
else if (pa.prefix =:= pc.prefix)
": their type parameters differ"
else
": their prefixes (i.e. enclosing instances) differ"
}
+ else if (abstractSym isSubClass concreteSym)
+ subclassMsg(abstractSym, concreteSym)
+ else if (concreteSym isSubClass abstractSym)
+ subclassMsg(concreteSym, abstractSym)
else ""
+ )
undefined("\n(Note that %s does not match %s%s)".format(pa, pc, addendum))
case xs =>
diff --git a/test/files/neg/abstract-concrete-methods.check b/test/files/neg/abstract-concrete-methods.check
new file mode 100644
index 0000000000..e128f77e26
--- /dev/null
+++ b/test/files/neg/abstract-concrete-methods.check
@@ -0,0 +1,5 @@
+abstract-concrete-methods.scala:7: error: class Outer2 needs to be abstract, since method score in trait Outer of type (i: Outer2#Inner)Double is not defined
+(Note that This#Inner does not match Outer2#Inner: class Inner in class Outer2 is a subclass of trait Inner in trait Outer, but method parameter types must match exactly.)
+class Outer2 extends Outer[Outer2] {
+ ^
+one error found
diff --git a/test/files/neg/abstract-concrete-methods.scala b/test/files/neg/abstract-concrete-methods.scala
new file mode 100644
index 0000000000..7f1aea0dbc
--- /dev/null
+++ b/test/files/neg/abstract-concrete-methods.scala
@@ -0,0 +1,10 @@
+trait Outer[This <: Outer[This]] {
+ self: This =>
+
+ trait Inner
+ def score(i: This#Inner): Double
+}
+class Outer2 extends Outer[Outer2] {
+ class Inner extends super.Inner
+ def score(i: Outer2#Inner) = 0.0
+}