Skip to content

Commit 127372d

Browse files
mboveljan-pieteriusildra
committed
Add note about type mismatch in automatically inserted apply argument
Co-Authored-By: Jan-Pieter van den Heuvel <[email protected]> Co-Authored-By: Lucas Nouguier <[email protected]>
1 parent fca115a commit 127372d

File tree

5 files changed

+36
-3
lines changed

5 files changed

+36
-3
lines changed

compiler/src/dotty/tools/dotc/reporting/Reporter.scala

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -263,6 +263,11 @@ abstract class Reporter extends interfaces.ReporterResult {
263263
/** If this reporter buffers messages, remove and return all buffered messages. */
264264
def removeBufferedMessages(using Context): List[Diagnostic] = Nil
265265

266+
/** If this reporter buffers messages, apply `f` to all buffered messages. */
267+
def mapBufferedMessages(f: Diagnostic => Diagnostic)(using Context): Unit =
268+
val mappedDiagnostics = removeBufferedMessages.map(f)
269+
mappedDiagnostics.foreach(report)
270+
266271
/** Issue all messages in this reporter to next outer one, or make sure they are written. */
267272
def flush()(using Context): Unit =
268273
val msgs = removeBufferedMessages

compiler/src/dotty/tools/dotc/reporting/StoreReporter.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ class StoreReporter(outer: Reporter | Null = Reporter.NoReporter, fromTyperState
2121

2222
protected var infos: mutable.ListBuffer[Diagnostic] | Null = null
2323

24-
def doReport(dia: Diagnostic)(using Context): Unit = {
24+
override def doReport(dia: Diagnostic)(using Context): Unit = {
2525
typr.println(s">>>> StoredError: ${dia.message}") // !!! DEBUG
2626
if (infos == null) infos = new mutable.ListBuffer
2727
infos.uncheckedNN += dia

compiler/src/dotty/tools/dotc/reporting/messages.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -289,7 +289,7 @@ extends NotFoundMsg(MissingIdentID) {
289289
}
290290
}
291291

292-
class TypeMismatch(val found: Type, expected: Type, inTree: Option[untpd.Tree], addenda: => String*)(using Context)
292+
class TypeMismatch(val found: Type, expected: Type, val inTree: Option[untpd.Tree], addenda: => String*)(using Context)
293293
extends TypeMismatchMsg(found, expected)(TypeMismatchID):
294294

295295
def msg(using Context) =

compiler/src/dotty/tools/dotc/typer/Applications.scala

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import Inferencing.*
2323
import reporting.*
2424
import Nullables.*, NullOpsDecorator.*
2525
import config.Feature
26+
import printing.Texts.{stringToText, Text}
2627

2728
import collection.mutable
2829
import config.Printers.{overload, typr, unapp}
@@ -1068,7 +1069,31 @@ trait Applications extends Compatibility {
10681069
simpleApply(fun1, proto)
10691070
} {
10701071
(failedVal, failedState) =>
1071-
def fail = { failedState.commit(); failedVal }
1072+
def fail =
1073+
insertedApplyNote()
1074+
failedState.commit()
1075+
failedVal
1076+
1077+
/** If the applied function is an automatically inserted `apply` method and one of its
1078+
* arguments has a type mistmathc , append a note
1079+
* to the error message that explains that the required type comes from a parameter
1080+
* of the inserted `apply` method. See #19680 and associated test case.
1081+
*/
1082+
def insertedApplyNote() =
1083+
if fun1.symbol.name == nme.apply && fun1.span.isSynthetic then
1084+
failedState.reporter.mapBufferedMessages:
1085+
case dia: Diagnostic.Error =>
1086+
dia.msg match
1087+
case msg: TypeMismatch =>
1088+
msg.inTree match
1089+
case Some(arg) if tree.args.exists(_.span == arg.span) =>
1090+
val Select(prefix, _apply) = fun1: @unchecked
1091+
val txt = ("\n\nThe required type comes from a parameter of the automatically inserted " ~ ("`" + ctx.printer.nameString(nme.apply ) + "`") ~ " method of " ~ prefix.tpe.show ~ ", which is the type of " ~ prefix.show ~ ".").show
1092+
Diagnostic.Error(msg.append(txt), dia.pos)
1093+
case _ => dia
1094+
case msg => dia
1095+
case dia => dia
1096+
10721097
// Try once with original prototype and once (if different) with tupled one.
10731098
// The reason we need to try both is that the decision whether to use tupled
10741099
// or not was already taken but might have to be revised when an implicit

tests/pos/19680.scala

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
class Config()
2+
def renderWebsite(path: String)(using config: Config): String = ???
3+
def renderWidget(using Config): Unit = renderWebsite("/tmp")(Config())

0 commit comments

Comments
 (0)