Skip to content

Commit 2d83885

Browse files
committed
Report rewrite errors at outermost rewrite call
1 parent e41bf9a commit 2d83885

File tree

1 file changed

+9
-2
lines changed

1 file changed

+9
-2
lines changed

compiler/src/dotty/tools/dotc/typer/Inliner.scala

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -362,7 +362,7 @@ class Inliner(call: tpd.Tree, rhsToInline: tpd.Tree)(implicit ctx: Context) {
362362
if (inlinedMethod == defn.Typelevel_constValue) {
363363
val constVal = tryConstValue
364364
if (!constVal.isEmpty) return constVal
365-
ctx.error(i"not a constant type: ${callTypeArgs.head}; cannot take constValue")
365+
ctx.error(i"not a constant type: ${callTypeArgs.head}; cannot take constValue", call.pos)
366366
}
367367
else if (inlinedMethod == defn.Typelevel_constValueOpt) {
368368
val constVal = tryConstValue
@@ -450,7 +450,14 @@ class Inliner(call: tpd.Tree, rhsToInline: tpd.Tree)(implicit ctx: Context) {
450450
case (msgArg :: Nil) :: Nil =>
451451
msgArg.tpe match {
452452
case ConstantType(Constant(msg: String)) =>
453-
ctx.error(msg, call.pos)
453+
// Usually `error` is called from within a rewrite method. In this
454+
// case we need to report the error at the point of the outermost enclosing inline
455+
// call. This way, a defensively written rewrite methid can always
456+
// report bad inputs at the point of call instead of revealing its internals.
457+
val callToReport = if (enclosingInlineds.nonEmpty) enclosingInlineds.last else call
458+
val ctxToReport = ctx.outersIterator.dropWhile(enclosingInlineds(_).nonEmpty).next
459+
def issueInCtx(implicit ctx: Context) = ctx.error(msg, callToReport.pos)
460+
issueInCtx(ctxToReport)
454461
case _ =>
455462
}
456463
case _ =>

0 commit comments

Comments
 (0)