EVALUATION
This is a regression that has been introduced by 6726015; that fix changed the order in which classes get desugared in the compiler pipeline. Let's have a look at the pipeline when compling the attached test case (those info have been generated by using -XDverboseCompilePolicy option)
The current (erroneous) behavior is:
1) Attr Y
2) Flow Y
3) Lower Y
3b) Attr W
3c) Flow W
4) Gen Y //at this point both Y, W and Z are erased (that is after Y's Lowering)
5) Lower W
5b) Attr Z
5c) Flow Z (Flow is executed on an erased AST!!)
6) Gen W
7) Lower Z - do nothing
8) Gen Z
It can be seen that flow analysis is indeed performed on Z only *after* Z has been erased (as a side-effect of erasing its supertype Y). This happens because the ScanNested visitor in JavaCompiler doesn't add all Y's supertypes in the dependency list that is then used in order to perform attribution and flow analysis on all the classes the class being desgugared depends on - only the direct supertype is added to the list.
This means that when desugaring Y, javac realizes that also W has to be attributed and analyzed - but that's it; instead javac should force also the attribution and analysis of Z (which is another, indirect, supertype of Y). If we do so the execution flows changes as follows:
1) Attr Y
2) Flow Y
3) Lower Y //Y is delayed because Y's supertype has not been lowered yet
3b) Attr W
3c) Flow W
3d) Attr Z
3e) Flow Z
4) Gen Y //at this point both Y, W and Z are erased (that is after Y's Lowering)
5) Lower W
6) Gen W
7) Lower Z
8) Gen Z
Note: javac used to defer desugaring of classes that have non-trivial supertype dependencies - which means that those classes were effectively moved at the end of the compiler pipeline. We want to avoid this behavior, as it poses severe problems wrt to future multi-threading patch that might improve the compiler pipeline.
|