diff options
Diffstat (limited to 'src/dotty/tools/dotc/typer/ErrorReporting.scala')
-rw-r--r-- | src/dotty/tools/dotc/typer/ErrorReporting.scala | 59 |
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 |