Skip to content

Commit ab6f29a

Browse files
committed
Pretty print type on f-interpolator, improve caret
1 parent d5b7aa2 commit ab6f29a

File tree

2 files changed

+19
-7
lines changed

2 files changed

+19
-7
lines changed

compiler/src/dotty/tools/dotc/transform/localopt/FormatChecker.scala

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import dotty.tools.dotc.core.Contexts._
1515
import dotty.tools.dotc.core.Symbols._
1616
import dotty.tools.dotc.core.Types._
1717
import dotty.tools.dotc.core.Phases.typerPhase
18+
import dotty.tools.dotc.util.Spans.Span
1819

1920
/** Formatter string checker. */
2021
class TypedFormatChecker(partsElems: List[Tree], parts: List[String], args: List[Tree])(using Context):
@@ -33,7 +34,7 @@ class TypedFormatChecker(partsElems: List[Tree], parts: List[String], args: List
3334
types.find(t => argConformsTo(argi, tpe, t))
3435
.orElse(types.find(t => argConvertsTo(argi, tpe, t)))
3536
.getOrElse {
36-
report.argError(s"Found: ${tpe.show}, Required: ${types.mkString(", ")}", argi)
37+
report.argError(s"Found: ${tpe.show}, Required: ${types.map(_.show).mkString(", ")}", argi)
3738
actuals += args(argi)
3839
types.head
3940
}
@@ -118,6 +119,7 @@ class TypedFormatChecker(partsElems: List[Tree], parts: List[String], args: List
118119

119120
extension (descriptor: Match)
120121
def at(g: SpecGroup): Int = descriptor.start(g.ordinal)
122+
def end(g: SpecGroup): Int = descriptor.end(g.ordinal)
121123
def offset(g: SpecGroup, i: Int = 0): Int = at(g) + i
122124
def group(g: SpecGroup): Option[String] = Option(descriptor.group(g.ordinal))
123125
def stringOf(g: SpecGroup): String = group(g).getOrElse("")
@@ -243,8 +245,8 @@ class TypedFormatChecker(partsElems: List[Tree], parts: List[String], args: List
243245
val i = flags.indexOf(f) match { case -1 => 0 case j => j }
244246
errorAt(Flags, i)(msg)
245247

246-
def errorAt(g: SpecGroup, i: Int = 0)(msg: String) = report.partError(msg, argi, descriptor.offset(g, i))
247-
def warningAt(g: SpecGroup, i: Int = 0)(msg: String) = report.partWarning(msg, argi, descriptor.offset(g, i))
248+
def errorAt(g: SpecGroup, i: Int = 0)(msg: String) = report.partError(msg, argi, descriptor.offset(g, i), descriptor.end(g))
249+
def warningAt(g: SpecGroup, i: Int = 0)(msg: String) = report.partWarning(msg, argi, descriptor.offset(g, i), descriptor.end(g))
248250

249251
object Conversion:
250252
def apply(m: Match, i: Int): Conversion =
@@ -272,12 +274,14 @@ class TypedFormatChecker(partsElems: List[Tree], parts: List[String], args: List
272274

273275
var reported = false
274276

275-
private def partPosAt(index: Int, offset: Int) =
277+
private def partPosAt(index: Int, offset: Int, end: Int) =
276278
val pos = partsElems(index).sourcePos
277-
pos.withSpan(pos.span.shift(offset))
279+
val bgn = pos.span.start + offset
280+
val fin = if end < 0 then pos.span.end else pos.span.start + end
281+
pos.withSpan(Span(bgn, fin, bgn))
278282

279283
extension (r: report.type)
280284
def argError(message: String, index: Int): Unit = r.error(message, args(index).srcPos).tap(_ => reported = true)
281-
def partError(message: String, index: Int, offset: Int): Unit = r.error(message, partPosAt(index, offset)).tap(_ => reported = true)
282-
def partWarning(message: String, index: Int, offset: Int): Unit = r.warning(message, partPosAt(index, offset)).tap(_ => reported = true)
285+
def partError(message: String, index: Int, offset: Int, end: Int = -1): Unit = r.error(message, partPosAt(index, offset, end)).tap(_ => reported = true)
286+
def partWarning(message: String, index: Int, offset: Int, end: Int = -1): Unit = r.warning(message, partPosAt(index, offset, end)).tap(_ => reported = true)
283287
end TypedFormatChecker

tests/neg/f-interpolator-tests.check

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
-- Error: tests/neg/f-interpolator-tests.scala:4:19 --------------------------------------------------------------------
2+
4 | def `um uh` = f"$s%d" // error
3+
| ^
4+
| Found: (T.this.s : String), Required: Int, Long, Byte, Short, BigInt
5+
-- Error: tests/neg/f-interpolator-tests.scala:10:10 -------------------------------------------------------------------
6+
10 | f"x % y = ${x % y}%d" // error: illegal conversion character 'y'
7+
| ^
8+
| illegal conversion character 'y'

0 commit comments

Comments
 (0)