[Scala 3] port ApplierUnapplier (Mirror-based)#881
Merged
halotukozak merged 4 commits intoJun 16, 2026
Conversation
Verbatim port from origin/master:core/src/main/scala-3/com/avsystem/commons/misc/ApplierUnapplier.scala.
Reshapes the Scala 2 macro `materialize` resolver into Scala 3 `given derived` typeclass derivation
based on `scala.deriving.Mirror.ProductOf`:
- Applier: given derived[T <: Product: Mirror.ProductOf as m]
- Unapplier: given derived[T <: Product] (productIterator-based)
- ApplierUnapplier: given derived[T: {Applier as applier, Unapplier as unapplier}]
Public trait surface (Applier / Unapplier / ApplierUnapplier / ProductUnapplier /
ProductApplierUnapplier) unchanged. Removes the `implicit def materialize[T] = ???` stubs left over
from Phase-1 big-bang. Added `import scala.deriving.Mirror` (CommonAliases export sweep is slice-3.x
territory; minimum local diff here). Local scalafmt applied.
ApplierUnapplierTest is exercised by the Mirror-based derivation since fork commit 7085bd8
re-enabled the test file; un-wrap follow-up commit will sync our copy.
Refs: APPLIERUNAPPLIER-01.
Sync test file with fork (origin/master:core/src/test/scala-3/com/avsystem/commons/misc/ApplierUnapplierTest.scala). Fork re-enabled this test at commit 7085bd8. Diff vs prior local copy: - trailing comma after `value: T` parameter (scalafmt scala3 dialect) - `test("custom") { roundtrip(Custom("", 42)) }` → `ignore("custom") { /* ... */ }` rationale documented in test comment: Mirror.ProductOf only fires for true case classes, not "case-class-like" types with hand-written apply/unapply. All 7 active cases green (`commons-core/testOnly *.ApplierUnapplierTest`), 1 ignored. Local scalafmt applied.
§3 new subsection "core — misc ApplierUnapplier (slice 5.3)" documenting the macro→Mirror.ProductOf
reshape: public Applier/Unapplier/ApplierUnapplier traits preserved; resolution mechanism flipped
from Scala 2 `implicit def materialize[T] = macro …` to Scala 3 `given derived[T <: Product:
Mirror.ProductOf as m]` / `given derived[T: {Applier as applier, Unapplier as unapplier}]`.
ApplierUnapplierTest re-enabled per fork commit 7085bd8; the `custom` case is `ignore`d because
Mirror.ProductOf only fires for true case classes/tuples, not hand-written "case-class-like" types.
Backlog: removed three stale rows for ApplierUnapplier.scala lines 13/25/37 (Applier.materialize,
Unapplier.materialize, ApplierUnapplier.materialize).
Refs: APPLIERUNAPPLIER-01.
halotukozak
force-pushed
the
05-03-applier-unapplier
branch
from
June 2, 2026 12:38
7997b19 to
92d26dc
Compare
halotukozak
marked this pull request as ready for review
June 2, 2026 12:39
| object ApplierUnapplier { | ||
| // TODO[scala3-port]: ApplierUnapplier.materialize (Scala 2 macro def) (L) | ||
| implicit def materialize[T]: ApplierUnapplier[T] = ??? | ||
| given derived[T: {Applier as applier, Unapplier as unapplier}]: ApplierUnapplier[T] = new ApplierUnapplier[T] { |
There was a problem hiding this comment.
Named context bounds in complex form like (T: {A as a, B as b}) is Scala 3.6+ feature - dont we want to support LTS 3.3 ? FYL LTS 3.9 is said to loose compatibility with scala 2
Contributor
Author
There was a problem hiding this comment.
we won't use it compatibility either way (because this library I macro-heavy). It would be better to have almost identical sources (in scala-2 and scala-3) with the copied content rather than one cross compiled, because we can use scala 3 features more freely, we can get used to scala 3 syntax, and our code will benefit and don't require another breaking change in the future (for example, we can replace implicit classes with extensions already, which have much better perf)
…ame `WithOpt` to `WithOption`.
Andrzej-Swietek
approved these changes
Jun 15, 2026
|
LGTM |
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.
Restores
misc.ApplierUnapplierfamily from Phase-1???stubs to real Scala 3 typeclass implementations backed byscala.deriving.Mirror.ProductOf. Cribbed verbatim from forkorigin/master:core/src/main/scala-3/com/avsystem/commons/misc/ApplierUnapplier.scala.What's restored
Applier[T <: Product]—Seq[Any] => TviaMirror.ProductOf[T] + Tuple.fromArray.Unapplier[T <: Product]—T => Seq[Any]viaproductIterator.ApplierUnapplier[T]— combined.ProductUnapplier[T]/ProductApplierUnapplier[T]— concrete/abstract base classes for downstream extension.All four use Scala 3
given derivedwith@implicitNotFoundmessages preserved.Tests
Restored
ApplierUnapplierTest(was wrapped in Phase 1). Expanded coverage beyond the fork:Empty,Single,Multiple,Varargs,Generic,Over22(>22 params),tuple.Optionfield,assertDoesNotCompilefor sealed traits,ProductApplierUnappliersubclass usage, standaloneApplier/Unappliersummoning.ignore("custom")stub — Mirror only derives for actual case classes, hand-writtenapply/unapplyis out of scope.Over22default valuesp14/p19/p20were copy-paste typos ("13"/"18"/"18").12/12 tests green, 0 ignored.
MIGRATION.md
§3 core — misc ApplierUnapplierentry; backlog rows for the threematerializeScala 2 macro stubs removed.Slice 5.3 / Phase 5 leaf-feature-restoration.