From 6a417ea00be361f663b38f35fc558dcc15109afd Mon Sep 17 00:00:00 2001 From: Som Snytt Date: Thu, 6 Feb 2025 01:08:48 -0800 Subject: [PATCH] Forward reference error includes line numbers --- .../dotty/tools/dotc/reporting/messages.scala | 5 +- tests/neg/i14401.check | 30 ++++++++++++ tests/neg/i14401.scala | 46 +++++++++++++++++++ tests/untried/neg/forward.check | 10 ---- tests/untried/neg/forward.scala | 24 ---------- 5 files changed, 80 insertions(+), 35 deletions(-) create mode 100644 tests/neg/i14401.check create mode 100644 tests/neg/i14401.scala delete mode 100644 tests/untried/neg/forward.check delete mode 100644 tests/untried/neg/forward.scala diff --git a/compiler/src/dotty/tools/dotc/reporting/messages.scala b/compiler/src/dotty/tools/dotc/reporting/messages.scala index 56420a0e0bc2..ac72ee4aa21f 100644 --- a/compiler/src/dotty/tools/dotc/reporting/messages.scala +++ b/compiler/src/dotty/tools/dotc/reporting/messages.scala @@ -1190,7 +1190,10 @@ extends DeclarationMsg(OverrideErrorID), NoDisambiguation: class ForwardReferenceExtendsOverDefinition(value: Symbol, definition: Symbol)(using Context) extends ReferenceMsg(ForwardReferenceExtendsOverDefinitionID) { - def msg(using Context) = i"${definition.name} is a forward reference extending over the definition of ${value.name}" + extension (sym: Symbol) def srcLine = sym.line + 1 + def msg(using Context) = i"${definition.name}${ + if value != definition then s" (defined on L${definition.srcLine})" else "" + } is a forward reference extending over the definition of ${value.name} (on L${value.srcLine})" def explain(using Context) = i"""|${definition.name} is used before you define it, and the definition of ${value.name} diff --git a/tests/neg/i14401.check b/tests/neg/i14401.check new file mode 100644 index 000000000000..929dbf3dac59 --- /dev/null +++ b/tests/neg/i14401.check @@ -0,0 +1,30 @@ +-- [E039] Reference Error: tests/neg/i14401.scala:6:17 ----------------------------------------------------------------- +6 | def f: Int = x; // error + | ^ + | x is a forward reference extending over the definition of x (on L7) + | + | longer explanation available when compiling with `-explain` +-- [E039] Reference Error: tests/neg/i14401.scala:10:17 ---------------------------------------------------------------- +10 | def f: Int = g; // error + | ^ + | g (defined on L12) is a forward reference extending over the definition of x (on L11) + | + | longer explanation available when compiling with `-explain` +-- [E039] Reference Error: tests/neg/i14401.scala:15:17 ---------------------------------------------------------------- +15 | def f: Int = g; // error + | ^ + | g (defined on L17) is a forward reference extending over the definition of x (on L16) + | + | longer explanation available when compiling with `-explain` +-- [E039] Reference Error: tests/neg/i14401.scala:31:15 ---------------------------------------------------------------- +31 | } yield a // error + | ^ + | ec (defined on L33) is a forward reference extending over the definition of z (on L29) + | + | longer explanation available when compiling with `-explain` +-- [E039] Reference Error: tests/neg/i14401.scala:41:28 ---------------------------------------------------------------- +41 | class NotUsed {val xs = args} // error + | ^^^^ + | args (defined on L44) is a forward reference extending over the definition of dummy (on L42) + | + | longer explanation available when compiling with `-explain` diff --git a/tests/neg/i14401.scala b/tests/neg/i14401.scala new file mode 100644 index 000000000000..a9be93cad998 --- /dev/null +++ b/tests/neg/i14401.scala @@ -0,0 +1,46 @@ +object Test { + def f: Int = x; + val x: Int = f; + + { + def f: Int = x; // error + val x: Int = f; + } + { + def f: Int = g; // error + val x: Int = f; + def g: Int = x; + } + { + def f: Int = g; // error + var x: Int = f; + def g: Int = x; + } + { + def f: Int = g; + Console.println("foo"); + def g: Int = f; + } + { + import scala.concurrent.{ExecutionContext, Future}, ExecutionContext.Implicits + + def foo: Future[Int] = { + val fInt = Future.successful(1) + val z = for { + a <- fInt + } yield a // error + + implicit val ec: ExecutionContext = Implicits.global + z + } + foo + } +} +object MyApp { + def main(args: Array[String]) = { + class NotUsed {val xs = args} // error + val dummy = false + // oops, shadows the parameter + def args = Seq("a","b","c") + } +} diff --git a/tests/untried/neg/forward.check b/tests/untried/neg/forward.check deleted file mode 100644 index 252c990370e0..000000000000 --- a/tests/untried/neg/forward.check +++ /dev/null @@ -1,10 +0,0 @@ -forward.scala:6: error: forward reference extends over definition of value x - def f: Int = x; - ^ -forward.scala:10: error: forward reference extends over definition of value x - def f: Int = g; - ^ -forward.scala:15: error: forward reference extends over definition of variable x - def f: Int = g; - ^ -three errors found diff --git a/tests/untried/neg/forward.scala b/tests/untried/neg/forward.scala deleted file mode 100644 index d5c0851f09e3..000000000000 --- a/tests/untried/neg/forward.scala +++ /dev/null @@ -1,24 +0,0 @@ -object Test { - def f: Int = x; - val x: Int = f; - - { - def f: Int = x; - val x: Int = f; - } - { - def f: Int = g; - val x: Int = f; - def g: Int = x; - } - { - def f: Int = g; - var x: Int = f; - def g: Int = x; - } - { - def f: Int = g; - Console.println("foo"); - def g: Int = f; - } -}