Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Inconsistent behaviour of case classes with and without an explicit companion object #4808

Closed
scabug opened this issue Jul 15, 2011 · 7 comments

Comments

@scabug
Copy link

scabug commented Jul 15, 2011

Writing an explicit companion object for a case class interferes with type inference for the auto-generated apply() method. Take the following code:

def f(g: (String, Int) => Any) = null

case class A(x: String, y: Int)
case class B(x: String, y: Int)
object B

val v1 = f(A.apply _)
val v2 = f(A)
val v3 = f(B.apply _)
val v4 = f(B)

v1, v2, and v3 compile.

v4 fails with:

error: type mismatch;
 found   : this.B.type (with underlying type object this.B)
 required: (String, Int) => Any
val v4 = f(B)

It seems that the explicit companion object prevents the proper Function trait from being mixed in automatically.

@scabug
Copy link
Author

scabug commented Jul 15, 2011

Imported From: https://issues.scala-lang.org/browse/SI-4808?orig=1
Reporter: @szeiger
Affected Versions: 2.8.1, 2.9.0, 2.10.2
Duplicates #3664

@scabug
Copy link
Author

scabug commented Jan 29, 2013

@retronym said (edited on Sep 19, 2013 7:03:46 AM UTC):
Deferring to 2.11.x, we can't change the parentage of explictly defined companions in a binary compatible manner (someone could rely on the Function1-ness of a stdlib case companion we ship in 2.10.1, and get a linkage error with 2.10.0).

Even beyond the question of binary compatibility, I don't think that doing this is a clear cut correct decision; we should consult the community before proceeding.

@scabug
Copy link
Author

scabug commented Sep 18, 2013

@refried said (edited on Sep 18, 2013 10:56:15 PM UTC):
Seems like the explicit case should have the same behavior (parentage, methods added) as the auto-generated case; if it helps: maybe an annotation to flip the default behavior for the companion? This would be more user-friendly than having to manually extend Function9, and maintain the arguments in two places.

Are there some stdlib case companions that have Function1-ness that could break? Would their Function1-ness go away?

Thanks!

@scabug
Copy link
Author

scabug commented Sep 19, 2013

@retronym said:
From an implementation perspective, I don't think this will be straight forward. The way we add the apply/unapply to a companion is already a fragile area of the compiler, so I expect that changing the parents will be just as awkward.

We don't have a precedent for annotations controlling what parts of case class translation are performed, and I'm unwilling to do that piecemeal.

You should also note the companions of type-parametric case classes don't (can't) extends FunctionN, either.

So I'm afraid that the status quo will have to remain.

@scabug
Copy link
Author

scabug commented Sep 19, 2013

@refried said:
Hmm... Yeah, I hadn't noted that. Maybe removing it from the auto-generated companions is the best choice, for symmetry. But, binary compatibility.

@scabug
Copy link
Author

scabug commented Oct 15, 2013

@gkossakowski said:
Unassigning and rescheduling to M7 as previous deadline was missed.

@scabug
Copy link
Author

scabug commented Feb 22, 2017

@dwijnand said:
Shouldn't this be closed as a strict duplicate of SI-3664?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant