Skip to content

Commit 04021ca

Browse files
committed
Use adjusted pos when rendering diagnostic
The previous code was unclear about what pos to adjust. The diagnostic pos yields an innermost "user pos" which is adjusted at EOF. The inline stack is already filtered by position for rendering.
1 parent bafdaff commit 04021ca

File tree

2 files changed

+41
-45
lines changed

2 files changed

+41
-45
lines changed

compiler/src/dotty/tools/dotc/reporting/MessageRendering.scala

Lines changed: 38 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -250,16 +250,8 @@ trait MessageRendering {
250250
* usually we intend to test `contains` or `coincidesWith`.
251251
*
252252
*/
253-
def messageAndPos(dia: Diagnostic)(using Context): String = {
254-
import dia.*
255-
val pos1 = pos.nonInlined
256-
val inlineStack = pos.inlinePosStack.filterNot(_.contains(pos1))
257-
val maxLineNumber =
258-
if pos.exists then (pos1 :: inlineStack).map(_.endLine).max + 1
259-
else 0
260-
given Level = Level(level)
261-
given Offset = Offset(maxLineNumber.toString.length + 2)
262-
val sb = StringBuilder()
253+
def messageAndPos(dia: Diagnostic)(using Context): String =
254+
// adjust a pos at EOF if preceded by newline
263255
def adjust(pos: SourcePosition): SourcePosition =
264256
if pos.span.isSynthetic
265257
&& pos.span.isZeroExtent
@@ -270,53 +262,57 @@ trait MessageRendering {
270262
pos.withSpan(pos.span.shift(-1))
271263
else
272264
pos
273-
val adjusted = adjust(pos)
274-
val posString = posStr(adjusted, msg, diagnosticLevel(dia))
275-
if (posString.nonEmpty) sb.append(posString).append(EOL)
276-
if (pos.exists) {
277-
if (pos1.exists && pos1.source.file.exists) {
278-
val readjusted =
279-
if pos1 == pos then adjusted
280-
else adjust(pos1)
281-
val (srcBefore, srcAfter, offset) = sourceLines(readjusted)
282-
val marker = positionMarker(readjusted)
283-
val err = errorMsg(readjusted, msg.message)
284-
sb.append((srcBefore ::: marker :: err :: srcAfter).mkString(EOL))
285-
286-
if inlineStack.nonEmpty then
287-
sb.append(EOL).append(newBox())
288-
sb.append(EOL).append(offsetBox).append(i"Inline stack trace")
289-
for inlinedPos <- inlineStack if inlinedPos != pos1 do
290-
sb.append(EOL).append(newBox(soft = true))
291-
sb.append(EOL).append(offsetBox).append(i"This location contains code that was inlined from $pos")
292-
if inlinedPos.source.file.exists then
293-
val (srcBefore, srcAfter, _) = sourceLines(inlinedPos)
294-
val marker = positionMarker(inlinedPos)
295-
sb.append(EOL).append((srcBefore ::: marker :: srcAfter).mkString(EOL))
296-
sb.append(EOL).append(endBox)
297-
}
298-
else sb.append(msg.message)
299-
}
265+
val msg = dia.msg
266+
val pos = dia.pos
267+
val pos1 = adjust(pos.nonInlined) // innermost pos contained by call.pos
268+
val outermost = pos.outermost // call.pos
269+
val inlineStack = pos.inlinePosStack.filterNot(outermost.contains(_))
270+
given Level = Level(dia.level)
271+
given Offset =
272+
val maxLineNumber =
273+
if pos.exists then (pos1 :: inlineStack).map(_.endLine).max + 1
274+
else 0
275+
Offset(maxLineNumber.toString.length + 2)
276+
val sb = StringBuilder()
277+
val posString = posStr(pos1, msg, diagnosticLevel(dia))
278+
if posString.nonEmpty then sb.append(posString).append(EOL)
279+
if pos.exists && pos1.exists && pos1.source.file.exists then
280+
val (srcBefore, srcAfter, offset) = sourceLines(pos1)
281+
val marker = positionMarker(pos1)
282+
val err = errorMsg(pos1, msg.message)
283+
sb.append((srcBefore ::: marker :: err :: srcAfter).mkString(EOL))
284+
285+
if inlineStack.nonEmpty then
286+
sb.append(EOL).append(newBox())
287+
sb.append(EOL).append(offsetBox).append(i"Inline stack trace")
288+
for inlinedPos <- inlineStack do
289+
sb.append(EOL).append(newBox(soft = true))
290+
sb.append(EOL).append(offsetBox).append(i"This location contains code that was inlined from $pos")
291+
if inlinedPos.source.file.exists then
292+
val (srcBefore, srcAfter, _) = sourceLines(inlinedPos)
293+
val marker = positionMarker(inlinedPos)
294+
sb.append(EOL).append((srcBefore ::: marker :: srcAfter).mkString(EOL))
295+
sb.append(EOL).append(endBox)
296+
end if
300297
else sb.append(msg.message)
301-
if (dia.isVerbose)
298+
if dia.isVerbose then
302299
appendFilterHelp(dia, sb)
303300

304301
if Diagnostic.shouldExplain(dia) then
305302
sb.append(EOL).append(newBox())
306303
sb.append(EOL).append(offsetBox).append(" Explanation (enabled by `-explain`)")
307304
sb.append(EOL).append(newBox(soft = true))
308-
dia.msg.explanation.split(raw"\R").foreach { line =>
305+
dia.msg.explanation.split(raw"\R").foreach: line =>
309306
sb.append(EOL).append(offsetBox).append(if line.isEmpty then "" else " ").append(line)
310-
}
311307
sb.append(EOL).append(endBox)
312308
else if dia.msg.canExplain then
313309
sb.append(EOL).append(offsetBox)
314310
sb.append(EOL).append(offsetBox).append(" longer explanation available when compiling with `-explain`")
315311

316312
sb.toString
317-
}
313+
end messageAndPos
318314

319-
private def hl(str: String)(using Context, Level): String =
315+
private def hl(str: String)(using Context, Level): String =
320316
summon[Level].value match
321317
case interfaces.Diagnostic.ERROR => Red(str).show
322318
case interfaces.Diagnostic.WARNING => Yellow(str).show

tests/neg/i23815.check

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,6 @@
44
| ':' or '{' expected, but 'end of statement' found
55
| Nested package statements that are not at the beginning of the file require braces or ':' with an indented body.
66
-- [E040] Syntax Error: tests/neg/i23815.scala:9:8 ---------------------------------------------------------------------
7-
9 |// error
8-
| ^
9-
| '}' expected, but eof found
7+
9 |// error
8+
| ^
9+
| '}' expected, but eof found

0 commit comments

Comments
 (0)