diff options
-rw-r--r-- | src/compiler/scala/tools/nsc/ast/TreeGen.scala | 16 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/backend/icode/GenICode.scala | 16 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/transform/LambdaLift.scala | 19 |
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 |