diff --git a/compiler/src/dotty/tools/dotc/reporting/MessageRendering.scala b/compiler/src/dotty/tools/dotc/reporting/MessageRendering.scala index 44006634dda5..43475053e983 100644 --- a/compiler/src/dotty/tools/dotc/reporting/MessageRendering.scala +++ b/compiler/src/dotty/tools/dotc/reporting/MessageRendering.scala @@ -43,6 +43,7 @@ trait MessageRendering { * @return (lines before error, lines after error, line numbers offset) */ def sourceLines(pos: SourcePosition, diagnosticLevel: String)(implicit ctx: Context): (List[String], List[String], Int) = { + assert(pos.exists && pos.source.file.exists) var maxLen = Int.MinValue def render(offsetAndLine: (Int, String)): String = { val (offset, line) = offsetAndLine @@ -113,7 +114,9 @@ trait MessageRendering { */ def posStr(pos: SourcePosition, diagnosticLevel: String, message: Message)(implicit ctx: Context): String = if (pos.exists) hl(diagnosticLevel)({ - val file = s"${pos.source.file.toString}:${pos.line + 1}:${pos.column}" + val file = + if (pos.source.file.exists) s"${pos.source.file.toString}:${pos.line + 1}:${pos.column}" + else s"${pos.source.file.toString}: offset ${pos.start} (missing source file)" val errId = if (message.errorId ne ErrorMessageID.NoExplanationID) { val errorNumber = message.errorId.errorNumber() @@ -145,7 +148,7 @@ trait MessageRendering { val sb = mutable.StringBuilder.newBuilder val posString = posStr(pos, diagnosticLevel, msg) if (posString.nonEmpty) sb.append(posString).append(EOL) - if (pos.exists) { + if (pos.exists && pos.source.file.exists) { val (srcBefore, srcAfter, offset) = sourceLines(pos, diagnosticLevel) val marker = columnMarker(pos, offset, diagnosticLevel) val err = errorMsg(pos, msg.msg, offset) diff --git a/project/scripts/cmdTests b/project/scripts/cmdTests index 1704fe749d14..93384739a345 100755 --- a/project/scripts/cmdTests +++ b/project/scripts/cmdTests @@ -32,6 +32,18 @@ clear_out "$OUT" "$SBT" ";dotc -d $OUT/out.jar $SOURCE; dotc -decompile -classpath $OUT/out.jar -color:never $MAIN" > "$tmp" grep -qe "def main(args: scala.Array\[scala.Predef.String\]): scala.Unit =" "$tmp" +# check that missing source file does not crash message rendering +echo "testing that missing source file does not crash message rendering" +clear_out "$OUT" +clear_out "$OUT1" +cp tests/neg/i6371/A_1.scala $OUT/A.scala +cp tests/neg/i6371/B_2.scala $OUT/B.scala +"$SBT" "dotc $OUT/A.scala -d $OUT1" +rm $OUT/A.scala +"$SBT" "dotc -classpath $OUT1 -d $OUT1 $OUT/B.scala" > "$tmp" 2>&1 || echo "ok" +grep -qe "A.scala: offset 63 (missing source file)" "$tmp" + + ## Disabled because of flakeyness, should be changed to not depend on sbt # echo "running Vulpix meta test" # tmp=$(mktemp) diff --git a/tests/neg/i6371/A_1.scala b/tests/neg/i6371/A_1.scala new file mode 100644 index 000000000000..9c7553af54ff --- /dev/null +++ b/tests/neg/i6371/A_1.scala @@ -0,0 +1,6 @@ +object A { + inline def foo(a: Any): Unit = a match { + case _: Int => // error + case _ => + } +} diff --git a/tests/neg/i6371/B_2.scala b/tests/neg/i6371/B_2.scala new file mode 100644 index 000000000000..fcc88d22da42 --- /dev/null +++ b/tests/neg/i6371/B_2.scala @@ -0,0 +1,3 @@ +object B { + A.foo("aa") +}