diff options
author | Enno <enno@runne.net> | 2017-02-14 12:52:20 +0100 |
---|---|---|
committer | Felix Mulder <felix.mulder@gmail.com> | 2017-02-14 12:52:20 +0100 |
commit | 47901c09885f8931d82a3bbc469985a50f790091 (patch) | |
tree | 4b478d0235a3cccb4416e9c50bdd9315b3e6f1e7 | |
parent | b29783237c03ade1dd19cc564170c7a87d7b8b84 (diff) | |
download | dotty-47901c09885f8931d82a3bbc469985a50f790091.tar.gz dotty-47901c09885f8931d82a3bbc469985a50f790091.tar.bz2 dotty-47901c09885f8931d82a3bbc469985a50f790091.zip |
Ennru forward reference error (#1973)
* Change 'forward reference extending over the definition' to Message
* Change 'forward reference extending over the definition' to Message
* pesky file should not be included
* Change 'forward reference extending over the definition' to Message (test case)
4 files changed, 51 insertions, 3 deletions
diff --git a/compiler/src/dotty/tools/dotc/reporting/diagnostic/messages.scala b/compiler/src/dotty/tools/dotc/reporting/diagnostic/messages.scala index c25c49597..4d61f21cf 100644 --- a/compiler/src/dotty/tools/dotc/reporting/diagnostic/messages.scala +++ b/compiler/src/dotty/tools/dotc/reporting/diagnostic/messages.scala @@ -1034,4 +1034,23 @@ object messages { |""" } + case class ForwardReferenceExtendsOverDefinition(value: Symbol, definition: Symbol)(implicit ctx: Context) + extends Message(39) { + val kind = "Reference" + val msg = hl"`${definition.name}` is a forward reference extending over the definition of `${value.name}`" + + val explanation = + hl"""|`${definition.name}` is used before you define it, and the definition of `${value.name}` + |appears between that use and the definition of `${definition.name}`. + | + |Forward references are allowed only, if there are no value definitions between + |the reference and the referred method definition. + | + |Define `${definition.name}` before it is used, + |or move the definition of `${value.name}` so it does not appear between + |the declartion of `${definition.name}` and its use, + |or define `${value.name}` as lazy. + |""".stripMargin + } + } diff --git a/compiler/src/dotty/tools/dotc/typer/RefChecks.scala b/compiler/src/dotty/tools/dotc/typer/RefChecks.scala index ada53047a..eab91701b 100644 --- a/compiler/src/dotty/tools/dotc/typer/RefChecks.scala +++ b/compiler/src/dotty/tools/dotc/typer/RefChecks.scala @@ -767,6 +767,7 @@ import RefChecks._ class RefChecks extends MiniPhase { thisTransformer => import tpd._ + import reporting.diagnostic.messages.ForwardReferenceExtendsOverDefinition override def phaseName: String = "refchecks" @@ -789,8 +790,7 @@ class RefChecks extends MiniPhase { thisTransformer => if (sym.exists && sym.owner.isTerm && !sym.is(Lazy)) currentLevel.levelAndIndex.get(sym) match { case Some((level, symIdx)) if symIdx < level.maxIndex => - ctx.debuglog("refsym = " + level.refSym) - ctx.error(s"forward reference extends over definition of $sym", level.refPos) + ctx.error(ForwardReferenceExtendsOverDefinition(sym, level.refSym), level.refPos) case _ => } tree diff --git a/compiler/test/dotty/tools/dotc/reporting/ErrorMessagesTests.scala b/compiler/test/dotty/tools/dotc/reporting/ErrorMessagesTests.scala index be641fe15..d9b7f7f67 100644 --- a/compiler/test/dotty/tools/dotc/reporting/ErrorMessagesTests.scala +++ b/compiler/test/dotty/tools/dotc/reporting/ErrorMessagesTests.scala @@ -4,7 +4,6 @@ package reporting import core.Contexts.Context import diagnostic.messages._ - import org.junit.Assert._ import org.junit.Test @@ -85,4 +84,27 @@ class ErrorMessagesTests extends ErrorMessagesTest { assert(sameName.forall(_.symbol.name.show == "bar"), "at least one method had an unexpected name") } + + @Test def forwardReference = + checkMessagesAfter("refchecks") { + """ + |object Forward { + | def block = { + | a.toInt + | val b = 2 + | val a = BigDecimal("4") + | } + |} + """.stripMargin + } + .expect { (ictx, messages) => + implicit val ctx: Context = ictx + val defn = ictx.definitions + + assertMessageCount(1, messages) + val ForwardReferenceExtendsOverDefinition(value, definition) :: Nil = messages + assertEquals("value b", value.show) + assertEquals("value a", definition.show) + } + } diff --git a/tests/repl/errmsgs.check b/tests/repl/errmsgs.check index 0dc8e8ae5..d7a230e61 100644 --- a/tests/repl/errmsgs.check +++ b/tests/repl/errmsgs.check @@ -85,4 +85,11 @@ scala> val x: List[Int] = "foo" :: List(1) | found: String($1$) | required: Int | +scala> { def f: Int = g; val x: Int = 1; def g: Int = 5; } +-- [E039] Reference Error: <console> ------------------------------------------- +5 |{ def f: Int = g; val x: Int = 1; def g: Int = 5; } + | ^ + | `g` is a forward reference extending over the definition of `x` + +longer explanation available when compiling with `-explain` scala> :quit |