Skip to content

Commit a57b7fb

Browse files
Merge pull request #7684 from dotty-staging/emit-inline-errors-at-expansion-site
Emit inline errors at expansion site
2 parents 9363540 + fb8ac6c commit a57b7fb

27 files changed

+82
-54
lines changed

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

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ trait MessageRendering {
3333
*/
3434
def outer(pos: SourcePosition, prefix: String)(implicit ctx: Context): List[String] =
3535
if (pos.outer.exists)
36-
i"$prefix| This location is in code that was inlined at ${pos.outer}" ::
36+
i"$prefix| This location contains code that was inlined from $pos" ::
3737
outer(pos.outer, prefix)
3838
else Nil
3939

@@ -114,9 +114,9 @@ trait MessageRendering {
114114
*/
115115
def posStr(pos: SourcePosition, diagnosticLevel: String, message: Message)(implicit ctx: Context): String =
116116
if (pos.exists) hl(diagnosticLevel)({
117+
val pos1 = pos.nonInlined
117118
val file =
118-
if (pos.source.file.exists) s"${pos.source.file.toString}:${pos.line + 1}:${pos.column}"
119-
else s"${pos.source.file.toString}: offset ${pos.start} (missing source file)"
119+
s"${pos1.source.file.toString}:${pos1.line + 1}:${pos1.column}"
120120
val errId =
121121
if (message.errorId ne ErrorMessageID.NoExplanationID) {
122122
val errorNumber = message.errorId.errorNumber
@@ -149,9 +149,10 @@ trait MessageRendering {
149149
val posString = posStr(pos, diagnosticLevel, msg)
150150
if (posString.nonEmpty) sb.append(posString).append(EOL)
151151
if (pos.exists && pos.source.file.exists) {
152-
val (srcBefore, srcAfter, offset) = sourceLines(pos, diagnosticLevel)
153-
val marker = columnMarker(pos, offset, diagnosticLevel)
154-
val err = errorMsg(pos, msg.msg, offset)
152+
val pos1 = pos.nonInlined
153+
val (srcBefore, srcAfter, offset) = sourceLines(pos1, diagnosticLevel)
154+
val marker = columnMarker(pos1, offset, diagnosticLevel)
155+
val err = errorMsg(pos1, msg.msg, offset)
155156
sb.append((srcBefore ::: marker :: err :: outer(pos, " " * (offset - 1)) ::: srcAfter).mkString(EOL))
156157
}
157158
else sb.append(msg.msg)

compiler/src/dotty/tools/dotc/util/SourcePosition.scala

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,17 @@ extends interfaces.SourcePosition with Showable {
6464
def outermost: SourcePosition =
6565
if outer == null || outer == NoSourcePosition then this else outer.outermost
6666

67+
/** Inner most position that is contained within the `outermost` position.
68+
* Most precise position that that comes from the call site.
69+
*/
70+
def nonInlined: SourcePosition = {
71+
val om = outermost
72+
def rec(self: SourcePosition): SourcePosition =
73+
if om.contains(self) then self else rec(self.outer)
74+
rec(this)
75+
}
76+
77+
6778
override def toString: String =
6879
s"${if (source.exists) source.file.toString else "(no source)"}:$span"
6980

@@ -75,4 +86,3 @@ extends interfaces.SourcePosition with Showable {
7586
override def toString: String = "?"
7687
override def withOuter(outer: SourcePosition): SourcePosition = outer
7788
}
78-

compiler/test/dotty/tools/vulpix/ParallelTesting.scala

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -679,11 +679,12 @@ trait ParallelTesting extends RunnerOrchestration { self =>
679679
}
680680

681681
def getMissingExpectedErrors(errorMap: HashMap[String, Integer], reporterErrors: Iterator[MessageContainer]) = !reporterErrors.forall { error =>
682-
val key = if (error.pos.exists) {
682+
val pos1 = error.pos.nonInlined
683+
val key = if (pos1.exists) {
683684
def toRelative(path: String): String = // For some reason, absolute paths leak from the compiler itself...
684685
path.split("/").dropWhile(_ != "tests").mkString("/")
685-
val fileName = toRelative(error.pos.source.file.toString)
686-
s"$fileName:${error.pos.line}"
686+
val fileName = toRelative(pos1.source.file.toString)
687+
s"$fileName:${pos1.line}"
687688

688689
} else "nopos"
689690

@@ -695,7 +696,7 @@ trait ParallelTesting extends RunnerOrchestration { self =>
695696
true
696697
}
697698
else {
698-
echo(s"Error reported in ${error.pos.source}, but no annotation found")
699+
echo(s"Error reported in ${pos1.source}, but no annotation found")
699700
false
700701
}
701702
}

project/scripts/cmdTests

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ cp tests/neg/i6371/B_2.scala $OUT/B.scala
5050
"$SBT" "dotc $OUT/A.scala -d $OUT1"
5151
rm $OUT/A.scala
5252
"$SBT" "dotc -classpath $OUT1 -d $OUT1 $OUT/B.scala" > "$tmp" 2>&1 || echo "ok"
53-
grep -qe "A.scala: offset 63 (missing source file)" "$tmp"
53+
grep -qe "B.scala:2:7" "$tmp"
5454

5555

5656
## Disabled because of flakeyness, should be changed to not depend on sbt

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

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

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,4 +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 is in code that was inlined at Test_2.scala:5
7+
| This location contains code that was inlined from Test_2.scala:5

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

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

tests/neg-macros/i6432.check

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,14 @@
33
4 | foo"abc${"123"}xyz${"456"}fgh" // error // error // error
44
| ^^^
55
| abc
6-
| This location is in code that was inlined at Test_2.scala:4
6+
| This location contains code that was inlined from Test_2.scala:4
77
-- Error: tests/neg-macros/i6432/Test_2.scala:4:17 ---------------------------------------------------------------------
88
4 | foo"abc${"123"}xyz${"456"}fgh" // error // error // error
99
| ^^^
1010
| xyz
11-
| This location is in code that was inlined at Test_2.scala:4
11+
| This location contains code that was inlined from Test_2.scala:4
1212
-- Error: tests/neg-macros/i6432/Test_2.scala:4:28 ---------------------------------------------------------------------
1313
4 | foo"abc${"123"}xyz${"456"}fgh" // error // error // error
1414
| ^^^
1515
| fgh
16-
| This location is in code that was inlined at Test_2.scala:4
16+
| This location contains code that was inlined from Test_2.scala:4

tests/neg-macros/i6432b.check

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,14 @@
33
4 | foo"""abc${"123"}xyz${"456"}fgh""" // error // error // error
44
| ^^^
55
| abc
6-
| This location is in code that was inlined at Test_2.scala:4
6+
| This location contains code that was inlined from Test_2.scala:4
77
-- Error: tests/neg-macros/i6432b/Test_2.scala:4:19 --------------------------------------------------------------------
88
4 | foo"""abc${"123"}xyz${"456"}fgh""" // error // error // error
99
| ^^^
1010
| xyz
11-
| This location is in code that was inlined at Test_2.scala:4
11+
| This location contains code that was inlined from Test_2.scala:4
1212
-- Error: tests/neg-macros/i6432b/Test_2.scala:4:30 --------------------------------------------------------------------
1313
4 | foo"""abc${"123"}xyz${"456"}fgh""" // error // error // error
1414
| ^^^
1515
| fgh
16-
| This location is in code that was inlined at Test_2.scala:4
16+
| This location contains code that was inlined from Test_2.scala:4

tests/neg-macros/i6976.check

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,4 @@
66
| scala.MatchError: Inlined(EmptyTree,List(),Literal(Constant(2))) (of class dotty.tools.dotc.ast.Trees$Inlined)
77
| at playground.macros$.mcrImpl(Macro_1.scala:12)
88
|
9-
| This location is in code that was inlined at Test_2.scala:5
9+
| This location contains code that was inlined from Test_2.scala:5

tests/neg-macros/macro-class-not-found-1.check

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,4 @@
55
| java.lang.NoClassDefFoundError
66
| at Foo$.aMacroImplementation(Foo.scala:8)
77
|
8-
| This location is in code that was inlined at Bar.scala:4
8+
| This location contains code that was inlined from Bar.scala:4

tests/neg-macros/macro-class-not-found-2.check

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,4 @@
55
| java.lang.NoClassDefFoundError: this.is.not.a.Class
66
| at Foo$.aMacroImplementation(Foo.scala:8)
77
|
8-
| This location is in code that was inlined at Bar.scala:4
8+
| This location contains code that was inlined from Bar.scala:4

tests/neg-macros/macros-in-same-project-2.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,9 @@ import scala.quoted._
33

44
object Bar {
55

6-
myMacro()
6+
myMacro() // error
77

8-
inline def myMacro(): Unit = myMacro2() // error
8+
inline def myMacro(): Unit = myMacro2()
99
inline def myMacro2(): Unit = ${ aMacroImplementation }
1010

1111
def aMacroImplementation(given QuoteContext): Expr[Unit] = '{}

tests/neg-macros/macros-in-same-project-6.check

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,4 @@
22
4 | Foo.myMacro() // error
33
| ^^^^^^^^^^^^^
44
| some error
5-
| This location is in code that was inlined at Bar.scala:4
5+
| This location contains code that was inlined from Bar.scala:4
Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,9 @@
1-
-- Error: tests/neg/cannot-reduce-inline-match.scala:3:13 --------------------------------------------------------------
2-
3 | inline x match { // error
3-
| ^
4-
| cannot reduce inline match with
5-
| scrutinee: {
6-
| "f"
7-
| } : String("f")
8-
| patterns : case _:Int
9-
| This location is in code that was inlined at cannot-reduce-inline-match.scala:9
10-
4 | case _: Int =>
11-
5 | }
1+
-- Error: tests/neg/cannot-reduce-inline-match.scala:9:5 ---------------------------------------------------------------
2+
9 | foo("f") // error
3+
| ^^^^^^^^
4+
| cannot reduce inline match with
5+
| scrutinee: {
6+
| "f"
7+
| } : String("f")
8+
| patterns : case _:Int
9+
| This location contains code that was inlined from cannot-reduce-inline-match.scala:3
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
object Test {
22
inline def foo[T](x: T) =
3-
inline x match { // error
3+
inline x match {
44
case _: Int =>
55
}
66

77
foo(4)
88

9-
foo("f")
9+
foo("f") // error
1010

1111
}
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
object Test {
22

33
inline def bar() =
4-
compiletime.summonFrom { // error
4+
compiletime.summonFrom {
55
case _: Int =>
66
}
77

@@ -10,5 +10,5 @@ object Test {
1010
bar()
1111
}
1212

13-
bar()
13+
bar() // error
1414
}

tests/neg/i6371/A_1.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
object A {
22
inline def foo(a: Any): Unit = a match {
3-
case _: Int => // error
3+
case _: Int =>
44
case _ =>
55
}
66
}

tests/neg/i6371/B_2.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
object B {
2-
A.foo("aa")
2+
A.foo("aa") // error
33
}

tests/neg/i7618.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ enum Exp {
1212
object Compiler {
1313
import Exp._
1414

15-
inline def compile(e: Exp, env: Map[String, Expr[Int]])(given ctx: QuoteContext): Expr[Int] = inline e match { // error
15+
inline def compile(e: Exp, env: Map[String, Expr[Int]])(given ctx: QuoteContext): Expr[Int] = inline e match {
1616
case Num(n) =>
1717
Expr(n)
1818
case Plus(e1, e2) =>
@@ -31,6 +31,6 @@ object Example {
3131
val exp = Plus(Plus(Num(2), Var("x")), Num(4))
3232
val letExp = Let("x", Num(3), exp)
3333

34-
Compiler.compile(letExp, Map.empty)(given QuoteContext.macroContext) // error
34+
Compiler.compile(letExp, Map.empty)(given QuoteContext.macroContext) // error // error
3535
}
3636
}

tests/neg/i7618b.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ enum Exp {
1212
object Compiler {
1313
import Exp._
1414

15-
inline def compile(e: Exp, env: Map[String, Expr[Int]])(given ctx: QuoteContext): Expr[Int] = inline e match { // error
15+
inline def compile(e: Exp, env: Map[String, Expr[Int]])(given ctx: QuoteContext): Expr[Int] = inline e match {
1616
case Num(n) =>
1717
Expr(n)
1818
case Plus(e1, e2) =>
@@ -31,6 +31,6 @@ object Example {
3131
val exp = Plus(Plus(Num(2), Var("x")), Num(4))
3232
val letExp = Let("x", Num(3), exp)
3333

34-
Compiler.compile(letExp, Map.empty)(given (??? : QuoteContext))
34+
Compiler.compile(letExp, Map.empty)(given (??? : QuoteContext)) // error
3535
}
3636
}

tests/neg/inline-error-pos.check

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
-- Error: tests/neg/inline-error-pos.scala:8:13 ------------------------------------------------------------------------
2+
8 | val b = foo(2) // error
3+
| ^^^^^^
4+
| cannot reduce inline match with
5+
| scrutinee: {
6+
| 2
7+
| } : Int(2)
8+
| patterns : case 1
9+
| This location contains code that was inlined from inline-error-pos.scala:3

tests/neg/inline-error-pos.scala

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
2+
inline def foo(x: Int): Int =
3+
inline x match
4+
case 1 => 9
5+
6+
object Foo {
7+
val a = foo(1)
8+
val b = foo(2) // error
9+
}

tests/neg/inlineAccess/C_1.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ package p
22
private class D
33
class C {
44
inline def inl(): Unit = {
5-
val d = new D() // error (when inlined): not accessible
5+
val d = new D()
66
}
77
}
88

tests/neg/inlineAccess/Test_2.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,6 @@
22
object Test {
33
def main(args: Array[String]) = {
44
val c = new p.C()
5-
c.inl()
5+
c.inl() // error (when inlined): not accessible
66
}
77
}

tests/neg/summonFrom-ambiguous-bind.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ object `implicit-match-ambiguous-bind` {
33
implicit val ibox: Box[Int] = Box(0)
44
implicit val sbox: Box[String] = Box("")
55
inline def unbox = compiletime.summonFrom {
6-
case b: Box[t] => b.value // error
6+
case b: Box[t] => b.value
77
}
8-
val unboxed = unbox
8+
val unboxed = unbox // error
99
}

tests/neg/summonFrom-ambiguous.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@ object Test {
55
implicit val a2: A = new A
66

77
inline def f: Any = compiletime.summonFrom {
8-
case _: A => ??? // error: ambiguous implicits
8+
case _: A => ???
99
}
1010

11-
f
11+
f // error: ambiguous implicits
1212
}

0 commit comments

Comments
 (0)