Skip to content

[SPARK-58043][SQL] Use explicit .apply instead of a case class companion as a function for Scala 3 compatibility#57129

Open
fangchenli wants to merge 4 commits into
apache:masterfrom
fangchenli:scala3-case-companion-function
Open

[SPARK-58043][SQL] Use explicit .apply instead of a case class companion as a function for Scala 3 compatibility#57129
fangchenli wants to merge 4 commits into
apache:masterfrom
fangchenli:scala3-case-companion-function

Conversation

@fangchenli

Copy link
Copy Markdown
Contributor

What changes were proposed in this pull request?

In Scala 2 a case class's companion object automatically extends FunctionN, so the bare companion can be passed wherever a function is expected. Scala 3 removed this (case companions no longer extend FunctionN), so these call sites fail to compile. Referencing Foo.apply, the method the synthetic FunctionN.apply forwarded to, restores the explicit form.

Why are the changes needed?

It's required for Scala 3 compatibility.

Does this PR introduce any user-facing change?

No

How was this patch tested?

Compiled with -Xsource:3

Was this patch authored or co-authored using generative AI tooling?

Generated-by: Claude Code (Claude Opus 4.8)

fangchenli and others added 2 commits July 8, 2026 10:26
…anion as a function for Scala 3 compatibility

### What changes were proposed in this pull request?
Replace bare case class companions used as function values with an explicit
`.apply` method reference across `catalyst`, `sql-core`, `hive`, and
`sql-api` (190 call sites), e.g.:
- `xs.reduceLeft(And)` -> `xs.reduceLeft(And.apply)`
- `convertUnaryExpr(expr, IsNull)` -> `convertUnaryExpr(expr, IsNull.apply)`
- `.map(sources.Not)` -> `.map(sources.Not.apply)`

Two lines are reflowed to stay within the 100-character limit.

### Why are the changes needed?
In Scala 2 a case class's companion object automatically extends `FunctionN`,
so the bare companion can be passed wherever a function is expected. Scala 3
removed this (case companions no longer extend `FunctionN`), so these call
sites fail to compile. Referencing `Foo.apply` -- the method the synthetic
`FunctionN.apply` forwarded to -- restores the explicit form. This is part of
the incremental Scala 3 readiness tracked in SPARK-54150.

### Does this PR introduce _any_ user-facing change?
No. `Foo.apply` is the exact method the synthetic `FunctionN.apply` delegated
to, so the change is behavior- and byte-identical on Scala 2.13.

### How was this patch tested?
Existing tests. The `catalyst`, `sql-core`, `hive`, and `sql-api` modules
compile under both the default build and `-Xsource:3`, `scalastyle` passes,
and no `case-companion-function` migration warnings remain in these modules.

### Was this patch authored or co-authored using generative AI tooling?
Generated-by: Claude Code (Claude Opus 4.8)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@fangchenli fangchenli marked this pull request as ready for review July 8, 2026 17:51
fangchenli and others added 2 commits July 8, 2026 22:00
…nion-function

# Conflicts:
#	sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/V2ExpressionUtils.scala
… count for eta-expansion

The case-companion -> .apply change in QueryStartedEvent's jobTags serialization
eta-expands to a lambda, which the Scala 2.13 compiler lifts to a synthetic public
$anonfun method on the class. Reflection-based test_number_of_public_methods sees
it via getMethods(), so bump the expected count from 16 to 17.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
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