Skip to content

$conforms[Nothing] shows up as a placeholder for missing implicits #8053

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

Closed
julienrf opened this issue Jan 21, 2020 · 2 comments · Fixed by #8611
Closed

$conforms[Nothing] shows up as a placeholder for missing implicits #8053

julienrf opened this issue Jan 21, 2020 · 2 comments · Fixed by #8611

Comments

@julienrf
Copy link
Contributor

julienrf commented Jan 21, 2020

minimized code

class Foo

List(new Foo).sorted

https://scastie.scala-lang.org/27qWTarCSHyAW7OtgXGGvg

The error message unexpectedly mentions $conform[Nothing].

No implicit Ordering defined for B

where:    B is a type variable with constraint >: Foo

I found:

    scala.math.Ordering.ordered[A]($conforms[Nothing])

But method $conforms in object Predef does not match type scala.math.Ordering.AsComparable[A].

expectation

The error message should be:

No implicit Ordering defined for B

where: B is a type variable with constraint >: Foo

(there should be no “I found: ...” part)

@julienrf
Copy link
Contributor Author

I’ve tried to work on this issue today but I’m not sure where this is going…

$conforms[Nothing] is inferred everywhere we look for a given A => B. I’ve noticed that here we check whether a given candidate is compatible with the expected type. And in our case the $conforms candidate has type A => A, which is not compatible with A => B but still the NoViewsAllowed.isCompatible method returns true… I’m not sure if the type comparison function is wrong or if it’s the way we call it that returns the wrong answer. Any hint?

@julienrf
Copy link
Contributor Author

julienrf commented Mar 25, 2020

As far as I understood, when we filter the given candidates, the comparison function does not take type parameter constraints into account. This is why a term with type [A] =>> A => A is considered to be a candidate for any function type.

You can reproduce the problem described in the first comment with this code:

summon[Int => String]

Gives the following error:

No implicit view available from Int => String.
I found:

    $conforms[Nothing]

But method $conforms in object Predef does not match type Int => String.

Since $conforms[Nothing] is uninhabited I think it would make sense to not show it to end-users. Unfortunately, in practice, it shows up a lot: any failing implicit search involving an Ordering instance might select $conforms[Nothing] because of this candidate, which is conditioned by a function. I’m not sure if there are other occurrences of this problem where we “find” a given candidate that turns out to not type check, but I believe it would be better to not keep those candidates in the first place when we filter them.

However, I’m not sure how to achieve this: if we try to fully type-check the given candidates when we filter them, this will surely slow down the compilation a lot…

What do you think of filtering the given candidates in two steps? First, the same step as the current filtering step, and then a second step which would try to type-chek only those that have passed the first step?

julienrf added a commit that referenced this issue Mar 25, 2020
Fixes #8053

When a given candidate turns out to not be applicable we used to report that
there is a mismatch between the candidate type and the expected type.

However, I believe that if there is a type mismatch, then the candidate should
not be a candidate in the first place.

I’ve changed the failure to be a `NoMatchingImplicitsFailure` instead of a mismatch.

Hopefully this won’t have a negative impact. I’ve added a couple of tests that used to
report a mismatch for the "candidate" `$conforms[Nothing]` and they now report that
no given could be found. One existing test was broken by my changes. This test was
very similar to the ones described in #8053, so I’ve changed the test expectation.
julienrf added a commit that referenced this issue Mar 25, 2020
Fixes #8053

When a given candidate turns out to not be applicable we used to report that
there is a mismatch between the candidate type and the expected type.

However, I believe that if there is a type mismatch, then the candidate should
not be a candidate in the first place.

I’ve changed the failure to be a `NoMatchingImplicitsFailure` instead of a mismatch.

Hopefully this won’t have a negative impact. I’ve added a couple of tests that used to
report a mismatch for the "candidate" `$conforms[Nothing]` and they now report that
no given could be found. One existing test was broken by my changes. This test was
very similar to the ones described in #8053, so I’ve changed the test expectation.
julienrf added a commit that referenced this issue Mar 25, 2020
Fixes #8053

When a given candidate turns out to not be applicable we used to report that
there is a mismatch between the candidate type and the expected type.

However, I believe that if there is a type mismatch, then the candidate should
not be a candidate in the first place.

I’ve changed the failure to be a `NoMatchingImplicitsFailure` instead of a mismatch.

Hopefully this won’t have a negative impact. I’ve added a couple of tests that used to
report a mismatch for the "candidate" `$conforms[Nothing]` and they now report that
no given could be found. One existing test was broken by my changes. This test was
very similar to the ones described in #8053, so I’ve changed the test expectation.
julienrf added a commit to scalacenter/dotty that referenced this issue Mar 30, 2020
…[Nothing]` and `<:<.refl[Nothing]`

Fixes scala#8053

When a given candidate turns out to not be applicable we used to report that
there is a mismatch between the candidate type and the expected type.

The goal is to report an error as precise as possible to the user. However, in some cases
showing the inferred candidate brings no value to the user, especially when the candidate
is uninhabited.

I’ve changed the failure to be a `NoMatchingImplicitsFailure` instead of a mismatch when
`$conforms[Nothing]` or `<:<.refl` are inferred because these values are uninhabited and
might be confusing for end users.
julienrf added a commit to scalacenter/dotty that referenced this issue Mar 30, 2020
…[Nothing]` and `<:<.refl[Nothing]`

Fixes scala#8053

When a given candidate turns out to not be applicable we used to report that
there is a mismatch between the candidate type and the expected type.

The goal is to report an error as precise as possible to the user. However, in some cases
showing the inferred candidate brings no value to the user, especially when the candidate
is uninhabited.

I’ve changed the failure to be a `NoMatchingImplicitsFailure` instead of a mismatch when
`$conforms[Nothing]` or `<:<.refl` are inferred because these values are uninhabited and
might be confusing for end users.
julienrf added a commit to scalacenter/dotty that referenced this issue Mar 30, 2020
…[Nothing]` and `<:<.refl[Nothing]`

Fixes scala#8053

When a given candidate turns out to not be applicable we used to report that
there is a mismatch between the candidate type and the expected type.

The goal is to report an error as precise as possible to the user. However, in some cases
showing the inferred candidate brings no value to the user, especially when the candidate
is uninhabited.

I’ve changed the failure to be a `NoMatchingImplicitsFailure` instead of a mismatch when
`$conforms[Nothing]` or `<:<.refl` are inferred because these values are uninhabited and
might be confusing for end users.
julienrf added a commit to scalacenter/dotty that referenced this issue Mar 30, 2020
…[Nothing]` and `<:<.refl[Nothing]`

Fixes scala#8053

When a given candidate turns out to not be applicable we used to report that
there is a mismatch between the candidate type and the expected type.

The goal is to report an error as precise as possible to the user. However, in some cases
showing the inferred candidate brings no value to the user, especially when the candidate
is uninhabited.

I’ve changed the failure to be a `NoMatchingImplicitsFailure` instead of a mismatch when
`$conforms[Nothing]` or `<:<.refl` are inferred because these values are uninhabited and
might be confusing for end users.
julienrf added a commit to scalacenter/dotty that referenced this issue Mar 30, 2020
…[Nothing]` and `<:<.refl[Nothing]`

Fixes scala#8053

When a given candidate turns out to not be applicable we used to report that
there is a mismatch between the candidate type and the expected type.

The goal is to report an error as precise as possible to the user. However, in some cases
showing the inferred candidate brings no value to the user, especially when the candidate
is uninhabited.

I’ve changed the failure to be a `NoMatchingImplicitsFailure` instead of a mismatch when
`$conforms[Nothing]` or `<:<.refl` are inferred because these values are uninhabited and
might be confusing for end users.
julienrf added a commit to scalacenter/dotty that referenced this issue Apr 6, 2020
…[Nothing]` and `<:<.refl[Nothing]`

Fixes scala#8053

When a given candidate turns out to not be applicable we used to report that
there is a mismatch between the candidate type and the expected type.

The goal is to report an error as precise as possible to the user. However, in some cases
showing the inferred candidate brings no value to the user, especially when the candidate
is uninhabited.

I’ve changed the failure to be a `NoMatchingImplicitsFailure` instead of a mismatch when
`$conforms[Nothing]` or `<:<.refl` are inferred because these values are uninhabited and
might be confusing for end users.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
2 participants