Replace *Ops conversions by direct extension methods - #26637
Open
halotukozak wants to merge 12 commits into
Open
Replace *Ops conversions by direct extension methods#26637halotukozak wants to merge 12 commits into
halotukozak wants to merge 12 commits into
Conversation
library-js has its own copy of NumericRange.scala that overrides the one in library/src for Scala.js builds. It still relied on `import num.mkNumericOps` as an implicit conversion to get `-`/`/` on T, which broke once mkNumericOps was deprecated and un-implicited. Mirrors the same fix already applied to library/src/.../NumericRange.scala.
It implements Numeric[A] overriding toInt/toLong/toFloat/toDouble as regular methods, which no longer compile now that these are abstract extension methods on scala.math.Numeric. This is upstream Scala.js test-suite code fetched at build time, so it can't be fixed in place; excluded following the existing pattern for other Scala 3 incompatibilities in this list.
…mericOps The macro spliced \$x * \$x relying on the implicit conversion from Numeric.Implicits.infixNumericOps to provide \`*\` on the generic Num type parameter. That no longer resolves now that Numeric's toInt/toLong/ toFloat/toDouble/abs are extension methods. Call num.times(...) directly instead, which is unambiguous and was always the semantic behind \`*\`.
withGiven's context-function-introduced instance wasn't picked up by extension method resolution for Numeric's * (which was the actual cause of the earlier "value * is not a member of Num" failure, not the deprecated infixNumericOps per se). Introducing the Numeric[Num] instance with a real `given` inside the quote fixes resolution, so the macro can go back to using * instead of calling num.times explicitly, and withGiven can be dropped entirely.
….type The original withGiven[U, T](inline x: T)(inline body: T ?=> U) widened the given to its nominal type T, which extension method resolution for * didn't pick up. Using x.type instead of a generic T ties the context function's given to the precise singleton type of the argument, which resolves correctly. inline had to be dropped from the x parameter since x.type requires a stable (non-inline) path.
The *Ops conversions (mkOrderingOps, mkNumericOps, infixOrderingOps, etc.) stay deprecated-but-non-implicit, so code needs to reach the new extension methods directly instead of falling back to the old implicit conversions. Updates checkfiles and test imports accordingly: - if-parse.scala: import the Ordering givens directly since the deprecated infixOrderingOps is no longer implicit. - more-specific.scala: accept the new [E008] extension-method diagnostic in place of the old [E007] implicit-conversion-rejection message; the restriction it guards (conversions must be more specific than AnyRef) still holds, just surfaced through a different code path. - transparent-inline-i12754-message.check: drop the now-invalid infixOrderingOps import suggestion. - i17371.scala: import the specific extension methods (ordA.>, ordB.<) instead of the no-op `import x.given` on a plain value, and drop the redundant `turns`/`circular` given-imports (they're already in scope via the using clause). - missing-implicit.scala: -/+/* on a Numeric-bounded T no longer need an explicit import, so only the > comparison still errors.
halotukozak
force-pushed
the
deprecate-ops-extension-methods
branch
from
August 13, 2026 09:00
18f0722 to
ddf4fbb
Compare
halotukozak
marked this pull request as ready for review
August 13, 2026 14:00
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Similar to #23872
there is a one design question: should the extension methods be on the top-level or in the type class?
I've chosen the second one, but I don't have a strong opinion.
Current draft doesn't break binary compatibility, but it does break the source one (only if someone extends the TC and it's not a problem in minor release, isn't it?).
Inner extension methods in several instances bring the method name clash (they have to be marked with
@targetName) but they allow to omit all the redundant bridges like this:Also, with top-level extensions, there is a problem with overloading (e.g. math.max vs math.max for Ordering)