From 0803aff2b464cf3f69e1217891182c6e89efb6d2 Mon Sep 17 00:00:00 2001 From: Uko Date: Wed, 26 Feb 2020 15:21:34 +0100 Subject: [PATCH] Fix #8362: Fail compilation if a compile time error can't be inlined because of a non-literal string parameter --- .../src/dotty/tools/dotc/typer/Inliner.scala | 25 +++++++++---------- tests/neg/i8362.scala | 5 ++++ 2 files changed, 17 insertions(+), 13 deletions(-) create mode 100644 tests/neg/i8362.scala diff --git a/compiler/src/dotty/tools/dotc/typer/Inliner.scala b/compiler/src/dotty/tools/dotc/typer/Inliner.scala index d1c65000726c..45e33741172f 100644 --- a/compiler/src/dotty/tools/dotc/typer/Inliner.scala +++ b/compiler/src/dotty/tools/dotc/typer/Inliner.scala @@ -559,19 +559,19 @@ class Inliner(call: tpd.Tree, rhsToInline: tpd.Tree)(implicit ctx: Context) { def issueError() = callValueArgss match { case (msgArg :: Nil) :: Nil => - msgArg.tpe match { - case ConstantType(Constant(msg: String)) => - // Usually `error` is called from within a rewrite method. In this - // case we need to report the error at the point of the outermost enclosing inline - // call. This way, a defensively written rewrite methid can always - // report bad inputs at the point of call instead of revealing its internals. - val callToReport = if (enclosingInlineds.nonEmpty) enclosingInlineds.last else call - val ctxToReport = ctx.outersIterator.dropWhile(enclosingInlineds(_).nonEmpty).next - def issueInCtx(implicit ctx: Context) = - ctx.error(msg, callToReport.sourcePos) - issueInCtx(ctxToReport) - case _ => + val message = msgArg.tpe match { + case ConstantType(Constant(msg: String)) => msg + case _ => s"A literal string is expected as an argument to `compiletime.error`. Got ${msgArg.show}" } + // Usually `error` is called from within a rewrite method. In this + // case we need to report the error at the point of the outermost enclosing inline + // call. This way, a defensively written rewrite methid can always + // report bad inputs at the point of call instead of revealing its internals. + val callToReport = if (enclosingInlineds.nonEmpty) enclosingInlineds.last else call + val ctxToReport = ctx.outersIterator.dropWhile(enclosingInlineds(_).nonEmpty).next + def issueInCtx(implicit ctx: Context) = + ctx.error(message, callToReport.sourcePos) + issueInCtx(ctxToReport) case _ => } @@ -1316,4 +1316,3 @@ class Inliner(call: tpd.Tree, rhsToInline: tpd.Tree)(implicit ctx: Context) { } }.apply(Nil, tree) } - diff --git a/tests/neg/i8362.scala b/tests/neg/i8362.scala new file mode 100644 index 000000000000..c1b498fbbb9a --- /dev/null +++ b/tests/neg/i8362.scala @@ -0,0 +1,5 @@ +object Test { + inline def foo: String = scala.compiletime.error(s"") + + def main(args: Array[String]): Unit = println(foo) // error +}