Skip to content

Commit 8e2fab7

Browse files
authored
Merge pull request #14417 from dotty-staging/revert-i14002
Revert "Show inlined positions with source code"
2 parents 4c7ec9b + 4bcd23b commit 8e2fab7

28 files changed

+111
-422
lines changed

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

Lines changed: 48 additions & 135 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,6 @@ import scala.annotation.switch
1616
import scala.collection.mutable
1717

1818
trait MessageRendering {
19-
import Highlight.*
20-
import Offsets.*
2119

2220
/** Remove ANSI coloring from `str`, useful for getting real length of
2321
* strings
@@ -27,25 +25,31 @@ trait MessageRendering {
2725
def stripColor(str: String): String =
2826
str.replaceAll("\u001b\\[.*?m", "")
2927

30-
/** List of all the inline calls that surround the position */
31-
def inlinePosStack(pos: SourcePosition): List[SourcePosition] =
32-
if pos.outer != null && pos.outer.exists then pos :: inlinePosStack(pos.outer)
28+
/** When inlining a method call, if there's an error we'd like to get the
29+
* outer context and the `pos` at which the call was inlined.
30+
*
31+
* @return a list of strings with inline locations
32+
*/
33+
def outer(pos: SourcePosition, prefix: String)(using Context): List[String] =
34+
if (pos.outer.exists)
35+
i"$prefix| This location contains code that was inlined from $pos" ::
36+
outer(pos.outer, prefix)
3337
else Nil
3438

3539
/** Get the sourcelines before and after the position, as well as the offset
3640
* for rendering line numbers
3741
*
3842
* @return (lines before error, lines after error, line numbers offset)
3943
*/
40-
private def sourceLines(pos: SourcePosition)(using Context, Level, Offset): (List[String], List[String], Int) = {
44+
def sourceLines(pos: SourcePosition, diagnosticLevel: String)(using Context): (List[String], List[String], Int) = {
4145
assert(pos.exists && pos.source.file.exists)
4246
var maxLen = Int.MinValue
4347
def render(offsetAndLine: (Int, String)): String = {
44-
val (offset1, line) = offsetAndLine
45-
val lineNbr = (pos.source.offsetToLine(offset1) + 1).toString
46-
val prefix = String.format(s"%${offset - 2}s |", lineNbr)
48+
val (offset, line) = offsetAndLine
49+
val lineNbr = pos.source.offsetToLine(offset)
50+
val prefix = s"${lineNbr + 1} |"
4751
maxLen = math.max(maxLen, prefix.length)
48-
val lnum = hl(" " * math.max(0, maxLen - prefix.length - 1) + prefix)
52+
val lnum = hl(diagnosticLevel)(" " * math.max(0, maxLen - prefix.length) + prefix)
4953
lnum + line.stripLineEnd
5054
}
5155

@@ -73,75 +77,23 @@ trait MessageRendering {
7377
)
7478
}
7579

76-
/** Generate box containing the report title
77-
*
78-
* ```
79-
* -- Error: source.scala ---------------------
80-
* ```
81-
*/
82-
private def boxTitle(title: String)(using Context, Level, Offset): String =
83-
val pageWidth = ctx.settings.pageWidth.value
84-
val line = "-" * (pageWidth - title.length - 4)
85-
hl(s"-- $title $line")
86-
87-
/** The position markers aligned under the error
88-
*
89-
* ```
90-
* | ^^^^^
91-
* ```
92-
*/
93-
private def positionMarker(pos: SourcePosition)(using Context, Level, Offset): String = {
80+
/** The column markers aligned under the error */
81+
def columnMarker(pos: SourcePosition, offset: Int, diagnosticLevel: String)(using Context): String = {
82+
val prefix = " " * (offset - 1)
9483
val padding = pos.startColumnPadding
95-
val carets =
84+
val carets = hl(diagnosticLevel) {
9685
if (pos.startLine == pos.endLine)
9786
"^" * math.max(1, pos.endColumn - pos.startColumn)
9887
else "^"
99-
hl(s"$offsetBox$padding$carets")
88+
}
89+
s"$prefix|$padding$carets"
10090
}
10191

102-
/** The horizontal line with the given offset
103-
*
104-
* ```
105-
* |
106-
* ```
107-
*/
108-
private def offsetBox(using Context, Level, Offset): String =
109-
val prefix = " " * (offset - 1)
110-
hl(s"$prefix|")
111-
112-
/** The end of a box section
113-
*
114-
* ```
115-
* |---------------
116-
* ```
117-
* Or if there `soft` is true,
118-
* ```
119-
* |···············
120-
* ```
121-
*/
122-
private def newBox(soft: Boolean = false)(using Context, Level, Offset): String =
123-
val pageWidth = ctx.settings.pageWidth.value
124-
val prefix = " " * (offset - 1)
125-
val line = (if soft then "·" else "-") * (pageWidth - offset)
126-
hl(s"$prefix|$line")
127-
128-
/** The end of a box section
129-
*
130-
* ```
131-
* ·----------------
132-
* ```
133-
*/
134-
private def endBox(using Context, Level, Offset): String =
135-
val pageWidth = ctx.settings.pageWidth.value
136-
val prefix = " " * (offset - 1)
137-
val line = "-" * (pageWidth - offset)
138-
hl(s"${prefix}·$line")
139-
14092
/** The error message (`msg`) aligned under `pos`
14193
*
14294
* @return aligned error message
14395
*/
144-
private def errorMsg(pos: SourcePosition, msg: String)(using Context, Level, Offset): String = {
96+
def errorMsg(pos: SourcePosition, msg: String, offset: Int)(using Context): String = {
14597
val padding = msg.linesIterator.foldLeft(pos.startColumnPadding) { (pad, line) =>
14698
val lineLength = stripColor(line).length
14799
val maxPad = math.max(0, ctx.settings.pageWidth.value - offset - lineLength) - offset
@@ -151,35 +103,35 @@ trait MessageRendering {
151103
}
152104

153105
msg.linesIterator
154-
.map { line => offsetBox + (if line.isEmpty then "" else padding + line) }
106+
.map { line => " " * (offset - 1) + "|" + (if line.isEmpty then "" else padding + line) }
155107
.mkString(EOL)
156108
}
157109

158110
/** The source file path, line and column numbers from the given SourcePosition */
159-
protected def posFileStr(pos: SourcePosition): String =
111+
def posFileStr(pos: SourcePosition): String =
160112
val path = pos.source.file.path
161113
if pos.exists then s"$path:${pos.line + 1}:${pos.column}" else path
162114

163115
/** The separator between errors containing the source file and error type
164116
*
165117
* @return separator containing error location and kind
166118
*/
167-
private def posStr(pos: SourcePosition, message: Message, diagnosticString: String)(using Context, Level, Offset): String =
168-
if (pos.source != NoSourcePosition.source) hl({
169-
val realPos = pos.nonInlined
170-
val fileAndPos = posFileStr(realPos)
119+
def posStr(pos: SourcePosition, diagnosticLevel: String, message: Message)(using Context): String =
120+
if (pos.source != NoSourcePosition.source) hl(diagnosticLevel)({
121+
val fileAndPos = posFileStr(pos.nonInlined)
122+
val file = if fileAndPos.isEmpty || fileAndPos.endsWith(" ") then fileAndPos else s"$fileAndPos "
171123
val errId =
172124
if (message.errorId ne ErrorMessageID.NoExplanationID) {
173125
val errorNumber = message.errorId.errorNumber
174126
s"[E${"0" * (3 - errorNumber.toString.length) + errorNumber}] "
175127
} else ""
176128
val kind =
177-
if (message.kind == "") diagnosticString
178-
else s"${message.kind} $diagnosticString"
179-
val title =
180-
if fileAndPos.isEmpty then s"$errId$kind:" // this happens in dotty.tools.repl.ScriptedTests // TODO add name of source or remove `:` (and update test files)
181-
else s"$errId$kind: $fileAndPos"
182-
boxTitle(title)
129+
if (message.kind == "") diagnosticLevel
130+
else s"${message.kind} $diagnosticLevel"
131+
val prefix = s"-- ${errId}${kind}: $file"
132+
133+
prefix +
134+
("-" * math.max(ctx.settings.pageWidth.value - stripColor(prefix).length, 0))
183135
}) else ""
184136

185137
/** Explanation rendered under "Explanation" header */
@@ -194,7 +146,7 @@ trait MessageRendering {
194146
sb.toString
195147
}
196148

197-
private def appendFilterHelp(dia: Diagnostic, sb: mutable.StringBuilder): Unit =
149+
def appendFilterHelp(dia: Diagnostic, sb: mutable.StringBuilder): Unit =
198150
import dia._
199151
val hasId = msg.errorId.errorNumber >= 0
200152
val category = dia match {
@@ -214,34 +166,17 @@ trait MessageRendering {
214166
/** The whole message rendered from `msg` */
215167
def messageAndPos(dia: Diagnostic)(using Context): String = {
216168
import dia._
217-
val pos1 = pos.nonInlined
218-
val inlineStack = inlinePosStack(pos).filter(_ != pos1)
219-
val maxLineNumber =
220-
if pos.exists then (pos1 :: inlineStack).map(_.endLine).max + 1
221-
else 0
222-
given Level = Level(level)
223-
given Offset = Offset(maxLineNumber.toString.length + 2)
169+
val levelString = diagnosticLevel(dia)
224170
val sb = mutable.StringBuilder()
225-
val posString = posStr(pos, msg, diagnosticLevel(dia))
171+
val posString = posStr(pos, levelString, msg)
226172
if (posString.nonEmpty) sb.append(posString).append(EOL)
227173
if (pos.exists) {
228174
val pos1 = pos.nonInlined
229175
if (pos1.exists && pos1.source.file.exists) {
230-
val (srcBefore, srcAfter, offset) = sourceLines(pos1)
231-
val marker = positionMarker(pos1)
232-
val err = errorMsg(pos1, msg.message)
233-
sb.append((srcBefore ::: marker :: err :: srcAfter).mkString(EOL))
234-
235-
if inlineStack.nonEmpty then
236-
sb.append(EOL).append(newBox())
237-
sb.append(EOL).append(offsetBox).append(i"Inline stack trace")
238-
for inlinedPos <- inlineStack if inlinedPos != pos1 do
239-
val (srcBefore, srcAfter, offset) = sourceLines(inlinedPos)
240-
val marker = positionMarker(inlinedPos)
241-
sb.append(EOL).append(newBox(soft = true))
242-
sb.append(EOL).append(offsetBox).append(i"This location contains code that was inlined from $pos")
243-
sb.append(EOL).append((srcBefore ::: marker :: srcAfter).mkString(EOL))
244-
sb.append(EOL).append(endBox)
176+
val (srcBefore, srcAfter, offset) = sourceLines(pos1, levelString)
177+
val marker = columnMarker(pos1, offset, levelString)
178+
val err = errorMsg(pos1, msg.message, offset)
179+
sb.append((srcBefore ::: marker :: err :: outer(pos, " " * (offset - 1)) ::: srcAfter).mkString(EOL))
245180
}
246181
else sb.append(msg.message)
247182
}
@@ -251,13 +186,15 @@ trait MessageRendering {
251186
sb.toString
252187
}
253188

254-
private def hl(str: String)(using Context, Level): String =
255-
summon[Level].value match
256-
case interfaces.Diagnostic.ERROR => Red(str).show
257-
case interfaces.Diagnostic.WARNING => Yellow(str).show
258-
case interfaces.Diagnostic.INFO => Blue(str).show
189+
def hl(diagnosticLevel: String)(str: String)(using Context): String = diagnosticLevel match {
190+
case "Info" => Blue(str).show
191+
case "Error" => Red(str).show
192+
case _ =>
193+
assert(diagnosticLevel.contains("Warning"))
194+
Yellow(str).show
195+
}
259196

260-
private def diagnosticLevel(dia: Diagnostic): String =
197+
def diagnosticLevel(dia: Diagnostic): String =
261198
dia match {
262199
case dia: FeatureWarning => "Feature Warning"
263200
case dia: DeprecationWarning => "Deprecation Warning"
@@ -268,28 +205,4 @@ trait MessageRendering {
268205
case interfaces.Diagnostic.WARNING => "Warning"
269206
case interfaces.Diagnostic.INFO => "Info"
270207
}
271-
272-
}
273-
274-
private object Highlight {
275-
opaque type Level = Int
276-
extension (level: Level) def value: Int = level
277-
object Level:
278-
def apply(level: Int): Level = level
279-
}
280-
281-
/** Size of the left offset added by the box
282-
*
283-
* ```
284-
* -- Error: ... ------------
285-
* 4 | foo
286-
* | ^^^
287-
* ^^^ // size of this offset
288-
* ```
289-
*/
290-
private object Offsets {
291-
opaque type Offset = Int
292-
def offset(using o: Offset): Int = o
293-
object Offset:
294-
def apply(level: Int): Offset = level
295208
}

compiler/src/dotty/tools/dotc/transform/Splicer.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ object Splicer {
4949
val oldContextClassLoader = Thread.currentThread().getContextClassLoader
5050
Thread.currentThread().setContextClassLoader(classLoader)
5151
try {
52-
val interpreter = new Interpreter(splicePos, classLoader)
52+
val interpreter = new Interpreter(spliceExpansionPos, classLoader)
5353

5454
// Some parts of the macro are evaluated during the unpickling performed in quotedExprToTree
5555
val interpretedExpr = interpreter.interpret[Quotes => scala.quoted.Expr[Any]](tree)

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -853,7 +853,7 @@ class Inliner(call: tpd.Tree, rhsToInline: tpd.Tree)(using Context) {
853853
evidence.tpe match
854854
case fail: Implicits.SearchFailureType =>
855855
val msg = evTyper.missingArgMsg(evidence, tpt.tpe, "")
856-
errorTree(call, em"$msg")
856+
errorTree(tpt, em"$msg")
857857
case _ =>
858858
evidence
859859
return searchImplicit(callTypeArgs.head)

compiler/test-resources/repl/i9227

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,5 @@ scala> import scala.quoted._; inline def myMacro[T]: Unit = ${ myMacroImpl[T] };
33
1 | import scala.quoted._; inline def myMacro[T]: Unit = ${ myMacroImpl[T] }; def myMacroImpl[T](using Quotes): Expr[Unit] = '{}; println(myMacro[Int])
44
| ^^^^^^^^^^^^
55
| Cannot call macro method myMacroImpl defined in the same source file
6+
| This location contains code that was inlined from rs$line$1:1
67
1 error found

tests/neg-macros/delegate-match-1.check

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,4 @@
44
| ^
55
| AmbiguousImplicits
66
| both value a1 in class Test1 and value a2 in class Test1 match type A
7+
| This location contains code that was inlined from Test_2.scala:6

tests/neg-macros/delegate-match-2.check

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,4 @@
44
| ^
55
| DivergingImplicit
66
| method a1 in class Test produces a diverging implicit search when trying to match type A
7+
| This location contains code that was inlined from Test_2.scala:5

tests/neg-macros/delegate-match-3.check

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,4 @@
44
| ^
55
| NoMatchingImplicits
66
| no implicit values were found that match type A
7+
| This location contains code that was inlined from Test_2.scala:3

tests/neg-macros/i11386.check

Lines changed: 4 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3,21 +3,11 @@
33
6 | dummy(0) // error
44
| ^
55
| test
6-
|---------------------------------------------------------------------------------------------------------------------
7-
|Inline stack trace
8-
|·····················································································································
9-
|This location contains code that was inlined from Test_2.scala:6
10-
7 | notNull(i)
11-
| ^^^^^^^^^^
12-
·---------------------------------------------------------------------------------------------------------------------
6+
| This location contains code that was inlined from Test_2.scala:6
7+
| This location contains code that was inlined from Macro_1.scala:7
138
-- Error: tests/neg-macros/i11386/Test_2.scala:8:20 --------------------------------------------------------------------
149
8 | dummy(int2String(0)) // error
1510
| ^^^^^^^^^^^^^
1611
| test
17-
|---------------------------------------------------------------------------------------------------------------------
18-
|Inline stack trace
19-
|·····················································································································
20-
|This location contains code that was inlined from Test_2.scala:8
21-
7 | notNull(i)
22-
| ^^^^^^^^^^
23-
·---------------------------------------------------------------------------------------------------------------------
12+
| This location contains code that was inlined from Test_2.scala:8
13+
| This location contains code that was inlined from Macro_1.scala:7

tests/neg-macros/i13991.check

Lines changed: 0 additions & 16 deletions
This file was deleted.

tests/neg-macros/i13991/Macro_1.scala

Lines changed: 0 additions & 10 deletions
This file was deleted.

tests/neg-macros/i13991/Test_2.scala

Lines changed: 0 additions & 6 deletions
This file was deleted.

tests/neg-macros/i6432.check

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,14 @@
33
4 | foo"abc${"123"}xyz${"456"}fgh" // error // error // error
44
| ^^^
55
| abc
6+
| This location contains code that was inlined from Test_2.scala:4
67
-- Error: tests/neg-macros/i6432/Test_2.scala:4:17 ---------------------------------------------------------------------
78
4 | foo"abc${"123"}xyz${"456"}fgh" // error // error // error
89
| ^^^
910
| xyz
11+
| This location contains code that was inlined from Test_2.scala:4
1012
-- Error: tests/neg-macros/i6432/Test_2.scala:4:28 ---------------------------------------------------------------------
1113
4 | foo"abc${"123"}xyz${"456"}fgh" // error // error // error
1214
| ^^^
1315
| fgh
16+
| This location contains code that was inlined from Test_2.scala:4

0 commit comments

Comments
 (0)