summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorPaul Phillips <paulp@improving.org>2010-10-25 21:15:34 +0000
committerPaul Phillips <paulp@improving.org>2010-10-25 21:15:34 +0000
commit7f365342d9875ffc4105af26faa260f81a270246 (patch)
tree4accac53322e84a6bfc9b530bcd2745283124f75 /src
parent5c322510b185e7ee50ec6f75057369c427b9724b (diff)
downloadscala-7f365342d9875ffc4105af26faa260f81a270246.tar.gz
scala-7f365342d9875ffc4105af26faa260f81a270246.tar.bz2
scala-7f365342d9875ffc4105af26faa260f81a270246.zip
The tree checkers revealed that Volatile*Refs w...
The tree checkers revealed that Volatile*Refs were being constructed without being given a constructor argument. Added a mkZero to treegen for creating zero trees of any type, and used it to construct those refs. Review by moors.
Diffstat (limited to 'src')
-rw-r--r--src/compiler/scala/tools/nsc/ast/TreeGen.scala16
-rw-r--r--src/compiler/scala/tools/nsc/backend/icode/GenICode.scala16
-rw-r--r--src/compiler/scala/tools/nsc/transform/LambdaLift.scala19
3 files changed, 29 insertions, 22 deletions
diff --git a/src/compiler/scala/tools/nsc/ast/TreeGen.scala b/src/compiler/scala/tools/nsc/ast/TreeGen.scala
index 34f07baef2..253d259af1 100644
--- a/src/compiler/scala/tools/nsc/ast/TreeGen.scala
+++ b/src/compiler/scala/tools/nsc/ast/TreeGen.scala
@@ -230,6 +230,22 @@ abstract class TreeGen {
/** Builds a list with given head and tail. */
def mkNil: Tree = mkAttributedRef(NilModule)
+ /** Builds a tree representing an undefined local, as in
+ * var x: T = _
+ * which is appropriate to the given Type.
+ */
+ def mkZero(tp: Type): Tree = {
+ val sym = tp.typeSymbol
+ val tree =
+ if (sym == UnitClass) Literal(())
+ else if (sym == BooleanClass) Literal(false)
+ else if (isValueClass(sym)) Literal(0)
+ else if (NullClass.tpe <:< tp) Literal(null: Any)
+ else abort("Cannot determine zero for " + tp)
+
+ tree setType tp
+ }
+
/** Builds a tuple */
def mkTuple(elems: List[Tree]): Tree =
if (elems.isEmpty) Literal(())
diff --git a/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala b/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala
index 903802759d..cd10434b3a 100644
--- a/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala
+++ b/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala
@@ -1233,22 +1233,6 @@ abstract class GenICode extends SubComponent {
def genCast(from: TypeKind, to: TypeKind, ctx: Context, cast: Boolean) =
ctx.bb.emit(if (cast) CHECK_CAST(to) else IS_INSTANCE(to))
- def zeroOf(k: TypeKind): Tree = k match {
- case UNIT => Literal(())
- case BOOL => Literal(false)
- case BYTE => Literal(0: Byte)
- case SHORT => Literal(0: Short)
- case CHAR => Literal(0: Char)
- case INT => Literal(0: Int)
- case LONG => Literal(0: Long)
- case FLOAT => Literal(0.0f)
- case DOUBLE => Literal(0.0d)
- case REFERENCE(cls) => Literal(null: Any)
- case ARRAY(elem) => Literal(null: Any)
- case BOXED(_) => Literal(null: Any)
- case ConcatClass => abort("no zero of ConcatClass")
- }
-
def getZeroOf(k: TypeKind): Instruction = k match {
case UNIT => CONSTANT(Constant(()))
case BOOL => CONSTANT(Constant(false))
diff --git a/src/compiler/scala/tools/nsc/transform/LambdaLift.scala b/src/compiler/scala/tools/nsc/transform/LambdaLift.scala
index 184065a7ed..e3f1427360 100644
--- a/src/compiler/scala/tools/nsc/transform/LambdaLift.scala
+++ b/src/compiler/scala/tools/nsc/transform/LambdaLift.scala
@@ -405,13 +405,20 @@ abstract class LambdaLift extends InfoTransform {
case ValDef(mods, name, tpt, rhs) =>
if (sym.isCapturedVariable) {
val tpt1 = TypeTree(sym.tpe) setPos tpt.pos
- val rhs1 =
- atPos(rhs.pos) {
- typer typed {
- Apply(Select(New(TypeTree(sym.tpe)), nme.CONSTRUCTOR), List(rhs))
+ /* Creating a constructor argument if one isn't present. */
+ val constructorArg = rhs match {
+ case EmptyTree =>
+ sym.primaryConstructor.info.paramTypes match {
+ case List(tp) => gen.mkZero(tp)
+ case _ =>
+ log("Couldn't determine how to properly construct " + sym)
+ rhs
}
- }
- treeCopy.ValDef(tree, mods, name, tpt1, rhs1)
+ case arg => arg
+ }
+ treeCopy.ValDef(tree, mods, name, tpt1, typer.typedPos(rhs.pos) {
+ Apply(Select(New(TypeTree(sym.tpe)), nme.CONSTRUCTOR), List(constructorArg))
+ })
} else tree
case Return(Block(stats, value)) =>
Block(stats, treeCopy.Return(tree, value)) setType tree.tpe setPos tree.pos