summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHubert Plociniczak <hubert.plociniczak@epfl.ch>2011-01-07 14:42:49 +0000
committerHubert Plociniczak <hubert.plociniczak@epfl.ch>2011-01-07 14:42:49 +0000
commit8e9f3c219d05c50cb72446297b236704662879cb (patch)
treeee5f0377ffd2d391d85b2f672361422c3b27bcb3
parent5cefd81ee9f99535e3e2ce8a23016206da65a92d (diff)
downloadscala-8e9f3c219d05c50cb72446297b236704662879cb.tar.gz
scala-8e9f3c219d05c50cb72446297b236704662879cb.tar.bz2
scala-8e9f3c219d05c50cb72446297b236704662879cb.zip
Closes #4047. Review by odersky
-rw-r--r--src/compiler/scala/tools/nsc/transform/Erasure.scala13
-rw-r--r--test/files/run/t4047.check5
-rw-r--r--test/files/run/t4047.scala34
3 files changed, 47 insertions, 5 deletions
diff --git a/src/compiler/scala/tools/nsc/transform/Erasure.scala b/src/compiler/scala/tools/nsc/transform/Erasure.scala
index 1df0b5bf3b..1a97c1f6c9 100644
--- a/src/compiler/scala/tools/nsc/transform/Erasure.scala
+++ b/src/compiler/scala/tools/nsc/transform/Erasure.scala
@@ -449,7 +449,10 @@ abstract class Erasure extends AddInterfaces with typechecker.Analyzer with ast.
case _ =>
typedPos(tree.pos)(tree.tpe.typeSymbol match {
case UnitClass =>
- if (treeInfo isPureExpr tree) REF(BoxedUnit_UNIT)
+ // Although lazy vals are pure expressions,
+ // we should still call them in bridge methods
+ if (treeInfo.isPureExpr(tree) && (tree.symbol == null || !tree.symbol.isLazy))
+ REF(BoxedUnit_UNIT)
else BLOCK(tree, REF(BoxedUnit_UNIT))
case x =>
assert(x != ArrayClass)
@@ -818,15 +821,15 @@ abstract class Erasure extends AddInterfaces with typechecker.Analyzer with ast.
while (opc.hasNext) {
val member = opc.overriding
val other = opc.overridden
- //Console.println("bridge? " + member + ":" + member.tpe + member.locationString + " to " + other + ":" + other.tpe + other.locationString);//DEBUG
+ //Console.println("bridge? " + member + ":" + member.tpe + member.locationString + " to " + other + ":" + other.tpe + other.locationString)//DEBUG
if (atPhase(currentRun.explicitouterPhase)(!member.isDeferred)) {
- val otpe = erasure(other.tpe);
+ val otpe = erasure(other.tpe)
val bridgeNeeded = atPhase(phase.next) (
!(other.tpe =:= member.tpe) &&
!(deconstMap(other.tpe) =:= deconstMap(member.tpe)) &&
{ var e = bridgesScope.lookupEntry(member.name)
while ((e ne null) && !((e.sym.tpe =:= otpe) && (bridgeTarget(e.sym) == member)))
- e = bridgesScope.lookupNextEntry(e);
+ e = bridgesScope.lookupNextEntry(e)
(e eq null)
}
);
@@ -860,7 +863,7 @@ abstract class Erasure extends AddInterfaces with typechecker.Analyzer with ast.
log("generating bridge from " + other + "(" + Flags.flagsToString(bridge.flags) + ")" + ":" + otpe + other.locationString + " to " + member + ":" + erasure(member.tpe) + member.locationString + " =\n " + bridgeDef);
bridgeDef
}
- } :: bridges;
+ } :: bridges
}
}
opc.next
diff --git a/test/files/run/t4047.check b/test/files/run/t4047.check
new file mode 100644
index 0000000000..2a942a70e0
--- /dev/null
+++ b/test/files/run/t4047.check
@@ -0,0 +1,5 @@
+Unit: called A.foo
+Unit: called B.foo
+Unit: called C.foo
+Unit: called D.foo
+Unit: called D.foo
diff --git a/test/files/run/t4047.scala b/test/files/run/t4047.scala
new file mode 100644
index 0000000000..cd42a8b4df
--- /dev/null
+++ b/test/files/run/t4047.scala
@@ -0,0 +1,34 @@
+trait Foo[T] { val foo: T}
+
+class A extends Foo[Unit]{
+ lazy val foo = println("Unit: called A.foo")
+}
+
+class B extends Foo[Unit]{
+ val foo = println("Unit: called B.foo")
+}
+
+trait Bar[T] { def foo: T}
+
+class C extends Bar[Unit]{
+ lazy val foo = println("Unit: called C.foo")
+}
+
+class D extends Bar[Unit]{
+ def foo = println("Unit: called D.foo")
+}
+
+object Test extends Application {
+ val a: Foo[Unit] = new A
+ a.foo
+ a.foo
+ val b: Foo[Unit] = new B
+ b.foo
+ b.foo
+ val c: Bar[Unit] = new C
+ c.foo
+ c.foo
+ val d: Bar[Unit] = new D
+ d.foo
+ d.foo
+}