scala / bug

Scala 2 bug reports only. Please, no questions — proper bug reports only.
https://scala-lang.org
232 stars 21 forks source link

assertion failed during type erasure #3425

Closed scabug closed 11 years ago

scabug commented 14 years ago

Compiling the code below with Scala 2.8.x

class Foo(x: Int)
class Bar extends Foo(1)

trait A {
  def foo[T <: Foo]
}
class B extends A {
  def foo[Bar] { println("B.foo[Bar]") }
}
object bug1 {
  val x = new B
  val y = new A {
    def foo[Bar] { println("A.foo[Bar]") }
  }
  def main(args: Array[String]) {
    x.foo // ok
    y.foo // <==== java.lang.AssertionError: assertion failed
  }
}

produces the following output :

Exception in thread "main" java.lang.AssertionError: assertion failed
    at scala.Predef$$.assert(Predef.scala:79)
    at scala.tools.nsc.ast.TreeGen.mkCast(TreeGen.scala:142)
    at scala.tools.nsc.Global$$gen$$.mkAttributedCast(Global.scala:74)
    at scala.tools.nsc.ast.TreeDSL$$CODE$$TreeMethods.AS_ATTR(TreeDSL.scala:125)
    at scala.tools.nsc.transform.Erasure$$Eraser.cast(Erasure.scala:503)
    at scala.tools.nsc.transform.Erasure$$Eraser.adaptMember(Erasure.scala:626)
    at scala.tools.nsc.transform.Erasure$$Eraser.liftedTree1$$1(Erasure.scala:652)
    at scala.tools.nsc.transform.Erasure$$Eraser.typed1(Erasure.scala:651)
    at scala.tools.nsc.typechecker.Typers$$Typer.typed(Typers.scala:4151)
        ...
scabug commented 14 years ago

Imported From: https://issues.scala-lang.org/browse/SI-3425?orig=1 Reporter: @michelou Affected Versions: 2.8.1, 2.9.2, 2.10.0

scabug commented 14 years ago

@paulp said: Your example kind of obscures the issue by introducing a type parameter named "Bar". The failure seems to be where constraints meet refinements in the land of erasure. You can have a refinement without altering the constraint, or change the constraint if you're not in a refinement. Illustrating, here are two variations which work:

  // don't change the constraint - any alteration crashes
  val y = new A {
    def foo[T <: Foo] { println("A.foo[Bar]") }
  }

  // annotate the type - now you can widen it.
  // (or put in a class, such as B.)
  val y: A = new A {
    def foo[T <: AnyRef] { println("A.foo[Bar]") }
  }
scabug commented 14 years ago

Mirko Stocker (misto) said: I just stumbled over a very similar error, judging from the stacktrace I got.

trait A
trait B
def x(a: (A { val y: Int }) with B { val y: Int }) = a.y

leads to

Exception in thread "main" java.lang.AssertionError: assertion failed
        at scala.Predef$$.assert(Predef.scala:78)
        at scala.tools.nsc.ast.TreeGen.mkCast(TreeGen.scala:141)
        at scala.tools.nsc.ast.TreeDSL$$CODE$$TreeMethods.AS_ATTR(TreeDSL.scala:126)
        at scala.tools.nsc.transform.Erasure$$Eraser.cast(Erasure.scala:500)
        at scala.tools.nsc.transform.Erasure$$Eraser.adaptMember(Erasure.scala:623)
        at scala.tools.nsc.transform.Erasure$$Eraser.liftedTree1$$1(Erasure.scala:649)
        at scala.tools.nsc.transform.Erasure$$Eraser.typed1(Erasure.scala:648)
        at scala.tools.nsc.typechecker.Typers$$Typer.typed(Typers.scala:4046)
        at scala.tools.nsc.typechecker.Typers$$Typer$$$$anonfun$$typedApply$$1$$1.apply(Typers.scala:3252)
        at scala.tools.nsc.typechecker.Typers$$Typer$$$$anonfun$$typedApply$$1$$1.apply(Typers.scala:3252)
...

(I was just exploring the AST, found it interesting that CompoundTypeTree takes a Template and played around with it until it suddenly crashed my REPL.)

scabug commented 13 years ago

@soc said: The example of the original reporter compiles and runs in the REPL with 2.9.0.r24438-b20110314020113.

The last example still crashes with

java.lang.AssertionError: assertion failed: a : <noprefix>.<root>.$$line3.$$read.$$iw.$$iw.<refinement> ~><noprefix>.<root>.$$line1.$$read.$$iw.$$iw.A
    at scala.Predef$$.assert(Predef.scala:100)
    at scala.tools.nsc.ast.TreeGen.mkCast(TreeGen.scala:137)
    at scala.tools.nsc.Global$$gen$$.mkAttributedCast(Global.scala:66)
    at scala.tools.nsc.ast.TreeDSL$$CODE$$TreeMethods.AS_ATTR(TreeDSL.scala:128)
    at scala.tools.nsc.transform.Erasure$$Eraser.cast(Erasure.scala:528)
    at scala.tools.nsc.transform.Erasure$$Eraser.adaptMember(Erasure.scala:611)
    at scala.tools.nsc.transform.Erasure$$Eraser.typed1(Erasure.scala:633)
    at scala.tools.nsc.typechecker.Typers$$Typer.typed(Typers.scala:4148)
    at scala.tools.nsc.typechecker.Typers$$Typer$$$$anonfun$$typedApply$$1$$1.apply(Typers.scala:3260)
    at scala.tools.nsc.typechecker.Typers$$Typer$$$$anonfun$$typedApply$$1$$1.apply(Typers.scala:3260)
    at scala.tools.nsc.typechecker.Typers$$Typer.silent(Typers.scala:623)
    at scala.tools.nsc.typechecker.Typers$$Typer.typedApply$$1(Typers.scala:3260)
    at scala.tools.nsc.typechecker.Typers$$Typer.typed1(Typers.scala:3993)
    at scala.tools.nsc.transform.Erasure$$Eraser.typed1(Erasure.scala:633)
    at scala.tools.nsc.typechecker.Typers$$Typer.typed(Typers.scala:4148)
    at scala.tools.nsc.typechecker.Typers$$Typer.transformedOrTyped(Typers.scala:4290)
    at scala.tools.nsc.typechecker.Typers$$Typer.typedDefDef(Typers.scala:1705)
    at scala.tools.nsc.typechecker.Typers$$Typer.typed1(Typers.scala:3808)
    at scala.tools.nsc.transform.Erasure$$Eraser.typed1(Erasure.scala:633)
    at scala.tools.nsc.typechecker.Typers$$Typer.typed(Typers.scala:4148)
    at scala.tools.nsc.typechecker.Typers$$Typer.typedStat$$1(Typers.scala:2039)
    at scala.tools.nsc.typechecker.Typers$$Typer$$$$anonfun$$24.apply(Typers.scala:2122)
    at scala.tools.nsc.typechecker.Typers$$Typer$$$$anonfun$$24.apply(Typers.scala:2122)
    at scala.collection.immutable.List.loop$$1(List.scala:117)
    at scala.collection.immutable.List.mapConserve(List.scala:133)
    at scala.tools.nsc.typechecker.Typers$$Typer.typedStats(Typers.scala:2122)
    at scala.tools.nsc.typechecker.Typers$$Typer.typedTemplate(Typers.scala:1458)
    at scala.tools.nsc.typechecker.Typers$$Typer.typedClassDef(Typers.scala:1223)
    at scala.tools.nsc.typechecker.Typers$$Typer.typed1(Typers.scala:3799)
    at scala.tools.nsc.transform.Erasure$$Eraser.typed1(Erasure.scala:633)
    at scala.tools.nsc.typechecker.Typers$$Typer.typed(Typers.scala:4148)
    at scala.tools.nsc.typechecker.Typers$$Typer.typedStat$$1(Typers.scala:2039)
    at scala.tools.nsc.typechecker.Typers$$Typer$$$$anonfun$$24.apply(Typers.scala:2122)
    at scala.tools.nsc.typechecker.Typers$$Typer$$$$anonfun$$24.apply(Typers.scala:2122)
    at scala.collection.immutable.List.loop$$1(List.scala:117)
    at scala.collection.immutable.List.mapConserve(List.scala:133)
    at scala.tools.nsc.typechecker.Typers$$Typer.typedStats(Typers.scala:2122)
    at scala.tools.nsc.typechecker.Typers$$Typer.typedTemplate(Typers.scala:1458)
    at scala.tools.nsc.typechecker.Typers$$Typer.typedClassDef(Typers.scala:1223)
    at scala.tools.nsc.typechecker.Typers$$Typer.typed1(Typers.scala:3799)
    at scala.tools.nsc.transform.Erasure$$Eraser.typed1(Erasure.scala:633)
    at scala.tools.nsc.typechecker.Typers$$Typer.typed(Typers.scala:4148)
    at scala.tools.nsc.typechecker.Typers$$Typer.typedStat$$1(Typers.scala:2039)
    at scala.tools.nsc.typechecker.Typers$$Typer$$$$anonfun$$24.apply(Typers.scala:2122)
    at scala.tools.nsc.typechecker.Typers$$Typer$$$$anonfun$$24.apply(Typers.scala:2122)
    at scala.collection.immutable.List.loop$$1(List.scala:117)
    at scala.collection.immutable.List.mapConserve(List.scala:133)
    at scala.tools.nsc.typechecker.Typers$$Typer.typedStats(Typers.scala:2122)
    at scala.tools.nsc.typechecker.Typers$$Typer.typedTemplate(Typers.scala:1458)
    at scala.tools.nsc.typechecker.Typers$$Typer.typedClassDef(Typers.scala:1223)
    at scala.tools.nsc.typechecker.Typers$$Typer.typed1(Typers.scala:3799)
    at scala.tools.nsc.transform.Erasure$$Eraser.typed1(Erasure.scala:633)
    at scala.tools.nsc.typechecker.Typers$$Typer.typed(Typers.scala:4148)
    at scala.tools.nsc.typechecker.Typers$$Typer.typedStat$$1(Typers.scala:2039)
    at scala.tools.nsc.typechecker.Typers$$Typer$$$$anonfun$$24.apply(Typers.scala:2122)
    at scala.tools.nsc.typechecker.Typers$$Typer$$$$anonfun$$24.apply(Typers.scala:2122)
    at scala.collection.immutable.List.loop$$1(List.scala:117)
    at scala.collection.immutable.List.mapConserve(List.scala:133)
    at scala.tools.nsc.typechecker.Typers$$Typer.typedStats(Typers.scala:2122)
    at scala.tools.nsc.typechecker.Typers$$Typer.typed1(Typers.scala:3795)
    at scala.tools.nsc.transform.Erasure$$Eraser.typed1(Erasure.scala:633)
    at scala.tools.nsc.typechecker.Typers$$Typer.typed(Typers.scala:4148)
    at scala.tools.nsc.typechecker.Typers$$Typer.typed(Typers.scala:4197)
    at scala.tools.nsc.transform.Erasure$$ErasureTransformer$$$$anonfun$$transform$$1.apply(Erasure.scala:1054)
    at scala.tools.nsc.transform.Erasure$$ErasureTransformer$$$$anonfun$$transform$$1.apply(Erasure.scala:1049)
    at scala.tools.nsc.symtab.SymbolTable.atPhase(SymbolTable.scala:96)
    at scala.tools.nsc.transform.Erasure$$ErasureTransformer.transform(Erasure.scala:1049)
    at scala.tools.nsc.ast.Trees$$Transformer.transformUnit(Trees.scala:878)
    at scala.tools.nsc.transform.Transform$$Phase.apply(Transform.scala:30)
    at scala.tools.nsc.Global$$GlobalPhase$$$$anonfun$$applyPhase$$1.apply(Global.scala:326)
    at scala.tools.nsc.Global$$GlobalPhase$$$$anonfun$$applyPhase$$1.apply(Global.scala:326)
    at scala.tools.nsc.reporters.Reporter.withSource(Reporter.scala:47)
    at scala.tools.nsc.Global$$GlobalPhase.applyPhase(Global.scala:326)
    at scala.tools.nsc.Global$$GlobalPhase$$$$anonfun$$run$$1.apply(Global.scala:294)
    at scala.tools.nsc.Global$$GlobalPhase$$$$anonfun$$run$$1.apply(Global.scala:294)
    at scala.collection.Iterator$$class.foreach(Iterator.scala:651)
    at scala.collection.mutable.ListBuffer$$$$anon$$1.foreach(ListBuffer.scala:311)
    at scala.tools.nsc.Global$$GlobalPhase.run(Global.scala:294)
    at scala.tools.nsc.Global$$Run.compileSources(Global.scala:896)
    at scala.tools.nsc.interpreter.IMain$$ReadEvalPrint.compileAndSaveRun(IMain.scala:706)
    at scala.tools.nsc.interpreter.IMain$$ReadEvalPrint.compile(IMain.scala:674)
    at scala.tools.nsc.interpreter.IMain$$Request.compile(IMain.scala:818)
    at scala.tools.nsc.interpreter.IMain.interpret(IMain.scala:576)
    at scala.tools.nsc.interpreter.IMain.interpret(IMain.scala:542)
    at scala.tools.nsc.interpreter.ILoop.reallyInterpret$$1(ILoop.scala:669)
    at scala.tools.nsc.interpreter.ILoop.interpretStartingWith(ILoop.scala:721)
    at scala.tools.nsc.interpreter.ILoop.command(ILoop.scala:554)
    at scala.tools.nsc.interpreter.ILoop.processLine$$1(ILoop.scala:445)
    at scala.tools.nsc.interpreter.ILoop.loop(ILoop.scala:452)
    at scala.tools.nsc.interpreter.ILoop.process(ILoop.scala:789)
    at scala.tools.nsc.interpreter.ILoop.main(ILoop.scala:814)
scabug commented 11 years ago

@retronym said: WIP: https://github.com/retronym/scala/tree/ticket/3425

scabug commented 11 years ago

@JamesIry said: 2.10.2 is about to be cut. Kicking down the road and un-assigning to foster work stealing.

scabug commented 11 years ago

@paulp said: Oops, I didn't see you had a wip here. Then again, that branch looks mysteriously barren. Was there something interesting in it in the past?

I think I took it a ways past wip, anyway. https://github.com/scala/scala/pull/2574

scabug commented 11 years ago

@retronym said: I must have lost it in the stash somewhere. But the fix is the same as yours: don't assume that an overridden member comes only is a non-refinement member. I'll give your PR proper review in the next day or two.