From 9a1274feb1600a6428c9803ed4018d94a5649c80 Mon Sep 17 00:00:00 2001 From: Georgi Krastev Date: Thu, 3 Jun 2021 23:03:07 +0300 Subject: [PATCH] More details to forward reference error messages Include the referenced symbol and the line where it's defined. --- .../scala/tools/nsc/typechecker/RefChecks.scala | 13 ++++++++----- test/files/neg/forward.check | 11 +++++++---- test/files/neg/forward.scala | 11 +++++++++++ test/files/neg/t2910.check | 10 +++++----- test/files/neg/t4098.check | 8 ++++---- test/files/neg/t4419.check | 2 +- test/files/neg/t5390.check | 2 +- test/files/neg/t5390b.check | 2 +- test/files/neg/t5390c.check | 2 +- test/files/neg/t5390d.check | 2 +- 10 files changed, 40 insertions(+), 23 deletions(-) diff --git a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala index d69f02710abc..88dd49c3417e 100644 --- a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala +++ b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala @@ -1215,14 +1215,18 @@ abstract class RefChecks extends Transform { finally popLevel() } + private def showCurrentRef: String = { + val refsym = currentLevel.refsym + s"$refsym defined on line ${refsym.pos.line}" + } + def transformStat(tree: Tree, index: Int): Tree = tree match { case t if treeInfo.isSelfConstrCall(t) => assert(index == 0, index) try transform(tree) finally if (currentLevel.maxindex > 0) { - // An implementation restriction to avoid VerifyErrors and lazyvals mishaps; see scala/bug#4717 - debuglog("refsym = " + currentLevel.refsym) - reporter.error(currentLevel.refpos, "forward reference not allowed from self constructor invocation") + // An implementation restriction to avoid VerifyErrors and lazy vals mishaps; see scala/bug#4717 + reporter.error(currentLevel.refpos, s"forward reference to $showCurrentRef not allowed from self constructor invocation") } case ValDef(_, _, _, _) => val tree1 = transform(tree) // important to do before forward reference check @@ -1230,8 +1234,7 @@ abstract class RefChecks extends Transform { else { val sym = tree.symbol if (sym.isLocalToBlock && index <= currentLevel.maxindex) { - debuglog("refsym = " + currentLevel.refsym) - reporter.error(currentLevel.refpos, "forward reference extends over definition of " + sym) + reporter.error(currentLevel.refpos, s"forward reference to $showCurrentRef extends over definition of $sym") } tree1 } diff --git a/test/files/neg/forward.check b/test/files/neg/forward.check index 12051a1c14f7..79630f888fbd 100644 --- a/test/files/neg/forward.check +++ b/test/files/neg/forward.check @@ -1,10 +1,13 @@ -forward.scala:6: error: forward reference extends over definition of value x +forward.scala:8: error: forward reference to value x defined on line 9 extends over definition of value x def f: Int = x; ^ -forward.scala:10: error: forward reference extends over definition of value x +forward.scala:12: error: forward reference to method g defined on line 14 extends over definition of value x def f: Int = g; ^ -forward.scala:15: error: forward reference extends over definition of variable x +forward.scala:17: error: forward reference to method g defined on line 19 extends over definition of variable x def f: Int = g; ^ -3 errors +forward.scala:29: error: forward reference to value ec defined on line 32 extends over definition of value z + a <- fInt + ^ +4 errors diff --git a/test/files/neg/forward.scala b/test/files/neg/forward.scala index d5c0851f09e3..bf1fc7ac8c95 100644 --- a/test/files/neg/forward.scala +++ b/test/files/neg/forward.scala @@ -1,3 +1,5 @@ +import scala.concurrent._ + object Test { def f: Int = x; val x: Int = f; @@ -21,4 +23,13 @@ object Test { Console.println("foo"); def g: Int = f; } + { + val fInt = Future.successful(1) + val z = for { + a <- fInt + } yield a + + implicit val ec: ExecutionContext = ExecutionContext.Implicits.global + z + } } diff --git a/test/files/neg/t2910.check b/test/files/neg/t2910.check index cdf36f9eaa14..fd98de338b06 100644 --- a/test/files/neg/t2910.check +++ b/test/files/neg/t2910.check @@ -1,16 +1,16 @@ -t2910.scala:3: error: forward reference extends over definition of value ret +t2910.scala:3: error: forward reference to value MyMatch defined on line 4 extends over definition of value ret val ret = l.collect({ case MyMatch(id) => id }) ^ -t2910.scala:9: error: forward reference extends over definition of value z +t2910.scala:9: error: forward reference to lazy value s defined on line 11 extends over definition of value z println(s.length) ^ -t2910.scala:16: error: forward reference extends over definition of value z +t2910.scala:16: error: forward reference to lazy value x defined on line 18 extends over definition of value z x ^ -t2910.scala:30: error: forward reference extends over definition of value x +t2910.scala:30: error: forward reference to value x defined on line 31 extends over definition of value x lazy val f: Int = x ^ -t2910.scala:35: error: forward reference extends over definition of variable x +t2910.scala:35: error: forward reference to lazy value g defined on line 37 extends over definition of variable x lazy val f: Int = g ^ 5 errors diff --git a/test/files/neg/t4098.check b/test/files/neg/t4098.check index 590cee98698d..8e15e90abaa3 100644 --- a/test/files/neg/t4098.check +++ b/test/files/neg/t4098.check @@ -1,13 +1,13 @@ -t4098.scala:3: error: forward reference not allowed from self constructor invocation +t4098.scala:3: error: forward reference to method b defined on line 4 not allowed from self constructor invocation this(b) ^ -t4098.scala:8: error: forward reference not allowed from self constructor invocation +t4098.scala:8: error: forward reference to lazy value b defined on line 9 not allowed from self constructor invocation this(b) ^ -t4098.scala:13: error: forward reference not allowed from self constructor invocation +t4098.scala:13: error: forward reference to value b defined on line 14 not allowed from self constructor invocation this(b) ^ -t4098.scala:18: error: forward reference not allowed from self constructor invocation +t4098.scala:18: error: forward reference to method b defined on line 20 not allowed from self constructor invocation this(b) ^ 4 errors diff --git a/test/files/neg/t4419.check b/test/files/neg/t4419.check index 7cf623541a9d..cce4223ecf24 100644 --- a/test/files/neg/t4419.check +++ b/test/files/neg/t4419.check @@ -1,4 +1,4 @@ -t4419.scala:2: error: forward reference extends over definition of value b +t4419.scala:2: error: forward reference to value a defined on line 2 extends over definition of value b { val b = a; val a = 1 ; println(a) } ^ 1 error diff --git a/test/files/neg/t5390.check b/test/files/neg/t5390.check index ddd56cd611ae..0f5b2a3a4e02 100644 --- a/test/files/neg/t5390.check +++ b/test/files/neg/t5390.check @@ -1,4 +1,4 @@ -t5390.scala:7: error: forward reference extends over definition of value b +t5390.scala:7: error: forward reference to value a defined on line 8 extends over definition of value b val b = a.B("") ^ 1 error diff --git a/test/files/neg/t5390b.check b/test/files/neg/t5390b.check index d54d6110b977..55c13c06d7d5 100644 --- a/test/files/neg/t5390b.check +++ b/test/files/neg/t5390b.check @@ -1,4 +1,4 @@ -t5390b.scala:7: error: forward reference extends over definition of value b +t5390b.scala:7: error: forward reference to value a defined on line 8 extends over definition of value b val b = a.B("") ^ 1 error diff --git a/test/files/neg/t5390c.check b/test/files/neg/t5390c.check index 861d6447b81d..1688bb3f4afb 100644 --- a/test/files/neg/t5390c.check +++ b/test/files/neg/t5390c.check @@ -1,4 +1,4 @@ -t5390c.scala:7: error: forward reference extends over definition of value b +t5390c.scala:7: error: forward reference to value a defined on line 8 extends over definition of value b val b = new a.B("") ^ 1 error diff --git a/test/files/neg/t5390d.check b/test/files/neg/t5390d.check index ed117ea9dac2..c814ddd53cb8 100644 --- a/test/files/neg/t5390d.check +++ b/test/files/neg/t5390d.check @@ -1,4 +1,4 @@ -t5390d.scala:7: error: forward reference extends over definition of value b +t5390d.scala:7: error: forward reference to value a defined on line 8 extends over definition of value b val b = a.B.toString ^ 1 error