Skip to content
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

DelayedInit crashes following $outer pointers #4683

Closed
scabug opened this issue Jun 9, 2011 · 13 comments
Closed

DelayedInit crashes following $outer pointers #4683

scabug opened this issue Jun 9, 2011 · 13 comments

Comments

@scabug
Copy link

scabug commented Jun 9, 2011

[Elided, replaced.]

class DelayedInitTest {
  def a = ()
  class B extends DelayedInit {
    a
    def delayedInit(body: => Unit) = ()
  }
}

scalac3 ./a.scala 
error: java.lang.Error: symbol value $outer does not exist in DelayedInitTest$B$delayedInit$body.apply
	at scala.reflect.internal.SymbolTable.abort(SymbolTable.scala:31)
	at scala.tools.nsc.backend.icode.GenICode$ICodePhase.scala$tools$nsc$backend$icode$GenICode$ICodePhase$$genLoad(GenICode.scala:1027)
	at scala.tools.nsc.backend.icode.GenICode$ICodePhase.genLoadQualifier(GenICode.scala:1175)
	at scala.tools.nsc.backend.icode.GenICode$ICodePhase.scala$tools$nsc$backend$icode$GenICode$ICodePhase$$genLoad(GenICode.scala:921)
	at scala.tools.nsc.backend.icode.GenICode$ICodePhase.scala$tools$nsc$backend$icode$GenICode$ICodePhase$$genStat(GenICode.scala:174)
@scabug
Copy link
Author

scabug commented Jun 9, 2011

Imported From: https://issues.scala-lang.org/browse/SI-4683?orig=1
Reporter: Flávio W. Brasil (fwbrasil)
Affected Versions: 2.10.4-RC1, 2.11.0-M8

@scabug
Copy link
Author

scabug commented Jun 29, 2011

Flávio W. Brasil (fwbrasil) said:
It's possible to have a prevision on when this issue will be treated?

@scabug
Copy link
Author

scabug commented Aug 25, 2011

@lexn82 said:
I wanted to open a separate issue, but they both seem to be related to the outer scope with DelayedInit.

The following code will generate "java.lang.NoSuchFieldError: a$1" at run-time:

object Error {
  def main(args: Array[String]) {
    val a: A = new A
    var b: B = null
    
    new Bug {
      val b = foo(a)
    }
  }
}

class A
class B
class Bug extends DelayedInit {
  def foo(a: A) :B = new B
  def delayedInit(init: => Unit) { init }
}

@scabug
Copy link
Author

scabug commented Dec 21, 2012

@jrudolph said:
Seems to be related to #4396.

I checked with 2.10.0 and the original compiletime crash and the runtime crash reported later are still the same.

@scabug
Copy link
Author

scabug commented Dec 21, 2012

@jrudolph said:
In spray we've got a similar problem reported here:

https://groups.google.com/d/topic/spray-user/LzV4lEVVccI/discussion

The same code works with 2.10 but fails to compile in 2.9.2.

@scabug
Copy link
Author

scabug commented Feb 23, 2013

Jesse Luehrs (doy) said:
I just ran into this bug with code that looks like this:

class Foo extends DelayedInit {
  def delayedInit (newBody: => Unit) {
    body = () => newBody
  }

  def foo = "FOO"

  var body: () => Unit = _
}

class Bar extends Foo {
  def bar = foo

  private class Baz extends Foo {
    bar
  }
}

This is on version 2.10.0-20121205-235900-18481cef9b.

@scabug
Copy link
Author

scabug commented Mar 4, 2013

@retronym said:
Another example:

trait MatExpWorld { self =>
  class T extends Runner { val expWorld: self.type = self }
}

trait Runner extends DelayedInit {
  val expWorld: MatExpWorld
}

@scabug
Copy link
Author

scabug commented May 20, 2013

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

@scabug
Copy link
Author

scabug commented Jul 16, 2013

@retronym said:
One more example:

class Entity extends DelayedInit {
 
  def delayedInit(x: => Unit) {x}
 
  class Field
 
  protected def EntityField[T <: Entity: Manifest] = new Field
 
  def find[T <: Entity: Manifest] {
    Nil.map(dbo => {
      class EntityHolder extends Entity {
        val entity = EntityField[T]
      }
    })
  }
 
}

@scabug
Copy link
Author

scabug commented Oct 4, 2013

Thornton Chamberlain (tchamberlain) said:
The following looks like it may be yet another manifestation of the same problem:

trait T extends DelayedInit {
  def delayedInit(body: => Unit) = {
    println("In delayedInit")
    body
  }
}
val f = {(p1: Int) => new T{println(p1)}}
f(5)

In 2.10.3, this fails with 'error: symbol value p1$1 does not exist in $anonfun$1$$anon$1$delayedInit$body.apply'

I encountered this when trying to use a Specs2 After context with a data table.

@scabug
Copy link
Author

scabug commented Oct 8, 2013

@retronym said:
The problem there is that the DelayedInit transformation happens in the 'constructors' compiler phase, by which point the prior 'lambdalift' phase has already decided that p2 need not be retained in the anonymous subclass as T as a field. Looks mighty tricky to fix. I would recommend against building on top of DelayedInit.

@scabug
Copy link
Author

scabug commented Nov 15, 2014

@retronym said:
Another example:

    class C extends DelayedInit {
      def delayedInit(body: => Unit) {}
    }
    class Injector {
      def test = {
        val name = ""
        class crash extends C {
          println(name)
        }
      }
    }

@scabug
Copy link
Author

scabug commented Sep 27, 2016

@lrytz said:
scala/scala#5423

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants