summaryrefslogtreecommitdiff
path: root/test/files
diff options
context:
space:
mode:
authorJason Zaugg <jzaugg@gmail.com>2013-11-27 15:13:50 +0100
committerJason Zaugg <jzaugg@gmail.com>2013-12-19 15:27:06 +0100
commitcca4d51dbf3f8478cb338e6d53e34003e9a3fa45 (patch)
tree047ae290cd9490c8494085f94dd07986ee801ec8 /test/files
parentd99a4919e0fa4894829c752a8f881d7b103d8cda (diff)
downloadscala-cca4d51dbf3f8478cb338e6d53e34003e9a3fa45.tar.gz
scala-cca4d51dbf3f8478cb338e6d53e34003e9a3fa45.tar.bz2
scala-cca4d51dbf3f8478cb338e6d53e34003e9a3fa45.zip
SI-5508 Fix crasher with private[this] in nested traits
Currently, accessors for private local trait fields are added very late in the game when the `Mixin` tree transformer treats the trait. By contrast, fields with weaker access have accessors created eagerly in `Namers`. // Mixin#addLateInterfaceMembers val getter = member.getter(clazz) if (getter == NoSymbol) addMember(clazz, newGetter(member)) `addMember` mutates the type of the interface to add the getter. (This seems like a pretty poor design: usually if a phase changes types, it should do in an `InfoTransformer`.) However, if an inner class or anonymous function of the trait has been flattened to a spot where it precedes the trait in the enclosing packages info, this code hasn't had a chance to run, and the lookup of the getter crashes as mixins `postTransform` runs over a selection of the not-yet-materialized getter. // Mixin#postTransform case Select(qual, name) if sym.owner.isImplClass && !isStaticOnly(sym) => val iface = toInterface(sym.owner.tpe).typeSymbol val ifaceGetter = sym getter iface This commit ensures that `Flatten` lifts inner classes to a position *after* the enclosing class in the stats of the enclosing package. Bonus fix: SI-7012 (the followup ticket to SI-6231 / SI-2897)
Diffstat (limited to 'test/files')
-rw-r--r--test/files/neg/t6231.check6
-rw-r--r--test/files/neg/t6231.flags1
-rw-r--r--test/files/pos/t5508-min-okay.scala6
-rw-r--r--test/files/pos/t5508-min-okay2.scala4
-rw-r--r--test/files/pos/t5508-min.scala6
-rw-r--r--test/files/pos/t5508.scala83
-rw-r--r--test/files/pos/t6231.scala (renamed from test/files/neg/t6231.scala)0
-rw-r--r--test/files/pos/t6231b.scala8
8 files changed, 107 insertions, 7 deletions
diff --git a/test/files/neg/t6231.check b/test/files/neg/t6231.check
deleted file mode 100644
index 6e107c97c7..0000000000
--- a/test/files/neg/t6231.check
+++ /dev/null
@@ -1,6 +0,0 @@
-t6231.scala:4: error: Implementation restriction: local trait Bug$X$1 is unable to automatically capture the
-free variable value ev$1 on behalf of <$anon: Function0>. You can manually assign it to a val inside the trait,
-and refer to that val in <$anon: Function0>. For more details, see SI-6231.
- def qux = { () => ev }
- ^
-one error found
diff --git a/test/files/neg/t6231.flags b/test/files/neg/t6231.flags
deleted file mode 100644
index ac96850b69..0000000000
--- a/test/files/neg/t6231.flags
+++ /dev/null
@@ -1 +0,0 @@
--Ydelambdafy:inline \ No newline at end of file
diff --git a/test/files/pos/t5508-min-okay.scala b/test/files/pos/t5508-min-okay.scala
new file mode 100644
index 0000000000..3a38b9c5ea
--- /dev/null
+++ b/test/files/pos/t5508-min-okay.scala
@@ -0,0 +1,6 @@
+object Test {
+ trait NestedTrait { // must be nested and a trait
+ private val _st : Int = 0 // crashes if changed to private[this]
+ val escape = { () => _st }
+ }
+}
diff --git a/test/files/pos/t5508-min-okay2.scala b/test/files/pos/t5508-min-okay2.scala
new file mode 100644
index 0000000000..935f28609c
--- /dev/null
+++ b/test/files/pos/t5508-min-okay2.scala
@@ -0,0 +1,4 @@
+trait TopTrait { // must be nested and a trait
+ private[this] val _st : Int = 0 // crashes if TopTrait is not top level
+ val escape = { () => _st }
+}
diff --git a/test/files/pos/t5508-min.scala b/test/files/pos/t5508-min.scala
new file mode 100644
index 0000000000..f59d2bd6ad
--- /dev/null
+++ b/test/files/pos/t5508-min.scala
@@ -0,0 +1,6 @@
+object Test {
+ trait NestedTrait { // must be nested and a trait
+ private[this] val _st : Int = 0 // must be private[this]
+ val escape = { () => _st }
+ }
+}
diff --git a/test/files/pos/t5508.scala b/test/files/pos/t5508.scala
new file mode 100644
index 0000000000..2b49758045
--- /dev/null
+++ b/test/files/pos/t5508.scala
@@ -0,0 +1,83 @@
+package TestTestters
+
+trait Test1 {
+ private[this] var _st : Int = 0
+ def close : PartialFunction[Any,Any] = {
+ case x : Int =>
+ _st = identity(_st)
+ }
+}
+
+object Base1 {
+ trait Test2 {
+ private[this] var _st : Int = 0
+ def close : PartialFunction[Any,Any] = {
+ case x : Int =>
+ _st = identity(_st)
+ }
+ }
+}
+
+class Test3 {
+ private[this] var _st : Int = 0
+ def close : PartialFunction[Any,Any] = {
+ case x : Int =>
+ _st = 1
+ }
+}
+
+object Base2 {
+ class Test4 {
+ private[this] var _st : Int = 0
+ def close : PartialFunction[Any,Any] = {
+ case x : Int =>
+ _st = 1
+ }
+ }
+}
+
+class Base3 {
+ trait Test5 {
+ private[this] var _st : Int = 0
+ def close : PartialFunction[Any,Any] = {
+ case x : Int =>
+ _st = 1
+ }
+ }
+}
+
+object Base4 {
+ trait Test6 {
+ private[this] var _st : Int = 0
+ def close : PartialFunction[Any,Any] = {
+ case x : Int => ()
+ }
+ }
+}
+
+object Base5 {
+ trait Test7 {
+ private[this] var _st : Int = 0
+ def close = () => {
+ _st = 1
+ }
+ }
+}
+
+object Base6 {
+ class Test8 {
+ private[this] var _st : Int = 0
+ def close = () => {
+ _st = 1
+ }
+ }
+}
+
+object Base7 {
+ trait Test9 {
+ var st : Int = 0
+ def close = () => {
+ st = 1
+ }
+ }
+}
diff --git a/test/files/neg/t6231.scala b/test/files/pos/t6231.scala
index 1e5b4e0e1a..1e5b4e0e1a 100644
--- a/test/files/neg/t6231.scala
+++ b/test/files/pos/t6231.scala
diff --git a/test/files/pos/t6231b.scala b/test/files/pos/t6231b.scala
new file mode 100644
index 0000000000..b4ddfe785b
--- /dev/null
+++ b/test/files/pos/t6231b.scala
@@ -0,0 +1,8 @@
+class Test {
+ def f1(t: String) = {
+ trait T {
+ def xs = Nil map (_ => t)
+ }
+ ()
+ }
+}