summaryrefslogtreecommitdiff
path: root/test/files/neg/t1422.check
diff options
context:
space:
mode:
authorPaul Phillips <paulp@improving.org>2011-10-21 16:27:23 +0000
committerPaul Phillips <paulp@improving.org>2011-10-21 16:27:23 +0000
commitad3dada12c9f4d23e58de19022b527e872db4308 (patch)
tree276952170b26c9384263332102350fe2621ae3e8 /test/files/neg/t1422.check
parentf262ab507ecf80c36cde4b5fb186f778911d916f (diff)
downloadscala-ad3dada12c9f4d23e58de19022b527e872db4308.tar.gz
scala-ad3dada12c9f4d23e58de19022b527e872db4308.tar.bz2
scala-ad3dada12c9f4d23e58de19022b527e872db4308.zip
Overhaul of Namers.
A digression into motivations: It's not there yet but the future looks bright. I have winnowed the number of mutation points down and I will take it down much further. There are only a few fundamental state changes which take place and these can be made to happen in a systematic fashion at well-known junctions. 1) Fresh symbols are allocated and (usually) assigned to a tree. 2) Symbol flags and access are manipulated. 3) A (possibly lazy) info is assigned to a symbol. 4) Synthetics are created or lazily positioned for creation Among the complications is that the symbol's info often cannot be determined in a straightforward fashion lest cycles develop. Type inference is obviously dependent on having some type information, so the black art is to pursue a) only the right information and b) only as far as necessary to avoid cycles. Compounding the difficulty is that synthetic methods must be introduced before the typer phase. Over time a variety of ad-hoc mechanisms have evolved to deal with these difficulties, and they have gotten us a good distance (we have bean setter/getters, case classes, copy methods, default getters, and more) but there are big disadvantages: - they are heavily custom fitted to the specific uses - because of the intertwingling of namer and typer, it is all only possible from the inside. Compiler plugins are shut out. A particularly difficult scenario has recently arisen with case classes. They now receive a ProductN parent, but because a class's parents must be completed before it can be completed, we encounter this: object Foo { type T = String } case class Foo(x: Foo.T, y: Foo.T) { } Now one of class Foo's parents is Product2[T, T]. So class Foo cannot be completed without information from object Foo. But object Foo needs to be given these synthetic methods: def apply(x: T, y: T): Foo def unapply(x: Foo): Option[(T, T)] You can see these two have their hands all over one another. The good news is that I have established in principle that the problem can be overcome, for that use and I think in a sufficiently general way that plugins will be able to perform this kind of method synthesis, with the following approach. For synthetic methods which require type information before they can be created (this is the catch-22: once type information is available, it's too late to add new synthetic methods) we create a "stub symbol" like so: val sym = owner.newMethod("nameOfMethod") sym setInfo stubMethodInfo stubMethodInfo will be some very general method type like Any* => Any (or Nothing => Any, it really depends on how or whether it is used), whatever it takes to pass type checking. At the same time, we enter the stub symbol into a map along with a thunk which creates the symbol and tree the way we would if we had full type information. Then, immediately after a class is typed, the template is examined for stub method symbols and when found, they are updated with the symbol info found in the map, assigned to the associated tree, and added to the class template. This approach will probably break down under some uses, but I think it can take us a long way. So all these changes in Namers are about evolving it to a point where I can roll out a principled division of responsibility for those entities which cannot be naively typed, and to unify the several different approaches to lazy typing under a consistent and predictable mechanism. If anyone would like to review this, please be my guest, but you might want to wait one more commit.
Diffstat (limited to 'test/files/neg/t1422.check')
-rw-r--r--test/files/neg/t1422.check5
1 files changed, 4 insertions, 1 deletions
diff --git a/test/files/neg/t1422.check b/test/files/neg/t1422.check
index 4db64f1d49..362d7ef36b 100644
--- a/test/files/neg/t1422.check
+++ b/test/files/neg/t1422.check
@@ -1,4 +1,7 @@
t1422.scala:1: error: private[this] not allowed for case class parameters
case class A(private[this] val foo:String) { }
^
-one error found
+t1422.scala:1: error: value foo in class A cannot be accessed in A
+case class A(private[this] val foo:String) { }
+ ^
+two errors found