aboutsummaryrefslogtreecommitdiff
path: root/src/dotty/tools/dotc
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2016-09-01 19:10:48 +0200
committerMartin Odersky <odersky@gmail.com>2016-10-02 16:11:21 +0200
commit617be516b261524c2f0762de10f2bde376043ad7 (patch)
tree093df00ecbb02bfe5b06b2040fad953a613b4f20 /src/dotty/tools/dotc
parentfaba2b7999bf73bf10116b391efbdd751054ead0 (diff)
downloaddotty-617be516b261524c2f0762de10f2bde376043ad7.tar.gz
dotty-617be516b261524c2f0762de10f2bde376043ad7.tar.bz2
dotty-617be516b261524c2f0762de10f2bde376043ad7.zip
Print inlining positions in error messages
Error messages now print the inlined positions as well as the position of the inlined call, recursively.
Diffstat (limited to 'src/dotty/tools/dotc')
-rw-r--r--src/dotty/tools/dotc/core/Contexts.scala8
-rw-r--r--src/dotty/tools/dotc/core/Decorators.scala14
-rw-r--r--src/dotty/tools/dotc/reporting/ConsoleReporter.scala19
-rw-r--r--src/dotty/tools/dotc/typer/Inliner.scala18
-rw-r--r--src/dotty/tools/dotc/util/SourcePosition.scala6
5 files changed, 42 insertions, 23 deletions
diff --git a/src/dotty/tools/dotc/core/Contexts.scala b/src/dotty/tools/dotc/core/Contexts.scala
index ea0ab95e6..f2a1fe53e 100644
--- a/src/dotty/tools/dotc/core/Contexts.scala
+++ b/src/dotty/tools/dotc/core/Contexts.scala
@@ -370,12 +370,8 @@ object Contexts {
/** The current source file; will be derived from current
* compilation unit.
*/
- def source: SourceFile = {
- val file = Inliner.inlinedSource
- if (file.exists) file
- else if (compilationUnit == null) NoSource
- else compilationUnit.source
- }
+ def source: SourceFile =
+ if (compilationUnit == null) NoSource else compilationUnit.source
/** Does current phase use an erased types interpretation? */
def erasedTypes: Boolean = phase.erasedTypes
diff --git a/src/dotty/tools/dotc/core/Decorators.scala b/src/dotty/tools/dotc/core/Decorators.scala
index 387e7e466..fc546667d 100644
--- a/src/dotty/tools/dotc/core/Decorators.scala
+++ b/src/dotty/tools/dotc/core/Decorators.scala
@@ -7,6 +7,8 @@ import Contexts._, Names._, Phases._, printing.Texts._, printing.Printer, printi
import util.Positions.Position, util.SourcePosition
import collection.mutable.ListBuffer
import dotty.tools.dotc.transform.TreeTransforms._
+import typer.Inliner
+import ast.tpd.Inlined
import scala.language.implicitConversions
import printing.Formatting._
@@ -148,8 +150,16 @@ object Decorators {
}
}
- implicit def sourcePos(pos: Position)(implicit ctx: Context): SourcePosition =
- ctx.source.atPos(pos)
+ implicit def sourcePos(pos: Position)(implicit ctx: Context): SourcePosition = {
+ def recur(inlineds: Stream[Inlined], pos: Position): SourcePosition = inlineds match {
+ case inlined #:: rest =>
+ Inliner.sourceFile(inlined).atPos(pos)
+ .withOuter(recur(rest, inlined.call.pos))
+ case empty =>
+ ctx.source.atPos(pos)
+ }
+ recur(Inliner.enclosingInlineds, pos)
+ }
implicit class StringInterpolators(val sc: StringContext) extends AnyVal {
diff --git a/src/dotty/tools/dotc/reporting/ConsoleReporter.scala b/src/dotty/tools/dotc/reporting/ConsoleReporter.scala
index f35293d8d..deb772db5 100644
--- a/src/dotty/tools/dotc/reporting/ConsoleReporter.scala
+++ b/src/dotty/tools/dotc/reporting/ConsoleReporter.scala
@@ -21,11 +21,15 @@ class ConsoleReporter(
/** maximal number of error messages to be printed */
protected def ErrorLimit = 100
- def printSourceLine(pos: SourcePosition) =
- printMessage(pos.lineContent.stripLineEnd)
-
- def printColumnMarker(pos: SourcePosition) =
- if (pos.exists) { printMessage(" " * pos.column + "^") }
+ def printPos(pos: SourcePosition): Unit =
+ if (pos.exists) {
+ printMessage(pos.lineContent.stripLineEnd)
+ printMessage(" " * pos.column + "^")
+ if (pos.outer.exists) {
+ printMessage(s"\n... this location is in code that was inlined at ${pos.outer}:\n")
+ printPos(pos.outer)
+ }
+ }
/** Prints the message. */
def printMessage(msg: String): Unit = { writer.print(msg + "\n"); writer.flush() }
@@ -34,10 +38,7 @@ class ConsoleReporter(
def printMessageAndPos(msg: String, pos: SourcePosition)(implicit ctx: Context): Unit = {
val posStr = if (pos.exists) s"$pos: " else ""
printMessage(posStr + msg)
- if (pos.exists) {
- printSourceLine(pos)
- printColumnMarker(pos)
- }
+ printPos(pos)
}
override def doReport(d: Diagnostic)(implicit ctx: Context): Unit = d match {
diff --git a/src/dotty/tools/dotc/typer/Inliner.scala b/src/dotty/tools/dotc/typer/Inliner.scala
index 28c725b33..8d25e3250 100644
--- a/src/dotty/tools/dotc/typer/Inliner.scala
+++ b/src/dotty/tools/dotc/typer/Inliner.scala
@@ -82,11 +82,19 @@ object Inliner {
def inlineContext(tree: untpd.Inlined)(implicit ctx: Context): Context =
ctx.fresh.setProperty(InlinedCall, tree)
- def inlinedSource(implicit ctx: Context): SourceFile = ctx.property(InlinedCall) match {
- case Some(inlined) =>
- val file = inlined.call.symbol.sourceFile
- if (file.exists) new SourceFile(file) else NoSource
- case _ => NoSource
+ def enclosingInlineds(implicit ctx: Context): Stream[Inlined] =
+ ctx.property(InlinedCall) match {
+ case found @ Some(inlined) =>
+ inlined #::
+ enclosingInlineds(
+ ctx.outersIterator.dropWhile(_.property(InlinedCall) == found).next)
+ case _ =>
+ Stream.Empty
+ }
+
+ def sourceFile(inlined: Inlined)(implicit ctx: Context) = {
+ val file = inlined.call.symbol.sourceFile
+ if (file.exists) new SourceFile(file) else NoSource
}
}
diff --git a/src/dotty/tools/dotc/util/SourcePosition.scala b/src/dotty/tools/dotc/util/SourcePosition.scala
index 0b2b2aa0b..68a9b6403 100644
--- a/src/dotty/tools/dotc/util/SourcePosition.scala
+++ b/src/dotty/tools/dotc/util/SourcePosition.scala
@@ -5,7 +5,8 @@ package util
import Positions.{Position, NoPosition}
/** A source position is comprised of a position in a source file */
-case class SourcePosition(source: SourceFile, pos: Position) extends interfaces.SourcePosition {
+case class SourcePosition(source: SourceFile, pos: Position, outer: SourcePosition = NoSourcePosition)
+extends interfaces.SourcePosition {
def exists = pos.exists
def lineContent: String = source.lineContent(point)
@@ -24,6 +25,8 @@ case class SourcePosition(source: SourceFile, pos: Position) extends interfaces.
def endLine: Int = source.offsetToLine(end)
def endColumn: Int = source.column(end)
+ def withOuter(outer: SourcePosition) = new SourcePosition(source, pos, outer)
+
override def toString =
if (source.exists) s"${source.file}:${line + 1}"
else s"(no source file, offset = ${pos.point})"
@@ -32,5 +35,6 @@ case class SourcePosition(source: SourceFile, pos: Position) extends interfaces.
/** A sentinel for a non-existing source position */
@sharable object NoSourcePosition extends SourcePosition(NoSource, NoPosition) {
override def toString = "?"
+ override def withOuter(outer: SourcePosition) = outer
}