summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Phillips <paulp@improving.org>2010-09-28 15:42:05 +0000
committerPaul Phillips <paulp@improving.org>2010-09-28 15:42:05 +0000
commit19b42dea4538d20b696de4bdb0b01e7fdef2dd36 (patch)
tree968d82f78e7407de8bc77719cdc48cfb30002cc5
parent7673099e4778f320ef3fe761fe90e7f009903038 (diff)
downloadscala-19b42dea4538d20b696de4bdb0b01e7fdef2dd36.tar.gz
scala-19b42dea4538d20b696de4bdb0b01e7fdef2dd36.tar.bz2
scala-19b42dea4538d20b696de4bdb0b01e7fdef2dd36.zip
Fixed an ancient crasher in explicitouter invol...
Fixed an ancient crasher in explicitouter involving singleton self-types. Closes #266, review by odersky.
-rw-r--r--src/compiler/scala/tools/nsc/ast/TreeDSL.scala1
-rw-r--r--src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala26
-rw-r--r--test/files/run/bug266.scala23
3 files changed, 37 insertions, 13 deletions
diff --git a/src/compiler/scala/tools/nsc/ast/TreeDSL.scala b/src/compiler/scala/tools/nsc/ast/TreeDSL.scala
index defe24dec8..3b7d4aa26d 100644
--- a/src/compiler/scala/tools/nsc/ast/TreeDSL.scala
+++ b/src/compiler/scala/tools/nsc/ast/TreeDSL.scala
@@ -287,6 +287,7 @@ trait TreeDSL {
def VAL(name: Name): ValTreeStart = new ValTreeStart(name)
def VAL(sym: Symbol): ValSymStart = new ValSymStart(sym)
+ def DEF(name: Name): DefTreeStart = new DefTreeStart(name)
def DEF(sym: Symbol): DefSymStart = new DefSymStart(sym)
def AND(guards: Tree*) =
if (guards.isEmpty) EmptyTree
diff --git a/src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala b/src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala
index 61f5c6e5d0..e65965d3ff 100644
--- a/src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala
+++ b/src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala
@@ -124,8 +124,8 @@ abstract class ExplicitOuter extends InfoTransform
else tp
case ClassInfoType(parents, decls, clazz) =>
var decls1 = decls
- if (isInner(clazz) && !(clazz hasFlag INTERFACE)) {
- decls1 = new Scope(decls.toList)
+ if (isInner(clazz) && !clazz.isInterface) {
+ decls1 = decls.cloneScope
val outerAcc = clazz.newMethod(clazz.pos, nme.OUTER) // 3
outerAcc expandName clazz
@@ -134,7 +134,7 @@ abstract class ExplicitOuter extends InfoTransform
if (hasOuterField(clazz)) { //2
val access = if (clazz.isFinal) PRIVATE | LOCAL else PROTECTED
decls1 enter (
- clazz.newValue(clazz.pos, nme getterToLocal nme.OUTER)
+ clazz.newValue(clazz.pos, nme.OUTER_LOCAL)
setFlag (SYNTHETIC | PARAMACCESSOR | access)
setInfo clazz.outerClass.thisType
)
@@ -144,7 +144,7 @@ abstract class ExplicitOuter extends InfoTransform
for (mc <- clazz.mixinClasses) {
val mixinOuterAcc: Symbol = atPhase(phase.next)(outerAccessor(mc))
if (mixinOuterAcc != NoSymbol) {
- if (decls1 eq decls) decls1 = new Scope(decls.toList)
+ if (decls1 eq decls) decls1 = decls.cloneScope
val newAcc = mixinOuterAcc.cloneSymbol(clazz)
newAcc resetFlag DEFERRED setInfo (clazz.thisType memberType mixinOuterAcc)
decls1 enter newAcc
@@ -239,9 +239,7 @@ abstract class ExplicitOuter extends InfoTransform
}
super.transform(tree)
}
- finally {
- outerParam = savedOuterParam
- }
+ finally outerParam = savedOuterParam
}
}
@@ -315,11 +313,14 @@ abstract class ExplicitOuter extends InfoTransform
if (outerAcc.isDeferred) EmptyTree
else This(currentClass) DOT outerField(currentClass)
- typedPos(currentClass.pos)(DEF(outerAcc) === rhs)
+ /** If we don't re-type the tree, we see self-type related crashes like #266.
+ */
+ localTyper typed {
+ (DEF(outerAcc) withType null) === rhs
+ } setPos currentClass.pos
}
- /** The definition tree of the outer accessor for class
- * <code>mixinClass</code>.
+ /** The definition tree of the outer accessor for class mixinClass.
*
* @param mixinClass The mixin class which defines the abstract outer
* accessor which is implemented by the generated one.
@@ -335,10 +336,9 @@ abstract class ExplicitOuter extends InfoTransform
localTyper typed {
DEF(outerAcc) === {
// Need to cast for nested outer refs in presence of self-types. See ticket #3274.
- // @S: atPos not good enough because of nested atPos in DefDef method, which gives position from wrong class!
- transformer.transform(path) AS_ANY outerAcc.info.resultType setPos currentClass.pos
+ transformer.transform(path) AS_ANY outerAcc.info.resultType
}
- } setPos currentClass.pos
+ } setPos currentClass.pos
}
/** If FLAG is set on symbol, sets notFLAG (this exists in anticipation of generalizing). */
diff --git a/test/files/run/bug266.scala b/test/files/run/bug266.scala
new file mode 100644
index 0000000000..20a29dabbb
--- /dev/null
+++ b/test/files/run/bug266.scala
@@ -0,0 +1,23 @@
+// #266, yee ha
+
+trait O {
+ self: Test.type =>
+
+ Nil foreach identity
+
+ def f = (1 to 10).toList map identity
+}
+
+object Test extends O {
+ def main(args: Array[String]): Unit = {
+ assert(f.sum == 55)
+ }
+}
+
+// Don't lose this part, it's what (formerly) crashes.
+// For some reason the one actually mixed in does not.
+object Pip
+
+trait P { self: Pip.type =>
+ Nil foreach identity
+} \ No newline at end of file