-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Multiversal Equality #1246
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
Multiversal Equality #1246
Conversation
inferImplicit(pt, argument, pos)(ctx.addMode(Mode.OldOverloadingResolution)) match { | ||
case altResult: SearchSuccess => | ||
ctx.migrationWarning( | ||
s"According to new implicit resolution rules, this will be ambiguous:\n ${result.explanation}", |
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.
There was one test that failed under new rules: run/t2030.scala. It was moved to pos-scala2.
This implements #1247 |
|
||
/** A marker trait indicating that values of kind `T` can be compared to values of type `U`. */ | ||
@implicitNotFound("Values of types ${L} and ${R} cannot be compared with == or !=") | ||
trait Eq[-L, -R] |
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.
I think this trait should be sealed
since the only subclass should be the object Eq
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.
Agreed.
/rebuild |
Can we change the signature of final def ==[T](that: T)(implicit _eq: Eq[this.type, T]): Boolean = this.equals(that) ? |
Actually we might not even need to make final def ==(that: Any)(implicit _eq: Eq[this.type, that.type]): Boolean =
this.equals(that) |
This would be complicated. The problem is that Any#== calls are generated by the pattern matcher, but we cannot do an implicit search then. So if we do it (and I am sure why we should!) then it can only be done during Typer, afterwards we'd have to change the signature. Does not look very appealing to me. |
Ready to merge? |
I'll try to review this more deeply today or tomorrow |
The two possible implicits are // Minimized from t2030.scala
class Both[-A, +B]
trait Factory[A] {
implicit def make: Both[A, A] = new Both[A, A]
}
trait X
object X extends Factory[X] {
override implicit def make: Both[X, X] = super.make
}
class Y extends X
object Y extends Factory[Y] {
// override implicit def make: Both[Y, Y] = super.make
}
object Test {
def get(implicit ev: Both[Y, X]) = ev
// There are two possible implicits here: X.make and Y.make, neither are
// subtype of each other, so who wins?
// - Under the old scheme it's X.make because `isAsGood` sees that X.make is defined
// in X whereas Y.make is defined in Factory
// - Under the new scheme it's ambiguous because we replace contravariance by covariance
// in top-level type parameters so Y.make is treated as a subtype of X.make
// In both schemes we can get Y.make to win by uncommenting the override for make in Y
// (Y wins against X because `isDerived` also considers the subtyping relationships
// of companion classes)
get
} This means that we can fix the issue in the standard library by adding an override of |
/rebuild |
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.
This came up when tasty-checking Eq.scala.
Compare selected contravariant arguments as if they were covariant. Which ones is explained in the doc comment for method `isAsSpecificValueType` in Applications.scala. This has the same motivation than what @paulp proposed around 2012. The solution is a bit different from the one proposed then because it only affects top-level parameters.
Also, check that pattern matching against idents/selects/literals makes sense. The hooks perform an implicit search for an instance of `Eq[L, R]`, where `L`, `R` are the argument types. So far this always succeeeds because Eq.eqAny matches all such types. A separate commit will check the returned search term for validity.
This is done by checking each instance of an eqAny implicit so that it does not contain non-bottom instances of equality types as instances.
(and add it to commit set).
Name, Symbol, Denotation, Type. This uncovered two nonsensical comparisons, one in CollectEntryPoints, the other in DottyBackendInterface.
Needed a fix in string interpolation for suriviving inserted types that contain `$` characters.
To make tests pass, this required a looser specification of `assumedCanEquals`, so that an abstract type T can be compared to arbitrary values, as long as its upper bound can be compared. E.g. T == null T == "abc"
@felixmulder Why do you need a mini-phase? I am thinking of a simple fix in typer. |
3c18a2a
to
2f3b895
Compare
/rebuild |
This is a backport of the following Dotty change to scalac, scala/scala3@8954026 As in the Dotty implementation the specificity comparison which is used for overload resolution and implicit selection is now performed as-if all contravariant positions in top level type constructors were covariant. Currently this breaks test/files/run/t2030.scala in exactly the same way as in Dotty as reported here, scala/scala3#1246 (comment) and in this PR it has been changed to a neg test. However, test/files/run/t2030.scala passes when this PR is combined with, scala#6139 so if/when that is merged it can be switched back to a pos test. Fixes scala/bug#2509. Fixes scala/bug#7768.
Fixed ScalaCheck treeset.scala compiler error and reinstated t2030.scala as a pos test by adding a newCanBuildFrom override in object TreeSet as suggested in this comment on related Dotty changes, scala/scala3#1246 (comment) This change will be made obsolete when the new collections land.
This is a backport of the following Dotty change to scalac, scala/scala3@8954026 As in the Dotty implementation the specificity comparison which is used for overload resolution and implicit selection is now performed as-if all contravariant positions in top level type constructors were covariant. Currently this breaks test/files/run/t2030.scala in exactly the same way as in Dotty as reported here, scala/scala3#1246 (comment) and in this PR it has been changed to a neg test. However, test/files/run/t2030.scala passes when this PR is combined with, scala#6139 so if/when that is merged it can be switched back to a pos test. Fixes scala/bug#2509. Fixes scala/bug#7768.
This is a backport of the following Dotty change to scalac, scala/scala3@8954026 As in the Dotty implementation the specificity comparison which is used for overload resolution and implicit selection is now performed as-if all contravariant positions in top level type constructors were covariant. Currently this breaks test/files/run/t2030.scala in exactly the same way as in Dotty as reported here, scala/scala3#1246 (comment) and in this PR it has been changed to a neg test. However, test/files/run/t2030.scala passes when this PR is combined with, scala#6139 so if/when that is merged it can be switched back to a pos test. Fixes scala/bug#2509. Fixes scala/bug#7768.
This is a backport of the following Dotty change to scalac, scala/scala3@8954026 As in the Dotty implementation the specificity comparison which is used for overload resolution and implicit selection is now performed as-if all contravariant positions in top level type constructors were covariant. Currently this breaks test/files/run/t2030.scala in exactly the same way as in Dotty as reported here, scala/scala3#1246 (comment) and in this PR it has been changed to a neg test. However, test/files/run/t2030.scala passes when this PR is combined with, scala#6139 so if/when that is merged it can be switched back to a pos test. Fixes scala/bug#2509. Fixes scala/bug#7768.
This is a backport of the following Dotty change to scalac, scala/scala3@8954026 As in the Dotty implementation the specificity comparison which is used for overload resolution and implicit selection is now performed as-if all contravariant positions in type constructors were covariant. Currently this breaks test/files/run/t2030.scala in exactly the same way as in Dotty as reported here, scala/scala3#1246 (comment) and in this PR it has been changed to a neg test. However, test/files/run/t2030.scala passes when this PR is combined with, scala#6139 so if/when that is merged it can be switched back to a pos test. Fixes scala/bug#2509. Fixes scala/bug#7768.
The first 4 commits were taken from the previous PR to add mutliversal equals. Review by @smarter.