diff options
author | Adriaan Moors <adriaan@lightbend.com> | 2016-09-28 11:56:13 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2016-09-28 11:56:13 -0700 |
commit | 5757e047a70504991a176aeb2fd8b829d9e9b093 (patch) | |
tree | 488fd012c9b7e84602bd75d4298fbcd79ffe595d /test | |
parent | 3b5d4e25e9409eca87c03b0374cd8e6946554546 (diff) | |
parent | ad6bf3033fbdbd1d2c8bdea245f8347cfe292c1b (diff) | |
download | scala-5757e047a70504991a176aeb2fd8b829d9e9b093.tar.gz scala-5757e047a70504991a176aeb2fd8b829d9e9b093.tar.bz2 scala-5757e047a70504991a176aeb2fd8b829d9e9b093.zip |
Merge pull request #5423 from lrytz/sd229
Fixes for DelayedInit classes capturing values
Fix scala/scala-dev#229
Diffstat (limited to 'test')
-rw-r--r-- | test/files/run/t9697.check | 1 | ||||
-rw-r--r-- | test/files/run/t9697.scala | 204 |
2 files changed, 205 insertions, 0 deletions
diff --git a/test/files/run/t9697.check b/test/files/run/t9697.check new file mode 100644 index 0000000000..2a4f01c14f --- /dev/null +++ b/test/files/run/t9697.check @@ -0,0 +1 @@ +warning: there were 9 deprecation warnings (since 2.11.0); re-run with -deprecation for details diff --git a/test/files/run/t9697.scala b/test/files/run/t9697.scala new file mode 100644 index 0000000000..eb8e44f8fc --- /dev/null +++ b/test/files/run/t9697.scala @@ -0,0 +1,204 @@ +object log { + val b = new collection.mutable.StringBuilder + def apply(s: Any): Unit = b.append(s) + def check(s: String) = { + val bs = b.toString + assert(s == bs, bs) + b.clear() + } +} + +package t9697 { + abstract class WA extends DelayedInit { + override def delayedInit(x: => Unit): Unit = x + val waField = "4" + } + + class C { + def b(s: String) = log(s) + val cField = "1" + + { + val dummyLocal = "2" + new WA { + val anonField = "3" + b(cField) + b(dummyLocal) + b(anonField) + b(waField) + } + } + } +} + +package sd229 { + class Broken { + def is(ee: AnyRef) = { + new Delayed { + log(ee) + } + } + } + + class Delayed extends DelayedInit { + def delayedInit(x: => Unit): Unit = x + } +} + + +// already fixed in 2.11.8, crashes in 2.10.6 +package t4683a { + class A { log("a") } + class B { log("b") } + class Bug extends DelayedInit { + log("bug") + def foo(a: A): B = new B + def delayedInit(init: => Unit): Unit = init + } +} + +// already fixed in 2.12.0-RC1, crashes in 2.11.8 +package t4683b { + class Entity extends DelayedInit { + def delayedInit(x: => Unit): Unit = x + + class Field + + protected def EntityField[T <: Entity: reflect.ClassTag] = new Field + + def find[T <: Entity: reflect.ClassTag] { + Nil.map(dbo => { + class EntityHolder extends Entity { + val entity = EntityField[T] + } + }) + log("find") + } + } +} + +package t4683c { + trait T extends DelayedInit { + def delayedInit(body: => Unit) = { + log("init") + body + } + } +} + +package t4683d { + class C extends DelayedInit { + def delayedInit(body: => Unit): Unit = body + } + class Injector { + def test: Object = { + val name = "k" + class crash extends C { + log(name) + } + new crash() + } + } +} + +package t4683e { + class DelayedInitTest { + def a = log("uh") + class B extends DelayedInit { + a + def delayedInit(body: => Unit): Unit = body + } + } +} + +package t4683f { + class Foo extends DelayedInit { + log("fooInit") + def delayedInit(newBody: => Unit): Unit = { + log("delayedInit") + inits = { + val f = () => newBody + if (inits == null) { + log("initsNull") + List(f) + } else + f :: inits + } + } + def foo = log("foo") + var inits: List[() => Unit] = Nil + } + + class Bar extends Foo { + log("barInit") + def bar = foo + def newBaz: Foo = new Baz + private class Baz extends Foo { + log("bazInit") + bar + } + } +} + +package t4683g { + trait MatExpWorld { self => + class T extends Runner { val expWorld: self.type = self } + } + + trait Runner extends DelayedInit { + def delayedInit(init: => Unit): Unit = init + val expWorld: MatExpWorld + } +} + + +object Test extends App { + new t9697.C() + log.check("1234") + + new sd229.Broken().is("hi") + log.check("hi") + + val a: t4683a.A = new t4683a.A + var b: t4683a.B = null + new t4683a.Bug { + val b = foo(a) + } + log.check("abugb") + + new t4683b.Entity().find[t4683b.Entity] + log.check("find") + + val f = (p1: Int) => new t4683c.T { log(p1) } + f(5) + log.check("init5") + + new t4683d.Injector().test + log.check("k") + + val dit = new t4683e.DelayedInitTest() + new dit.B() + log.check("uh") + + val fuu = new t4683f.Foo + log.check("delayedInitinitsNull") + fuu.inits.foreach(_.apply()) + log.check("fooInit") + assert(fuu.inits == Nil) // the (delayed) initializer of Foo sets the inits field to Nil + + val brr = new t4683f.Bar + log.check("delayedInitinitsNulldelayedInit") // delayedInit is called once for each constructor + brr.inits.foreach(_.apply()) + log.check("barInitfooInit") + assert(brr.inits == Nil) + + val bzz = brr.newBaz + log.check("delayedInitinitsNulldelayedInit") + bzz.inits.foreach(_.apply()) + log.check("bazInitfoofooInit") + assert(bzz.inits == Nil) + + val mew = new t4683g.MatExpWorld { } + val mt = new mew.T + assert(mt.expWorld == mew) +} |