From 47901c09885f8931d82a3bbc469985a50f790091 Mon Sep 17 00:00:00 2001 From: Enno Date: Tue, 14 Feb 2017 12:52:20 +0100 Subject: 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) --- .../tools/dotc/reporting/diagnostic/messages.scala | 19 +++++++++++++++++ .../src/dotty/tools/dotc/typer/RefChecks.scala | 4 ++-- .../tools/dotc/reporting/ErrorMessagesTests.scala | 24 +++++++++++++++++++++- 3 files changed, 44 insertions(+), 3 deletions(-) (limited to 'compiler') 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) + } + } -- cgit v1.2.3