From aaae563d6de83e5f60ef763d384d1b4f76f9c1dd Mon Sep 17 00:00:00 2001 From: Shane Delmore Date: Tue, 25 Oct 2016 13:35:46 -0700 Subject: Improve error message formatting --- .../tools/dotc/reporting/diagnostic/messages.scala | 66 +++++++++++++--------- 1 file changed, 39 insertions(+), 27 deletions(-) (limited to 'src') diff --git a/src/dotty/tools/dotc/reporting/diagnostic/messages.scala b/src/dotty/tools/dotc/reporting/diagnostic/messages.scala index 7e897f081..2913f4f4c 100644 --- a/src/dotty/tools/dotc/reporting/diagnostic/messages.scala +++ b/src/dotty/tools/dotc/reporting/diagnostic/messages.scala @@ -4,7 +4,7 @@ package reporting package diagnostic import dotc.core._ -import Contexts.Context, Decorators._, Symbols._, Names._, Types._ +import Contexts.Context, Decorators._, Symbols._, Names._, NameOps._, Types._ import ast.untpd.{Modifiers, ModuleDef} import util.{SourceFile, NoSource} import util.{SourcePosition, NoSourcePosition} @@ -607,63 +607,75 @@ object messages { |""".stripMargin } case class WrongNumberOfArgs(fntpe: Type, argKind: String, expectedArgs: List[TypeParamInfo], actual: List[untpd.Tree])(implicit ctx: Context) - extends Message(18) { + extends Message(22) { 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("[", ", ", "]") + //TODO add def simpleParamName to TypeParamInfo + val expectedArgString = fntpe.widen.typeParams.map(_.paramName.unexpandedName.show).mkString("[", ", ", "]") - val actualArgString = actual.map(_.show.split("\\.").last).mkString("[", ", ", "]") + val actualArgString = actual.map(_.show).mkString("[", ", ", "]") + + val prettyName = fntpe.termSymbol match { + case NoSymbol => fntpe.show + case symbol => symbol.showFullName + } val msg = - hl"""|$msgPrefix ${argKind} arguments for $fntpe + hl"""|${NoColor(msgPrefix)} ${argKind} arguments for $prettyName$expectedArgString |expected: $expectedArgString |actual: $actualArgString""".stripMargin val explanation = { + val tooManyTypeParams = + """|val tuple2: (Int, String) = (1, "one") + |val list: List[(Int, String)] = List(tuple2)""".stripMargin + 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 + |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: + | + |${tooManyTypeParams}""".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 + |If you specify one type parameter then you need to specify every type parameter.""".stripMargin } } case class IllegalVariableInPatternAlternative()(implicit ctx: Context) - extends Message(19) { + extends Message(23) { val kind = "Syntax" val msg = hl"""|Variables are not allowed in alternative patterns""" val explanation = { + val varInAlternative = + """|def g(pair: (Int,Int)): Int = pair match { + | case (1, n) | (n, 1) => n + | case _ => 0 + |}""".stripMargin + + val fixedVarInAlternative = + """|def g(pair: (Int,Int)): Int = pair match { + | case (1, n) => n + | case (n, 1) => n + | case _ => 0 + |}""".stripMargin + hl"""|Variables are not allowed within alternate pattern matches. |You can workaround this issue by adding additional cases for each alternative. |For example, the illegal function: - | def g(pair: (Int,Int)): Int = pair match { - | case (1, n) | (n, 1) => n - | case _ => 0 - | } - | - | could be implemented by moving each alternative into a separate case: - | def g(pair: (Int,Int)): Int = pair match { - | case (1, n) => n - | case (n, 1) => n - | case _ => 0 - | } | - |""".stripMargin + |$varInAlternative + |could be implemented by moving each alternative into a separate case: + | + |$fixedVarInAlternative""".stripMargin } } } -- cgit v1.2.3