case class Foo[S](s: S) {
def copy(s: S = s): Foo[S] = Foo(s) // error
}
case class Foo0(s: String) {
def copy(s: String = s): Foo0 = Foo0(s) // ok
}
[error] -- Error: /dotty-example/src/main/scala/Main.scala:1:0
[error] 1 |case class Foo[S](s: S) {
[error] |^
[error] |two or more overloaded variants of method copy have default arguments
[error] one error found
Compile successfully as in scala 2.
0.22.0-RC1= s in def copy) then error:[error] -- [E120] Duplicate Symbol Error: /dotty-example/src/main/scala/Main.scala:2:6
[error] 2 | def copy(s: S): Foo[S] = Foo(s) // error
[error] | ^
[error] | Double definition:
[error] | def copy(s: Object): Foo in class Foo at line 1 and
[error] | def copy(s: Object): Foo in class Foo at line 2
[error] | have the same type after erasure.
-
FSM / State[S,D]case class Foo[S](s: S) {
def copy(s: S = s): Foo[S] = Foo(s) // error
}
This creates an overload of the copy method instead of replacing the copy method generated for the case class, because the generated one has a type parameter [S]. If State#copy was declared with two type parameters like the class itself, it would compile (and this could be changed without breaking binary-compatibility). Is there a good reason to not do so ? Otherwise, is it worth trying to imitate scalac exactly here ?
We know we differ in the way copy methods get generated. We treat copy like apply: I.e. a method is synthesized unless there is one which is already given which has the same signature as the original copy method. scalac does something coarser. I am not quite sure, but I think a copy method does not get generated if there is _any_ other method called copy in scope. I believe the way it is done now is better.
Ah. Thank you.
But I think the error messages is not clear:
[error] -- [E120] Duplicate Symbol Error: /dotty-example/src/main/scala/Main.scala:2:6
[error] 2 | def copy(s: S): Foo[S] = Foo(s) // error
[error] | ^
[error] | Double definition:
[error] | def copy(s: Object): Foo in class Foo at line 1 and
[error] | def copy(s: Object): Foo in class Foo at line 2
[error] | have the same type after erasure.
As a normal scala developer (not compiler developer), I should be provided an error message like this:
...
[error] | def copy[S](s: S): Foo in class Foo at line 2
...
Similar for the error message two or more overloaded variants...