diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 2847bfd578b9..d9da3baee124 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -112,7 +112,8 @@ jobs: - name: Cmd Tests run: | ./project/scripts/sbt ";dist/pack; scala3-bootstrapped/compile; scala3-bootstrapped/test;sjsSandbox/run;sjsSandbox/test;sjsJUnitTests/test;sjsCompilerTests/test ;sbt-test/scripted scala2-compat/* ;configureIDE ;stdlib-bootstrapped/test:run ;stdlib-bootstrapped-tasty-tests/test; scala3-compiler-bootstrapped/scala3CompilerCoursierTest:test" - ./project/scripts/bootstrapCmdTests + ./project/scripts/cmdTests + ./project/scripts/bootstrappedOnlyCmdTests - name: MiMa run: | @@ -447,7 +448,8 @@ jobs: - name: Test run: | ./project/scripts/sbt ";dist/pack ;scala3-bootstrapped/compile ;scala3-bootstrapped/test;sjsSandbox/run;sjsSandbox/test;sjsJUnitTests/test;sjsCompilerTests/test ;sbt-test/scripted scala2-compat/* ;configureIDE ;stdlib-bootstrapped/test:run ;stdlib-bootstrapped-tasty-tests/test" - ./project/scripts/bootstrapCmdTests + ./project/scripts/cmdTests + ./project/scripts/bootstrappedOnlyCmdTests publish_nightly: runs-on: [self-hosted, Linux] diff --git a/compiler/src/dotty/tools/dotc/reporting/MessageRendering.scala b/compiler/src/dotty/tools/dotc/reporting/MessageRendering.scala index f5b566f3ba60..b8f2d763fc83 100644 --- a/compiler/src/dotty/tools/dotc/reporting/MessageRendering.scala +++ b/compiler/src/dotty/tools/dotc/reporting/MessageRendering.scala @@ -16,6 +16,8 @@ import scala.annotation.switch import scala.collection.mutable trait MessageRendering { + import Highlight.* + import Offsets.* /** Remove ANSI coloring from `str`, useful for getting real length of * strings @@ -25,15 +27,9 @@ trait MessageRendering { def stripColor(str: String): String = str.replaceAll("\u001b\\[.*?m", "") - /** When inlining a method call, if there's an error we'd like to get the - * outer context and the `pos` at which the call was inlined. - * - * @return a list of strings with inline locations - */ - def outer(pos: SourcePosition, prefix: String)(using Context): List[String] = - if (pos.outer.exists) - i"$prefix| This location contains code that was inlined from $pos" :: - outer(pos.outer, prefix) + /** List of all the inline calls that surround the position */ + def inlinePosStack(pos: SourcePosition): List[SourcePosition] = + if pos.outer != null && pos.outer.exists then pos :: inlinePosStack(pos.outer) else Nil /** Get the sourcelines before and after the position, as well as the offset @@ -41,15 +37,15 @@ trait MessageRendering { * * @return (lines before error, lines after error, line numbers offset) */ - def sourceLines(pos: SourcePosition, diagnosticLevel: String)(using Context): (List[String], List[String], Int) = { + private def sourceLines(pos: SourcePosition)(using Context, Level, Offset): (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 - val lineNbr = pos.source.offsetToLine(offset) - val prefix = s"${lineNbr + 1} |" + val (offset1, line) = offsetAndLine + val lineNbr = (pos.source.offsetToLine(offset1) + 1).toString + val prefix = String.format(s"%${offset - 2}s |", lineNbr) maxLen = math.max(maxLen, prefix.length) - val lnum = hl(diagnosticLevel)(" " * math.max(0, maxLen - prefix.length) + prefix) + val lnum = hl(" " * math.max(0, maxLen - prefix.length - 1) + prefix) lnum + line.stripLineEnd } @@ -77,23 +73,75 @@ trait MessageRendering { ) } - /** The column markers aligned under the error */ - def columnMarker(pos: SourcePosition, offset: Int, diagnosticLevel: String)(using Context): String = { - val prefix = " " * (offset - 1) + /** Generate box containing the report title + * + * ``` + * -- Error: source.scala --------------------- + * ``` + */ + private def boxTitle(title: String)(using Context, Level, Offset): String = + val pageWidth = ctx.settings.pageWidth.value + val line = "-" * (pageWidth - title.length - 4) + hl(s"-- $title $line") + + /** The position markers aligned under the error + * + * ``` + * | ^^^^^ + * ``` + */ + private def positionMarker(pos: SourcePosition)(using Context, Level, Offset): String = { val padding = pos.startColumnPadding - val carets = hl(diagnosticLevel) { + val carets = if (pos.startLine == pos.endLine) "^" * math.max(1, pos.endColumn - pos.startColumn) else "^" - } - s"$prefix|$padding$carets" + hl(s"$offsetBox$padding$carets") } + /** The horizontal line with the given offset + * + * ``` + * | + * ``` + */ + private def offsetBox(using Context, Level, Offset): String = + val prefix = " " * (offset - 1) + hl(s"$prefix|") + + /** The end of a box section + * + * ``` + * |--------------- + * ``` + * Or if there `soft` is true, + * ``` + * |··············· + * ``` + */ + private def newBox(soft: Boolean = false)(using Context, Level, Offset): String = + val pageWidth = ctx.settings.pageWidth.value + val prefix = " " * (offset - 1) + val line = (if soft then "·" else "-") * (pageWidth - offset) + hl(s"$prefix|$line") + + /** The end of a box section + * + * ``` + * ·---------------- + * ``` + */ + private def endBox(using Context, Level, Offset): String = + val pageWidth = ctx.settings.pageWidth.value + val prefix = " " * (offset - 1) + val line = "-" * (pageWidth - offset) + hl(s"${prefix}·$line") + /** The error message (`msg`) aligned under `pos` * * @return aligned error message */ - def errorMsg(pos: SourcePosition, msg: String, offset: Int)(using Context): String = { + private def errorMsg(pos: SourcePosition, msg: String)(using Context, Level, Offset): String = { val padding = msg.linesIterator.foldLeft(pos.startColumnPadding) { (pad, line) => val lineLength = stripColor(line).length val maxPad = math.max(0, ctx.settings.pageWidth.value - offset - lineLength) - offset @@ -103,12 +151,12 @@ trait MessageRendering { } msg.linesIterator - .map { line => " " * (offset - 1) + "|" + (if line.isEmpty then "" else padding + line) } + .map { line => offsetBox + (if line.isEmpty then "" else padding + line) } .mkString(EOL) } /** The source file path, line and column numbers from the given SourcePosition */ - def posFileStr(pos: SourcePosition): String = + protected def posFileStr(pos: SourcePosition): String = val path = pos.source.file.path if pos.exists then s"$path:${pos.line + 1}:${pos.column}" else path @@ -116,22 +164,22 @@ trait MessageRendering { * * @return separator containing error location and kind */ - def posStr(pos: SourcePosition, diagnosticLevel: String, message: Message)(using Context): String = - if (pos.source != NoSourcePosition.source) hl(diagnosticLevel)({ - val fileAndPos = posFileStr(pos.nonInlined) - val file = if fileAndPos.isEmpty || fileAndPos.endsWith(" ") then fileAndPos else s"$fileAndPos " + private def posStr(pos: SourcePosition, message: Message, diagnosticString: String)(using Context, Level, Offset): String = + if (pos.source != NoSourcePosition.source) hl({ + val realPos = pos.nonInlined + val fileAndPos = posFileStr(realPos) val errId = if (message.errorId ne ErrorMessageID.NoExplanationID) { val errorNumber = message.errorId.errorNumber s"[E${"0" * (3 - errorNumber.toString.length) + errorNumber}] " } else "" val kind = - if (message.kind == "") diagnosticLevel - else s"${message.kind} $diagnosticLevel" - val prefix = s"-- ${errId}${kind}: $file" - - prefix + - ("-" * math.max(ctx.settings.pageWidth.value - stripColor(prefix).length, 0)) + if (message.kind == "") diagnosticString + else s"${message.kind} $diagnosticString" + val title = + 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) + else s"$errId$kind: $fileAndPos" + boxTitle(title) }) else "" /** Explanation rendered under "Explanation" header */ @@ -146,7 +194,7 @@ trait MessageRendering { sb.toString } - def appendFilterHelp(dia: Diagnostic, sb: mutable.StringBuilder): Unit = + private def appendFilterHelp(dia: Diagnostic, sb: mutable.StringBuilder): Unit = import dia._ val hasId = msg.errorId.errorNumber >= 0 val category = dia match { @@ -166,17 +214,35 @@ trait MessageRendering { /** The whole message rendered from `msg` */ def messageAndPos(dia: Diagnostic)(using Context): String = { import dia._ - val levelString = diagnosticLevel(dia) + val pos1 = pos.nonInlined + val inlineStack = inlinePosStack(pos).filter(_ != pos1) + val maxLineNumber = + if pos.exists then (pos1 :: inlineStack).map(_.endLine).max + 1 + else 0 + given Level = Level(level) + given Offset = Offset(maxLineNumber.toString.length + 2) val sb = mutable.StringBuilder() - val posString = posStr(pos, levelString, msg) + val posString = posStr(pos, msg, diagnosticLevel(dia)) if (posString.nonEmpty) sb.append(posString).append(EOL) if (pos.exists) { val pos1 = pos.nonInlined if (pos1.exists && pos1.source.file.exists) { - val (srcBefore, srcAfter, offset) = sourceLines(pos1, levelString) - val marker = columnMarker(pos1, offset, levelString) - val err = errorMsg(pos1, msg.message, offset) - sb.append((srcBefore ::: marker :: err :: outer(pos, " " * (offset - 1)) ::: srcAfter).mkString(EOL)) + val (srcBefore, srcAfter, offset) = sourceLines(pos1) + val marker = positionMarker(pos1) + val err = errorMsg(pos1, msg.message) + sb.append((srcBefore ::: marker :: err :: srcAfter).mkString(EOL)) + + if inlineStack.nonEmpty then + sb.append(EOL).append(newBox()) + sb.append(EOL).append(offsetBox).append(i"Inline stack trace") + for inlinedPos <- inlineStack if inlinedPos != pos1 do + sb.append(EOL).append(newBox(soft = true)) + sb.append(EOL).append(offsetBox).append(i"This location contains code that was inlined from $pos") + if inlinedPos.source.file.exists then + val (srcBefore, srcAfter, _) = sourceLines(inlinedPos) + val marker = positionMarker(inlinedPos) + sb.append(EOL).append((srcBefore ::: marker :: srcAfter).mkString(EOL)) + sb.append(EOL).append(endBox) } else sb.append(msg.message) } @@ -186,15 +252,13 @@ trait MessageRendering { sb.toString } - def hl(diagnosticLevel: String)(str: String)(using Context): String = diagnosticLevel match { - case "Info" => Blue(str).show - case "Error" => Red(str).show - case _ => - assert(diagnosticLevel.contains("Warning")) - Yellow(str).show - } + private def hl(str: String)(using Context, Level): String = + summon[Level].value match + case interfaces.Diagnostic.ERROR => Red(str).show + case interfaces.Diagnostic.WARNING => Yellow(str).show + case interfaces.Diagnostic.INFO => Blue(str).show - def diagnosticLevel(dia: Diagnostic): String = + private def diagnosticLevel(dia: Diagnostic): String = dia match { case dia: FeatureWarning => "Feature Warning" case dia: DeprecationWarning => "Deprecation Warning" @@ -205,4 +269,28 @@ trait MessageRendering { case interfaces.Diagnostic.WARNING => "Warning" case interfaces.Diagnostic.INFO => "Info" } + +} + +private object Highlight { + opaque type Level = Int + extension (level: Level) def value: Int = level + object Level: + def apply(level: Int): Level = level +} + +/** Size of the left offset added by the box + * + * ``` + * -- Error: ... ------------ + * 4 | foo + * | ^^^ + * ^^^ // size of this offset + * ``` + */ +private object Offsets { + opaque type Offset = Int + def offset(using o: Offset): Int = o + object Offset: + def apply(level: Int): Offset = level } diff --git a/compiler/src/dotty/tools/dotc/transform/Splicer.scala b/compiler/src/dotty/tools/dotc/transform/Splicer.scala index 49b6f5564620..dcd5b8d8c4b5 100644 --- a/compiler/src/dotty/tools/dotc/transform/Splicer.scala +++ b/compiler/src/dotty/tools/dotc/transform/Splicer.scala @@ -49,7 +49,7 @@ object Splicer { val oldContextClassLoader = Thread.currentThread().getContextClassLoader Thread.currentThread().setContextClassLoader(classLoader) try { - val interpreter = new Interpreter(spliceExpansionPos, classLoader) + val interpreter = new Interpreter(splicePos, classLoader) // Some parts of the macro are evaluated during the unpickling performed in quotedExprToTree val interpretedExpr = interpreter.interpret[Quotes => scala.quoted.Expr[Any]](tree) diff --git a/compiler/src/dotty/tools/dotc/typer/Inliner.scala b/compiler/src/dotty/tools/dotc/typer/Inliner.scala index 722e3abfec85..c99ccbd24428 100644 --- a/compiler/src/dotty/tools/dotc/typer/Inliner.scala +++ b/compiler/src/dotty/tools/dotc/typer/Inliner.scala @@ -853,7 +853,7 @@ class Inliner(call: tpd.Tree, rhsToInline: tpd.Tree)(using Context) { evidence.tpe match case fail: Implicits.SearchFailureType => val msg = evTyper.missingArgMsg(evidence, tpt.tpe, "") - errorTree(tpt, em"$msg") + errorTree(call, em"$msg") case _ => evidence return searchImplicit(callTypeArgs.head) diff --git a/compiler/test-resources/repl/i9227 b/compiler/test-resources/repl/i9227 index 45d1731dae39..40f9248898a2 100644 --- a/compiler/test-resources/repl/i9227 +++ b/compiler/test-resources/repl/i9227 @@ -3,5 +3,4 @@ scala> import scala.quoted._; inline def myMacro[T]: Unit = ${ myMacroImpl[T] }; 1 | import scala.quoted._; inline def myMacro[T]: Unit = ${ myMacroImpl[T] }; def myMacroImpl[T](using Quotes): Expr[Unit] = '{}; println(myMacro[Int]) | ^^^^^^^^^^^^ | Cannot call macro method myMacroImpl defined in the same source file - | This location contains code that was inlined from rs$line$1:1 1 error found diff --git a/project/scripts/bootstrapCmdTests b/project/scripts/bootstrappedOnlyCmdTests similarity index 100% rename from project/scripts/bootstrapCmdTests rename to project/scripts/bootstrappedOnlyCmdTests diff --git a/project/scripts/cmdTests b/project/scripts/cmdTests index 659b2808ed07..6a175db23e99 100755 --- a/project/scripts/cmdTests +++ b/project/scripts/cmdTests @@ -33,7 +33,7 @@ echo "testing that paths SourceFile annotations are relativized" clear_out "$OUT" "$SBT" "scalac -d $OUT/out.jar -sourceroot tests/pos $(pwd)/tests/pos/i10430/lib.scala $(pwd)/tests/pos/i10430/app.scala" "$SBT" "scalac -print-tasty -color:never $OUT/out.jar" > "$tmp" -cat "$tmp" # for debugging +# cat "$tmp" # for debugging grep -q ": i10430/lib.scala" "$tmp" grep -q ": i10430/app.scala" "$tmp" grep -q "[i10430/lib.scala]" "$tmp" @@ -56,6 +56,7 @@ cp tests/neg/i6371/B_2.scala $OUT/B.scala "$SBT" "scalac $OUT/A.scala -d $OUT1" rm $OUT/A.scala "$SBT" "scalac -classpath $OUT1 -d $OUT1 $OUT/B.scala" > "$tmp" 2>&1 || echo "ok" +cat "$tmp" # for debugging grep -qe "B.scala:2:7" "$tmp" grep -qe "This location contains code that was inlined from A.scala:3" "$tmp" diff --git a/tests/neg-macros/delegate-match-1.check b/tests/neg-macros/delegate-match-1.check index 6d88d021416f..93b20beba183 100644 --- a/tests/neg-macros/delegate-match-1.check +++ b/tests/neg-macros/delegate-match-1.check @@ -4,4 +4,3 @@ | ^ | AmbiguousImplicits | both value a1 in class Test1 and value a2 in class Test1 match type A - | This location contains code that was inlined from Test_2.scala:6 diff --git a/tests/neg-macros/delegate-match-2.check b/tests/neg-macros/delegate-match-2.check index 112e5ee00474..e26742452b5b 100644 --- a/tests/neg-macros/delegate-match-2.check +++ b/tests/neg-macros/delegate-match-2.check @@ -4,4 +4,3 @@ | ^ | DivergingImplicit | method a1 in class Test produces a diverging implicit search when trying to match type A - | This location contains code that was inlined from Test_2.scala:5 diff --git a/tests/neg-macros/delegate-match-3.check b/tests/neg-macros/delegate-match-3.check index 278aa92a4117..2b6fda278fda 100644 --- a/tests/neg-macros/delegate-match-3.check +++ b/tests/neg-macros/delegate-match-3.check @@ -4,4 +4,3 @@ | ^ | NoMatchingImplicits | no implicit values were found that match type A - | This location contains code that was inlined from Test_2.scala:3 diff --git a/tests/neg-macros/i11386.check b/tests/neg-macros/i11386.check index 0377ca6389db..1cce199159a5 100644 --- a/tests/neg-macros/i11386.check +++ b/tests/neg-macros/i11386.check @@ -3,11 +3,21 @@ 6 | dummy(0) // error | ^ | test - | This location contains code that was inlined from Test_2.scala:6 - | This location contains code that was inlined from Macro_1.scala:7 + |--------------------------------------------------------------------------------------------------------------------- + |Inline stack trace + |····················································································································· + |This location contains code that was inlined from Test_2.scala:6 +7 | notNull(i) + | ^^^^^^^^^^ + ·--------------------------------------------------------------------------------------------------------------------- -- Error: tests/neg-macros/i11386/Test_2.scala:8:20 -------------------------------------------------------------------- 8 | dummy(int2String(0)) // error | ^^^^^^^^^^^^^ | test - | This location contains code that was inlined from Test_2.scala:8 - | This location contains code that was inlined from Macro_1.scala:7 + |--------------------------------------------------------------------------------------------------------------------- + |Inline stack trace + |····················································································································· + |This location contains code that was inlined from Test_2.scala:8 +7 | notNull(i) + | ^^^^^^^^^^ + ·--------------------------------------------------------------------------------------------------------------------- diff --git a/tests/neg-macros/i13991.check b/tests/neg-macros/i13991.check new file mode 100644 index 000000000000..15f45af227e5 --- /dev/null +++ b/tests/neg-macros/i13991.check @@ -0,0 +1,16 @@ + +-- Error: tests/neg-macros/i13991/Test_2.scala:6:5 --------------------------------------------------------------------- +6 | v2 // error + | ^^ + | Error + |--------------------------------------------------------------------------------------------------------------------- + |Inline stack trace + |····················································································································· + |This location contains code that was inlined from Test_2.scala:3 +3 | inline def v2 = InlineMac.sample("foo") + | ^^^^^ + |····················································································································· + |This location contains code that was inlined from Test_2.scala:3 +3 | inline def v2 = InlineMac.sample("foo") + | ^^^^^^^^^^^^^^^^^^^^^^^ + ·--------------------------------------------------------------------------------------------------------------------- diff --git a/tests/neg-macros/i13991/Macro_1.scala b/tests/neg-macros/i13991/Macro_1.scala new file mode 100644 index 000000000000..76cfa93cdde5 --- /dev/null +++ b/tests/neg-macros/i13991/Macro_1.scala @@ -0,0 +1,10 @@ +import scala.quoted.* + +object InlineMac: + + inline def sample(inline expr: String): Int = + ${ sampleImpl('expr) } + + def sampleImpl(expr: Expr[String])(using Quotes): Expr[Int] = + import quotes.reflect.* + report.errorAndAbort("Error", expr) diff --git a/tests/neg-macros/i13991/Test_2.scala b/tests/neg-macros/i13991/Test_2.scala new file mode 100644 index 000000000000..572ad324b129 --- /dev/null +++ b/tests/neg-macros/i13991/Test_2.scala @@ -0,0 +1,6 @@ +object Main: + def main(args: Array[String]): Unit = + inline def v2 = InlineMac.sample("foo") + inline def v1 = v2 + + v2 // error diff --git a/tests/neg-macros/i6432.check b/tests/neg-macros/i6432.check index 0e01f99be404..2ea6f3ba0300 100644 --- a/tests/neg-macros/i6432.check +++ b/tests/neg-macros/i6432.check @@ -3,14 +3,11 @@ 4 | foo"abc${"123"}xyz${"456"}fgh" // error // error // error | ^^^ | abc - | This location contains code that was inlined from Test_2.scala:4 -- Error: tests/neg-macros/i6432/Test_2.scala:4:17 --------------------------------------------------------------------- 4 | foo"abc${"123"}xyz${"456"}fgh" // error // error // error | ^^^ | xyz - | This location contains code that was inlined from Test_2.scala:4 -- Error: tests/neg-macros/i6432/Test_2.scala:4:28 --------------------------------------------------------------------- 4 | foo"abc${"123"}xyz${"456"}fgh" // error // error // error | ^^^ | fgh - | This location contains code that was inlined from Test_2.scala:4 diff --git a/tests/neg-macros/i6432b.check b/tests/neg-macros/i6432b.check index 4dd1be84fa3c..395d089c92e9 100644 --- a/tests/neg-macros/i6432b.check +++ b/tests/neg-macros/i6432b.check @@ -3,14 +3,11 @@ 4 | foo"""abc${"123"}xyz${"456"}fgh""" // error // error // error | ^^^ | abc - | This location contains code that was inlined from Test_2.scala:4 -- Error: tests/neg-macros/i6432b/Test_2.scala:4:19 -------------------------------------------------------------------- 4 | foo"""abc${"123"}xyz${"456"}fgh""" // error // error // error | ^^^ | xyz - | This location contains code that was inlined from Test_2.scala:4 -- Error: tests/neg-macros/i6432b/Test_2.scala:4:30 -------------------------------------------------------------------- 4 | foo"""abc${"123"}xyz${"456"}fgh""" // error // error // error | ^^^ | fgh - | This location contains code that was inlined from Test_2.scala:4 diff --git a/tests/neg-macros/i6976.check b/tests/neg-macros/i6976.check index 2057e55550b4..b67f05960a79 100644 --- a/tests/neg-macros/i6976.check +++ b/tests/neg-macros/i6976.check @@ -6,4 +6,10 @@ | scala.MatchError: Inlined(EmptyTree,List(),Literal(Constant(2))) (of class dotty.tools.dotc.ast.Trees$Inlined) | at playground.macros$.mcrImpl(Macro_1.scala:10) | - | This location contains code that was inlined from Test_2.scala:5 + |--------------------------------------------------------------------------------------------------------------------- + |Inline stack trace + |····················································································································· + |This location contains code that was inlined from Macro_1.scala:6 +6 | inline def mcr(x: => Any) = ${mcrImpl('x)} + | ^^^^^^^^^^^^^^ + ·--------------------------------------------------------------------------------------------------------------------- diff --git a/tests/neg-macros/i9014.check b/tests/neg-macros/i9014.check index 509eac067fc8..c0d08a42ef2a 100644 --- a/tests/neg-macros/i9014.check +++ b/tests/neg-macros/i9014.check @@ -3,4 +3,3 @@ 1 |val tests = summon[Bar] // error | ^ | Failed to expand! - | This location contains code that was inlined from Test_2.scala:1 diff --git a/tests/neg-macros/ill-abort.check b/tests/neg-macros/ill-abort.check index 25d7654b1b69..2aa9d3396e53 100644 --- a/tests/neg-macros/ill-abort.check +++ b/tests/neg-macros/ill-abort.check @@ -3,4 +3,10 @@ 1 |def test = fail() // error | ^^^^^^ |Macro expansion was aborted by the macro without any errors reported. Macros should issue errors to end-users to facilitate debugging when aborting a macro expansion. - | This location contains code that was inlined from quoted_1.scala:3 + |--------------------------------------------------------------------------------------------------------------------- + |Inline stack trace + |····················································································································· + |This location contains code that was inlined from quoted_1.scala:3 +3 |inline def fail(): Unit = ${ impl } + | ^^^^^^^^^ + ·--------------------------------------------------------------------------------------------------------------------- diff --git a/tests/neg-macros/macro-class-not-found-1.check b/tests/neg-macros/macro-class-not-found-1.check index 445523c6ade2..08ba5b99f0b8 100644 --- a/tests/neg-macros/macro-class-not-found-1.check +++ b/tests/neg-macros/macro-class-not-found-1.check @@ -5,4 +5,10 @@ | java.lang.NoClassDefFoundError | at Foo$.aMacroImplementation(Foo.scala:8) | - | This location contains code that was inlined from Bar.scala:4 + |--------------------------------------------------------------------------------------------------------------------- + |Inline stack trace + |····················································································································· + |This location contains code that was inlined from Foo.scala:5 +5 | inline def myMacro(): Unit = ${ aMacroImplementation } + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + ·--------------------------------------------------------------------------------------------------------------------- diff --git a/tests/neg-macros/macro-class-not-found-2.check b/tests/neg-macros/macro-class-not-found-2.check index 3cb7506e6bb2..d4ed8f222ba0 100644 --- a/tests/neg-macros/macro-class-not-found-2.check +++ b/tests/neg-macros/macro-class-not-found-2.check @@ -5,4 +5,10 @@ | java.lang.NoClassDefFoundError: this.is.not.a.Class | at Foo$.aMacroImplementation(Foo.scala:8) | - | This location contains code that was inlined from Bar.scala:4 + |--------------------------------------------------------------------------------------------------------------------- + |Inline stack trace + |····················································································································· + |This location contains code that was inlined from Foo.scala:5 +5 | inline def myMacro(): Unit = ${ aMacroImplementation } + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + ·--------------------------------------------------------------------------------------------------------------------- diff --git a/tests/neg-macros/macros-in-same-project-6.check b/tests/neg-macros/macros-in-same-project-6.check index 485f5062db92..17f696508259 100644 --- a/tests/neg-macros/macros-in-same-project-6.check +++ b/tests/neg-macros/macros-in-same-project-6.check @@ -2,4 +2,3 @@ 4 | Foo.myMacro() // error | ^^^^^^^^^^^^^ | some error - | This location contains code that was inlined from Bar.scala:4 diff --git a/tests/neg-scalajs/js-enums.check b/tests/neg-scalajs/js-enums.check index eb358f16e57a..e54b2a5af2da 100644 --- a/tests/neg-scalajs/js-enums.check +++ b/tests/neg-scalajs/js-enums.check @@ -4,9 +4,9 @@ |MyEnum extends scala.reflect.Enum which does not extend js.Any. 5 | case Foo -- Error: tests/neg-scalajs/js-enums.scala:9:5 ------------------------------------------------------------------------- -7 |@js.native -8 |@JSGlobal -9 |enum MyEnumNative extends js.Object: // error + 7 |@js.native + 8 |@JSGlobal + 9 |enum MyEnumNative extends js.Object: // error |^ |MyEnumNative extends scala.reflect.Enum which does not extend js.Any. 10 | case Bar diff --git a/tests/neg/cannot-reduce-inline-match.check b/tests/neg/cannot-reduce-inline-match.check index ceca40a74cbd..e35066949333 100644 --- a/tests/neg/cannot-reduce-inline-match.check +++ b/tests/neg/cannot-reduce-inline-match.check @@ -4,4 +4,12 @@ | cannot reduce inline match with | scrutinee: "f" : ("f" : String) | patterns : case _:Int - | This location contains code that was inlined from cannot-reduce-inline-match.scala:3 + |--------------------------------------------------------------------------------------------------------------------- + |Inline stack trace + |····················································································································· + |This location contains code that was inlined from cannot-reduce-inline-match.scala:3 +3 | inline x match { + | ^ +4 | case _: Int => +5 | } + ·--------------------------------------------------------------------------------------------------------------------- diff --git a/tests/neg/i11225.check b/tests/neg/i11225.check index 60805a27b22d..0aa5f720e24b 100644 --- a/tests/neg/i11225.check +++ b/tests/neg/i11225.check @@ -42,4 +42,10 @@ 30 | var x7: Int = uni // error | ^^^ | `uninitialized` can only be used as the right hand side of a mutable field definition - | This location contains code that was inlined from i11225.scala:25 + |-------------------------------------------------------------------------------------------------------------------- + |Inline stack trace + |···················································································································· + |This location contains code that was inlined from i11225.scala:25 +25 | transparent inline def uni = uninitialized + | ^^^^^^^^^^^^^ + ·-------------------------------------------------------------------------------------------------------------------- diff --git a/tests/neg/i13044.check b/tests/neg/i13044.check index 87b8a1fe9ae2..b3e278792148 100644 --- a/tests/neg/i13044.check +++ b/tests/neg/i13044.check @@ -4,41 +4,143 @@ | given instance gen is declared as `inline`, but was not inlined | | Try increasing `-Xmax-inlines` above 32 - | This location contains code that was inlined from i13044.scala:17 - | This location contains code that was inlined from i13044.scala:31 - | This location contains code that was inlined from i13044.scala:37 - | This location contains code that was inlined from i13044.scala:17 - | This location contains code that was inlined from i13044.scala:31 - | This location contains code that was inlined from i13044.scala:37 - | This location contains code that was inlined from i13044.scala:17 - | This location contains code that was inlined from i13044.scala:31 - | This location contains code that was inlined from i13044.scala:37 - | This location contains code that was inlined from i13044.scala:17 - | This location contains code that was inlined from i13044.scala:31 - | This location contains code that was inlined from i13044.scala:37 - | This location contains code that was inlined from i13044.scala:17 - | This location contains code that was inlined from i13044.scala:18 - | This location contains code that was inlined from i13044.scala:31 - | This location contains code that was inlined from i13044.scala:37 + |-------------------------------------------------------------------------------------------------------------------- + |Inline stack trace + |···················································································································· + |This location contains code that was inlined from i13044.scala:17 +17 | val builder = summonInline[Schema[t]].asInstanceOf[Schema[Any]] + | ^ + |···················································································································· + |This location contains code that was inlined from i13044.scala:17 +31 | lazy val fields = recurse[m.MirroredElemTypes] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + |···················································································································· + |This location contains code that was inlined from i13044.scala:17 +37 | inline given gen[A]: Schema[A] = derived + | ^^^^^^^ + |···················································································································· + |This location contains code that was inlined from i13044.scala:17 +17 | val builder = summonInline[Schema[t]].asInstanceOf[Schema[Any]] + | ^ + |···················································································································· + |This location contains code that was inlined from i13044.scala:17 +31 | lazy val fields = recurse[m.MirroredElemTypes] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + |···················································································································· + |This location contains code that was inlined from i13044.scala:17 +37 | inline given gen[A]: Schema[A] = derived + | ^^^^^^^ + |···················································································································· + |This location contains code that was inlined from i13044.scala:17 +17 | val builder = summonInline[Schema[t]].asInstanceOf[Schema[Any]] + | ^ + |···················································································································· + |This location contains code that was inlined from i13044.scala:17 +31 | lazy val fields = recurse[m.MirroredElemTypes] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + |···················································································································· + |This location contains code that was inlined from i13044.scala:17 +37 | inline given gen[A]: Schema[A] = derived + | ^^^^^^^ + |···················································································································· + |This location contains code that was inlined from i13044.scala:17 +17 | val builder = summonInline[Schema[t]].asInstanceOf[Schema[Any]] + | ^ + |···················································································································· + |This location contains code that was inlined from i13044.scala:17 +31 | lazy val fields = recurse[m.MirroredElemTypes] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + |···················································································································· + |This location contains code that was inlined from i13044.scala:17 +37 | inline given gen[A]: Schema[A] = derived + | ^^^^^^^ + |···················································································································· + |This location contains code that was inlined from i13044.scala:17 +17 | val builder = summonInline[Schema[t]].asInstanceOf[Schema[Any]] + | ^ + |···················································································································· + |This location contains code that was inlined from i13044.scala:17 +18 | builder :: recurse[ts] + | ^^^^^^^^^^^ + |···················································································································· + |This location contains code that was inlined from i13044.scala:17 +31 | lazy val fields = recurse[m.MirroredElemTypes] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + |···················································································································· + |This location contains code that was inlined from i13044.scala:17 +37 | inline given gen[A]: Schema[A] = derived + | ^^^^^^^ + ·-------------------------------------------------------------------------------------------------------------------- -- Error: tests/neg/i13044.scala:50:40 --------------------------------------------------------------------------------- 50 | implicit def typeSchema: Schema[A] = Schema.gen // error // error | ^^^^^^^^^^ | method recurse is declared as `inline`, but was not inlined | | Try increasing `-Xmax-inlines` above 32 - | This location contains code that was inlined from i13044.scala:18 - | This location contains code that was inlined from i13044.scala:31 - | This location contains code that was inlined from i13044.scala:37 - | This location contains code that was inlined from i13044.scala:17 - | This location contains code that was inlined from i13044.scala:31 - | This location contains code that was inlined from i13044.scala:37 - | This location contains code that was inlined from i13044.scala:17 - | This location contains code that was inlined from i13044.scala:31 - | This location contains code that was inlined from i13044.scala:37 - | This location contains code that was inlined from i13044.scala:17 - | This location contains code that was inlined from i13044.scala:31 - | This location contains code that was inlined from i13044.scala:37 - | This location contains code that was inlined from i13044.scala:17 - | This location contains code that was inlined from i13044.scala:18 - | This location contains code that was inlined from i13044.scala:31 - | This location contains code that was inlined from i13044.scala:37 + |-------------------------------------------------------------------------------------------------------------------- + |Inline stack trace + |···················································································································· + |This location contains code that was inlined from i13044.scala:18 +18 | builder :: recurse[ts] + | ^^^^^^^ + |···················································································································· + |This location contains code that was inlined from i13044.scala:18 +31 | lazy val fields = recurse[m.MirroredElemTypes] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + |···················································································································· + |This location contains code that was inlined from i13044.scala:18 +37 | inline given gen[A]: Schema[A] = derived + | ^^^^^^^ + |···················································································································· + |This location contains code that was inlined from i13044.scala:18 +17 | val builder = summonInline[Schema[t]].asInstanceOf[Schema[Any]] + | ^ + |···················································································································· + |This location contains code that was inlined from i13044.scala:18 +31 | lazy val fields = recurse[m.MirroredElemTypes] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + |···················································································································· + |This location contains code that was inlined from i13044.scala:18 +37 | inline given gen[A]: Schema[A] = derived + | ^^^^^^^ + |···················································································································· + |This location contains code that was inlined from i13044.scala:18 +17 | val builder = summonInline[Schema[t]].asInstanceOf[Schema[Any]] + | ^ + |···················································································································· + |This location contains code that was inlined from i13044.scala:18 +31 | lazy val fields = recurse[m.MirroredElemTypes] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + |···················································································································· + |This location contains code that was inlined from i13044.scala:18 +37 | inline given gen[A]: Schema[A] = derived + | ^^^^^^^ + |···················································································································· + |This location contains code that was inlined from i13044.scala:18 +17 | val builder = summonInline[Schema[t]].asInstanceOf[Schema[Any]] + | ^ + |···················································································································· + |This location contains code that was inlined from i13044.scala:18 +31 | lazy val fields = recurse[m.MirroredElemTypes] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + |···················································································································· + |This location contains code that was inlined from i13044.scala:18 +37 | inline given gen[A]: Schema[A] = derived + | ^^^^^^^ + |···················································································································· + |This location contains code that was inlined from i13044.scala:18 +17 | val builder = summonInline[Schema[t]].asInstanceOf[Schema[Any]] + | ^ + |···················································································································· + |This location contains code that was inlined from i13044.scala:18 +18 | builder :: recurse[ts] + | ^^^^^^^^^^^ + |···················································································································· + |This location contains code that was inlined from i13044.scala:18 +31 | lazy val fields = recurse[m.MirroredElemTypes] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + |···················································································································· + |This location contains code that was inlined from i13044.scala:18 +37 | inline given gen[A]: Schema[A] = derived + | ^^^^^^^ + ·-------------------------------------------------------------------------------------------------------------------- diff --git a/tests/neg/i13570.check b/tests/neg/i13570.check index 90e29476b7b1..cf1649b5f4a6 100644 --- a/tests/neg/i13570.check +++ b/tests/neg/i13570.check @@ -6,4 +6,13 @@ | patterns : case s @ _:Seq[Int] if s.isEmpty | case s @ _:Seq[Int] | case _ - | This location contains code that was inlined from i13570.scala:3 + |--------------------------------------------------------------------------------------------------------------------- + |Inline stack trace + |····················································································································· + |This location contains code that was inlined from i13570.scala:3 +3 | inline seq match + | ^ +4 | case s: Seq[Int] if s.isEmpty => println("seq is empty") +5 | case s: Seq[Int] => println("seq is not empty") +6 | case _ => println("somthing hinky happened") + ·--------------------------------------------------------------------------------------------------------------------- diff --git a/tests/neg/i13991.check b/tests/neg/i13991.check new file mode 100644 index 000000000000..fd092b759c2b --- /dev/null +++ b/tests/neg/i13991.check @@ -0,0 +1,15 @@ +-- Error: tests/neg/i13991.scala:5:7 ----------------------------------------------------------------------------------- + 5 | first[String] // error // before line 10 to test alignment of the error message `|` + | ^^^^^^^^^^^^^ + | no implicit argument of type Foo[String] was found + |-------------------------------------------------------------------------------------------------------------------- + |Inline stack trace + |···················································································································· + |This location contains code that was inlined from i13991.scala:8 + 8 | compiletime.summonInline[Foo[A]].foo + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + |···················································································································· + |This location contains code that was inlined from i13991.scala:8 +11 | second[A] + 42 // after line 10 to test alignment of the error message `|` + | ^^^^^^^^^ + ·-------------------------------------------------------------------------------------------------------------------- diff --git a/tests/neg/i13991.scala b/tests/neg/i13991.scala new file mode 100644 index 000000000000..af15891e82d3 --- /dev/null +++ b/tests/neg/i13991.scala @@ -0,0 +1,11 @@ +trait Foo[X]: + def foo: Int + +def foo = + first[String] // error // before line 10 to test alignment of the error message `|` + +inline def second[A]: Int = + compiletime.summonInline[Foo[A]].foo + +inline def first[A]: Int = + second[A] + 42 // after line 10 to test alignment of the error message `|` diff --git a/tests/neg/inline-error-pos.check b/tests/neg/inline-error-pos.check index 121684fe14d6..1d65175c6c39 100644 --- a/tests/neg/inline-error-pos.check +++ b/tests/neg/inline-error-pos.check @@ -4,4 +4,11 @@ | cannot reduce inline match with | scrutinee: 2 : (2 : Int) | patterns : case 1 - | This location contains code that was inlined from inline-error-pos.scala:3 + |--------------------------------------------------------------------------------------------------------------------- + |Inline stack trace + |····················································································································· + |This location contains code that was inlined from inline-error-pos.scala:3 +3 | inline x match + | ^ +4 | case 1 => 9 + ·--------------------------------------------------------------------------------------------------------------------- diff --git a/tests/neg/summonInline.check b/tests/neg/summonInline.check old mode 100755 new mode 100644 index d118299d6dc5..db9b6968ee43 --- a/tests/neg/summonInline.check +++ b/tests/neg/summonInline.check @@ -2,9 +2,21 @@ 19 |val missing1 = summonInlineCheck(1) // error | ^^^^^^^^^^^^^^^^^^^^ | Missing One - | This location contains code that was inlined from summonInline.scala:15 + |-------------------------------------------------------------------------------------------------------------------- + |Inline stack trace + |···················································································································· + |This location contains code that was inlined from summonInline.scala:15 +15 | case 1 => summonInline[Missing1] + | ^^^^^^^^^^^^^^^^^^^^^^ + ·-------------------------------------------------------------------------------------------------------------------- -- Error: tests/neg/summonInline.scala:20:32 --------------------------------------------------------------------------- 20 |val missing2 = summonInlineCheck(2) // error | ^^^^^^^^^^^^^^^^^^^^ | Missing Two - | This location contains code that was inlined from summonInline.scala:16 + |-------------------------------------------------------------------------------------------------------------------- + |Inline stack trace + |···················································································································· + |This location contains code that was inlined from summonInline.scala:16 +16 | case 2 => summonInline[Missing2] + | ^^^^^^^^^^^^^^^^^^^^^^ + ·-------------------------------------------------------------------------------------------------------------------- diff --git a/tests/pos/i12973.scala b/tests/pos/i12973.scala index 9cda7dbc120b..53c6476d798e 100644 --- a/tests/pos/i12973.scala +++ b/tests/pos/i12973.scala @@ -1,4 +1,4 @@ -// Compiled and placed on the REPL classpath in the bootstrapCmdTests script +// Compiled and placed on the REPL classpath in the bootstrappedOnlyCmdTests script // to test that launching the REPL with `scala -cp ` works (issue #12973) case class Bug12973(): def check = s"$productPrefix is fixed"