aboutsummaryrefslogtreecommitdiff
path: root/src/dotty/tools/dotc/typer/ErrorReporting.scala
diff options
context:
space:
mode:
Diffstat (limited to 'src/dotty/tools/dotc/typer/ErrorReporting.scala')
-rw-r--r--src/dotty/tools/dotc/typer/ErrorReporting.scala59
1 files changed, 47 insertions, 12 deletions
diff --git a/src/dotty/tools/dotc/typer/ErrorReporting.scala b/src/dotty/tools/dotc/typer/ErrorReporting.scala
index 7a91adde6..bf2d19e85 100644
--- a/src/dotty/tools/dotc/typer/ErrorReporting.scala
+++ b/src/dotty/tools/dotc/typer/ErrorReporting.scala
@@ -5,9 +5,11 @@ package typer
import ast._
import core._
import Trees._
-import Types._, Contexts._, Decorators._, Denotations._
+import Types._, Contexts._, Decorators._, Denotations._, Symbols._
import Applications._
import util.Positions._
+import printing.Showable
+import reporting.Reporter.SuppressedMessage
object ErrorReporting {
@@ -27,11 +29,11 @@ object ErrorReporting {
case tp: FunProtoType =>
val result = tp.resultType match {
case tp: WildcardType => ""
- case tp => s"and expected result type $tp"
+ case tp => i"and expected result type $tp"
}
- s"arguments (${tp.typedArgs map (_.tpe.show) mkString ", "})$result"
+ i"arguments (${tp.typedArgs.tpes}%, %)$result"
case _ =>
- s"expected type ${tp.show}"
+ i"expected type $tp"
}
def anonymousTypeMemberStr(tpe: Type) = {
@@ -40,12 +42,12 @@ object ErrorReporting {
case _: PolyType | _: MethodType => "method"
case _ => "value of type"
}
- s"$kind $tpe"
+ i"$kind $tpe"
}
def overloadedAltsStr(alts: List[SingleDenotation]) =
- s"overloaded alternatives of ${denotStr(alts.head)} with types\n" +
- s" ${alts map (_.info) mkString "\n "}"
+ i"overloaded alternatives of ${denotStr(alts.head)} with types\n" +
+ i" ${alts map (_.info)}%\n %"
def denotStr(denot: Denotation): String =
if (denot.isOverloaded) overloadedAltsStr(denot.alternatives)
@@ -61,13 +63,46 @@ object ErrorReporting {
def patternConstrStr(tree: Tree): String = ???
- def typeMismatch(tree: Tree, pt: Type): Tree =
- errorTree(tree,
- s"""type mismatch:
- | found : ${tree.tpe.show}
- | required: ${pt.show}""".stripMargin)
+ def typeMismatch(tree: Tree, pt: Type): Tree = {
+ val result = errorTree(tree,
+ i"""type mismatch:
+ | found : ${tree.tpe}
+ | required: $pt""".stripMargin)
+ if (ctx.settings.explaintypes.value)
+ new ExplainingTypeComparer().isSubType(tree.tpe, pt)
+ result
+ }
}
def err(implicit ctx: Context): Errors = new Errors
+
+ def isSensical(arg: Any)(implicit ctx: Context): Boolean = arg match {
+ case tpe: Type if tpe.isErroneous => false
+ case NoSymbol => false
+ case _ => true
+ }
+
+ def treatArg(arg: Any, suffix: String)(implicit ctx: Context): (Any, String) = arg match {
+ case arg: Showable =>
+ (arg.show, suffix)
+ case arg: List[_] if suffix.head == '%' =>
+ val (sep, rest) = suffix.tail.span(_ != '%')
+ if (rest.nonEmpty) (arg mkString sep, rest.tail)
+ else (arg, suffix)
+ case _ =>
+ (arg, suffix)
+ }
+
+ /** Implementation of i"..." string interpolator */
+ implicit class InfoString(val sc: StringContext) extends AnyVal {
+
+ def i(args: Any*)(implicit ctx: Context): String = {
+ if (ctx.reporter.hasErrors && ctx.suppressNonSensicalErrors && !args.forall(isSensical(_)))
+ throw new SuppressedMessage
+ val prefix :: suffixes = sc.parts.toList
+ val (args1, suffixes1) = (args, suffixes).zipped.map(treatArg(_, _)).unzip
+ new StringContext(prefix :: suffixes1.toList: _*).s(args1: _*)
+ }
+ }
} \ No newline at end of file