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
fsc never reuses a compiler instance #1683
Comments
Imported From: https://issues.scala-lang.org/browse/SI-1683?orig=1
|
@paulp said: class Settings {
val settings: List[Setting] = List(Setting1("bob"))
abstract class Setting(descr: String) {
def name: String
}
case class Setting1(name: String) extends Setting("foo") {
override def equals(other: Any) = other match {
case x: Setting1 => true
case _ => false
}
}
case class Setting2(name: String) extends Setting("bar") {
override def equals(other: Any) = other match {
case x: Setting2 => true
case _ => false
}
}
override def equals(other: Any) = other match {
case s: Settings => List.forall2(settings, s.settings)(_ == _)
case x => false
}
}
object go
{
def main(args: Array[String]): Unit = {
val set1 = new Settings
val set2 = new Settings
println("set1 == set2? " + (set1 == set2))
println("isInstanceOf == " + set1.settings.head.isInstanceOf[set2.Setting1])
}
} $$ scala27 go
set1 == set2? false
isInstanceOf == true |
@odersky said: Pro: This seems to be what one wants most of the time. What do people think? Thanks -- Martin |
@paulp said: Perhaps some metatheory is out there which can capture the inconsistency in a consistent way, a la newtonian mechanics giving way to relativity. |
I was working on bug #84 and the first thing I noticed was that it doesn't do that. So I thought someone had fixed it, but investigation revealed that fsc never reused a compiler instance even on identical consecutive commands, so of course stale cache entries were not a problem.
The reason is this: before reusing a compiler instance, CompileServer verifies that the settings are identical by calling the custom equals method in Settings, which does this:
This is a very interesting trap, because all the relevant fields of all the settings are indeed equal, but this still always returns false -- in fact no two settings ever compare equal. The reason is that the logic of the equals methods looks like this:
The individual Setting (singular) objects being compared were born in two different Settings (plural) objects, so they are not the same class, and the case bs: BooleanSetting always fails. It should instead look like this:
I have attached a patch against trunk that fixes this issue -- and with that applied I'm "happy" to say that bug #84 is still a valid bug. This took me a long time to figure out and seems like a very easy trap to fall into, so I wonder if anyone has ideas as to how to make it harder to burn yourself this way.
The text was updated successfully, but these errors were encountered: