aboutsummaryrefslogtreecommitdiff
path: root/src/dotty
diff options
context:
space:
mode:
authorShane Delmore <shane@delmore.io>2016-10-24 17:34:37 -0700
committerShane Delmore <shane@delmore.io>2016-10-25 14:37:00 -0700
commit63f1a3c5d0149d173eb8f65405b5983591752229 (patch)
treef12825d3305e9752654de33ff2714695315edf42 /src/dotty
parent0ab12174a5a60616a0ef818a86b21adeb21395bb (diff)
downloaddotty-63f1a3c5d0149d173eb8f65405b5983591752229.tar.gz
dotty-63f1a3c5d0149d173eb8f65405b5983591752229.tar.bz2
dotty-63f1a3c5d0149d173eb8f65405b5983591752229.zip
Improve error message for WrongNumberOfArgs
Diffstat (limited to 'src/dotty')
-rw-r--r--src/dotty/tools/dotc/reporting/diagnostic/messages.scala35
-rw-r--r--src/dotty/tools/dotc/typer/ErrorReporting.scala4
-rw-r--r--src/dotty/tools/dotc/typer/TypeAssigner.scala6
-rw-r--r--src/dotty/tools/dotc/typer/Typer.scala2
4 files changed, 41 insertions, 6 deletions
diff --git a/src/dotty/tools/dotc/reporting/diagnostic/messages.scala b/src/dotty/tools/dotc/reporting/diagnostic/messages.scala
index f76512bc7..57d96224a 100644
--- a/src/dotty/tools/dotc/reporting/diagnostic/messages.scala
+++ b/src/dotty/tools/dotc/reporting/diagnostic/messages.scala
@@ -10,6 +10,7 @@ import util.{SourceFile, NoSource}
import util.{SourcePosition, NoSourcePosition}
import config.Settings.Setting
import interfaces.Diagnostic.{ERROR, WARNING, INFO}
+import dotty.tools.dotc.ast.tpd
import printing.Highlighting._
import printing.Formatting
@@ -605,4 +606,38 @@ object messages {
|${"func(bool => // do something...)"}
|""".stripMargin
}
+ case class WrongNumberOfArgs(fntpe: Type, argKind: String, expectedArgs: List[TypeParamInfo], actual: List[untpd.Tree])(implicit ctx: Context)
+ extends Message(18) {
+ val kind = "Syntax"
+ val expectedCount = expectedArgs.length
+ val actualCount = actual.length
+ val msgPrefix = if (actualCount > expectedCount) "Too many" else "Not enough"
+
+ val expectedArgString = (fntpe.widen match {
+ case pt: MethodOrPoly => pt //ensure we return a type that will have useful typeParms
+ case _ => fntpe
+ }).typeParams.map(_.paramName.show.split("\\$").last).mkString("[", ", ", "]")
+
+ val actualArgString = actual.map(_.show.split("\\.").last).mkString("[", ", ", "]")
+
+ val msg =
+ hl"""|$msgPrefix ${argKind} arguments for $fntpe
+ |expected: $expectedArgString
+ |actual: $actualArgString""".stripMargin
+
+ val explanation = {
+ if (actualCount > expectedCount)
+ hl"""|You have supplied too many type parameters
+ |
+ |For example List takes a single type parameter (List[A])
+ | If you need to hold more types in a list then you need to combine them
+ | into another data type that can contain the number of types you need,
+ | In this example one solution would be to use a Tuple:
+ | val tuple2: Tuple2[Int, String = (1, "one)
+ | List[(Int, String)] = List(tuple2)""".stripMargin
+ else
+ hl"""|You have not supplied enough type parameters
+ | If you specify one type parameter then you need to specify every type parameter.""".stripMargin
+ }
+ }
}
diff --git a/src/dotty/tools/dotc/typer/ErrorReporting.scala b/src/dotty/tools/dotc/typer/ErrorReporting.scala
index 1d22dc646..a18c83ff8 100644
--- a/src/dotty/tools/dotc/typer/ErrorReporting.scala
+++ b/src/dotty/tools/dotc/typer/ErrorReporting.scala
@@ -49,8 +49,8 @@ object ErrorReporting {
errorMsg(ex.show, ctx)
}
- def wrongNumberOfArgs(fntpe: Type, kind: String, expected: Int, pos: Position)(implicit ctx: Context) =
- errorType(em"wrong number of ${kind}arguments for $fntpe, expected: $expected", pos)
+ def wrongNumberOfArgs(fntpe: Type, kind: String, expectedArgs: List[TypeParamInfo], actual: List[untpd.Tree], pos: Position)(implicit ctx: Context) =
+ errorType(WrongNumberOfArgs(fntpe, kind, expectedArgs, actual)(ctx), pos)
class Errors(implicit ctx: Context) {
diff --git a/src/dotty/tools/dotc/typer/TypeAssigner.scala b/src/dotty/tools/dotc/typer/TypeAssigner.scala
index 861847b11..b1fed308c 100644
--- a/src/dotty/tools/dotc/typer/TypeAssigner.scala
+++ b/src/dotty/tools/dotc/typer/TypeAssigner.scala
@@ -314,7 +314,7 @@ trait TypeAssigner {
val ownType = fn.tpe.widen match {
case fntpe @ MethodType(_, ptypes) =>
if (sameLength(ptypes, args) || ctx.phase.prev.relaxedTyping) fntpe.instantiate(args.tpes)
- else wrongNumberOfArgs(fn.tpe, "", ptypes.length, tree.pos)
+ else wrongNumberOfArgs(fn.tpe, "", fntpe.typeParams, args, tree.pos)
case t =>
errorType(i"${err.exprStr(fn)} does not take parameters", tree.pos)
}
@@ -369,7 +369,7 @@ trait TypeAssigner {
else {
val argTypes = args.tpes
if (sameLength(argTypes, paramNames) || ctx.phase.prev.relaxedTyping) pt.instantiate(argTypes)
- else wrongNumberOfArgs(fn.tpe, "type ", pt.paramNames.length, tree.pos)
+ else wrongNumberOfArgs(fn.tpe, "type", pt.typeParams, args, tree.pos)
}
case _ =>
errorType(i"${err.exprStr(fn)} does not take type parameters", tree.pos)
@@ -451,7 +451,7 @@ trait TypeAssigner {
val ownType =
if (hasNamedArg(args)) (tycon.tpe /: args)(refineNamed)
else if (sameLength(tparams, args)) tycon.tpe.appliedTo(args.tpes)
- else wrongNumberOfArgs(tycon.tpe, "type ", tparams.length, tree.pos)
+ else wrongNumberOfArgs(tycon.tpe, "type", tparams, args, tree.pos)
tree.withType(ownType)
}
diff --git a/src/dotty/tools/dotc/typer/Typer.scala b/src/dotty/tools/dotc/typer/Typer.scala
index 6fb0dd7c7..56c04c063 100644
--- a/src/dotty/tools/dotc/typer/Typer.scala
+++ b/src/dotty/tools/dotc/typer/Typer.scala
@@ -1035,7 +1035,7 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
if (hasNamedArg(args)) typedNamedArgs(args)
else {
if (args.length != tparams.length) {
- wrongNumberOfArgs(tpt1.tpe, "type ", tparams.length, tree.pos)
+ wrongNumberOfArgs(tpt1.tpe, "type", tparams, args, tree.pos)
args = args.take(tparams.length)
}
def typedArg(arg: untpd.Tree, tparam: TypeParamInfo) = {