Dotty: `private[this] var x: String = _` crashes with "key not found: class String" in the backend

Created on 18 May 2017  路  2Comments  路  Source: lampepfl/dotty

class A {
  private[this] var x: String = _
}

```scala
java.util.NoSuchElementException: key not found: class String
at scala.collection.MapLike$class.default(MapLike.scala:228)
at scala.collection.AbstractMap.default(Map.scala:59)
at scala.collection.mutable.HashMap.apply(HashMap.scala:65)
at scala.tools.nsc.backend.jvm.BCodeSkelBuilder$PlainSkelBuilder$locals$.load(BCodeSkelBuilder.scala:402)
at scala.tools.nsc.backend.jvm.BCodeBodyBuilder$PlainBodyBuilder.genLoad(BCodeBodyBuilder.scala:391)
at scala.tools.nsc.backend.jvm.BCodeBodyBuilder$PlainBodyBuilder.genLoad(BCodeBodyBuilder.scala:290)
at scala.tools.nsc.backend.jvm.BCodeBodyBuilder$PlainBodyBuilder.genStat(BCodeBodyBuilder.scala:89)
at scala.tools.nsc.backend.jvm.BCodeBodyBuilder$PlainBodyBuilder$$anonfun$genNormalBlock$1$1.apply(BCodeBodyBuilder.scala:860)
at scala.tools.nsc.backend.jvm.BCodeBodyBuilder$PlainBodyBuilder$$anonfun$genNormalBlock$1$1.apply(BCodeBodyBuilder.scala:860)
at scala.collection.immutable.List.foreach(List.scala:392)
at scala.tools.nsc.backend.jvm.BCodeBodyBuilder$PlainBodyBuilder.genNormalBlock$1(BCodeBodyBuilder.scala:860)
at scala.tools.nsc.backend.jvm.BCodeBodyBuilder$PlainBodyBuilder.genBlock(BCodeBodyBuilder.scala:892)
at scala.tools.nsc.backend.jvm.BCodeBodyBuilder$PlainBodyBuilder.genLoad(BCodeBodyBuilder.scala:408)
at scala.tools.nsc.backend.jvm.BCodeSkelBuilder$PlainSkelBuilder.emitNormalMethodBody$1(BCodeSkelBuilder.scala:606)
at scala.tools.nsc.backend.jvm.BCodeSkelBuilder$PlainSkelBuilder.genDefDef(BCodeSkelBuilder.scala:640)
at scala.tools.nsc.backend.jvm.BCodeSkelBuilder$PlainSkelBuilder.gen(BCodeSkelBuilder.scala:509)
at scala.tools.nsc.backend.jvm.BCodeSkelBuilder$PlainSkelBuilder$$anonfun$gen$1.apply(BCodeSkelBuilder.scala:511)
at scala.tools.nsc.backend.jvm.BCodeSkelBuilder$PlainSkelBuilder$$anonfun$gen$1.apply(BCodeSkelBuilder.scala:511)
at scala.collection.immutable.List.foreach(List.scala:392)
at scala.tools.nsc.backend.jvm.BCodeSkelBuilder$PlainSkelBuilder.gen(BCodeSkelBuilder.scala:511)
at scala.tools.nsc.backend.jvm.BCodeSkelBuilder$PlainSkelBuilder.genPlainClass(BCodeSkelBuilder.scala:118)
at dotty.tools.backend.jvm.GenBCodePipeline$Worker1.visit(GenBCode.scala:199)
at dotty.tools.backend.jvm.GenBCodePipeline$Worker1.run(GenBCode.scala:152)
at dotty.tools.backend.jvm.GenBCodePipeline.buildAndSendToDisk(GenBCode.scala:367)
at dotty.tools.backend.jvm.GenBCodePipeline.run(GenBCode.scala:333)
at dotty.tools.backend.jvm.GenBCode.run(GenBCode.scala:54)
at dotty.tools.dotc.core.Phases$Phase$$anonfun$runOn$1.apply(Phases.scala:283)
at dotty.tools.dotc.core.Phases$Phase$$anonfun$runOn$1.apply(Phases.scala:281)
at scala.collection.immutable.List.map(List.scala:284)
at dotty.tools.dotc.core.Phases$Phase$class.runOn(Phases.scala:281)
at dotty.tools.backend.jvm.GenBCode.runOn(GenBCode.scala:38)
at dotty.tools.dotc.Run$$anonfun$compileUnits$1$$anonfun$apply$mcV$sp$1.apply(Run.scala:82)
at dotty.tools.dotc.Run$$anonfun$compileUnits$1$$anonfun$apply$mcV$sp$1.apply(Run.scala:79)
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:79)
at dotty.tools.dotc.Run$$anonfun$compileUnits$1.apply(Run.scala:67)
at dotty.tools.dotc.Run$$anonfun$compileUnits$1.apply(Run.scala:67)
at dotty.tools.dotc.util.Stats$.monitorHeartBeat(Stats.scala:76)
at dotty.tools.dotc.Run.compileUnits(Run.scala:67)
at dotty.tools.dotc.Run.compileSources(Run.scala:64)
at dotty.tools.dotc.Run.compile(Run.scala:48)
at dotty.tools.dotc.Driver.doCompile(Driver.scala:26)
at dotty.tools.dotc.Driver.process(Driver.scala:124)
at dotty.tools.dotc.Driver.process(Driver.scala:93)
at dotty.tools.dotc.Driver.process(Driver.scala:105)
at dotty.tools.dotc.Driver.main(Driver.scala:132)
at dotty.tools.dotc.Main.main(Main.scala)

Interestingly, this also crashes:
```scala
class A {
  private[this] var x: String = _

  x = "foo"
}

But this doesn't:

class A {
  private[this] var x: String = _

  def test: Unit = {
    x = "foo"
  }
}
backend novice bug

Most helpful comment

This bug is a nice way for people to learn how to write tree transforms.

This bug is result of a bunch of interactions: constructors makes an optimization decision to make x NOT be a field, and instead be a local constructor variable.

result of i2468.scala after TreeTransform:{..., constructors, ...}:

package <empty> {
  @scala.annotation.internal.SourceFile("i2468.scala") class A extends Object {
    def <init>(): Unit =
      {
        super()
        var x: String = _
        ()
      }
  }
}

Backend does not expect to get underscores in assignments of local variables, as it shouldn't :-).
The solution will be to introduce a mini-phase in block of lambdaLift-restoreScopes that will replace _ by null and a post-condition that such assignments are gone.

All 2 comments

/cc @DarkDimius

This bug is a nice way for people to learn how to write tree transforms.

This bug is result of a bunch of interactions: constructors makes an optimization decision to make x NOT be a field, and instead be a local constructor variable.

result of i2468.scala after TreeTransform:{..., constructors, ...}:

package <empty> {
  @scala.annotation.internal.SourceFile("i2468.scala") class A extends Object {
    def <init>(): Unit =
      {
        super()
        var x: String = _
        ()
      }
  }
}

Backend does not expect to get underscores in assignments of local variables, as it shouldn't :-).
The solution will be to introduce a mini-phase in block of lambdaLift-restoreScopes that will replace _ by null and a post-condition that such assignments are gone.

Was this page helpful?
0 / 5 - 0 ratings