summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIulian Dragos <jaguarul@gmail.com>2008-07-31 22:01:37 +0000
committerIulian Dragos <jaguarul@gmail.com>2008-07-31 22:01:37 +0000
commit24426432a02c6662c55752fbddbf87166bb4dd2e (patch)
treeb4d96a9c7a00970c666bca6ba01696b60d4517b3
parent520647cf0e8ca839f89b35b877d2f43e2d7faa1b (diff)
downloadscala-24426432a02c6662c55752fbddbf87166bb4dd2e.tar.gz
scala-24426432a02c6662c55752fbddbf87166bb4dd2e.tar.bz2
scala-24426432a02c6662c55752fbddbf87166bb4dd2e.zip
Fixed initialization for vars initialized to th...
Fixed initialization for vars initialized to the default value (inside traits). Should fix failing test 'bugs.scala'.
-rw-r--r--src/compiler/scala/tools/nsc/ast/parser/Parsers.scala1
-rw-r--r--src/compiler/scala/tools/nsc/symtab/Flags.scala3
-rw-r--r--src/compiler/scala/tools/nsc/symtab/Symbols.scala3
-rw-r--r--src/compiler/scala/tools/nsc/transform/AddInterfaces.scala2
-rw-r--r--src/compiler/scala/tools/nsc/transform/Constructors.scala7
-rw-r--r--src/compiler/scala/tools/nsc/transform/Mixin.scala32
6 files changed, 15 insertions, 33 deletions
diff --git a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala
index 0c734d23bf..23fb13277d 100644
--- a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala
+++ b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala
@@ -1952,6 +1952,7 @@ trait Parsers extends NewScanners with MarkupParsers {
if (!tp.isEmpty && newmods.hasFlag(Flags.MUTABLE) &&
(lhs.toList forall (_.isInstanceOf[Ident])) && inToken == USCORE) {
inNextToken
+ newmods = newmods | Flags.DEFAULTINIT
EmptyTree
} else {
expr()
diff --git a/src/compiler/scala/tools/nsc/symtab/Flags.scala b/src/compiler/scala/tools/nsc/symtab/Flags.scala
index f8ea35df70..b2819712ef 100644
--- a/src/compiler/scala/tools/nsc/symtab/Flags.scala
+++ b/src/compiler/scala/tools/nsc/symtab/Flags.scala
@@ -37,6 +37,7 @@ object Flags extends Enumeration {
final val BYNAMEPARAM = 0x00010000 // parameter is by name
final val CONTRAVARIANT = 0x00020000 // symbol is a contravariant type variable
final val LABEL = 0x00020000 // method symbol is a label. Set by TailCall
+ final val DEFAULTINIT = 0x00020000 // field is initialized to the default value (used by checkinit)
final val INCONSTRUCTOR = 0x00020000 // class symbol is defined in this/superclass
// constructor.
final val ABSOVERRIDE = 0x00040000 // combination of abstract & override
@@ -189,7 +190,7 @@ object Flags extends Enumeration {
case DEPRECATED => "<deprecated>"
case COVARIANT => "<covariant/captured/byname>"
- case CONTRAVARIANT => "<contravariant/label/inconstr>"
+ case CONTRAVARIANT => "<contravariant/label/inconstr/defaultinit>"
case ABSOVERRIDE => "abstract override"
case LOCAL => "<local>"
diff --git a/src/compiler/scala/tools/nsc/symtab/Symbols.scala b/src/compiler/scala/tools/nsc/symtab/Symbols.scala
index b5df166790..2baeee7fff 100644
--- a/src/compiler/scala/tools/nsc/symtab/Symbols.scala
+++ b/src/compiler/scala/tools/nsc/symtab/Symbols.scala
@@ -203,7 +203,8 @@ trait Symbols {
final def isLocalDummy = isTerm && nme.isLocalDummyName(name)
final def isMethod = isTerm && hasFlag(METHOD)
final def isSourceMethod = isTerm && (flags & (METHOD | STABLE)) == METHOD
- final def isLabel = isTerm && hasFlag(LABEL)
+ final def isLabel = isMethod && !hasFlag(ACCESSOR) && hasFlag(LABEL)
+ final def isInitializedToDefault = !isType && (getFlag(DEFAULTINIT | ACCESSOR) == (DEFAULTINIT | ACCESSOR))
final def isClassConstructor = isTerm && (name == nme.CONSTRUCTOR)
final def isMixinConstructor = isTerm && (name == nme.MIXIN_CONSTRUCTOR)
final def isConstructor = isTerm && (name == nme.CONSTRUCTOR) || (name == nme.MIXIN_CONSTRUCTOR)
diff --git a/src/compiler/scala/tools/nsc/transform/AddInterfaces.scala b/src/compiler/scala/tools/nsc/transform/AddInterfaces.scala
index 77f5cf60aa..85031d706c 100644
--- a/src/compiler/scala/tools/nsc/transform/AddInterfaces.scala
+++ b/src/compiler/scala/tools/nsc/transform/AddInterfaces.scala
@@ -58,7 +58,7 @@ abstract class AddInterfaces extends InfoTransform {
private def isInterfaceMember(sym: Symbol): Boolean = {
sym.isType ||
{ sym.info; // to set lateMETHOD flag if necessary
- sym.isMethod && !(sym hasFlag (PRIVATE | BRIDGE | LABEL)) &&
+ sym.isMethod && !sym.isLabel && !(sym hasFlag (PRIVATE | BRIDGE)) &&
!sym.isConstructor && !sym.isImplOnly
}
}
diff --git a/src/compiler/scala/tools/nsc/transform/Constructors.scala b/src/compiler/scala/tools/nsc/transform/Constructors.scala
index 50be9600b2..9bccf5c95f 100644
--- a/src/compiler/scala/tools/nsc/transform/Constructors.scala
+++ b/src/compiler/scala/tools/nsc/transform/Constructors.scala
@@ -190,12 +190,9 @@ abstract class Constructors extends Transform {
// the initializer goes as an assignment into the constructor
// if the val def is an early initialized or a parameter accessor, it goes
// before the superclass constructor call, otherwise it goes after.
- // Lazy vals don't get the assignment in the constructor. Fields initialized
- // to default values are not eliminated until the mixin phase, when
- // checked initializers are added
+ // Lazy vals don't get the assignment in the constructor.
if (!stat.symbol.tpe.isInstanceOf[ConstantType]) {
- if ((rhs != EmptyTree || !stat.symbol.originalName.startsWith(nme.OUTER))
- && !stat.symbol.hasFlag(LAZY)) {
+ if (rhs != EmptyTree && !stat.symbol.hasFlag(LAZY)) {
val rhs1 = intoConstructor(stat.symbol, rhs);
(if (canBeMoved(stat)) constrPrefixBuf else constrStatBuf) += mkAssign(
stat.symbol, rhs1)
diff --git a/src/compiler/scala/tools/nsc/transform/Mixin.scala b/src/compiler/scala/tools/nsc/transform/Mixin.scala
index f22cde9669..5dd4fa83e7 100644
--- a/src/compiler/scala/tools/nsc/transform/Mixin.scala
+++ b/src/compiler/scala/tools/nsc/transform/Mixin.scala
@@ -628,9 +628,6 @@ abstract class Mixin extends InfoTransform {
localTyper.typed(atPos(pos)(Block(List(result), retVal)))
}
- /** Fields that are initialized to their default value. They don't need a checked accessor. */
- val initToDefault = new mutable.HashSet[Symbol]
-
/** Complete lazy field accessors. Applies only to classes, for it's own (non inherited) lazy fields.
* If 'checkinit' is enabled, getters that check for the initialized bit are generated, and
* the class constructor is changed to set the initialized bits.
@@ -659,7 +656,7 @@ abstract class Mixin extends InfoTransform {
}
copy.DefDef(stat, mods, name, tp, vp, tpt, rhs1)
- case DefDef(mods, name, tp, vp, tpt, rhs) if sym.isClassConstructor =>
+ case DefDef(mods, name, tp, vp, tpt, rhs) if sym.isConstructor =>
copy.DefDef(stat, mods, name, tp, vp, tpt, addInitBits(clazz, rhs))
case _ => stat
@@ -671,7 +668,7 @@ abstract class Mixin extends InfoTransform {
def needsInitFlag(sym: Symbol) = {
val res = (settings.checkInit.value
&& sym.isGetter
- && !initToDefault(sym)
+ && !sym.isInitializedToDefault
&& !sym.hasFlag(PARAMACCESSOR)
&& !sym.accessed.hasFlag(PRESUPER)
&& !sym.isOuterAccessor)
@@ -679,7 +676,7 @@ abstract class Mixin extends InfoTransform {
if (settings.debug.value) {
println("needsInitFlag(" + sym.fullNameString + "): " + res)
println("\tsym.isGetter: " + sym.isGetter)
- println("\t!initToDefault(sym): " + !initToDefault(sym))
+ println("\t!isInitializedToDefault: " + !sym.isInitializedToDefault + sym.hasFlag(DEFAULTINIT) + sym.hasFlag(ACCESSOR) + sym.isTerm)
println("\t!sym.hasFlag(PARAMACCESSOR): " + !sym.hasFlag(PARAMACCESSOR))
//println("\t!sym.accessed.hasFlag(PRESUPER): " + !sym.accessed.hasFlag(PRESUPER))
println("\t!sym.isOuterAccessor: " + !sym.isOuterAccessor)
@@ -706,7 +703,9 @@ abstract class Mixin extends InfoTransform {
} else {
List(stat)
}
-
+ case Apply(setter @ Select(Ident(self), _), List(EmptyTree)) if setter.symbol.isSetter =>
+ // remove initialization for default values
+ List()
case _ => List(stat)
}
}
@@ -751,23 +750,6 @@ abstract class Mixin extends InfoTransform {
}
}
- // Look for fields that are initialized to the default value
- // They won't get init fields.
- new Traverser {
- override def traverse(tree: Tree): Unit = tree match {
- case DefDef(mods, name, tparams, vparamss, tpt, rhs) if tree.symbol.isClassConstructor =>
- val Block(stats, _) = rhs
- for (s <- stats) s match {
- case Assign(f @ Select(This(_), _), EmptyTree) =>
- val getter = clazz.info.decl(nme.getterName(f.symbol.name))
- if (getter != NoSymbol)
- initToDefault += getter
- case _ => ()
- }
- case _ => super.traverse(tree)
- }
- }.traverseTrees(stats)
-
buildFieldPositions(clazz)
// begin addNewDefs
var stats1 = addCheckedGetters(clazz, stats)
@@ -826,7 +808,7 @@ abstract class Mixin extends InfoTransform {
} else
init
}
- } else if (!sym.hasFlag(LAZY) && settings.checkInit.value) {
+ } else if (!sym.hasFlag(LAZY) && needsInitFlag(sym)) {
mkCheckedAccessor(clazz, accessedRef, fieldOffset(sym), sym.pos)
} else
gen.mkCheckInit(accessedRef)