Skip to content

Commit 66ff62f

Browse files
committed
Improve the message per excellent review
1 parent ca334ab commit 66ff62f

File tree

7 files changed

+104
-51
lines changed

7 files changed

+104
-51
lines changed

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

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1215,16 +1215,21 @@ extends DeclarationMsg(OverrideErrorID), NoDisambiguation:
12151215
class ForwardReferenceExtendsOverDefinition(value: Symbol, definition: Symbol)(using Context)
12161216
extends ReferenceMsg(ForwardReferenceExtendsOverDefinitionID) {
12171217
extension (sym: Symbol) def srcLine = sym.line + 1
1218-
def msg(using Context) = i"${definition.name}${
1219-
if value != definition then s" (defined on L${definition.srcLine})" else ""
1220-
} is a forward reference extending over the definition of ${value.name} (on L${value.srcLine})"
1218+
1219+
def msg(using Context) =
1220+
val ref =
1221+
if value != definition then i"${definition.name} (defined on line ${definition.srcLine})"
1222+
else i"${definition.name}"
1223+
i"forward reference to ${ref} extends over the definition of ${value.name} (on line ${value.srcLine})"
12211224

12221225
def explain(using Context) =
12231226
i"""|${definition.name} is used before you define it, and the definition of ${value.name}
12241227
|appears between that use and the definition of ${definition.name}.
12251228
|
1226-
|Forward references are allowed only, if there are no value definitions between
1227-
|the reference and the referred method definition.
1229+
|Forward references are allowed only if there are no value definitions between
1230+
|the reference and the definition that is referred to.
1231+
|Specifically, any statement between the reference and the definition
1232+
|cannot be a variable definition, and if it's a value definition, it must be lazy.
12281233
|
12291234
|Define ${definition.name} before it is used,
12301235
|or move the definition of ${value.name} so it does not appear between

tests/neg/i14401.check

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,30 @@
11
-- [E039] Reference Error: tests/neg/i14401.scala:6:17 -----------------------------------------------------------------
2-
6 | def f: Int = x; // error
2+
6 | def f: Int = x // error
33
| ^
4-
| x is a forward reference extending over the definition of x (on L7)
4+
| forward reference to x extends over the definition of x (on line 7)
55
|
66
| longer explanation available when compiling with `-explain`
77
-- [E039] Reference Error: tests/neg/i14401.scala:10:17 ----------------------------------------------------------------
8-
10 | def f: Int = g; // error
8+
10 | def f: Int = g // error
99
| ^
10-
| g (defined on L12) is a forward reference extending over the definition of x (on L11)
10+
| forward reference to g (defined on line 12) extends over the definition of x (on line 11)
1111
|
1212
| longer explanation available when compiling with `-explain`
1313
-- [E039] Reference Error: tests/neg/i14401.scala:15:17 ----------------------------------------------------------------
14-
15 | def f: Int = g; // error
14+
15 | def f: Int = g // error
1515
| ^
16-
| g (defined on L17) is a forward reference extending over the definition of x (on L16)
16+
| forward reference to g (defined on line 17) extends over the definition of x (on line 16)
1717
|
1818
| longer explanation available when compiling with `-explain`
1919
-- [E039] Reference Error: tests/neg/i14401.scala:31:20 ----------------------------------------------------------------
20-
31 | } yield a + 27 // error
20+
31 | yield a + 27 // error
2121
| ^
22-
| ec (defined on L33) is a forward reference extending over the definition of z (on L29)
22+
| forward reference to ec (defined on line 32) extends over the definition of z (on line 29)
2323
|
2424
| longer explanation available when compiling with `-explain`
25-
-- [E039] Reference Error: tests/neg/i14401.scala:41:28 ----------------------------------------------------------------
26-
41 | class NotUsed {val xs = args} // error
25+
-- [E039] Reference Error: tests/neg/i14401.scala:38:28 ----------------------------------------------------------------
26+
38 | class NotUsed {val xs = args} // error
2727
| ^^^^
28-
| args (defined on L44) is a forward reference extending over the definition of dummy (on L42)
28+
| forward reference to args (defined on line 41) extends over the definition of dummy (on line 39)
2929
|
3030
| longer explanation available when compiling with `-explain`

tests/neg/i14401.scala

Lines changed: 30 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,46 +1,41 @@
1-
object Test {
2-
def f: Int = x;
3-
val x: Int = f;
1+
object Test:
2+
def f: Int = x
3+
val x: Int = f
44

5-
{
6-
def f: Int = x; // error
7-
val x: Int = f;
8-
}
9-
{
10-
def f: Int = g; // error
11-
val x: Int = f;
12-
def g: Int = x;
13-
}
14-
{
15-
def f: Int = g; // error
16-
var x: Int = f;
17-
def g: Int = x;
18-
}
19-
{
20-
def f: Int = g;
21-
Console.println("foo");
22-
def g: Int = f;
23-
}
24-
{
5+
locally:
6+
def f: Int = x // error
7+
val x: Int = f
8+
9+
locally:
10+
def f: Int = g // error
11+
val x: Int = f
12+
def g: Int = x
13+
14+
locally:
15+
def f: Int = g // error
16+
var x: Int = f
17+
def g: Int = x
18+
19+
locally:
20+
def f: Int = g
21+
Console.println("foo")
22+
def g: Int = f
23+
24+
locally:
2525
import scala.concurrent.{ExecutionContext, Future}, ExecutionContext.Implicits
2626

27-
def foo: Future[Int] = {
27+
def foo: Future[Int] =
2828
val fInt = Future.successful(42)
29-
val z = for {
30-
a <- fInt
31-
} yield a + 27 // error
32-
29+
val z =
30+
for a <- fInt
31+
yield a + 27 // error
3332
implicit val ec: ExecutionContext = Implicits.global
3433
z
35-
}
3634
foo
37-
}
38-
}
39-
object MyApp {
40-
def main(args: Array[String]) = {
35+
36+
object MyApp:
37+
def main(args: Array[String]) =
4138
class NotUsed {val xs = args} // error
4239
val dummy = false
4340
// oops, shadows the parameter
4441
def args = Seq("a","b","c")
45-
}
46-
}

tests/neg/i14401b.check

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
-- [E039] Reference Error: tests/neg/i14401b.scala:5:17 ----------------------------------------------------------------
2+
5 | def f: Int = x; // error
3+
| ^
4+
| forward reference to x extends over the definition of x (on line 6)
5+
|---------------------------------------------------------------------------------------------------------------------
6+
| Explanation (enabled by `-explain`)
7+
|- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
8+
| x is used before you define it, and the definition of x
9+
| appears between that use and the definition of x.
10+
|
11+
| Forward references are allowed only if there are no value definitions between
12+
| the reference and the definition that is referred to.
13+
| Specifically, any statement between the reference and the definition
14+
| cannot be a variable definition, and if it's a value definition, it must be lazy.
15+
|
16+
| Define x before it is used,
17+
| or move the definition of x so it does not appear between
18+
| the declaration of x and its use,
19+
| or define x as lazy.
20+
---------------------------------------------------------------------------------------------------------------------

tests/neg/i14401b.scala

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
//> using options --explain
2+
3+
object Test:
4+
locally:
5+
def f: Int = x; // error
6+
val x: Int = f;

tests/neg/i14401c.check

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
-- [E039] Reference Error: tests/neg/i14401c.scala:5:17 ----------------------------------------------------------------
2+
5 | def f: Int = g // error
3+
| ^
4+
| forward reference to g (defined on line 7) extends over the definition of x (on line 6)
5+
|---------------------------------------------------------------------------------------------------------------------
6+
| Explanation (enabled by `-explain`)
7+
|- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
8+
| g is used before you define it, and the definition of x
9+
| appears between that use and the definition of g.
10+
|
11+
| Forward references are allowed only if there are no value definitions between
12+
| the reference and the definition that is referred to.
13+
| Specifically, any statement between the reference and the definition
14+
| cannot be a variable definition, and if it's a value definition, it must be lazy.
15+
|
16+
| Define g before it is used,
17+
| or move the definition of x so it does not appear between
18+
| the declaration of g and its use,
19+
| or define x as lazy.
20+
---------------------------------------------------------------------------------------------------------------------

tests/neg/i14401c.scala

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
//> using options --explain
2+
3+
object Test:
4+
locally:
5+
def f: Int = g // error
6+
var x: Int = f
7+
def g: Int = x

0 commit comments

Comments
 (0)