<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
</head>
<body style="overflow-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;">
<div>
<blockquote type="cite">
<div>On May 29, 2024, at 7:57 AM, Maurizio Cimadamore <maurizio.cimadamore@oracle.com> wrote:</div>
<br class="Apple-interchange-newline">
<div>
<div>
<div class="markdown-here-wrapper" data-md-url="" style="" markdown-here-wrapper-content-modified="true">
<p style="margin: 0px 0px 1.2em !important;">On 28/05/2024 18:20, Stephan Herrmann wrote:</p>
<div class="markdown-here-exclude">
<blockquote type="cite" cite="mid:89c6e982-5129-47bf-950d-27b5ebe51eb6@berlin.de">
* §8.1.3: "An instance of an anonymous class whose declaration occurs in a pre-construction context (8.8.7.1) has no immediately enclosing instance."
</blockquote>
<div><br class="webkit-block-placeholder">
</div>
</div>
</div>
</div>
</div>
</blockquote>
<div><br>
</div>
<div>To clarify the model: yes, this rule was intentionally removed. It becomes very complicated if you want to make rules about which enclosing instances exist or don't exist based on positioning within a constructor. Example:</div>
<div><br>
</div>
<div>class C1 {</div>
<div>    C1() {</div>
<div>        super();</div>
<div>        class C2 { // not early for C1</div>
<div>            C2() {</div>
<div>                class C3 { // early for C2</div>
<div>                    C3() {</div>
<div>                        super();</div>
<div>                        class C4 { // not early for C3</div>
<div>                            ...</div>
<div>                        }</div>
<div>                    }</div>
<div>                }</div>
<div>                super();</div>
<div>            }</div>
<div>        }</div>
<div>    }</div>
<div>}</div>
<div><br>
</div>
<div>Does C4 have a 1st enclosing instance? Yep. 2nd? Maybe no? 3rd? It better...</div>
<div><br>
</div>
<div>Instead, the approach we settled on was: early construction contexts have no bearing on whether a class "has" an enclosing instance. It always does, if it's not in a static context.</div>
<div><br>
</div>
<div>Meanwhile, there are a bunch of rules about what you can reference from an early construction context *of a particular class*. So, e.g., C4 is in the early construction context of C2, so it is illegal to reference the members of C2 in the body of C4.</div>
<div><br>
</div>
<div>(Note that this model has nothing to do with how a compiler translates these classes into bytecode, which enclosing instances get stored in fields, etc. That's a separate problem for javac to deal with.)</div>
<div><br>
</div>
<blockquote type="cite">
<div>
<div class="markdown-here-wrapper" data-md-url="" style="" markdown-here-wrapper-content-modified="true">
<div class="markdown-here-exclude"></div>
<div style="margin: 0px 0px 1.2em !important;">Consider the following example:</div>
<pre style="font-size: 0.85em; font-family: Consolas, Inconsolata, Courier, monospace;font-size: 1em; line-height: 1.2em;margin: 1.2em 0px;"><code class="hljs language-java" style="font-size: 0.85em; font-family: Consolas, Inconsolata, Courier, monospace;margin: 0px 0.15em; padding: 0px 0.3em; white-space: pre-wrap; border: 1px solid rgb(234, 234, 234); background-color: rgb(248, 248, 248); border-radius: 3px; display: inline;white-space: pre; overflow: auto; border-radius: 3px; border: 1px solid rgb(204, 204, 204); padding: 0.5em 0.7em; display: block !important;display: block; overflow-x: auto; padding: 0.5em; color: rgb(51, 51, 51); background: rgb(248, 248, 248); -moz-text-size-adjust: none;"><span class="hljs-class"><span class="hljs-keyword" style="color: rgb(51, 51, 51); font-weight: bold;">class</span> <span class="hljs-title" style="color: rgb(153, 0, 0); font-weight: bold;color: rgb(68, 85, 136); font-weight: bold;">Outer</span> </span>{
    <span class="hljs-class"><span class="hljs-keyword" style="color: rgb(51, 51, 51); font-weight: bold;">class</span> <span class="hljs-title" style="color: rgb(153, 0, 0); font-weight: bold;color: rgb(68, 85, 136); font-weight: bold;">Inner</span> </span>{
       Inner() {
          <span class="hljs-class"><span class="hljs-keyword" style="color: rgb(51, 51, 51); font-weight: bold;">class</span> <span class="hljs-title" style="color: rgb(153, 0, 0); font-weight: bold;color: rgb(68, 85, 136); font-weight: bold;">Local</span> </span>{
             <span class="hljs-function"><span class="hljs-keyword" style="color: rgb(51, 51, 51); font-weight: bold;">void</span> <span class="hljs-title" style="color: rgb(153, 0, 0); font-weight: bold;">test</span><span class="hljs-params">()</span> </span>{ m(); }
          }
          <span class="hljs-keyword" style="color: rgb(51, 51, 51); font-weight: bold;">new</span> Local().test();
          <span class="hljs-keyword" style="color: rgb(51, 51, 51); font-weight: bold;">super</span>();
       }
    }

    <span class="hljs-function"><span class="hljs-keyword" style="color: rgb(51, 51, 51); font-weight: bold;">void</span> <span class="hljs-title" style="color: rgb(153, 0, 0); font-weight: bold;">m</span><span class="hljs-params">()</span> </span>{ }

    <span class="hljs-function"><span class="hljs-keyword" style="color: rgb(51, 51, 51); font-weight: bold;">public</span> <span class="hljs-keyword" style="color: rgb(51, 51, 51); font-weight: bold;">static</span> <span class="hljs-keyword" style="color: rgb(51, 51, 51); font-weight: bold;">void</span> <span class="hljs-title" style="color: rgb(153, 0, 0); font-weight: bold;">main</span><span class="hljs-params">(String[] args)</span> </span>{
       <span class="hljs-keyword" style="color: rgb(51, 51, 51); font-weight: bold;">new</span> Outer().<span class="hljs-keyword" style="color: rgb(51, 51, 51); font-weight: bold;">new</span> Inner();
    }
}
</code></pre>
<p style="margin: 0px 0px 1.2em !important;">Here, <code style="font-size: 0.85em; font-family: Consolas, Inconsolata, Courier, monospace;margin: 0px 0.15em; padding: 0px 0.3em; white-space: pre-wrap; border: 1px solid rgb(234, 234, 234); background-color: rgb(248, 248, 248); border-radius: 3px; display: inline;">
Local</code> occurs in an early context (used to be pre-constructor, or static). So it has no enclosing instance. But then, how can it refer to
<code style="font-size: 0.85em; font-family: Consolas, Inconsolata, Courier, monospace;margin: 0px 0.15em; padding: 0px 0.3em; white-space: pre-wrap; border: 1px solid rgb(234, 234, 234); background-color: rgb(248, 248, 248); border-radius: 3px; display: inline;">
Outer::m</code> ?</p>
</div>
</div>
</blockquote>
<div>Revised rules say that Local does not appear in the early construction context *of Outer*, so therefore is allowed to refer to the members of Outer.</div>
<br>
<blockquote type="cite">
<div>
<div class="markdown-here-wrapper" data-md-url="" style="" markdown-here-wrapper-content-modified="true">
<p style="margin: 0px 0px 1.2em !important;">In 15.12.1 we say:</p>
<blockquote style="margin: 1.2em 0px;border-left: 4px solid rgb(221, 221, 221); padding: 0px 1em; color: rgb(119, 119, 119); quotes: none;">
<p style="margin: 0px 0px 1.2em !important;">If there is an enclosing class or interface declaration of which that method is a member, let E be the innermost such class or interface declaration. The type to search is the type of E.this (§15.8.4).
</p>
</blockquote>
<p style="margin: 0px 0px 1.2em !important;">Ok, so the above program is valid if
<code style="font-size: 0.85em; font-family: Consolas, Inconsolata, Courier, monospace;margin: 0px 0.15em; padding: 0px 0.3em; white-space: pre-wrap; border: 1px solid rgb(234, 234, 234); background-color: rgb(248, 248, 248); border-radius: 3px; display: inline;">
Outer.this</code> makes sense. But, as per 15.8.4:</p>
<blockquote style="margin: 1.2em 0px;border-left: 4px solid rgb(221, 221, 221); padding: 0px 1em; color: rgb(119, 119, 119); quotes: none;">
<p style="margin: 0px 0px 1.2em !important;">The value of a qualified this expression TypeName.this is the n’th lexically enclosing instance of this.
</p>
</blockquote>
<p style="margin: 0px 0px 1.2em !important;">But there’s no enclosing instance for
<code style="font-size: 0.85em; font-family: Consolas, Inconsolata, Courier, monospace;margin: 0px 0.15em; padding: 0px 0.3em; white-space: pre-wrap; border: 1px solid rgb(234, 234, 234); background-color: rgb(248, 248, 248); border-radius: 3px; display: inline;">
Local</code>, so what does <code style="font-size: 0.85em; font-family: Consolas, Inconsolata, Courier, monospace;margin: 0px 0.15em; padding: 0px 0.3em; white-space: pre-wrap; border: 1px solid rgb(234, 234, 234); background-color: rgb(248, 248, 248); border-radius: 3px; display: inline;">
Outer.this</code> evaluates to?</p>
</div>
</div>
</blockquote>
<div>Yep, that's part of what motivated this change. You need to be able to talk about the full chain of enclosing instances of Local, even if some of them are "unusable".</div>
<br>
<blockquote type="cite">
<div>
<div class="markdown-here-wrapper" data-md-url="" style="" markdown-here-wrapper-content-modified="true">
<p style="margin: 0px 0px 1.2em !important;">I think this has always been a bit of an issue - we always treated anonymous classes occurring in super calls as “static”, but that doesn’t explain how such classes seem to have access to members of enclosing classes.</p>
</div>
</div>
</blockquote>
<div>Agree, it wasn't well-specified before.</div>
<div><br>
</div>
<blockquote type="cite">
<div>
<div class="markdown-here-wrapper" data-md-url="" style="" markdown-here-wrapper-content-modified="true">
<p style="margin: 0px 0px 1.2em !important;">It seems like this area needs a bit of an overhaul? Or am I missing something?</p>
</div>
</div>
</blockquote>
<div>Right. The first step was to recognize that an early construction context is not the same thing as a static context. The next step was to allow enclosing instances for classes in early construction contexts. And the third step was to ensure that the restrictions
 on references from early construction contexts continue to apply appropriately inside nested classes.</div>
<div><br>
</div>
<div>I believe this is now appropriately handled by the spec changes Gavin shared, but it's good to validate that with extra eyeballs.</div>
<div><br>
</div>
</div>
</body>
</html>