Skip to content

Commit

Permalink
Add note about type mismatch in automatically inserted apply argument
Browse files Browse the repository at this point in the history
Co-Authored-By: Jan-Pieter van den Heuvel <[email protected]>
Co-Authored-By: Lucas Nouguier <[email protected]>
  • Loading branch information
3 people committed Mar 26, 2024
1 parent fca115a commit 127372d
Show file tree
Hide file tree
Showing 5 changed files with 36 additions and 3 deletions.
5 changes: 5 additions & 0 deletions compiler/src/dotty/tools/dotc/reporting/Reporter.scala
Original file line number Diff line number Diff line change
Expand Up @@ -263,6 +263,11 @@ abstract class Reporter extends interfaces.ReporterResult {
/** If this reporter buffers messages, remove and return all buffered messages. */
def removeBufferedMessages(using Context): List[Diagnostic] = Nil

/** If this reporter buffers messages, apply `f` to all buffered messages. */
def mapBufferedMessages(f: Diagnostic => Diagnostic)(using Context): Unit =
val mappedDiagnostics = removeBufferedMessages.map(f)
mappedDiagnostics.foreach(report)

/** Issue all messages in this reporter to next outer one, or make sure they are written. */
def flush()(using Context): Unit =
val msgs = removeBufferedMessages
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ class StoreReporter(outer: Reporter | Null = Reporter.NoReporter, fromTyperState

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

def doReport(dia: Diagnostic)(using Context): Unit = {
override def doReport(dia: Diagnostic)(using Context): Unit = {
typr.println(s">>>> StoredError: ${dia.message}") // !!! DEBUG
if (infos == null) infos = new mutable.ListBuffer
infos.uncheckedNN += dia
Expand Down
2 changes: 1 addition & 1 deletion compiler/src/dotty/tools/dotc/reporting/messages.scala
Original file line number Diff line number Diff line change
Expand Up @@ -289,7 +289,7 @@ extends NotFoundMsg(MissingIdentID) {
}
}

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

def msg(using Context) =
Expand Down
27 changes: 26 additions & 1 deletion compiler/src/dotty/tools/dotc/typer/Applications.scala
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import Inferencing.*
import reporting.*
import Nullables.*, NullOpsDecorator.*
import config.Feature
import printing.Texts.{stringToText, Text}

import collection.mutable
import config.Printers.{overload, typr, unapp}
Expand Down Expand Up @@ -1068,7 +1069,31 @@ trait Applications extends Compatibility {
simpleApply(fun1, proto)
} {
(failedVal, failedState) =>
def fail = { failedState.commit(); failedVal }
def fail =
insertedApplyNote()
failedState.commit()
failedVal

/** If the applied function is an automatically inserted `apply` method and one of its
* arguments has a type mistmathc , append a note
* to the error message that explains that the required type comes from a parameter
* of the inserted `apply` method. See #19680 and associated test case.
*/
def insertedApplyNote() =
if fun1.symbol.name == nme.apply && fun1.span.isSynthetic then
failedState.reporter.mapBufferedMessages:
case dia: Diagnostic.Error =>
dia.msg match
case msg: TypeMismatch =>
msg.inTree match
case Some(arg) if tree.args.exists(_.span == arg.span) =>
val Select(prefix, _apply) = fun1: @unchecked
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
Diagnostic.Error(msg.append(txt), dia.pos)
case _ => dia
case msg => dia
case dia => dia

// Try once with original prototype and once (if different) with tupled one.
// The reason we need to try both is that the decision whether to use tupled
// or not was already taken but might have to be revised when an implicit
Expand Down
3 changes: 3 additions & 0 deletions tests/pos/19680.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
class Config()
def renderWebsite(path: String)(using config: Config): String = ???
def renderWidget(using Config): Unit = renderWebsite("/tmp")(Config())

0 comments on commit 127372d

Please sign in to comment.