-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Add multiversal equals #1234
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
Add multiversal equals #1234
Conversation
|
||
object equality { | ||
|
||
case class Str(str: String) extends EqClass[_] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shouldn't this be EqClass[Str]
? I'm not even sure what extends EqClass[_]
means, that syntax is not allowed in scala 2.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you extend EqClass[_]
it means you have to provide instances of Eq
yourself; the eqEq
one won't work.
Null was ignored so far, but it requires more overloads to work correctly.
If all overloaded variants of a method are uniary, we should also allow auto-tupling. This is necessary to make overloaded `==' methods work in cases like: xs == (1, 2)
tpd.applyOverloaded should not do type parameter inference; therefore it has to make sure all eligible alternatives have the same number of type parameters as there are type arguments.
Caches were set when information was not complete yet. Problem was exhibited by missing some `eqName` implicits when adding safe equality for Name.
Trait definitions supporting equality
Map them to Any_==, which is the only method supported by the backend.
This came up when tasty-checking Eq.scala.
Typer can still accept equality tests between members of Any and members of some equality class. These are weeded out in PostTyper.
Name, Symbol, Denotation, Type. This uncovered two nonsensical comparisons, one in CollectEntryPoints, the other in DottyBackendInterface.
Keep just one: EqClass, which is parameterized, like EqClassOf was. Unparameterized EqClass can be expressed as EqClass[_].
792bed3
to
f7f742b
Compare
Rebased to master. This is complete enough to be useful. Ready to be reviewed. |
It's interesting to compare this approach with the one in scalac: https://github.com/scala/scala/blob/2.12.x/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala#L1092-L1126 : |
* final def == [T >: this.type <: EqClass[_](other: T)(implicit ce: Eq[T]): Boolean = this.equals(other) | ||
* final def != [T >: this.type <: EqClass[_](other: T)(implicit ce: Eq[T]): Boolean = this.equals(other) | ||
* } | ||
* |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A minor typo here: missing closing bracket for type parameters.
This seems to me a clever design that I feel a little difficult to appreciate fully the intricacies, e.g. what would happen:
- if we change
trait EqClass[-U]
totrait EqClass
,U
is not explicitly used in the body? - if we use
[T >: this.type <: EqClass[T]
instead[T >: this.type <: EqClass[_]
?
Superseded by #1247 |
Based on #1231. Review by @smarter.
This makes == safe for classes that inherit from dotty.EqClass.