-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Wrong error message for ambiguous given instances #19414
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
Perhaps a related issue - when the instance below |
If I add |
This issue was picked for the Issue Spree No. 42 of February 6th, 2024. @mbovel, @KuceraMartin, @nmcb will be working on it. If you have any insight into the issue or guidance on how to fix it, please leave it here. |
Note: it works if the default parameter is in a separate list: given[B](using writer: JsonWriter[B])(using printer: JsonPrinter = new JsonPrinter): BodySerializer[B] = ??? |
The contextual bound desugars to an implicit rather than using which seems to cause a problem in Applications.scala:641 (it doesn't fall into the else if branch because it's not a contextual function) |
We tried: diff --git a/compiler/src/dotty/tools/dotc/typer/Typer.scala b/compiler/src/dotty/tools/dotc/typer/Typer.scala
index 7727c125d1..9d35f80f66 100644
--- a/compiler/src/dotty/tools/dotc/typer/Typer.scala
+++ b/compiler/src/dotty/tools/dotc/typer/Typer.scala
@@ -3899,7 +3899,7 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
// If method has default params, fall back to regular application
// where all inferred implicits are passed as named args.
- if hasDefaultParams && !propFail.isInstanceOf[AmbiguousImplicits] then
+ if hasDefaultParams && !args.exists(_.tpe.isInstanceOf[AmbiguousImplicits]) then
val namedArgs = wtp.paramNames.lazyZip(args).flatMap { (pname, arg) =>
if (arg.tpe.isError) Nil else untpd.NamedArg(pname, untpd.TypedSplice(arg)) :: Nil which yields the following error message:
Note: it says I also tried: diff --git a/compiler/src/dotty/tools/dotc/typer/Typer.scala b/compiler/src/dotty/tools/dotc/typer/Typer.scala
index 7727c125d1..32c9474891 100644
--- a/compiler/src/dotty/tools/dotc/typer/Typer.scala
+++ b/compiler/src/dotty/tools/dotc/typer/Typer.scala
@@ -3899,9 +3899,9 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
// If method has default params, fall back to regular application
// where all inferred implicits are passed as named args.
- if hasDefaultParams && !propFail.isInstanceOf[AmbiguousImplicits] then
+ if hasDefaultParams then
val namedArgs = wtp.paramNames.lazyZip(args).flatMap { (pname, arg) =>
- if (arg.tpe.isError) Nil else untpd.NamedArg(pname, untpd.TypedSplice(arg)) :: Nil
+ if (arg.tpe.isError && !arg.tpe.isInstanceOf[AmbiguousImplicits]) Nil else untpd.NamedArg(pname, untpd.TypedSplice(arg))
:: Nil
} which yields the following error message:
Note: the note is wrong. |
I don't understand why It returns the first non-ambiguous error if there is one, or else the first error, or else Written otherwise: val firstNonAmbiguous = args.tpes.find(tp => tp.isError && !tp.isInstanceOf[AmbiguousImplicits])
def firstError = args.tpes.find(_.isError)
val propFail = firstNonAmbiguous.orElse(firstError).getOrElse(NoType) Why isn't it the opposite; why doesn't it return the first ambiguous error if there is one? val firstAmbiguous = args.tpes.find(_.isInstanceOf[AmbiguousImplicits])
def firstError = args.tpes.find(_.isError)
val propFail = firstAmbiguous.orElse(firstError).getOrElse(NoType) Can adding default arguments avoid an ambiguous error? That would explain it. If not, we could probably report it directly. |
Something else: even when the expected message is shown |
Ambiguous implicits often arise when something else is failing (for instance a variable was not instantiated enough). That's why we try to find first other errors. That was the thinking behind the current semantic. So I am not sure reversing this as in #19647 is always the thing to do. It might make error messages worse in other contexts. |
Looking again into this, the main difference between the case with the default arg and the case without is that in the former, I made two tentatives to call it in the default args case:
Neither look very nice… Not sure if there is a simpler way. By the way, I also found why the parameters name is wrong: as the |
Compiler version
3.3.1, 3.4.0-RC1-bin-20240109-91db06a-NIGHTLY
Minimized code
Output
Expectation
note: the expectation is what I got when I removed the implicit
JsonPrinter
parameter from the givenBodySerializer
:The text was updated successfully, but these errors were encountered: