Skip to content

[Scala 3] tighten HKT wildcards (_ → ?)#869

Open
halotukozak wants to merge 6 commits into
AVSystem:scala-3from
halotukozak:03-02-hkt-wildcards
Open

[Scala 3] tighten HKT wildcards (_ → ?)#869
halotukozak wants to merge 6 commits into
AVSystem:scala-3from
halotukozak:03-02-hkt-wildcards

Conversation

@halotukozak

@halotukozak halotukozak commented Jun 1, 2026

Copy link
Copy Markdown
Member

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

Summary

Applied-position HKT wildcards [_] / [_, _] rewritten to [?] / [?, ?] per Scala 3 changed-features. Includes bounded existentials [_ <: X] / [_ >: X][? <: X] / [? >: X]. Kind-parameter declarations (class C[F[_]], def m[K[_]], case x: T[_, _], etc.) preserved verbatim — Scala 3 still uses _ in kind-decl and type-pattern positions.

Translated from origin/master@848b8e9e (mongo subset).

Commits (6, fork cadence — do not squash)

  • refactor(scala-3,core): F[_] → F[?] in applied positions (serialization)
  • refactor(scala-3,core): F[_] → F[?] in applied positions (rpc)
  • refactor(scala-3,core): F[_] → F[?] in applied positions (misc + di)
  • refactor(scala-3,mongo): F[_] → F[?] in applied positions (sweep)
  • refactor(scala-3,mongo): tighten HKT wildcards with bounds in applied positions — bounded-existential follow-up (50 rewrites across 18 mongo files: BsonRef, MongoRef, MongoPropertyRef, MongoOrder, MongoProjection, Filter.DocKey, etc.)
  • docs(migration): record HKT wildcard tightening (type-level only, no source-compat)

Source-compat impact

None. F[?] vs F[_] is parse-level only — no call-site or downstream consumer effect. Pure type-argument-position syntax change.

Verification

  • sbt compile ; Test/compile ; scalafmtCheckAll — exit 0
  • Acceptance grep over core/src/main/scala, mongo/{jvm,js}/src/main/scala, hocon/src/main/scala — all remaining hits are kind-parameter declarations, type patterns (case x: T[_, _]), or scaladoc comments (manually verified per Pitfall 3 in slice planning).
  • No new @nowarn / -Wconf introduced.

Notes on Pitfall 3 (kind-decl vs applied)

Kind-parameter declarations + type patterns preserved verbatim. Applied positions rewritten across 12 + 18 = 30 files.

Targeted rewrites: Array[GenCodec[?]], Array[Class[?]], List[Case[?]],
Opt[cborKey[?]], Opt[cborDiscriminator[?]], List[Field[?]],
List[CborKeyInfo[?]], Array[GenCodec.OOOFieldsObjectCodec[?]],
Array[OOOFieldsObjectCodec[?]], InputMetadata[?], BIterable[?],
Transformed[?, ?].

Kind-parameter declarations (trait PolyCodec[C[_]], abstract class
HasPolyGenCodec[C[_]], abstract class HasPolyGenObjectCodec[C[_]],
trait PolyObjectCodec[C[_]], abstract class HasPolyGenObjectCodecWithDeps[D, C[_]],
abstract class HasPolyGenCodecWithDeps[D, C[_]], trait GadtCodec[C[_]],
abstract class HasGadtCodec[C[_]], trait CborAdtPolyInstances[C[_]],
abstract class HasPolyCborCodec[C[_]]) preserved verbatim per Pitfall 3.
Targeted rewrites: Iterator[?], List[ParamMetadata[?]],
Map[String, FunctionSignature[?]], Map[String, GetterSignature[?]].

Kind-parameter declarations (def materialize[M[_], Real],
def materializeForApi[M[_], Real], trait RpcMetadataCompanion[M[_]],
trait ApiMetadataCompanion[M[_]]) preserved verbatim per Pitfall 3.
Targeted rewrites: GenKeyCodec[TypeString[?]], GenCodec[TypeString[?]],
GenKeyCodec[JavaClassName[?]], GenCodec[JavaClassName[?]], Entry[K, ?]*,
Component[?], AtomicReference[?], MHashMap[Component[?], ...],
MHashSet[Component[?]], AtomicReference[Future[?]].

Kind-parameter declarations (class TypedMap[K[_]], case class Entry[K[_], T],
def pairToEntry[K[_], T], def empty[K[_]], def apply[K[_]],
trait GenCodecMapping[K[_]], def typedMapCodec[K[_]],
def instancesFor[TC[_], T], case class SelfInstance[C[_]],
def materialize[C[_]], trait AdtMetadataCompanion[M[_]],
trait MetadataCompanion[M[_]], type MColBuilder[Elem, +Col[_]],
trait TupleDerivation[C[_]]) preserved verbatim per Pitfall 3.
Translated from origin/master@848b8e9e (mongo subset).

Targeted rewrites: InputMetadata[?], MongoQueryOperator[?], MongoFilter[?],
List[Case[?]], Map[Class[?], Case[?]], Map[Class[?], UnionFormat[?]],
MHashMap[Class[?], (SealedParent[?], MListBuffer[Case[?]])],
List[SealedParent[?]], Opt[Field[?]], List[Field[?]],
Map[String, Field[?]], MongoCollection[?].

Kind-parameter declarations (final case class TypedMapFormat[K[_]],
implicit def typedMapFormat[K[_]], implicit class typedMapFormatOps[K[_]],
trait MongoPolyAdtInstances[D[_]], abstract class
AbstractMongoPolyDataCompanion[Implicits, D[_]], abstract class
MongoPolyDataCompanion[D[_]], implicit class TypedMapRefOps[E, K[_]],
trait MongoFormatMapping[K[_]]) preserved verbatim per Pitfall 3.
…source-compat)

Slice 3.2: `_` → `?` in applied positions across core + mongo.
Kind-parameter declarations preserved. Pure type-argument-position syntax
change; downstream callers unaffected.
@halotukozak halotukozak added this to the Scala 3 milestone Jun 1, 2026
@halotukozak halotukozak marked this pull request as ready for review June 1, 2026 17:50
… positions

Prior sweep handled simple [_] / [_, _] applied positions. This polish
catches remaining sites flagged by user 2026-06-01:

- DocKey[A, _] / DocKey[_, _] / DocKey[_, _ <: BsonArray] → [A, ?] / [?, ?] / [?, ? <: BsonArray]
  in Filter, Sort, Update (object-level helpers)
- BsonRef[_, T] / BsonRef[_, C[E]] / BsonRef[_, _] in mongo/core/ops/* (8 files)
- DocKey[_, _] type ascriptions in KeyGetter
- MongoRef[E, _], MongoRef[_, _], MongoPropertyRef[E, _], MongoToplevelRef[E, _]
  type ascriptions (parameter and return types only — type-patterns in case
  clauses preserved as `_` to mirror fork master shape)
- MongoProjection[E, _] type ascription in ProjectionZippers

Type-pattern wildcards in `case x: T[_, _]` clauses intentionally kept as `_`
to match fork master @ origin/master (see MongoQueryOperator, MongoUpdate,
MongoUpdateOperator, MongoRef.computePath/extractBson, MongoFormat.fieldRefFor).
Per-file fork-shape comparison done; all applied-position rewrites mirror
fork's canonical scala-3 form.

Acceptance gate: every remaining [_]/[_ <: X] in scope is either a kind-decl
position, a value-pattern wildcard, or a type-pattern in a case clause (fork-
canonical).

sbt compile Test/compile scalafmtCheckAll → exit 0, no new warnings, no
@nowarn / -Wconf added.
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