summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2006-08-18 17:09:14 +0000
committerMartin Odersky <odersky@gmail.com>2006-08-18 17:09:14 +0000
commitd283455a24148f43d33f69f4be1b627705d35ab6 (patch)
tree91d5b9c6025077a542c0e3517a00927d86c241bb
parentd5aee9e7a1dde5fd3215f8ee6c8a811745535a16 (diff)
downloadscala-d283455a24148f43d33f69f4be1b627705d35ab6.tar.gz
scala-d283455a24148f43d33f69f4be1b627705d35ab6.tar.bz2
scala-d283455a24148f43d33f69f4be1b627705d35ab6.zip
fixed bug 704
-rw-r--r--src/compiler/scala/tools/nsc/ast/TreeGen.scala24
-rw-r--r--src/compiler/scala/tools/nsc/symtab/Flags.scala1
-rw-r--r--src/compiler/scala/tools/nsc/transform/Mixin.scala68
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/RefChecks.scala30
-rw-r--r--test/files/neg/bug708.check5
-rw-r--r--test/files/neg/bug708.scala12
-rw-r--r--test/files/pos/bug704.scala14
7 files changed, 86 insertions, 68 deletions
diff --git a/src/compiler/scala/tools/nsc/ast/TreeGen.scala b/src/compiler/scala/tools/nsc/ast/TreeGen.scala
index 4ec47829e2..92bd5ad0c0 100644
--- a/src/compiler/scala/tools/nsc/ast/TreeGen.scala
+++ b/src/compiler/scala/tools/nsc/ast/TreeGen.scala
@@ -171,6 +171,30 @@ abstract class TreeGen {
)
}
+ // var m$: T = null; or, if class member: local var m$: T = _;
+ def mkModuleVarDef(accessor: Symbol) = {
+ val mvar = accessor.owner.newVariable(accessor.pos, nme.moduleVarName(accessor.name))
+ .setInfo(accessor.tpe.finalResultType)
+ .setFlag(MODULEVAR);
+ if (mvar.owner.isClass) {
+ mvar setFlag (PRIVATE | LOCAL | SYNTHETIC);
+ mvar.owner.info.decls.enter(mvar);
+ }
+ ValDef(mvar, if (mvar.owner.isClass) EmptyTree else Literal(Constant(null)))
+ }
+
+ // def m: T = { if (m$ == null) m$ = new m$class; m$ }
+ def mkModuleAccessDef(accessor: Symbol, mvar: Symbol) =
+ DefDef(accessor, vparamss =>
+ mkCached(mvar,
+ New(TypeTree(mvar.tpe),
+ List(for (val pt <- mvar.tpe.symbol.primaryConstructor.info.paramTypes)
+ yield This(accessor.owner.enclClass)))))
+
+ // def m: T;
+ def mkModuleAccessDcl(accessor: Symbol) =
+ DefDef(accessor setFlag lateDEFERRED, vparamss => EmptyTree)
+
def mkRuntimeCall(meth: Name, args: List[Tree]): Tree =
Apply(Select(mkAttributedRef(ScalaRunTimeModule), meth), args)
}
diff --git a/src/compiler/scala/tools/nsc/symtab/Flags.scala b/src/compiler/scala/tools/nsc/symtab/Flags.scala
index d54a12159b..12327875a0 100644
--- a/src/compiler/scala/tools/nsc/symtab/Flags.scala
+++ b/src/compiler/scala/tools/nsc/symtab/Flags.scala
@@ -85,6 +85,7 @@ object Flags {
final val lateFINAL = (FINAL: long) << LateShift;
final val lateMETHOD = (METHOD: long) << LateShift;
final val notPRIVATE = (PRIVATE: long) << AntiShift;
+ final val notDEFERRED = (DEFERRED: long) << AntiShift;
final val notPROTECTED = (PROTECTED: long) << AntiShift;
final val notABSTRACT = (ABSTRACT: long) << AntiShift;
final val notOVERRIDE = (OVERRIDE: long) << AntiShift;
diff --git a/src/compiler/scala/tools/nsc/transform/Mixin.scala b/src/compiler/scala/tools/nsc/transform/Mixin.scala
index 4879f59250..a1eb5d003c 100644
--- a/src/compiler/scala/tools/nsc/transform/Mixin.scala
+++ b/src/compiler/scala/tools/nsc/transform/Mixin.scala
@@ -90,11 +90,6 @@ abstract class Mixin extends InfoTransform {
var setter = member.setter(clazz)
if (setter == NoSymbol) setter = addMember(clazz, newSetter(member))
}
-/*
- } else if ((member hasFlag BRIDGE) && !(member hasFlag PRIVATE)) {
- member.expandName(clazz);
- addMember(clazz, member.cloneSymbol(clazz) resetFlag FINAL);
-*/
}
}
if (settings.debug.value) log("new defs of " + clazz + " = " + clazz.info.decls);
@@ -125,31 +120,6 @@ abstract class Mixin extends InfoTransform {
member1.asInstanceOf[TermSymbol] setAlias member;
}
}
-/*
- //System.out.println("adding forwarded method " + member + " " + mmap(member) + member.locationString + " to " + clazz + " " + (clazz.info.member(member.name).alternatives));//DEBUG
- if (isForwarded(member) && !isStatic(member)) {
- if (clazz.info.findMember(member.name, 0, 0).alternatives contains mmap(member)) {
- val mmember = member.overriddenSymbol(mixinClass.toInterface)
- if (!mmember.hasFlag(lateDEFERRED))
- Console.println("SURPRISE0: "+member+" "+mmember+mmember.locationString+" is not late deferred")
- if (mmember.overridingSymbol(clazz) != NoSymbol)
- Console.println("SURPRISE1: "+member+" "+mmember+mmember.locationString+" is overridden by class")
- if (!atPhase(phase.next)(clazz.info).findMember(member.name, 0, lateDEFERRED).alternatives.contains(mmember))
- Console.println("SURPRISE2: "+member+" "+mmember+mmember.locationString+" is not among late deferred members")
- val member1 = addMember(
- clazz,
- member.cloneSymbol(clazz) setPos clazz.pos resetFlag (DEFERRED | lateDEFERRED));
- member1.asInstanceOf[TermSymbol] setAlias member;
- } else {
- val mmember = member.overriddenSymbol(mixinClass.toInterface)
- if (!mmember.hasFlag(lateDEFERRED))
- Console.println("SURPRISE3: "+member+" "+mmember+mmember.locationString+" is not late deferred")
- if (mmember.overridingSymbol(clazz) == NoSymbol)
- if (atPhase(phase.next)(clazz.info).findMember(member.name, 0, lateDEFERRED).alternatives.contains(mmember))
- Console.println("SURPRISE4: "+member+" "+mmember+mmember.locationString+" is mixed in but violates conditions")
- }
- }
-*/
}
} else if (mixinClass.hasFlag(lateINTERFACE)) {
addLateInterfaceMembers(mixinClass)
@@ -289,16 +259,14 @@ abstract class Mixin extends InfoTransform {
private def addNewDefs(clazz: Symbol, stats: List[Tree]): List[Tree] = {
val newDefs = new ListBuffer[Tree]
- def addDef(pos: int, tree: Tree): unit = {
+ def attributedDef(pos: int, tree: Tree): Tree = {
if (settings.debug.value) System.out.println("add new def to " + clazz + ": " + tree);
- newDefs += localTyper.typed {
- atPos(pos) {
- tree
- }
- }
+ localTyper.typed { atPos(pos) { tree } }
}
def position(sym: Symbol) =
if (sym.pos == Position.NOPOS) clazz.pos else sym.pos
+ def addDef(pos: int, tree: Tree): unit =
+ newDefs += attributedDef(pos, tree)
def addDefDef(sym: Symbol, rhs: List[Symbol] => Tree): unit =
addDef(position(sym), DefDef(sym, vparamss => rhs(vparamss.head)))
def add(stats: List[Tree], newDefs: List[Tree]) = {
@@ -327,6 +295,23 @@ abstract class Mixin extends InfoTransform {
case _ =>
stat
}
+ def implementPrivateObject(stat: Tree): List[Tree] = {
+ val sym = stat.symbol
+ stat match {
+ case _: DefDef if (sym.isModule && sym.hasFlag(PRIVATE)) =>
+ val vdef = attributedDef(position(sym), gen.mkModuleVarDef(sym))
+ val adef = attributedDef(
+ position(sym),
+ DefDef(sym, vparamss =>
+ gen.mkCached(
+ vdef.symbol,
+ New(TypeTree(vdef.symbol.tpe), vparamss map (.map(Ident))))))
+ sym resetFlag lateDEFERRED
+ List(vdef, adef)
+ case _ =>
+ List(stat)
+ }
+ }
for (val sym <- clazz.info.decls.toList) {
if (sym hasFlag MIXEDIN) {
if (clazz hasFlag lateINTERFACE) {
@@ -340,9 +325,9 @@ abstract class Mixin extends InfoTransform {
}
if (sym.isSetter) Assign(accessedRef, Ident(vparams.head)) else accessedRef})
} else if (sym.isModule && !(sym hasFlag LIFTED)) {
- val vdef = refchecks.newModuleVarDef(sym);
+ val vdef = gen.mkModuleVarDef(sym);
addDef(position(sym), vdef)
- addDef(position(sym), refchecks.newModuleAccessDef(sym, vdef.symbol))
+ addDef(position(sym), gen.mkModuleAccessDef(sym, vdef.symbol))
} else if (!sym.isMethod) {
addDef(position(sym), ValDef(sym))
} else if (sym hasFlag SUPERACCESSOR) {
@@ -353,10 +338,11 @@ abstract class Mixin extends InfoTransform {
Apply(staticRef(sym.alias), gen.mkAttributedThis(clazz) :: (vparams map Ident)))
}
}
- }
}
- val stats1 = add(stats, newDefs.toList)
- if (clazz.isTrait) stats1 else stats1 map completeSuperAccessor;
+ var stats1 = add(stats, newDefs.toList)
+ if (!clazz.isTrait) stats1 = stats1 map completeSuperAccessor
+ if (clazz.isImplClass) stats1 = stats1 flatMap implementPrivateObject
+ stats1
}
private def postTransform(tree: Tree): Tree = {
diff --git a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala
index c745290cc9..5a2d7f8b7b 100644
--- a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala
@@ -46,30 +46,6 @@ abstract class RefChecks extends InfoTransform {
} else tp
}
- // var m$: T = null; or, if class member: local var m$: T = _;
- def newModuleVarDef(accessor: Symbol) = {
- val mvar = accessor.owner.newVariable(accessor.pos, nme.moduleVarName(accessor.name))
- .setInfo(accessor.tpe.finalResultType)
- .setFlag(MODULEVAR);
- if (mvar.owner.isClass) {
- mvar setFlag (PRIVATE | LOCAL | SYNTHETIC);
- mvar.owner.info.decls.enter(mvar);
- }
- ValDef(mvar, if (mvar.owner.isClass) EmptyTree else Literal(Constant(null)))
- }
-
- // def m: T = { if (m$ == null) m$ = new m$class; m$ }
- def newModuleAccessDef(accessor: Symbol, mvar: Symbol) =
- DefDef(accessor, vparamss =>
- gen.mkCached(mvar,
- New(TypeTree(mvar.tpe),
- List(for (val pt <- mvar.tpe.symbol.primaryConstructor.info.paramTypes)
- yield This(accessor.owner.enclClass)))))
-
- // def m: T;
- def newModuleAccessDcl(accessor: Symbol) =
- DefDef(accessor setFlag lateDEFERRED, vparamss => EmptyTree);
-
class RefCheckTransformer(unit: CompilationUnit) extends Transformer {
var localTyper: analyzer.Typer = typer;
@@ -458,15 +434,15 @@ abstract class RefChecks extends InfoTransform {
val vdef =
localTyper.typed {
atPos(tree.pos) {
- newModuleVarDef(sym)
+ gen.mkModuleVarDef(sym)
}
}
val ddef =
atPhase(phase.next) {
localTyper.typed {
- if (sym.owner.isTrait) newModuleAccessDcl(sym)
- else newModuleAccessDef(sym, vdef.symbol)
+ if (sym.owner.isTrait) gen.mkModuleAccessDcl(sym)
+ else gen.mkModuleAccessDef(sym, vdef.symbol)
}
}
diff --git a/test/files/neg/bug708.check b/test/files/neg/bug708.check
new file mode 100644
index 0000000000..30b31b662a
--- /dev/null
+++ b/test/files/neg/bug708.check
@@ -0,0 +1,5 @@
+bug708.scala:8 error: error overriding type A$$S in trait X with bounds >: scala.All <: A.this.T;
+ type A$$S has incompatible type scala.Any
+ override private[A] type S = Any;
+ ^
+one error found
diff --git a/test/files/neg/bug708.scala b/test/files/neg/bug708.scala
new file mode 100644
index 0000000000..f86a005811
--- /dev/null
+++ b/test/files/neg/bug708.scala
@@ -0,0 +1,12 @@
+trait A {
+ type T;
+ trait X {
+ private[A] type S <: T;
+ /*private[A]*/ def foo : S;
+ }
+ trait Y extends X {
+ override private[A] type S = Any;
+ override /*private[A]*/ def foo = null;
+ }
+}
+
diff --git a/test/files/pos/bug704.scala b/test/files/pos/bug704.scala
new file mode 100644
index 0000000000..aea8292f2d
--- /dev/null
+++ b/test/files/pos/bug704.scala
@@ -0,0 +1,14 @@
+trait D {
+ private val x = 1
+ private object xxxx { Console.println(x) }
+}
+object Go extends D {
+ def main(args : Array[String]) : Unit = {};
+}
+trait D2 {
+ val x = 1
+ object yyyy { Console.println(x) }
+}
+object Go2 extends D2 {
+ def main(args : Array[String]) : Unit = {};
+}