diff options
author | Martin Odersky <odersky@gmail.com> | 2016-04-22 11:55:36 +0200 |
---|---|---|
committer | Martin Odersky <odersky@gmail.com> | 2016-04-22 12:06:31 +0200 |
commit | 89f9091c2d10aa23c5d6259694df104fc14c60f7 (patch) | |
tree | b78bab097099c5b4fa8a62fe422419227a4adf07 /src | |
parent | 320ca51f0226cf61dfa6d882d30de15ab221f07b (diff) | |
download | dotty-89f9091c2d10aa23c5d6259694df104fc14c60f7.tar.gz dotty-89f9091c2d10aa23c5d6259694df104fc14c60f7.tar.bz2 dotty-89f9091c2d10aa23c5d6259694df104fc14c60f7.zip |
Support implicitNotFound annotation
Diffstat (limited to 'src')
-rw-r--r-- | src/dotty/tools/dotc/core/Definitions.scala | 2 | ||||
-rw-r--r-- | src/dotty/tools/dotc/typer/ErrorReporting.scala | 12 | ||||
-rw-r--r-- | src/dotty/tools/dotc/typer/Typer.scala | 11 |
3 files changed, 24 insertions, 1 deletions
diff --git a/src/dotty/tools/dotc/core/Definitions.scala b/src/dotty/tools/dotc/core/Definitions.scala index 5376ed591..9128bd3a5 100644 --- a/src/dotty/tools/dotc/core/Definitions.scala +++ b/src/dotty/tools/dotc/core/Definitions.scala @@ -449,6 +449,8 @@ class Definitions { def ContravariantBetweenAnnot(implicit ctx: Context) = ContravariantBetweenAnnotType.symbol.asClass lazy val DeprecatedAnnotType = ctx.requiredClassRef("scala.deprecated") def DeprecatedAnnot(implicit ctx: Context) = DeprecatedAnnotType.symbol.asClass + lazy val ImplicitNotFoundAnnotType = ctx.requiredClassRef("scala.annotation.implicitNotFound") + def ImplicitNotFoundAnnot(implicit ctx: Context) = ImplicitNotFoundAnnotType.symbol.asClass lazy val InvariantBetweenAnnotType = ctx.requiredClassRef("dotty.annotation.internal.InvariantBetween") def InvariantBetweenAnnot(implicit ctx: Context) = InvariantBetweenAnnotType.symbol.asClass lazy val MigrationAnnotType = ctx.requiredClassRef("scala.annotation.migration") diff --git a/src/dotty/tools/dotc/typer/ErrorReporting.scala b/src/dotty/tools/dotc/typer/ErrorReporting.scala index d6a87acf6..69c12e5f5 100644 --- a/src/dotty/tools/dotc/typer/ErrorReporting.scala +++ b/src/dotty/tools/dotc/typer/ErrorReporting.scala @@ -116,6 +116,18 @@ object ErrorReporting { | found : $found | required: $expected""".stripMargin + whyNoMatchStr(found, expected) } + + /** Format `raw` implicitNotFound argument, replacing all + * occurrences of `${X}` where `X` is in `paramNames` with the + * corresponding shown type in `args`. + */ + def implicitNotFoundString(raw: String, paramNames: List[String], args: List[Type]): String = { + def translate(name: String): Option[String] = { + val idx = paramNames.indexOf(name) + if (idx >= 0) Some(args(idx).show) else None + } + """\$\{\w*\}""".r.replaceSomeIn(raw, m => translate(m.matched.drop(2).init)) + } } def err(implicit ctx: Context): Errors = new Errors diff --git a/src/dotty/tools/dotc/typer/Typer.scala b/src/dotty/tools/dotc/typer/Typer.scala index b95acc7ca..f263d3093 100644 --- a/src/dotty/tools/dotc/typer/Typer.scala +++ b/src/dotty/tools/dotc/typer/Typer.scala @@ -1541,7 +1541,16 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit case failure: SearchFailure => val arg = synthesizedClassTag(formal) if (!arg.isEmpty) arg - else implicitArgError(d"no implicit argument of type $formal found for $where" + failure.postscript) + else { + var msg = d"no implicit argument of type $formal found for $where" + failure.postscript + for (notFound <- formal.typeSymbol.getAnnotation(defn.ImplicitNotFoundAnnot); + Literal(Constant(raw: String)) <- notFound.argument(0)) + msg = err.implicitNotFoundString( + raw, + formal.typeSymbol.typeParams.map(_.name.unexpandedName.toString), + formal.argInfos) + implicitArgError(msg) + } } } if (errors.nonEmpty) { |