scala/scala — pull request #3247 by soc (2013-12-09 23:21:09+00:00)
Title: SI-8058 Better support for enum trees

Replace the approach of “detect some magic combination of flags to
trigger some action” by introducing an enum flag which makes the
semantics and the intentions of the code using it more explicit.

This basically involves wiring up the existing ACC_ENUM bit to a new
modifier flag and making sure it is set correctly when encountering
enums.

The existing enum tests files/pos/t5165 and files/pos/t2764 keep
working, showing that this hasn't introduced any obvious regressions.

Tests for the changes in Namer which prevent scalac from messing with
enum trees can't be added yet, because one currently can't define an
enum in Scala without the help of the macro paradise.
The intention is to add the @enum macro as a full test suite as soon
as one can depend on macro annotations.

One might wonder why we don't check for
clazz.superClass == JavaEnumClass (where clazz is the owning class)
in isEnumConstant.

The reason is that this causes illegal cyclic reference error.

Explanation by Eugene why this happens:

(23:17:52) xeno_by: so here's what happens as far as I can understand at 11pm :)
(23:18:09) xeno_by: scalac tries to complete the signature of the newly expanded class
(23:18:11) xeno_by: to do that
(23:18:40) xeno_by: to do that it needs three things
(23:18:51) xeno_by: because the signature of a class is ClassInfoType which consists of three things
(23:19:05) xeno_by: parents
(23:19:08) xeno_by: decls
(23:19:09) xeno_by: and symbol
(23:19:20) xeno_by: symbol is easy - it's already there
(23:19:30) xeno_by: parents are also easy
(23:19:39) xeno_by: you just typecheck the things that come after "extends"
(23:19:42) xeno_by: but decls are tricky
(23:19:51) xeno_by: scalac goes through all the members of the class
(23:20:03) xeno_by: and doesn't typecheck them... no, it doesn't
(23:20:07) xeno_by: it just enters them
(23:20:32) xeno_by: i.e. creates symbols for them and assigns lazy completers to those symbols so that if someone wants to know their signatures, they will go through the completers
(23:20:34) xeno_by: and then
(23:20:38) xeno_by: wait
(23:20:40) xeno_by: there's one but
(23:20:42) xeno_by: BUT
(23:20:47) xeno_by: while we enter those symbols
(23:20:53) xeno_by: our ClassInfoType is not ready yet
(23:21:09) xeno_by: the class we're completing is still considered to be in the middle of being completing
(23:21:12) xeno_by: so
(23:21:24) xeno_by: when inside enterSym you try to ask that class for its super class
(23:21:35) xeno_by: what happens is that check asks the class for its type signature
(23:21:45) xeno_by: the ClassInfoType that consists of parents and decls
(23:21:54) xeno_by: even though the parents are already calculated
(23:22:01) xeno_by: the ClassInfoType as a whole is not
(23:22:16) xeno_by: so scalac says that you're trying to complete something that's currently being completed
(23:22:20) xeno_by: cyclic reference error
(23:22:59) xeno_by: "cyclic" in English looks an awful lot like "суслик" in Russian (which means "gopher")