Given simplified code example:
sealed trait A {
val c1: String
val c2: Int
def copy[Z <: A](src: File) : Z
}
case class B(c1: String, c2: Int, src: File) extends A
case class C(c1: String, c2: Int, c3: MyClass, src: File) extends A
how do I define copy method in trait A so it will match generated one for case class and 'target' file? Given definition does typecheck and complains about missing method copy in classes B and C.
scala compiler will not generate copy methods for case class that defines method with name copy.
scala -Xprint:typer -e "sealed trait A { def copy[T <: A](s: String):T }; case class B(x: Int, y:Int) extends A"
outputs:
/var/folders/fm/fm4b21vj6jl995ywlrd99t49tjthjc/T/scalacmd3413244935208502669.scala:1: error: class B needs to be abstract, since method copy in trait A of type [T <: this.A](s: String)T is not defined
sealed trait A { def copy[T <: A](s: String):T }; case class B(x: Int, y: Int) extends A
^
one error found
[[syntax trees at end of typer]] // scalacmd3413244935208502669.scala
package <empty> {
object Main extends scala.AnyRef {
def <init>(): Main.type = {
Main.super.<init>();
()
};
def main(argv: Array[String]): Unit = {
val args: Array[String] = argv;
{
final class $anon extends scala.AnyRef {
def <init>(): anonymous class $anon = {
$anon.super.<init>();
()
};
sealed abstract trait A extends scala.AnyRef {
def copy[T >: Nothing <: this.A](s: String): T
};
case class B extends AnyRef with this.A with Product with Serializable {
<caseaccessor> <paramaccessor> private[this] val x: Int = _;
<stable> <caseaccessor> <accessor> <paramaccessor> def x: Int = B.this.x;
<caseaccessor> <paramaccessor> private[this] val y: Int = _;
<stable> <caseaccessor> <accessor> <paramaccessor> def y: Int = B.this.y;
def <init>(x: Int, y: Int): this.B = {
B.super.<init>();
()
};
override <synthetic> def productPrefix: String = "B";
<synthetic> def productArity: Int = 2;
<synthetic> def productElement(x$1: Int): Any = x$1 match {
case 0 => B.this.x
case 1 => B.this.y
case _ => throw new IndexOutOfBoundsException(x$1.toString())
};
override <synthetic> def productIterator: Iterator[Any] = runtime.this.ScalaRunTime.typedProductIterator[Any](B.this);
<synthetic> def canEqual(x$1: Any): Boolean = x$1.$isInstanceOf[this.B]();
override <synthetic> def hashCode(): Int = {
<synthetic> var acc: Int = -889275714;
acc = Statics.this.mix(acc, x);
acc = Statics.this.mix(acc, y);
Statics.this.finalizeHash(acc, 2)
};
override <synthetic> def toString(): String = ScalaRunTime.this._toString(B.this);
override <synthetic> def equals(x$1: Any): Boolean = B.this.eq(x$1.asInstanceOf[Object]).||(x$1 match {
case (_: this.B) => true
case _ => false
}.&&({
<synthetic> val B$1: this.B = x$1.asInstanceOf[this.B];
B.this.x.==(B$1.x).&&(B.this.y.==(B$1.y)).&&(B$1.canEqual(B.this))
}))
};
<synthetic> private object B extends scala.runtime.AbstractFunction2[Int,Int,this.B] with Serializable {
def <init>(): this.B.type = {
B.super.<init>();
()
};
final override <synthetic> def toString(): String = "B";
case <synthetic> def apply(x: Int, y: Int): this.B = new B(x, y);
case <synthetic> def unapply(x$0: this.B): Option[(Int, Int)] = if (x$0.==(null))
scala.this.None
else
Some.apply[(Int, Int)](Tuple2.apply[Int, Int](x$0.x, x$0.y));
<synthetic> private def readResolve(): Object = $anon.this.B
}
};
{
new $anon();
()
}
}
}
}
}