Hi folks, I was putting together a blog post on supporting Multiversal Equality with Groovy. It's an optional feature in Scala 3:
https://docs.scala-lang.org/scala3/book/ca-multiversal-equality.html Using the example (involving print and audio books) from the above link, we can write an ad-hoc type checking extension something like this: beforeMethodCall { call -> if (call.methodAsString == 'equals') { lhsType = getType(call.objectExpression) rhsType = getType(call.arguments[0]) if (lhsType != rhsType && lhsType != classNodeFor(PrintedBook) && rhsType != classNodeFor(AudioBook)) { addStaticTypeError("Invalid equality check: $lhsType.name != $rhsType.name", call) handled = true } } } This turns on strict equality checking except for the particular ad-hoc exclusion listed for print and audio books. So the following would be true: 42.equals('foo') // STC error: int and String aren't compatible aBook.equals(pBook) // STC error: due to the order we gave in the exclusion pBook.equals(aBook) // compiles and returns true due to equals definition (not shown) The blog discusses how we could make it less ad-hoc if we wanted to by introducing a CanEqual marker interface and so forth, but that's off-topic for just now. What I wanted to show is the same examples but using the '==' and '!=' operators, since that would be the typical Groovy style for this scenario. Unfortunately, using the type checking extension DSL doesn't currently work for binary operators. The swap from '==' to the 'equals' method call occurs well after type checking is finished. The same would apply to operators eventually falling back to 'compareTo'. You can still make it work by not using the DSL and writing your own type checking extension, but that's significantly more work. Our options seem to be: (1) not trying to make this work (2) modify operators to method call expressions earlier (might remove some optimization steps) (3) tweak StaticTypeCheckingVisitor#visitBinaryExpression to support before/after method call hooks for known cases like equals/compareTo with a pretend method call (4) alter the TypeCheckingExtension interface with before/after binary expression calls. Note that while the multiversal equality example has some interest, it isn't really what I am trying to fix here. It just shows a hole in the type checking extension DSL support that I'd like to fix if we can find a nice fix. If someone wanted to make it a type error to compare 'int's and 'float's (say), they would face the same issue but with compareTo not equals. Does anyone have strong opinions on this before I start having a play and seeing what might work? In particular, a preference for option 3 or 4? Cheers, Paul.