Skip to content

Commit fb4dd54

Browse files
committed
Add case-class-companion incompatibility
1 parent 2c81888 commit fb4dd54

File tree

6 files changed

+57
-2
lines changed

6 files changed

+57
-2
lines changed

docs/incompatibilities/other-changed-features.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,3 +26,6 @@ title: Other Changed Features
2626

2727
```scala mdoc:file:incompat-30/wildcard-argument/README.md
2828
```
29+
30+
```scala mdoc:file:incompat-30/case-class-companion/README.md
31+
```

docs/incompatibilities/table.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ Some proven features are simplified or restricted to make the language easier an
8383
|[Non-private constructor in private class](other-changed-features.md#non-private-constructor-in-private-class)||warning|||
8484
|[Reflective call](other-changed-features.md#reflective-call)||||Type inference problem|
8585
|[Wildcard type argument](other-changed-features.md#wildcard-type-argument)|||||
86-
86+
|[Case class companion](other-changed-features.md#case-class-companion)|||||
8787

8888
## Implicit Resolution
8989

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
## Case class companion
2+
3+
The companion object of a case class does not extend any of the `Function{0-23}` traits anymore.
4+
In particular, it does not inherit their methods: `tupled`, `curried`, `andThen`, `compose`...
5+
6+
For instance, the following lines of code are invalid.
7+
8+
```scala
9+
case class Foo(x: Int, b: Boolean)
10+
11+
Foo.curried(1)(true)
12+
Foo.tupled((2, false))
13+
```
14+
15+
A cross-compiling solution is to explicitly eta-expand the method `Foo.apply`.
16+
17+
```scala
18+
(Foo.apply _).curried(1)(true)
19+
(Foo.apply _).tupled((2, false))
20+
```
21+
22+
Or, for performance reason, you can introduce an intermediate function value.
23+
24+
```scala
25+
val fooCtr: (Int, Boolean) => Foo = (x, b) => Foo(x, b)
26+
27+
fooCtr.curried(1)(true)
28+
fooCtr.tupled((2, false))
29+
```
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
package foo
2+
3+
case class Foo(x: Int, b: Boolean)
4+
5+
object Bar {
6+
val f1 = Foo.curried(1)(true)
7+
val f2 = Foo.tupled((2, false))
8+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
package foo
2+
3+
case class Foo(x: Int, b: Boolean)
4+
5+
object Bar {
6+
val f1 = (Foo.apply _).curried(1)(true)
7+
val f2 = (Foo.apply _).tupled((1, true))
8+
9+
val fooCtr: (Int, Boolean) => Foo = (x, b) => Foo(x, b)
10+
11+
val f1Bis = fooCtr.curried(1)(true)
12+
val f2Bis = fooCtr.tupled((2, false))
13+
}

incompat.sbt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,8 @@ lazy val otherIncompats = Seq[ProjectReference](
152152
ambiguousConversion,
153153
implicitView,
154154
typeOfImplicitDef,
155-
viewBound
155+
viewBound,
156+
caseClassCompanion
156157
)
157158

158159
// Syntactic incompatibilities
@@ -172,6 +173,7 @@ lazy val existentialType = project.in(file("incompat-30/existential-type")).sett
172173
lazy val wildcardArgument = project.in(file("incompat-30/wildcard-argument")).settings(incompat30Settings)
173174
lazy val explicitCallToUnapply = project.in(file("incompat-30/explicit-call-to-unapply")).settings(incompat30Settings)
174175
lazy val reflectiveCall = project.in(file("incompat-30/reflective-call")).settings(incompat30Settings)
176+
lazy val caseClassCompanion = project.in(file("incompat-30/case-class-companion")).settings(incompat30Settings)
175177

176178
// Contextual abstraction incompatibilities
177179
lazy val ambiguousConversion =

0 commit comments

Comments
 (0)