@@ -1258,7 +1258,8 @@ public void visitMethodDef(JCMethodDecl tree) {
12581258 PrologueVisitorMode .WARNINGS_ONLY :
12591259 thisInvocation ?
12601260 PrologueVisitorMode .THIS_CONSTRUCTOR :
1261- PrologueVisitorMode .SUPER_CONSTRUCTOR );
1261+ PrologueVisitorMode .SUPER_CONSTRUCTOR ,
1262+ false );
12621263 ctorPrologueVisitor .scan (prologueCode .toList ());
12631264 }
12641265 }
@@ -1282,11 +1283,13 @@ enum PrologueVisitorMode {
12821283 class CtorPrologueVisitor extends TreeScanner {
12831284 Env <AttrContext > localEnv ;
12841285 PrologueVisitorMode mode ;
1286+ boolean isInitializer ;
12851287
1286- CtorPrologueVisitor (Env <AttrContext > localEnv , PrologueVisitorMode mode ) {
1288+ CtorPrologueVisitor (Env <AttrContext > localEnv , PrologueVisitorMode mode , boolean isInitializer ) {
12871289 this .localEnv = localEnv ;
12881290 currentClassSym = localEnv .enclClass .sym ;
12891291 this .mode = mode ;
1292+ this .isInitializer = isInitializer ;
12901293 }
12911294
12921295 boolean insideLambdaOrClassDef = false ;
@@ -1512,10 +1515,14 @@ void analyzeSymbol(JCTree tree) {
15121515 } else if (isEarlyReference (localEnv , tree , sym )) {
15131516 /* now this is a `proper` instance field of the current class
15141517 * references to fields of identity classes which happen to have initializers are
1515- * not allowed in the prologue
1518+ * not allowed in the prologue.
1519+ * But it is OK for a field with initializer to refer to another field with initializer,
1520+ * so no warning or error if we are analyzing a field initializer.
15161521 */
15171522 if (insideLambdaOrClassDef ||
1518- (!localEnv .enclClass .sym .isValueClass () && (sym .flags_field & HASINIT ) != 0 ))
1523+ (!localEnv .enclClass .sym .isValueClass () &&
1524+ (sym .flags_field & HASINIT ) != 0 &&
1525+ !isInitializer ))
15191526 reportPrologueError (tree , sym );
15201527 // we will need to generate a proxy for this field later on
15211528 if (!isInLHS ) {
@@ -1642,13 +1649,13 @@ public void visitVarDef(JCVariableDecl tree) {
16421649 chk .checkDeprecatedAnnotation (tree .pos (), v );
16431650
16441651 if (tree .init != null ) {
1652+ Env <AttrContext > initEnv = memberEnter .initEnv (tree , env );
16451653 if ((v .flags_field & FINAL ) == 0 ||
16461654 !memberEnter .needsLazyConstValue (tree .init )) {
16471655 // Not a compile-time constant
16481656 // Attribute initializer in a new environment
16491657 // with the declared variable as owner.
16501658 // Check that initializer conforms to variable's declared type.
1651- Env <AttrContext > initEnv = memberEnter .initEnv (tree , env );
16521659 initEnv .info .lint = lint ;
16531660 // In order to catch self-references, we set the variable's
16541661 // declaration position to maximal possible value, effectively
@@ -1665,16 +1672,17 @@ public void visitVarDef(JCVariableDecl tree) {
16651672 //fixup local variable type
16661673 v .type = chk .checkLocalVarType (tree , tree .init .type , tree .name );
16671674 }
1668- if (allowValueClasses && v .owner .kind == TYP && !v .isStatic ()) {
1669- // strict field initializers are inlined in constructor's prologues
1670- CtorPrologueVisitor ctorPrologueVisitor = new CtorPrologueVisitor (initEnv ,
1671- !v .isStrict () ? PrologueVisitorMode .WARNINGS_ONLY : PrologueVisitorMode .SUPER_CONSTRUCTOR );
1672- ctorPrologueVisitor .scan (tree .init );
1673- }
16741675 } finally {
16751676 initEnv .info .ctorPrologue = previousCtorPrologue ;
16761677 }
16771678 }
1679+ if (allowValueClasses && v .owner .kind == TYP && !v .isStatic ()) {
1680+ // strict field initializers are inlined in constructor's prologues
1681+ CtorPrologueVisitor ctorPrologueVisitor = new CtorPrologueVisitor (initEnv ,
1682+ !v .isStrict () ? PrologueVisitorMode .WARNINGS_ONLY : PrologueVisitorMode .SUPER_CONSTRUCTOR ,
1683+ true );
1684+ ctorPrologueVisitor .scan (tree .init );
1685+ }
16781686 if (tree .isImplicitlyTyped ()) {
16791687 setSyntheticVariableType (tree , v .type );
16801688 }
0 commit comments