Open jvican opened 8 years ago
Compiling:
package test object HoistUpNestedIfElses { def main(args: Array[String]): Unit = { sealed trait Animal case class Cat(name: String) extends Animal case class Cow(typeOfMilk: String) extends Animal sealed trait Food case object Meat extends Food case object Grass extends Food def getFoodFor(a: Animal) = a match { case c: Cat => Meat case cw: Cow => Grass } getFoodFor(Cat("Garfield")) getFoodFor(Cow("UHV")) } }
fails with:
checking test/test/HoistUpNestedIfElses.scala after phase frontend checking test/test/HoistUpNestedIfElses.scala after phase posttyper checking test/test/HoistUpNestedIfElses.scala after phase pickler checking test/test/HoistUpNestedIfElses.scala after phase summaries checking test/test/HoistUpNestedIfElses.scala after phase TreeTransform:{firstTransform, checkReentrant} checking test/test/HoistUpNestedIfElses.scala after phase TreeTransform:{prespecialize, refchecks, elimRepeated, normalizeFlags, extmethods, expandSAMs, tailrec, liftTry, classOf} checking test/test/HoistUpNestedIfElses.scala after phase TreeTransform:{patternMatcher, explicitOuter, explicitSelf, crossCast, splitter} method equals after inlineLabelsCalledOnce became this.eq(x$0.asInstanceOf[Object]).||({ case val selector11: Any = x$0 { { if selector11.isInstanceOf[Cat] then { val x$0: Cat = selector11.asInstanceOf[Cat(x$0)] { this.name.==(x$0.name) } } else { if selector11.isInstanceOf[Any] then { false } else throw new MatchError(selector11) } } } }) method equals after devalify became this.eq(x$0.asInstanceOf[Object]).||({ { { if x$0.isInstanceOf[Cat] then { val x$0: Cat = x$0.asInstanceOf[Cat(x$0)] { this.name.==(x$0.name) } } else { if x$0.isInstanceOf[Any] then { false } else throw new MatchError(x$0) } } } }) method equals after dropNoEffects became this.eq(x$0.asInstanceOf[Object]).||( if x$0.isInstanceOf[Cat] then { val x$0: Cat = x$0.asInstanceOf[Cat(x$0)] this.name.==(x$0.name) } else if x$0.isInstanceOf[Any] then false else throw new MatchError(x$0) ) method equals after inlineLabelsCalledOnce became this.eq(x$0.asInstanceOf[Object]).||({ case val selector12: Any = x$0 { { if selector12.isInstanceOf[Cow] then { val x$0: Cow = selector12.asInstanceOf[Cow(x$0)] { this.typeOfMilk.==(x$0.typeOfMilk) } } else { if selector12.isInstanceOf[Any] then { false } else throw new MatchError(selector12) } } } }) method equals after devalify became this.eq(x$0.asInstanceOf[Object]).||({ { { if x$0.isInstanceOf[Cow] then { val x$0: Cow = x$0.asInstanceOf[Cow(x$0)] { this.typeOfMilk.==(x$0.typeOfMilk) } } else { if x$0.isInstanceOf[Any] then { false } else throw new MatchError(x$0) } } } }) method equals after dropNoEffects became this.eq(x$0.asInstanceOf[Object]).||( if x$0.isInstanceOf[Cow] then { val x$0: Cow = x$0.asInstanceOf[Cow(x$0)] this.typeOfMilk.==(x$0.typeOfMilk) } else if x$0.isInstanceOf[Any] then false else throw new MatchError(x$0) ) method equals after inlineLabelsCalledOnce became this.eq(x$0.asInstanceOf[Object]).||({ case val selector13: Any = x$0 { { if selector13.isInstanceOf[Meat$] then { val x$0: Meat$ = selector13.asInstanceOf[Meat$(x$0)] { true } } else { if selector13.isInstanceOf[Any] then { false } else throw new MatchError(selector13) } } } }) method equals after devalify became this.eq(x$0.asInstanceOf[Object]).||({ { { if x$0.isInstanceOf[Meat$] then { x$0.asInstanceOf[Meat$(x$0)] { true } } else { if x$0.isInstanceOf[Any] then { false } else throw new MatchError(x$0) } } } }) method equals after dropNoEffects became this.eq(x$0.asInstanceOf[Object]).||( if x$0.isInstanceOf[Meat$] then { x$0.asInstanceOf[Meat$(x$0)] true } else if x$0.isInstanceOf[Any] then false else throw new MatchError(x$0) ) method equals after inlineLabelsCalledOnce became this.eq(x$0.asInstanceOf[Object]).||({ case val selector14: Any = x$0 { { if selector14.isInstanceOf[Grass$] then { val x$0: Grass$ = selector14.asInstanceOf[Grass$(x$0)] { true } } else { if selector14.isInstanceOf[Any] then { false } else throw new MatchError(selector14) } } } }) method equals after devalify became this.eq(x$0.asInstanceOf[Object]).||({ { { if x$0.isInstanceOf[Grass$] then { x$0.asInstanceOf[Grass$(x$0)] { true } } else { if x$0.isInstanceOf[Any] then { false } else throw new MatchError(x$0) } } } }) method equals after dropNoEffects became this.eq(x$0.asInstanceOf[Object]).||( if x$0.isInstanceOf[Grass$] then { x$0.asInstanceOf[Grass$(x$0)] true } else if x$0.isInstanceOf[Any] then false else throw new MatchError(x$0) ) method getFoodFor after inlineLabelsCalledOnce became { case val selector15: Animal = a { { if selector15.isInstanceOf[Cat] then { val c: Cat = selector15.asInstanceOf[Cat(c)] { { Meat } } } else { if selector15.isInstanceOf[Cow] then { val cw: Cow = selector15.asInstanceOf[Cow(cw)] { { Grass } } } else throw new MatchError(selector15) } } } } method getFoodFor after devalify became { { { if a.isInstanceOf[Cat] then { a.asInstanceOf[Cat(c)] { { Meat } } } else { if a.isInstanceOf[Cow] then { a.asInstanceOf[Cow(cw)] { { Grass } } } else throw new MatchError(a) } } } } method getFoodFor after dropNoEffects became if a.isInstanceOf[Cat] then { a.asInstanceOf[Cat(c)] Meat } else if a.isInstanceOf[Cow] then { a.asInstanceOf[Cow(cw)] Grass } else throw new MatchError(a) exception while transforming def main(args: Array[String]): Unit = { <trait> sealed interface trait Animal() extends Object {} final lazy module val Animal: Animal$ = new Animal$() final module class Animal$() extends Object() { this: Animal.type =>} case class Cat(name: String) extends Object() with Animal with Product1[String ] { val name: String def copy(name: String): Cat = new Cat(name) def copy$default$1: String @uncheckedVariance = this.name: String @uncheckedVariance def isDefined: Boolean = true def _1: String = this.name override def hashCode(): Int = { var acc: Int = -889275714 acc = scala.runtime.Statics$#mix(acc, scala.runtime.Statics$#anyHash(this.name) ) scala.runtime.Statics$#finalizeHash(acc, 1) } override def equals(x$0: Any): Boolean = this.eq(x$0.asInstanceOf[Object]).||({ case val selector11: Any = x$0 { def case11(): Boolean = { def case21(): Boolean = { def matchFail11(): Boolean = throw new MatchError(selector11) if selector11.isInstanceOf[Any] then { false } else matchFail11() } if selector11.isInstanceOf[Cat] then { val x$0: Cat = selector11.asInstanceOf[Cat(x$0)] { this.name.==(x$0.name) } } else case21() } case11() } }) override def toString(): String = scala.runtime.ScalaRunTime._toString(this) override def canEqual(that: Any): Boolean = that.isInstanceOf[Cat] override def productPrefix: String = "Cat" } final lazy module val Cat: Cat$ = new Cat$() final module class Cat$() extends Object() with (String => Cat) { this: Cat.type => def apply(name: String): Cat = new Cat(name) def unapply(x$1: Cat): Cat = x$1 } case class Cow(typeOfMilk: String) extends Object() with Animal with Product1[ String ] { val typeOfMilk: String def copy(typeOfMilk: String): Cow = new Cow(typeOfMilk) def copy$default$1: String @uncheckedVariance = this.typeOfMilk: String @uncheckedVariance def isDefined: Boolean = true def _1: String = this.typeOfMilk override def hashCode(): Int = { var acc: Int = -889275714 acc = scala.runtime.Statics$#mix(acc, scala.runtime.Statics$#anyHash(this.typeOfMilk) ) scala.runtime.Statics$#finalizeHash(acc, 1) } override def equals(x$0: Any): Boolean = this.eq(x$0.asInstanceOf[Object]).||({ case val selector12: Any = x$0 { def case31(): Boolean = { def case41(): Boolean = { def matchFail21(): Boolean = throw new MatchError(selector12) if selector12.isInstanceOf[Any] then { false } else matchFail21() } if selector12.isInstanceOf[Cow] then { val x$0: Cow = selector12.asInstanceOf[Cow(x$0)] { this.typeOfMilk.==(x$0.typeOfMilk) } } else case41() } case31() } }) override def toString(): String = scala.runtime.ScalaRunTime._toString(this) override def canEqual(that: Any): Boolean = that.isInstanceOf[Cow] override def productPrefix: String = "Cow" } final lazy module val Cow: Cow$ = new Cow$() final module class Cow$() extends Object() with (String => Cow) { this: Cow.type => def apply(typeOfMilk: String): Cow = new Cow(typeOfMilk) def unapply(x$1: Cow): Cow = x$1 } <trait> sealed interface trait Food() extends Object {} final lazy module val Food: Food$ = new Food$() final module class Food$() extends Object() { this: Food.type =>} final lazy module case val Meat: Meat$ = new Meat$() final module case class Meat$() extends Object() with Food with Product0 { this: Meat.type => override def hashCode(): Int = { var acc: Int = -889275714 scala.runtime.Statics$#finalizeHash(acc, 0) } override def equals(x$0: Any): Boolean = this.eq(x$0.asInstanceOf[Object]).||({ case val selector13: Any = x$0 { def case51(): Boolean = { def case61(): Boolean = { def matchFail31(): Boolean = throw new MatchError(selector13) if selector13.isInstanceOf[Any] then { false } else matchFail31() } if selector13.isInstanceOf[Meat$] then { val x$0: Meat$ = selector13.asInstanceOf[Meat$(x$0)] { true } } else case61() } case51() } }) override def toString(): String = scala.runtime.ScalaRunTime._toString(this) override def canEqual(that: Any): Boolean = that.isInstanceOf[Meat$] override def productPrefix: String = "Meat$" } final lazy module case val Grass: Grass$ = new Grass$() final module case class Grass$() extends Object() with Food with Product0 { this: Grass.type => override def hashCode(): Int = { var acc: Int = -889275714 scala.runtime.Statics$#finalizeHash(acc, 0) } override def equals(x$0: Any): Boolean = this.eq(x$0.asInstanceOf[Object]).||({ case val selector14: Any = x$0 { def case71(): Boolean = { def case81(): Boolean = { def matchFail41(): Boolean = throw new MatchError(selector14) if selector14.isInstanceOf[Any] then { false } else matchFail41() } if selector14.isInstanceOf[Grass$] then { val x$0: Grass$ = selector14.asInstanceOf[Grass$(x$0)] { true } } else case81() } case71() } }) override def toString(): String = scala.runtime.ScalaRunTime._toString(this) override def canEqual(that: Any): Boolean = that.isInstanceOf[Grass$] override def productPrefix: String = "Grass$" } def getFoodFor(a: Animal): Food & Product0 = { case val selector15: Animal = a { def case91(): Meat$ | Grass$ = { def case101(): Meat$ | Grass$ = { def matchFail51(): Meat$ | Grass$ = throw new MatchError(selector15) if selector15.isInstanceOf[Cow] then { val cw: Cow = selector15.asInstanceOf[Cow(cw)] { { Grass } } } else matchFail51() } if selector15.isInstanceOf[Cat] then { val c: Cat = selector15.asInstanceOf[Cat(c)] { { Meat } } } else case101() } case91() } } getFoodFor(Cat.apply("Garfield")) { getFoodFor(Cow.apply("UHV")) () } } of class class dotty.tools.dotc.ast.Trees$DefDef # 1607 exception while transforming () extends Object() { this: test.HoistUpNestedIfElses.type => def main(args: Array[String]): Unit = { <trait> sealed interface trait Animal() extends Object {} final lazy module val Animal: Animal$ = new Animal$() final module class Animal$() extends Object() { this: Animal.type =>} case class Cat(name: String) extends Object() with Animal with Product1[ String ] { val name: String def copy(name: String): Cat = new Cat(name) def copy$default$1: String @uncheckedVariance = this.name: String @uncheckedVariance def isDefined: Boolean = true def _1: String = this.name override def hashCode(): Int = { var acc: Int = -889275714 acc = scala.runtime.Statics$#mix(acc, scala.runtime.Statics$#anyHash(this.name) ) scala.runtime.Statics$#finalizeHash(acc, 1) } override def equals(x$0: Any): Boolean = this.eq(x$0.asInstanceOf[Object]).||({ case val selector11: Any = x$0 { def case11(): Boolean = { def case21(): Boolean = { def matchFail11(): Boolean = throw new MatchError(selector11) if selector11.isInstanceOf[Any] then { false } else matchFail11() } if selector11.isInstanceOf[Cat] then { val x$0: Cat = selector11.asInstanceOf[Cat(x$0)] { this.name.==(x$0.name) } } else case21() } case11() } }) override def toString(): String = scala.runtime.ScalaRunTime._toString(this) override def canEqual(that: Any): Boolean = that.isInstanceOf[Cat] override def productPrefix: String = "Cat" } final lazy module val Cat: Cat$ = new Cat$() final module class Cat$() extends Object() with (String => Cat) { this: Cat.type => def apply(name: String): Cat = new Cat(name) def unapply(x$1: Cat): Cat = x$1 } case class Cow(typeOfMilk: String) extends Object() with Animal with Product1 [String] { val typeOfMilk: String def copy(typeOfMilk: String): Cow = new Cow(typeOfMilk) def copy$default$1: String @uncheckedVariance = this.typeOfMilk: String @uncheckedVariance def isDefined: Boolean = true def _1: String = this.typeOfMilk override def hashCode(): Int = { var acc: Int = -889275714 acc = scala.runtime.Statics$#mix(acc, scala.runtime.Statics$#anyHash(this.typeOfMilk) ) scala.runtime.Statics$#finalizeHash(acc, 1) } override def equals(x$0: Any): Boolean = this.eq(x$0.asInstanceOf[Object]).||({ case val selector12: Any = x$0 { def case31(): Boolean = { def case41(): Boolean = { def matchFail21(): Boolean = throw new MatchError(selector12) if selector12.isInstanceOf[Any] then { false } else matchFail21() } if selector12.isInstanceOf[Cow] then { val x$0: Cow = selector12.asInstanceOf[Cow(x$0)] { this.typeOfMilk.==(x$0.typeOfMilk) } } else case41() } case31() } }) override def toString(): String = scala.runtime.ScalaRunTime._toString(this) override def canEqual(that: Any): Boolean = that.isInstanceOf[Cow] override def productPrefix: String = "Cow" } final lazy module val Cow: Cow$ = new Cow$() final module class Cow$() extends Object() with (String => Cow) { this: Cow.type => def apply(typeOfMilk: String): Cow = new Cow(typeOfMilk) def unapply(x$1: Cow): Cow = x$1 } <trait> sealed interface trait Food() extends Object {} final lazy module val Food: Food$ = new Food$() final module class Food$() extends Object() { this: Food.type =>} final lazy module case val Meat: Meat$ = new Meat$() final module case class Meat$() extends Object() with Food with Product0 { this: Meat.type => override def hashCode(): Int = { var acc: Int = -889275714 scala.runtime.Statics$#finalizeHash(acc, 0) } override def equals(x$0: Any): Boolean = this.eq(x$0.asInstanceOf[Object]).||({ case val selector13: Any = x$0 { def case51(): Boolean = { def case61(): Boolean = { def matchFail31(): Boolean = throw new MatchError(selector13) if selector13.isInstanceOf[Any] then { false } else matchFail31() } if selector13.isInstanceOf[Meat$] then { val x$0: Meat$ = selector13.asInstanceOf[Meat$(x$0)] { true } } else case61() } case51() } }) override def toString(): String = scala.runtime.ScalaRunTime._toString(this) override def canEqual(that: Any): Boolean = that.isInstanceOf[Meat$] override def productPrefix: String = "Meat$" } final lazy module case val Grass: Grass$ = new Grass$() final module case class Grass$() extends Object() with Food with Product0 { this: Grass.type => override def hashCode(): Int = { var acc: Int = -889275714 scala.runtime.Statics$#finalizeHash(acc, 0) } override def equals(x$0: Any): Boolean = this.eq(x$0.asInstanceOf[Object]).||({ case val selector14: Any = x$0 { def case71(): Boolean = { def case81(): Boolean = { def matchFail41(): Boolean = throw new MatchError(selector14) if selector14.isInstanceOf[Any] then { false } else matchFail41() } if selector14.isInstanceOf[Grass$] then { val x$0: Grass$ = selector14.asInstanceOf[Grass$(x$0)] { true } } else case81() } case71() } }) override def toString(): String = scala.runtime.ScalaRunTime._toString(this) override def canEqual(that: Any): Boolean = that.isInstanceOf[Grass$] override def productPrefix: String = "Grass$" } def getFoodFor(a: Animal): Food & Product0 = { case val selector15: Animal = a { def case91(): Meat$ | Grass$ = { def case101(): Meat$ | Grass$ = { def matchFail51(): Meat$ | Grass$ = throw new MatchError(selector15) if selector15.isInstanceOf[Cow] then { val cw: Cow = selector15.asInstanceOf[Cow(cw)] { { Grass } } } else matchFail51() } if selector15.isInstanceOf[Cat] then { val c: Cat = selector15.asInstanceOf[Cat(c)] { { Meat } } } else case101() } case91() } } getFoodFor(Cat.apply("Garfield")) { getFoodFor(Cow.apply("UHV")) () } } } of class class dotty.tools.dotc.ast.Trees$Template # 1608 exception while transforming final module class HoistUpNestedIfElses$() extends Object() { this: test.HoistUpNestedIfElses.type => def main(args: Array[String]): Unit = { <trait> sealed interface trait Animal() extends Object {} final lazy module val Animal: Animal$ = new Animal$() final module class Animal$() extends Object() { this: Animal.type =>} case class Cat(name: String) extends Object() with Animal with Product1[ String ] { val name: String def copy(name: String): Cat = new Cat(name) def copy$default$1: String @uncheckedVariance = this.name: String @uncheckedVariance def isDefined: Boolean = true def _1: String = this.name override def hashCode(): Int = { var acc: Int = -889275714 acc = scala.runtime.Statics$#mix(acc, scala.runtime.Statics$#anyHash(this.name) ) scala.runtime.Statics$#finalizeHash(acc, 1) } override def equals(x$0: Any): Boolean = this.eq(x$0.asInstanceOf[Object]).||({ case val selector11: Any = x$0 { def case11(): Boolean = { def case21(): Boolean = { def matchFail11(): Boolean = throw new MatchError(selector11) if selector11.isInstanceOf[Any] then { false } else matchFail11() } if selector11.isInstanceOf[Cat] then { val x$0: Cat = selector11.asInstanceOf[Cat(x$0)] { this.name.==(x$0.name) } } else case21() } case11() } }) override def toString(): String = scala.runtime.ScalaRunTime._toString(this) override def canEqual(that: Any): Boolean = that.isInstanceOf[Cat] override def productPrefix: String = "Cat" } final lazy module val Cat: Cat$ = new Cat$() final module class Cat$() extends Object() with (String => Cat) { this: Cat.type => def apply(name: String): Cat = new Cat(name) def unapply(x$1: Cat): Cat = x$1 } case class Cow(typeOfMilk: String) extends Object() with Animal with Product1 [String] { val typeOfMilk: String def copy(typeOfMilk: String): Cow = new Cow(typeOfMilk) def copy$default$1: String @uncheckedVariance = this.typeOfMilk: String @uncheckedVariance def isDefined: Boolean = true def _1: String = this.typeOfMilk override def hashCode(): Int = { var acc: Int = -889275714 acc = scala.runtime.Statics$#mix(acc, scala.runtime.Statics$#anyHash(this.typeOfMilk) ) scala.runtime.Statics$#finalizeHash(acc, 1) } override def equals(x$0: Any): Boolean = this.eq(x$0.asInstanceOf[Object]).||({ case val selector12: Any = x$0 { def case31(): Boolean = { def case41(): Boolean = { def matchFail21(): Boolean = throw new MatchError(selector12) if selector12.isInstanceOf[Any] then { false } else matchFail21() } if selector12.isInstanceOf[Cow] then { val x$0: Cow = selector12.asInstanceOf[Cow(x$0)] { this.typeOfMilk.==(x$0.typeOfMilk) } } else case41() } case31() } }) override def toString(): String = scala.runtime.ScalaRunTime._toString(this) override def canEqual(that: Any): Boolean = that.isInstanceOf[Cow] override def productPrefix: String = "Cow" } final lazy module val Cow: Cow$ = new Cow$() final module class Cow$() extends Object() with (String => Cow) { this: Cow.type => def apply(typeOfMilk: String): Cow = new Cow(typeOfMilk) def unapply(x$1: Cow): Cow = x$1 } <trait> sealed interface trait Food() extends Object {} final lazy module val Food: Food$ = new Food$() final module class Food$() extends Object() { this: Food.type =>} final lazy module case val Meat: Meat$ = new Meat$() final module case class Meat$() extends Object() with Food with Product0 { this: Meat.type => override def hashCode(): Int = { var acc: Int = -889275714 scala.runtime.Statics$#finalizeHash(acc, 0) } override def equals(x$0: Any): Boolean = this.eq(x$0.asInstanceOf[Object]).||({ case val selector13: Any = x$0 { def case51(): Boolean = { def case61(): Boolean = { def matchFail31(): Boolean = throw new MatchError(selector13) if selector13.isInstanceOf[Any] then { false } else matchFail31() } if selector13.isInstanceOf[Meat$] then { val x$0: Meat$ = selector13.asInstanceOf[Meat$(x$0)] { true } } else case61() } case51() } }) override def toString(): String = scala.runtime.ScalaRunTime._toString(this) override def canEqual(that: Any): Boolean = that.isInstanceOf[Meat$] override def productPrefix: String = "Meat$" } final lazy module case val Grass: Grass$ = new Grass$() final module case class Grass$() extends Object() with Food with Product0 { this: Grass.type => override def hashCode(): Int = { var acc: Int = -889275714 scala.runtime.Statics$#finalizeHash(acc, 0) } override def equals(x$0: Any): Boolean = this.eq(x$0.asInstanceOf[Object]).||({ case val selector14: Any = x$0 { def case71(): Boolean = { def case81(): Boolean = { def matchFail41(): Boolean = throw new MatchError(selector14) if selector14.isInstanceOf[Any] then { false } else matchFail41() } if selector14.isInstanceOf[Grass$] then { val x$0: Grass$ = selector14.asInstanceOf[Grass$(x$0)] { true } } else case81() } case71() } }) override def toString(): String = scala.runtime.ScalaRunTime._toString(this) override def canEqual(that: Any): Boolean = that.isInstanceOf[Grass$] override def productPrefix: String = "Grass$" } def getFoodFor(a: Animal): Food & Product0 = { case val selector15: Animal = a { def case91(): Meat$ | Grass$ = { def case101(): Meat$ | Grass$ = { def matchFail51(): Meat$ | Grass$ = throw new MatchError(selector15) if selector15.isInstanceOf[Cow] then { val cw: Cow = selector15.asInstanceOf[Cow(cw)] { { Grass } } } else matchFail51() } if selector15.isInstanceOf[Cat] then { val c: Cat = selector15.asInstanceOf[Cat(c)] { { Meat } } } else case101() } case91() } } getFoodFor(Cat.apply("Garfield")) { getFoodFor(Cow.apply("UHV")) () } } } of class class dotty.tools.dotc.ast.Trees$TypeDef # 1609 exception while transforming package test { final lazy module val HoistUpNestedIfElses: test.HoistUpNestedIfElses$ = new test.HoistUpNestedIfElses$() final module class HoistUpNestedIfElses$() extends Object() { this: test.HoistUpNestedIfElses.type => def main(args: Array[String]): Unit = { <trait> sealed interface trait Animal() extends Object {} final lazy module val Animal: Animal$ = new Animal$() final module class Animal$() extends Object() { this: Animal.type =>} case class Cat(name: String) extends Object() with Animal with Product1[ String ] { val name: String def copy(name: String): Cat = new Cat(name) def copy$default$1: String @uncheckedVariance = this.name: String @uncheckedVariance def isDefined: Boolean = true def _1: String = this.name override def hashCode(): Int = { var acc: Int = -889275714 acc = scala.runtime.Statics$#mix(acc, scala.runtime.Statics$#anyHash(this.name) ) scala.runtime.Statics$#finalizeHash(acc, 1) } override def equals(x$0: Any): Boolean = this.eq(x$0.asInstanceOf[Object]).||({ case val selector11: Any = x$0 { def case11(): Boolean = { def case21(): Boolean = { def matchFail11(): Boolean = throw new MatchError(selector11) if selector11.isInstanceOf[Any] then { false } else matchFail11() } if selector11.isInstanceOf[Cat] then { val x$0: Cat = selector11.asInstanceOf[Cat(x$0)] { this.name.==(x$0.name) } } else case21() } case11() } }) override def toString(): String = scala.runtime.ScalaRunTime._toString(this) override def canEqual(that: Any): Boolean = that.isInstanceOf[Cat] override def productPrefix: String = "Cat" } final lazy module val Cat: Cat$ = new Cat$() final module class Cat$() extends Object() with (String => Cat) { this: Cat.type => def apply(name: String): Cat = new Cat(name) def unapply(x$1: Cat): Cat = x$1 } case class Cow(typeOfMilk: String) extends Object() with Animal with Product1 [String] { val typeOfMilk: String def copy(typeOfMilk: String): Cow = new Cow(typeOfMilk) def copy$default$1: String @uncheckedVariance = this.typeOfMilk: String @uncheckedVariance def isDefined: Boolean = true def _1: String = this.typeOfMilk override def hashCode(): Int = { var acc: Int = -889275714 acc = scala.runtime.Statics$#mix(acc, scala.runtime.Statics$#anyHash(this.typeOfMilk) ) scala.runtime.Statics$#finalizeHash(acc, 1) } override def equals(x$0: Any): Boolean = this.eq(x$0.asInstanceOf[Object]).||({ case val selector12: Any = x$0 { def case31(): Boolean = { def case41(): Boolean = { def matchFail21(): Boolean = throw new MatchError(selector12) if selector12.isInstanceOf[Any] then { false } else matchFail21() } if selector12.isInstanceOf[Cow] then { val x$0: Cow = selector12.asInstanceOf[Cow(x$0)] { this.typeOfMilk.==(x$0.typeOfMilk) } } else case41() } case31() } }) override def toString(): String = scala.runtime.ScalaRunTime._toString(this) override def canEqual(that: Any): Boolean = that.isInstanceOf[Cow] override def productPrefix: String = "Cow" } final lazy module val Cow: Cow$ = new Cow$() final module class Cow$() extends Object() with (String => Cow) { this: Cow.type => def apply(typeOfMilk: String): Cow = new Cow(typeOfMilk) def unapply(x$1: Cow): Cow = x$1 } <trait> sealed interface trait Food() extends Object {} final lazy module val Food: Food$ = new Food$() final module class Food$() extends Object() { this: Food.type =>} final lazy module case val Meat: Meat$ = new Meat$() final module case class Meat$() extends Object() with Food with Product0 { this: Meat.type => override def hashCode(): Int = { var acc: Int = -889275714 scala.runtime.Statics$#finalizeHash(acc, 0) } override def equals(x$0: Any): Boolean = this.eq(x$0.asInstanceOf[Object]).||({ case val selector13: Any = x$0 { def case51(): Boolean = { def case61(): Boolean = { def matchFail31(): Boolean = throw new MatchError(selector13) if selector13.isInstanceOf[Any] then { false } else matchFail31() } if selector13.isInstanceOf[Meat$] then { val x$0: Meat$ = selector13.asInstanceOf[Meat$(x$0)] { true } } else case61() } case51() } }) override def toString(): String = scala.runtime.ScalaRunTime._toString(this) override def canEqual(that: Any): Boolean = that.isInstanceOf[Meat$] override def productPrefix: String = "Meat$" } final lazy module case val Grass: Grass$ = new Grass$() final module case class Grass$() extends Object() with Food with Product0 { this: Grass.type => override def hashCode(): Int = { var acc: Int = -889275714 scala.runtime.Statics$#finalizeHash(acc, 0) } override def equals(x$0: Any): Boolean = this.eq(x$0.asInstanceOf[Object]).||({ case val selector14: Any = x$0 { def case71(): Boolean = { def case81(): Boolean = { def matchFail41(): Boolean = throw new MatchError(selector14) if selector14.isInstanceOf[Any] then { false } else matchFail41() } if selector14.isInstanceOf[Grass$] then { val x$0: Grass$ = selector14.asInstanceOf[Grass$(x$0)] { true } } else case81() } case71() } }) override def toString(): String = scala.runtime.ScalaRunTime._toString(this) override def canEqual(that: Any): Boolean = that.isInstanceOf[Grass$] override def productPrefix: String = "Grass$" } def getFoodFor(a: Animal): Food & Product0 = { case val selector15: Animal = a { def case91(): Meat$ | Grass$ = { def case101(): Meat$ | Grass$ = { def matchFail51(): Meat$ | Grass$ = throw new MatchError(selector15) if selector15.isInstanceOf[Cow] then { val cw: Cow = selector15.asInstanceOf[Cow(cw)] { { Grass } } } else matchFail51() } if selector15.isInstanceOf[Cat] then { val c: Cat = selector15.asInstanceOf[Cat(c)] { { Meat } } } else case101() } case91() } } getFoodFor(Cat.apply("Garfield")) { getFoodFor(Cow.apply("UHV")) () } } } } of class class dotty.tools.dotc.ast.Trees$PackageDef # 1610 exception occurred while compiling test/test/HoistUpNestedIfElses.scala Exception in thread "main" java.lang.AssertionError: assertion failed: asTerm called on not-a-Term val <none> at scala.Predef$.assert(Predef.scala:165) at dotty.tools.dotc.core.Symbols$Symbol.asTerm(Symbols.scala:409) at dotty.tools.dotc.ast.tpd$.New(tpd.scala:386) at dotty.tools.dotc.transform.linker.Simplify$$anonfun$5$$anonfun$6$$anonfun$apply$6.apply(Simplify.scala:113) at dotty.tools.dotc.transform.linker.Simplify$$anonfun$5$$anonfun$6$$anonfun$apply$6.apply(Simplify.scala:110) at dotty.tools.dotc.transform.linker.Simplify$$anon$1.transform(Simplify.scala:93) at dotty.tools.dotc.ast.Trees$Instance$TreeMap$$anonfun$transform$2.apply(Trees.scala:1182) at dotty.tools.dotc.ast.Trees$Instance$TreeMap$$anonfun$transform$2.apply(Trees.scala:1182) at scala.collection.immutable.List.loop$1(List.scala:173) at scala.collection.immutable.List.mapConserve(List.scala:189) at dotty.tools.dotc.ast.Trees$Instance$TreeMap.transform(Trees.scala:1182) at dotty.tools.dotc.ast.Trees$Instance$TreeMap.transform(Trees.scala:1101) at dotty.tools.dotc.transform.linker.Simplify$$anon$1.transform(Simplify.scala:93) at dotty.tools.dotc.ast.Trees$Instance$TreeMap$$anonfun$transform$2.apply(Trees.scala:1182) at dotty.tools.dotc.ast.Trees$Instance$TreeMap$$anonfun$transform$2.apply(Trees.scala:1182) at scala.collection.immutable.List.loop$1(List.scala:173) at scala.collection.immutable.List.mapConserve(List.scala:189) at dotty.tools.dotc.ast.Trees$Instance$TreeMap.transform(Trees.scala:1182) at dotty.tools.dotc.ast.Trees$Instance$TreeMap.transformStats(Trees.scala:1180) at dotty.tools.dotc.ast.Trees$Instance$TreeMap.transform(Trees.scala:1117) at dotty.tools.dotc.transform.linker.Simplify$$anon$1.transform(Simplify.scala:93) at dotty.tools.dotc.transform.linker.Simplify.transformDefDef(Simplify.scala:94) at dotty.tools.dotc.transform.TreeTransforms$TreeTransformer.goDefDef(TreeTransform.scala:834) at dotty.tools.dotc.transform.TreeTransforms$TreeTransformer.transformNamed(TreeTransform.scala:1005) at dotty.tools.dotc.transform.TreeTransforms$TreeTransformer$$anonfun$transform$2.apply(TreeTransform.scala:1212) at dotty.tools.dotc.transform.TreeTransforms$TreeTransformer$$anonfun$transform$2.apply(TreeTransform.scala:1205) at dotty.tools.dotc.reporting.Reporting$class.traceIndented(Reporter.scala:154) at dotty.tools.dotc.core.Contexts$Context.traceIndented(Contexts.scala:53) at dotty.tools.dotc.transform.TreeTransforms$TreeTransformer.transform(TreeTransform.scala:1204) at dotty.tools.dotc.transform.TreeTransforms$TreeTransformer.dotty$tools$dotc$transform$TreeTransforms$TreeTransformer$$transformStat$1(TreeTransform.scala:1238) at dotty.tools.dotc.transform.TreeTransforms$TreeTransformer$$anonfun$38.apply(TreeTransform.scala:1242) at dotty.tools.dotc.transform.TreeTransforms$TreeTransformer$$anonfun$38.apply(TreeTransform.scala:1242) at dotty.tools.dotc.core.Decorators$ListDecorator$.loop$1(Decorators.scala:51) at dotty.tools.dotc.core.Decorators$ListDecorator$.mapconserve$extension(Decorators.scala:67) at dotty.tools.dotc.transform.TreeTransforms$TreeTransformer.transformStats(TreeTransform.scala:1242) at dotty.tools.dotc.transform.TreeTransforms$TreeTransformer.transformUnnamed(TreeTransform.scala:1183) at dotty.tools.dotc.transform.TreeTransforms$TreeTransformer$$anonfun$transform$2.apply(TreeTransform.scala:1213) at dotty.tools.dotc.transform.TreeTransforms$TreeTransformer$$anonfun$transform$2.apply(TreeTransform.scala:1205) at dotty.tools.dotc.reporting.Reporting$class.traceIndented(Reporter.scala:154) at dotty.tools.dotc.core.Contexts$Context.traceIndented(Contexts.scala:53) at dotty.tools.dotc.transform.TreeTransforms$TreeTransformer.transform(TreeTransform.scala:1204) at dotty.tools.dotc.transform.TreeTransforms$TreeTransformer.transformNamed(TreeTransform.scala:1011) at dotty.tools.dotc.transform.TreeTransforms$TreeTransformer$$anonfun$transform$2.apply(TreeTransform.scala:1212) at dotty.tools.dotc.transform.TreeTransforms$TreeTransformer$$anonfun$transform$2.apply(TreeTransform.scala:1205) at dotty.tools.dotc.reporting.Reporting$class.traceIndented(Reporter.scala:154) at dotty.tools.dotc.core.Contexts$Context.traceIndented(Contexts.scala:53) at dotty.tools.dotc.transform.TreeTransforms$TreeTransformer.transform(TreeTransform.scala:1204) at dotty.tools.dotc.transform.TreeTransforms$TreeTransformer.dotty$tools$dotc$transform$TreeTransforms$TreeTransformer$$transformStat$1(TreeTransform.scala:1238) at dotty.tools.dotc.transform.TreeTransforms$TreeTransformer$$anonfun$38.apply(TreeTransform.scala:1242) at dotty.tools.dotc.transform.TreeTransforms$TreeTransformer$$anonfun$38.apply(TreeTransform.scala:1242) at dotty.tools.dotc.core.Decorators$ListDecorator$.loop$1(Decorators.scala:51) at dotty.tools.dotc.core.Decorators$ListDecorator$.mapconserve$extension(Decorators.scala:67) at dotty.tools.dotc.transform.TreeTransforms$TreeTransformer.transformStats(TreeTransform.scala:1242) at dotty.tools.dotc.transform.TreeTransforms$TreeTransformer.transformUnnamed(TreeTransform.scala:1192) at dotty.tools.dotc.transform.TreeTransforms$TreeTransformer$$anonfun$transform$2.apply(TreeTransform.scala:1213) at dotty.tools.dotc.transform.TreeTransforms$TreeTransformer$$anonfun$transform$2.apply(TreeTransform.scala:1205) at dotty.tools.dotc.reporting.Reporting$class.traceIndented(Reporter.scala:154) at dotty.tools.dotc.core.Contexts$Context.traceIndented(Contexts.scala:53) at dotty.tools.dotc.transform.TreeTransforms$TreeTransformer.transform(TreeTransform.scala:1204) at dotty.tools.dotc.transform.TreeTransforms$TreeTransformer.macroTransform(TreeTransform.scala:563) at dotty.tools.dotc.transform.TreeTransforms$TreeTransformer.run(TreeTransform.scala:480) at dotty.tools.dotc.core.Phases$Phase$$anonfun$runOn$1.apply(Phases.scala:279) at dotty.tools.dotc.core.Phases$Phase$$anonfun$runOn$1.apply(Phases.scala:277) at scala.collection.immutable.List.map(List.scala:273) at dotty.tools.dotc.core.Phases$Phase$class.runOn(Phases.scala:277) at dotty.tools.dotc.transform.TreeTransforms$TreeTransformer.runOn(TreeTransform.scala:474) at dotty.tools.dotc.Run$$anonfun$compileUnits$1$$anonfun$apply$mcV$sp$1.apply(Run.scala:67) at dotty.tools.dotc.Run$$anonfun$compileUnits$1$$anonfun$apply$mcV$sp$1.apply(Run.scala:64) at scala.collection.IndexedSeqOptimized$class.foreach(IndexedSeqOptimized.scala:33) at scala.collection.mutable.ArrayOps$ofRef.foreach(ArrayOps.scala:186) at dotty.tools.dotc.Run$$anonfun$compileUnits$1.apply$mcV$sp(Run.scala:64) at dotty.tools.dotc.Run$$anonfun$compileUnits$1.apply(Run.scala:59) at dotty.tools.dotc.Run$$anonfun$compileUnits$1.apply(Run.scala:59) at dotty.tools.dotc.util.Stats$.monitorHeartBeat(Stats.scala:69) at dotty.tools.dotc.Run.compileUnits(Run.scala:59) at dotty.tools.dotc.Run.compileSources(Run.scala:56) at dotty.tools.dotc.Run.compile(Run.scala:40) at dotty.tools.dotc.Driver.doCompile(Driver.scala:21) at dotty.tools.dotc.Driver.process(Driver.scala:47) at dotty.tools.dotc.Driver.process(Driver.scala:57) at dotty.tools.dotc.Driver.main(Driver.scala:65) at dotty.tools.dotc.Main.main(Main.scala)
in the simplify branch while scalac compiles it just fine. It looks like it's a problem with the optimizations performed in the simplify phase.
Fixed in unstuch branch to get you unstuck. Will work on a proper fix after student presentations.
unstuch
Compiling:
fails with:
in the simplify branch while scalac compiles it just fine. It looks like it's a problem with the optimizations performed in the simplify phase.