- About Scala
- Documentation
- Code Examples
- Software
- Scala Developers
scalac 2.8.1 bug: immutable updates in nested case classes
Mon, 2011-07-25, 20:56
Given two case classes, one composed of the other:
case class Bug(name: String = "", last: String = "")
case class Bugger(bug: Bug) {
def name(s: String) = copy(bug = bug.copy(name = s))
def last(s: String) = copy(bug = bug.copy(last = s))
}
scalac 2.9.0-1 compiles as expected.
scalac 2.8.1 fails to compile and dumps a big stack trace detailing
the parse error. The problem seems to be related to having method
names in Bugger matching property names in Bug. changing either such
that the method and property name don't match resolves the problem, as
does having only one method with matching names as opposed to two.
Because this works fine in 2.9.0-1, I assume it was caught,
documented, and then resolved. I was curious if someone could direct
me to the ticket? Thanks! Following is the stack trace.
-chris
TREE: bug.copy(last = s)
TRANSFORM: /Users/clewis/Development/Source/highchair/datastore/src/
main/scala/bug.scala
TREE: Bugger.this.copy(bug.copy(last = s))
TRANSFORM: /Users/clewis/Development/Source/highchair/datastore/src/
main/scala/bug.scala
TREE: def last(s: String): Bugger = Bugger.this.copy(bug.copy(last =
s))
TRANSFORM: /Users/clewis/Development/Source/highchair/datastore/src/
main/scala/bug.scala
TREE: java.lang.Object with ScalaObject with Product {
def copy$default$1: Bug
@scala.annotation.unchecked.uncheckedVariance = Bugger.this.bug;
private[this] val bug: Bug = _;
def bug: Bug =
Bugger.this.bug;
def this(bug: Bug): Bugger = {
Bugger.super.this();
()
};
def name(s: String): Bugger =
Bugger.this.copy(Bugger.this.bug.copy(s, Bugger.this.bug.copy$default
$2));
def last(s: String): Bugger = Bugger.this.copy(bug.copy(last = s));
def copy(bug: Bug = bug): Bugger = new Bugger(bug);
override def hashCode(): Int =
ScalaRunTime.this._hashCode(Bugger.this);
override def toString(): String =
ScalaRunTime.this._toString(Bugger.this);
override def equals(x$1: Any): Boolean = Bugger.this.eq(x$1).||(x$1
match {
case (bug: Bug)Bugger((bug$1 @ _)) if bug$1.==(bug) => x
$1.asInstanceOf[Bugger].canEqual(Bugger.this)
case _ => false
});
override def productPrefix: java.lang.String = "Bugger";
override def productArity: Int = 1;
override def productElement(x$1: Int): Any = x$1 match {
case 0 => bug
case _ => throw new java.lang.IndexOutOfBoundsException(x
$1.toString())
};
override def canEqual(x$1: Any): Boolean = x$1.$isInstanceOf[Bugger]
()
}
TRANSFORM: /Users/clewis/Development/Source/highchair/datastore/src/
main/scala/bug.scala
TREE: @serializable case class Bugger extends java.lang.Object with
ScalaObject with Product {
def copy$default$1: Bug
@scala.annotation.unchecked.uncheckedVariance = Bugger.this.bug;
private[this] val bug: Bug = _;
def bug: Bug =
Bugger.this.bug;
def this(bug: Bug): Bugger = {
Bugger.super.this();
()
};
def name(s: String): Bugger =
Bugger.this.copy(Bugger.this.bug.copy(s, Bugger.this.bug.copy$default
$2));
def last(s: String): Bugger = Bugger.this.copy(bug.copy(last = s));
def copy(bug: Bug = bug): Bugger = new Bugger(bug);
override def hashCode(): Int =
ScalaRunTime.this._hashCode(Bugger.this);
override def toString(): String =
ScalaRunTime.this._toString(Bugger.this);
override def equals(x$1: Any): Boolean = Bugger.this.eq(x$1).||(x$1
match {
case (bug: Bug)Bugger((bug$1 @ _)) if bug$1.==(bug) => x
$1.asInstanceOf[Bugger].canEqual(Bugger.this)
case _ => false
});
override def productPrefix: java.lang.String = "Bugger";
override def productArity: Int = 1;
override def productElement(x$1: Int): Any = x$1 match {
case 0 => bug
case _ => throw new java.lang.IndexOutOfBoundsException(x
$1.toString())
};
override def canEqual(x$1: Any): Boolean = x$1.$isInstanceOf[Bugger]
()
}
TRANSFORM: null
TREE: package {
@serializable case class Bug extends java.lang.Object with
ScalaObject with Product {
def copy$default$2: String
@scala.annotation.unchecked.uncheckedVariance = Bug.this.last;
def copy$default$1: String
@scala.annotation.unchecked.uncheckedVariance = Bug.this.name;
private[this] val name: String = _;
def name: String =
Bug.this.name;
private[this] val last: String = _;
def last: String =
Bug.this.last;
def this(name: String = "", last: String = ""): Bug = {
Bug.super.this();
()
};
def copy(name: String = name, last: String = last): Bug =
new Bug(name, last);
override def hashCode(): Int =
ScalaRunTime.this._hashCode(Bug.this);
override def toString(): String =
ScalaRunTime.this._toString(Bug.this);
override def equals(x$1: Any): Boolean = Bug.this.eq(x$1).||(x$1
match {
case (name: String,last: String)Bug((name$1 @ _), (last$1 @ _))
if name$1.==(name).&&(last$1.==(last)) => x
$1.asInstanceOf[Bug].canEqual(Bug.this)
case _ => false
});
override def productPrefix: java.lang.String = "Bug";
override def productArity: Int = 2;
override def productElement(x$1: Int): Any = x$1 match {
case 0 => name
case 1 => last
case _ => throw new java.lang.IndexOutOfBoundsException(x
$1.toString())
};
override def canEqual(x$1: Any): Boolean = x$1.$isInstanceOf[Bug]
()
};
@serializable case class Bugger extends java.lang.Object with
ScalaObject with Product {
def copy$default$1: Bug
@scala.annotation.unchecked.uncheckedVariance = Bugger.this.bug;
private[this] val bug: Bug = _;
def bug: Bug =
Bugger.this.bug;
def this(bug: Bug): Bugger = {
Bugger.super.this();
()
};
def name(s: String): Bugger =
Bugger.this.copy(Bugger.this.bug.copy(s, Bugger.this.bug.copy$default
$2));
def last(s: String): Bugger = Bugger.this.copy(bug.copy(last =
s));
def copy(bug: Bug = bug): Bugger = new Bugger(bug);
override def hashCode(): Int =
ScalaRunTime.this._hashCode(Bugger.this);
override def toString(): String =
ScalaRunTime.this._toString(Bugger.this);
override def equals(x$1: Any): Boolean = Bugger.this.eq(x$1).||(x
$1 match {
case (bug: Bug)Bugger((bug$1 @ _)) if bug$1.==(bug) => x
$1.asInstanceOf[Bugger].canEqual(Bugger.this)
case _ => false
});
override def productPrefix: java.lang.String = "Bugger";
override def productArity: Int = 1;
override def productElement(x$1: Int): Any = x$1 match {
case 0 => bug
case _ => throw new java.lang.IndexOutOfBoundsException(x
$1.toString())
};
override def canEqual(x$1: Any): Boolean = x
$1.$isInstanceOf[Bugger]()
};
final object Bugger extends
scala.runtime.AbstractFunction1[Bug,Bugger] with ScalaObject {
def this(): object Bugger = {
Bugger.super.this();
()
};
case def unapply(x$0: Bugger): Option[Bug] = if (x
$0.==(null))
scala.this.None
else
scala.Some.apply[Bug](x$0.bug);
case def apply(bug: Bug): Bugger = new Bugger(bug);
protected def readResolve(): java.lang.Object = Bugger
};
final object Bug extends
scala.runtime.AbstractFunction2[String,String,Bug] with ScalaObject {
def init$default$2: String
@scala.annotation.unchecked.uncheckedVariance = "";
def init$default$1: String
@scala.annotation.unchecked.uncheckedVariance = "";
def apply$default$2: String
@scala.annotation.unchecked.uncheckedVariance = "";
def apply$default$1: String
@scala.annotation.unchecked.uncheckedVariance = "";
def this(): object Bug = {
Bug.super.this();
()
};
case def unapply(x$0: Bug): Option[(String, String)] =
if (x$0.==(null))
scala.this.None
else
scala.Some.apply[(String, String)](scala.Tuple2.apply[String,
String](x$0.name, x$0.last));
case def apply(name: String = "", last: String = ""):
Bug = new Bug(name, last);
protected def readResolve(): java.lang.Object = Bug
}
}