Skip to content
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

Can one disable eqAny? #2707

Closed
Blaisorblade opened this issue Jun 7, 2017 · 4 comments
Closed

Can one disable eqAny? #2707

Blaisorblade opened this issue Jun 7, 2017 · 4 comments
Assignees

Comments

@Blaisorblade
Copy link
Contributor

https://www.reddit.com/r/programming/comments/6elim6/announcing_dotty_012rc1_a_major_step_towards/dik7j1b/ points out that this code compiles, unlike I would have expected:

import dotty.DottyPredef.{eqAny => _, _}
import scala.{Eq => _, _}

object Main {
  def equal[S, T](s: S, t: T) = s == t
}

The second import tried to prevent the Eq instance from being found. But using -Xprint:all suggests Eq instances don't come into play. I suspect something like this should be a testcase.

I don't know what should be the way to disable eqAny, but I do think it should be possible and that seems the appropriate syntax. In particular, this example appears to contradict this quote from #1247:

The idea is that the Scala compiler will check every time it encounters a potentially problematic comparison between values of types T and U that there is an implicit instance of Eq[T, U]. A comparison is potentially problematic if it is between incompatible types. As long as T <: U or U <: T the equality could make sense because both sides can potentially be the same value.

This bug and #2698 might need to be fixed in cooperation.

@Blaisorblade
Copy link
Contributor Author

Oh, eqAny was moved to Predef exactly so that it could be disabled: #1247

@Blaisorblade
Copy link
Contributor Author

I don't know what should be the way to disable eqAny, but I do think it should be possible and that seems the appropriate syntax.

Disabling eqAny also appears to work in scala/collection-strawman#100 for methods that actually take an Eq instance.

If phantom classes are added, making Eq a phantom class and adding it to the signature for == might be better (if it works and doesn't create compatibility issues). Even if Dotty can't make Eq a phantom class, it should have similar semantics.

@Blaisorblade
Copy link
Contributor Author

Last: @smarter proposed earlier for == to take an Eq argument—it seems that would (in principle) avoid this problem.
#1246 (comment)

@abgruszecki
Copy link
Contributor

There is now a dedicated way to disable eqAny - scala.language.strictEquality. However, this code compiles:

scala> import scala.language.strictEquality
     | object Main {
     |   def equal[S, T](s: S, t: T) = s == t
     | }
// defined object Main

This seems to be as specified in https://github.com/lampepfl/dotty/blob/36740bf877869fd226618537b3aa677459676f83/docs/docs/reference/other-new-features/multiversal-equality.md:

A comparison using x == y or x != y between values x: T and y: U is legal if either T and U are the same, or one of the types is a subtype of the "lifted" version of the other type, or an implicit value of type scala.Eq[T, U] is found. See the description on Github for a definition of lifting.

The linked issue (#1247 (comment)) defines lift as:

Let lift be a function on types that maps every covariant occurrence of an abstract type to its upper bound and that drops all refinements in covariant positions.

Which means that: lift(S) = Any and T <: Any (or the other way around). @Blaisorblade if you believe this to be problematic please open a separate up-to-date issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants