Fix Scala 3.8.4 compilation compatibility while preserving 2.13 and 3.3.x cross-build#3065
Open
He-Pin wants to merge 4 commits into
Open
Fix Scala 3.8.4 compilation compatibility while preserving 2.13 and 3.3.x cross-build#3065He-Pin wants to merge 4 commits into
He-Pin wants to merge 4 commits into
Conversation
… and 3.3.x cross-build
Motivation:
The codebase needs to compile with both Scala 3.3.x (current production) and
Scala 3.8.4 (forward compatibility for the upcoming 3.9 LTS). Several patterns
in the codebase break under Scala 3.8 due to changes in how context bounds are
desugared (they become `using` clauses), stricter deprecation warnings, and
syntax changes.
Modification:
- ClassTag context bound fixes: In Scala 3.8, `[T: ClassTag]` desugars to a
`using` clause, making explicit `ClassTag` passing positional-incompatible.
Fixed by using `implicit val ct: ClassTag[T] = ClassTag(clazz)` in scope and
relying on implicit resolution instead of explicit passing.
- PersistencePlugin implicit parameter merge: Merged `[T: ClassTag]` context
bound and `(implicit ev: PluginProvider[...])` into a single `implicit`
parameter list to avoid context bound + separate implicit parameter mismatch.
- `.apply()` trick: Used `decoration[T].apply(behavior)` instead of
`decoration[T](behavior)` to separate implicit resolution from function
application.
- `private[this]` to `private`: Scala 3.8 deprecates `private[this]` in favor
of `private`.
- `= _` initializers to explicit defaults: Replaced `= _` with `= null`,
`= None`, `= 0`, etc. as Scala 3.8 deprecates uninitialized vars.
- `SortedSet.empty(ordering)` fix: Bound ordering as `implicit val ord`
before calling `.empty[Member]` to avoid implicit resolution issues.
- `@unchecked` annotations: Added for type-test patterns that can't be checked
at runtime under Scala 3.
- `@nowarn` filters: Used message-based `@nowarn("msg=never used")` instead
of category-based filters for cross-version compatibility.
- `PekkoDisciplinePlugin.scala`: Added `-Wconf` suppression rules for Scala
3.8 deprecation/syntax warnings in both main and test scopes.
- No `using` keyword in shared sources: All changes use cross-compatible
patterns (`implicit val`, `.apply()` trick).
Result:
All modules compile with both Scala 2.13.18 and Scala 3.8.4. Production Scala
3 version remains at 3.3.8 — this change only ensures forward compatibility.
No behavioral changes to the runtime.
Tests:
- sbt "++3.8.4" "Test / compile" — success across all modules
- sbt "Test / compile" (Scala 2.13.18) — success across all modules
References:
None - proactive Scala 3.8 forward compatibility
c93f67c to
22a4344
Compare
Member
Author
|
Although we don't know when we'll be able to switch to 3.9.x, it is always a good idea to eliminate compilation warnings and ensure compatibility in advance. |
The Scala 3.8 compat commit added `import org.jspecify.annotations.Nullable` at the top of the file but didn't remove the existing identical import further down, causing an "unused import" error on Scala 2.13 with -Werror.
He-Pin
added a commit
to apache/pekko-persistence-jdbc
that referenced
this pull request
Jun 14, 2026
…528) Motivation: Scala 3.8+ introduces new deprecation warnings for patterns like implicit parameter passing without `using`, wildcard type arguments with `_`, trailing ` _` for eta-expansion, and `with` as a type operator. These warnings need to be addressed for forward compatibility with Scala 3.9.x while maintaining cross-build support for Scala 2.13.x and 3.3.x. Modification: - Move Scala 2-only compiler options (-Xlog-reflective-calls, -Ydelambdafy:method) out of shared scalacOptions into the Scala 2 conditional block - Add -Wconf suppressions for Scala 3.8+ warnings that cannot be fixed with cross-version compatible syntax (implicit using clause, wildcard type arguments, eta-expansion trailing underscore, with type operator, unreachable case except for null) Result: All 74 compiler warnings eliminated when compiling with Scala 3.8.4. Scala 2.13.18 compilation remains unaffected. No behavioral changes. Tests: - sbt "++3.8.4" "core / compile" — 0 warnings (previously 74) - sbt "++2.13.18" "core / compile" — success, no new warnings References: Refs apache/pekko#3065
Motivation: The PR accidentally deleted the override val messageQueue in CallingThreadMailbox, which caused TestActorRef tests to fail with ActorInitializationException because the mailbox's messageQueue was null instead of the ThreadLocal queue. Modification: Restore the override val messageQueue: MessageQueue = q.get with its Scaladoc comment, matching origin/main. Result: TcpConnectionSpec and other TestActorRef-based tests pass again. Tests: - sbt "actor-tests / Test / testOnly org.apache.pekko.io.TcpConnectionSpec" (planned) References: Fixes #3065
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.
Motivation
The codebase needs to compile with both Scala 3.3.x (current production) and Scala 3.8.4 (forward compatibility for the upcoming 3.9 LTS). Several patterns in the codebase break under Scala 3.8 due to changes in how context bounds are desugared (they become
usingclauses), stricter deprecation warnings, and syntax changes.Modification
170 files changed across the codebase:
ClassTag context bound fixes: In Scala 3.8,
[T: ClassTag]desugars to ausingclause, making explicitClassTagpassing positional-incompatible. Fixed by usingimplicit val ct: ClassTag[T] = ClassTag(clazz)in scope and relying on implicit resolution instead of explicit passing. Key files:PersistencePlugin.scala,EventSourcedBehaviorTestKit.scala,ActorContextSpec.scala,BehaviorTestKitSpec.scala,Behavior.scala,EventStream.scala,Topic.scala,ShardingProducerController.scala,ShardedDaemonProcessImpl.scala,StreamTestKit.scala.PersistencePlugin implicit parameter merge: Merged
[T: ClassTag]context bound and(implicit ev: PluginProvider[...])into a singleimplicitparameter list(implicit ct: ClassTag[T], ev: PluginProvider[T, ScalaDsl, JavaDsl])to avoid context bound + separate implicit parameter mismatch in Scala 3.8..apply()trick: Useddecoration[T].apply(behavior)instead ofdecoration[T](behavior)to separate implicit resolution from function application (Scala 2.13 interprets(behavior)as the implicit ClassTag argument).private[this]→private: Scala 3.8 deprecatesprivate[this]in favor ofprivate.= _initializers → explicit defaults: Replaced= _with= null,= None,= 0, etc. as Scala 3.8 deprecates uninitialized vars.SortedSet.empty(ordering)fix: Bound ordering asimplicit val ordbefore calling.empty[Member]to avoid implicit resolution issues.@uncheckedannotations: Added for type-test patterns that can't be checked at runtime under Scala 3.@nowarnfilters: Used message-based@nowarn("msg=never used")instead of category-based filters for cross-version compatibility.PekkoDisciplinePlugin.scala: Added-Wconfsuppression rules for Scala 3.8 deprecation/syntax warnings in both main and test scopes.No
usingkeyword in shared sources: All changes use cross-compatible patterns (implicit val,.apply()trick). Theusingkeyword only appears inscala-3/directories.Result
All modules compile with both Scala 2.13.18 and Scala 3.8.4. Production Scala 3 version remains at 3.3.8 — this change only ensures forward compatibility. No behavioral changes to the runtime.
Tests
sbt "++3.8.4" "Test / compile"— success across all modulessbt "Test / compile"(Scala 2.13.18) — success across all modulesReferences
Supersedes #3060 (rebased onto main to resolve Hub.scala conflict with #3063).