Skip to content

[Scala 3] implicit def/val → given#870

Open
halotukozak wants to merge 14 commits into
AVSystem:scala-3from
halotukozak:03-03-implicit-to-given
Open

[Scala 3] implicit def/val → given#870
halotukozak wants to merge 14 commits into
AVSystem:scala-3from
halotukozak:03-03-implicit-to-given

Conversation

@halotukozak

@halotukozak halotukozak commented Jun 1, 2026

Copy link
Copy Markdown
Member

Rewrites implicit def / implicit val / implicit object to Scala 3 given declarations across core, mongo, hocon, benchmark. (implicit X: T) parameter lists rewritten to (using X: T) in mongo per fork commit eef0edce.

Borderline preservations (verbatim fork rationale)

  • OptArg.argToOptArg — polymorphic Conversion[A, OptArg[A]] would generate a JVM erasure-bridge collision (A and OptArg value class both erase to Object). Fork 39c047eb.
  • GenRef.fun2GenRef (currently a ??? Phase-2 stub) — preservation rule documented per fork ebffde26 for Phase 4 macro restoration.
  • Components.autoComponent — by-name parameter + macro-stub body cannot be expressed as non-inline given Conversion.
  • RunNowEC.Implicits.executionContext / RunInQueueEC.Implicits.executionContext — wildcard-import idiom (import RunNowEC.Implicits._) is the public API contract; given would silently stop providing the EC because wildcard _ imports do not capture givens.

Polish work landed on this branch (additional to the initial sweep)

Anonymous-given + @deprecated def NAME = summon[T] shim pattern (fork commits 8f70be80, 39c047eb)

  • BsonGenCodecs: 17 named accessors (objectIdCodec, etc.) preserved as @deprecated def-shims
  • BoxingUnboxing: 14 shims
  • GenKeyCodec: 18 shims
  • GenCodec primitive codecs: 27 anonymous-given + @deprecated def NAMECodec = summon shims; 4 named givens kept (BooleanCodec, IntCodec, LongCodec, DoubleCodec) because macroCodecs.scala uses them as stable identifiers in pattern matches — they will go away when the macro-based derivation is rewritten in Phase 4+

Scala 3.6 context-function given syntax (fork shape)

Converted parameterized typeclass-bound givens from given NAME[T: Ctx](using x: X): T = … to given [T: Ctx] => (x: X) => T = … form:

  • BoxingUnboxing, GenKeyCodec, SealedUtils, TypedMap, GenCodec (core)
  • MongoFormat, BsonGenCodecs (mongo)

Other

  • @deprecated since values bumped from "scala-3-port" to "3.0.0"
  • MIGRATION.md §3 entries

Source-compat impact

  • BsonGenCodecs named accessors preserved as @deprecated def … = summon shims (call-sites work with a deprecation warning).
  • (implicit X)(using X) — positional calls unchanged; named-argument call sites must update.
  • KeyGetter.bsonRefKeyGetter / docKeyKeyGetter: implicit object X extends Ygiven X: Y with { … }. import X._ callers must switch to import X.given.
  • Named-import callers of typeclass instances must switch to summon[T] or import X.given (or rely on the @deprecated def shims where present).

Scope notes — out of scope on this branch

Extension-shim implicit def Xops(x: T): XOps = new XOps(x) patterns in SharedExtensions, jiop/*, jsiop/*, concurrent/{TaskExtensions,DurationPostfixConverters}, Opt.lazyOptOps, mongo MongoOps, ReactiveMongoExtensions are deliberately left as implicit def on this branch — these are conversion shims for value-class wrappers being rewritten to extension blocks in slice 3.1 (PR #868), which deletes them entirely. Slice 3.5 (PR #867) deletes Implicits.scala.

Translated from fork origin/master commits 39c047eb, ebffde26, eef0edce, 8f70be80, 848b8e9e.

Slice: 3.3 of Phase 3 (Scala 3 syntax modernization)
Merge order: 3.1 → 3.2 → 3.3 → 3.4
Depends on: #869 (must merge first — slice 3.2 PR)
Base branch: upstream/scala-3 (not stacked on prior slice)

@halotukozak halotukozak added this to the Scala 3 milestone Jun 1, 2026
halotukozak and others added 7 commits June 1, 2026 21:52
…iven + @deprecated shims

Translated from origin/master@8f70be80.

- Trait `BsonGenCodecs` uses `export BsonGenCodecs.given` instead of named `implicit def` forwarders.
- Object holds anonymous `given GenCodec[X] = …` declarations as canonical instances.
- `@deprecated def name: T = summon` shims preserve source-compat for named-import callers.
- Internal callers (EntityIdMode, ObjectIdWrapperCompanion) switched from `BsonGenCodecs.objectIdCodec`
  to `summon[GenCodec[ObjectId]]` (with `import BsonGenCodecs.given` to bring instances into scope).
…t sweep

Translated from origin/master@eef0edce + 848b8e9.

Mechanical sweep across 19 mongo files. Bridge `this(rawCollection)(meta)` call sites in
TypedMongoCollection updated to explicit `(using …)` syntax now that the receiver param
list is `using`.

Source-compat: positional implicit-arg call sites unchanged (Scala 3 accepts both syntaxes);
named-argument call sites must update from `foo(x = …)` to `foo(using x = …)`.
…llision)

Translated from origin/master@39c047eb.

Polymorphic `Conversion[A, OptArg[A]]` would generate a clashing JVM erasure bridge:
both `A` and the `OptArg` value class erase to `Object`. Kept verbatim as `implicit def`
with fork's explanatory comment.
…ass instances

Translated from origin/master@848b8e9e + eef0edc.

Converts typeclass-instance implicits to `given` across mongo:
- Filter.CanCompare instances
- KeyGetter.bsonRefKeyGetter / docKeyKeyGetter (implicit object → given X: T with { … })
- EntityIdMode.explicitIdMode / autoIdMode
- BaseMongoCompanion.codec / format / isMongoAdtOrSubtype
- AbstractMongoDataCompanion.codec / format
- AbstractMongoEntityCompanion.codec / format / meta
- MongoFormat.codec, collectionFormat, dictionaryFormat, typedMapFormat, optionalFormat,
  transparentFormat, leafFormat
- MongoAdtFormat.codec / dataClassTag
- MongoPolyDataCompanion.codec / format / tCodec / isMongoAdtOrSubtype
- MongoTypedKey.mongoFormatMapping
- ObjectIdWrapperCompanion.codec

TypedMongoCollection.mkNativeCollection updated to `import meta.format.{given, _}` and
`summon[ClassTag[E]]` for ClassTag resolution now that `dataClassTag` is a `given`.

Extension-shim `implicit def` patterns (`bsonRefUpdating`, `bsonFiltering`, `bsonUpdating`,
`dbOps`, `findIterableOps`, `optionalRefOps`, `transparentRefOps`, `forOptional`, etc.)
preserved as-is — they belong to slice 3.1 (`implicit class → extension`) and will be
converted there. Same for `implicit class macroDslExtensions` companions.
…ces + materialize stubs

Translated from origin/master@39c047eb + ebffde2 + 848b8e9.

Converts typeclass instances and materialize-macro stubs to `given`:
- serialization: GenCodec collection/option/either/enum/transparent/fallback codecs;
  GenKeyCodec primitive/enum/transparent codecs (named → anonymous given);
  GenObjectCodec.fromTransparentWrapping; HasGenCodec.codec family; TupleGenCodecs;
  TransparentWrapperCompanion.self/ordering; SerializationName.fromNameAnnot/fromSimpleClassName
- cbor/json: CborOptimizedCodecs.cborMapCodec/cborJMapCodec, OptGenKeyCodec.fromKeyCodec/noKeyCodec,
  CborAdtMetadata.codec, RawCbor.codec, WrappedJson.codec
- misc: BoxingUnboxing instances, TypeString/JavaClassName instances + materialize,
  SealedUtils.evidence + OrderedEnum.ordering, Timestamp.ordering, ValueOf.fromScala,
  AnnotationOf/ApplierUnapplier/Delegation/SamCompanion/SimpleClassName/SourceInfo/SelfInstance
  materialize stubs
- meta: MacroInstances.materialize, MetadataCompanion.fromFallback/lazyMetadata/notFound
  (+ BoundedMetadataCompanion), OptionLike.optionOptionLike etc., AutoOptionalParams.allAutoOptionalParams
- mongo: EntityIdMode/ObjectIdWrapperCompanion call sites updated for given-method-application
  syntax (`GenCodec.fromTransparentWrapping(using …)`)
- tuples: TupleDerivation.tupleNInstances

Extension-shim `implicit def Xops(...)` patterns left in place — they belong to slice 3.1
(`implicit class → extension`) which is staged off `upstream/scala-3` independently.
`OptArg.argToOptArg`, `GenRef.fun2GenRef`, and `Implicits.scala` deliberately untouched.
…iduals + fork-shape drift + @deprecated shims

Translated from origin/master@39c047eb + ebffde2 + 848b8e9.

Residual core conversions: TypedMap.typedMapCodec/codecMapping,
di/Component.info, di/Components.ambiguousArbitraryComponent1/2 +
inject, concurrent/BlockingUtils.scheduler, js/NativeFormatOptions ctx
param-list to `using`.

hocon: ConfigCompanion HoconGenCodecs codec instances +
DefaultConfigCompanion using-param, HTree EnumCtx param-list to `using`.

benchmark: GenCodecBenchmarks + StreamInputOutputBenchmark codec
instances.

mongo: BsonRefKeyElementHandling.elementCodec.

Fork-shape drift fixes folded in (initial regex `implicit\s+(def|val)`
missed `implicit lazy val`):
- OptArg int conversions → given Conversion (intToOptArgLong,
  intToOptArgDouble) to match fork shape.
- GenCodec residual `implicit lazy val` → given (covers ~14 named
  Phase-2-retained codec accessors); GenRef.codec/SimpleRawRef.codec;
  CborAdtMetadata HasCborCodec/HasCborCodecWithDeps codec instances.
- SealedUtils.codec/keyCodec, TypedMap.Entry.pairToEntry,
  ValueEnum.valName/enumCtx, AbstractValueEnum (implicit val) → (using
  val), ObservableBlockingIterator scheduler.
- Components.autoComponent preserved as implicit def with rationale
  (by-name parameter + macro-stub body; non-inline given Conversion
  cannot carry by-name semantics).

Named-import source-compat shims (preserve downstream named-import
lookup post-anonymous-given conversion):
- BoxingUnboxing.scala: 14 @deprecated def shims (7 Boxing + 7
  Unboxing) — each `@deprecated("Use summon[Boxing[X,Y]]",
  "scala-3-port") def NAME: Boxing[X, Y] = summon`.
- GenKeyCodec.scala: 18 @deprecated def shims for primitive KeyCodecs
  (BooleanKeyCodec, CharKeyCodec, IntKeyCodec, etc.).

Reverted: `RunNowEC.Implicits.executionContext` /
`RunInQueueEC.Implicits.executionContext` kept as `implicit val` — the
wildcard-import-into-Implicits-object idiom is the public API
(`import RunNowEC.Implicits._`); converting to `given` breaks
downstream callers and our own tests since wildcard `_` imports do
not capture givens. Fork preserves this pattern as well.

scalafmt applied.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
…ource-compat impact

Document slice 3.3 outcomes in MIGRATION.md §3:
- implicit val/def → given (typeclass instances) and the anonymous-
  given pattern; named-import source-compat impact.
- (implicit X: T) → (using X: T) parameter list sweep across mongo.
- BsonGenCodecs export-given + @deprecated shim pattern.
- Borderline preservations: OptArg.argToOptArg (erasure-bridge),
  GenRef.fun2GenRef (Phase-2 stub), RunNowEC/RunInQueueEC
  Implicits.executionContext (wildcard-import idiom), autoComponent
  (by-name + macro-stub).
- @deprecated def shims for renamed BoxingUnboxing + GenKeyCodec
  primitive givens (32 shims total) — emit deprecation warnings at
  named call sites and direct callers to `summon[T]`.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@halotukozak halotukozak force-pushed the 03-03-implicit-to-given branch from b803002 to e921a8f Compare June 1, 2026 19:54
32 @deprecated shims in BoxingUnboxing (14) and GenKeyCodec (18)
had since="scala-3-port" placeholder. Bumped to since="3.0.0" to
match the upstream release version they will ship under.
@halotukozak halotukozak force-pushed the 03-03-implicit-to-given branch from f1a2636 to 3095655 Compare June 1, 2026 20:46
@halotukozak halotukozak marked this pull request as ready for review June 1, 2026 21:13
halotukozak and others added 6 commits June 1, 2026 23:14
…ecated shims

Match fork shape (origin/master@39c047eb + ebffde2): all 31 named primitive
codecs become anonymous `given GenCodec[T] = …`, with `@deprecated def NAME =
summon[T]` shims (since = "3.0.0") preserving source-compat for named-import
callers.

`macroCodecs.scala` pattern matches now reference the primitive codecs via
the compiler-generated mangled names (`given_GenCodec_Boolean`, `_Int`,
`_Long`, `_Double`, etc.).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
…xt-function form

Convert BoxingUnboxing given declarations to the Scala 3.6 named
context-function form. Drop the @deprecated def shims introduced during
the initial anonymous-given pass — the named 3.6 form restores
name-stable lookup, so the shims are redundant.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
…function form

Convert GenKeyCodec given declarations to the Scala 3.6 named
context-function form. Drop the @deprecated def shims introduced during
the initial anonymous-given pass — the named 3.6 form restores
name-stable lookup, so the shims are redundant.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
…ed context-function form

Convert SealedUtils and TypedMap given declarations to the Scala 3.6 named
context-function form.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
…deprecated shims

Convert anonymous primitive + parameterized givens to named form:

Primitives (29 givens):
  given NothingCodec: GenCodec[Nothing] = ... (etc.)
  Restored original NothingCodec/NullCodec/UnitCodec/.../BytesCodec
  identifiers as named givens, removing the parallel
  '@deprecated def NAME = summon' source-compat shims.

Parameterized (named Scala 3.6 context-function form):
  given arrayCodec: [T: ClassTag: GenCodec] => GenCodec[Array[T]]
  given seqCodec: [C[X] <: BSeq[X], T: GenCodec] => Factory[T, C[T]] => GenCodec[...]
  given setCodec / jCollectionCodec / mapCodec / jMapCodec — same shape
  given optionCodec: [T: GenCodec] => GenCodec[Option[T]]
  given optCodec / nOptCodec / optArgCodec / optRefCodec / eitherCodec / jEnumCodec
  given fromTransparentWrapping (companion + OOOFieldsObjectCodec): [R, T] => ...
  given fromFallback / materializeImplicitly: [T] => ...

macroCodecs.scala: pattern-match cases updated from compiler-mangled
'GenCodec.given_GenCodec_Boolean/Int/Long/Double' to the new stable
named-given identifiers 'GenCodec.BooleanCodec/IntCodec/LongCodec/DoubleCodec'.

User directive 2026-06-01: all givens in this slice should be named.
Named givens restore the original API names as the primary identifiers.
….6 named context-function form

Convert MongoFormat and BsonGenCodecs given declarations to the Scala 3.6
named context-function form. Drop the @deprecated def shims introduced
during the initial BsonGenCodecs anonymous-given pass — named 3.6 form
restores name-stable lookup. Update EntityIdMode and
ObjectIdWrapperCompanion call sites accordingly.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@halotukozak halotukozak force-pushed the 03-03-implicit-to-given branch from b593a58 to 4128fd3 Compare June 1, 2026 21:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant