<html><head><meta http-equiv="Content-Type" content="text/html charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class="">Georgiy asked me to take a look at this.  FWIW, I agree: this is the kind of thing that the check is supposed to prevent (and, downstream, I wonder what Signature attribute we end up with, since we can't express 'B<Y>'.<div class=""><br class=""></div><div class="">—Dan</div><div class=""><br class=""><div><blockquote type="cite" class=""><div class="">On Apr 22, 2015, at 11:32 AM, Maurizio Cimadamore <<a href="mailto:maurizio.cimadamore@oracle.com" class="">maurizio.cimadamore@oracle.com</a>> wrote:</div><br class="Apple-interchange-newline"><div class="">
  
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" class="">
  
  <div bgcolor="#FFFFFF" text="#000000" class="">
    I believe you are correct - and I believe the issue is that the
    fresh variable generated by javac is internally a TypeVar object,
    rather than a CapturedType object - meaning that it will fool the
    denotable check (which looks for CapturedTypes).<br class="">
    <br class="">
    @Srikanth - can you look into this?<br class="">
    <br class="">
    @Georgiy - good catch! Many thanks!<br class="">
    <br class="">
    Maurizio<br class="">
    <br class="">
    <div class="moz-cite-prefix">On 22/04/15 17:37, Georgiy Rakov wrote:<br class="">
    </div>
    <blockquote cite="mid:5537CE5E.9040103@oracle.com" type="cite" class="">
      <meta http-equiv="content-type" content="text/html; charset=UTF-8" class="">
      <div class="moz-text-html" lang="x-unicode">
        <div class="moz-text-html" lang="x-unicode"> Hello,<br class="">
          <br class="">
          let's consider following example:<br class="">
          <blockquote class=""> </blockquote>
          <blockquote class=""> <tt class="">class B<V> {}</tt><tt class=""><br class="">
            </tt><tt class=""><br class="">
            </tt><tt class="">class Foo<E extends B<E>> {</tt><tt class=""><br class="">
            </tt><tt class="">    public Foo<E> complexMethod(E a) { return
              this; }</tt><tt class=""><br class="">
            </tt><tt class="">}</tt><tt class=""><br class="">
            </tt><tt class=""><br class="">
            </tt><tt class="">public class Test65  {</tt><tt class=""><br class="">
            </tt><tt class="">    public static void check() {</tt><tt class=""><br class="">
            </tt><tt class="">        Foo t4 = new Foo<>() {</tt><tt class=""><br class="">
            </tt><tt class="">        };</tt><tt class=""><br class="">
            </tt><tt class="">    }</tt><tt class=""><br class="">
            </tt><tt class="">}</tt></blockquote>
          This code successfully compiles on JDK9b60. However according
          to my understanding the compilation should have failed as per
          new spec. Could you please tell if this understanding is
          correct.<br class="">
          <br class="">
          The reasons why I think that the compilation should have
          failed are presented below.<br class="">
          <br class="">
          E is inferred as B<Y>, where Y is a fresh type variable
          with the upper bound B<Y>.  If this is correct the given
          code should cause compilation failure according to following
          new assertions presented in the <a moz-do-not-send="true" href="https://bugs.openjdk.java.net/browse/JDK-8073593?focusedCommentId=13622110&page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#comment-13622110" class="">JDK-8073593



            issue comment</a>:<br class="">
          <blockquote class=""><tt class="">***It is a compile-time error if the
              superclass or superinterface type of the anonymous class,
              T, or any subexpression of T, has one of the following
              forms: </tt><tt class=""><br class="">
            </tt><tt class=""> - A type variable (4.4) that was not declared as a
              type parameter (such as a type variable produced by
              capture conversion (5.1.10)) </tt><tt class=""><br class="">
            </tt><tt class=""> - An intersection type (4.9) </tt><tt class=""><br class="">
            </tt><tt class=""> - A class or interface type, where the class or
              interface declaration is not accessible from the class or
              interface in which the expression appears.*** </tt><tt class=""><br class="">
            </tt><tt class=""> The term "subexpression" includes type arguments
              of parameterized types (4.5), bounds of wildcards (4.5.1),
              and element types of array types (10.1). It excludes
              bounds of type variables.*** </tt> </blockquote>
          The reason for this is that anonymous class super type, which
          is parameterized, has a type argument (subexpression) being a
          <i class="">type variable which was not declared as a type parameter.</i><i class=""><br class="">
          </i><i class=""> </i><br class="">
          The fact that E is inferred as a type variable with the upper
          bound becomes more obvious if we decide to override <tt class="">complexMethod</tt>:<br class="">
          <pre style="background-color: rgb(255, 255, 255); font-family: 'Courier New';" class=""><tt class="">        Foo t4 = new Foo<>() {</tt><tt class="">
</tt><tt class="">            public Foo<? extends B> complexMethod(B a){ return this; }</tt><tt class="">
</tt><tt class="">            //public Foo<B> complexMethod(B a){ return this; } ;//this causes compilation failure</tt><tt class="">
</tt><tt class="">        };</tt>

</pre>
          In this case providing return type as <tt class="">Foo<B></tt>
          causes compilation failure. Only specifying the return type as
          <tt class="">Foo<? extends B></tt> gets compilation to succeed.<br class="">
          <br class="">
          In general the reasons why I think that E is inferred here as
          B<Y> are presented below (just meaningful steps are
          presented). Could you please tell if they are correct.<br class="">
          <br class="">
          1. Initial bounds set created from type parameter bounds
          contains following items as per JLS 18.1.3:<br class="">
          <blockquote class=""><tt class="">e :< B<e></tt> (e - is inference
            variable);<br class="">
            <tt class="">e :< Object</tt> (this is added because e had no
            proper upper bounds);<br class="">
          </blockquote>
          2. Then these bounds are processed by resolution process (JLS
          18.4). During resolution <tt class="">e :< Object</tt> causes
          instantiation <tt class="">e=Object</tt> according to following
          assertion from JLS 18.4:<br class="">
          <blockquote class=""><tt class="">Otherwise, where <span class="symbol">a</span><span class="type"><sub class="">i</sub></span>
                has <span class="emphasis"><em class="">proper</em></span> upper
                bounds <span class="type">U<sub class="">1</sub></span>, ..., <span class="type">U<sub class="">k</sub></span>, <span class="type">T<sub class="">i</sub></span>
                = glb(<span class="type">U<sub class="">1</sub></span>, ..., <span class="type">U<sub class="">k</sub></span>)</tt><tt class=""><br class="">
            </tt></blockquote>
          3. Incorporating <tt class="">e=Object</tt> causes following new
          constraint to be added <tt class="">Object :< B<Object></tt>
          according to following assertion from JLS 18.3.1:    <font class="txtPRECISE"><span class="symbol"></span></font><tt class=""><br class="">
              </tt>
          <blockquote class=""><tt class=""><span class="symbol">a</span>
                = <span class="type">U</span> and <span class="type">S</span>
                <code class="literal"><:</code> <span class="type">T</span>
                imply ‹<span class="type">S</span><code class="literal">[</code><span class="symbol">a</span>:=<span class="type">U</span><code class="literal">]</code> <code class="literal"><:</code>
                <span class="type">T</span><code class="literal">[</code><span class="symbol">a</span>:=<span class="type">U</span><code class="literal">]</code>›</tt><br class="">
          </blockquote>
          5. Constraint <tt class="">Object :< B<Object></tt> reduces
          to <tt class="">false </tt>causing the second resolution attempt to
          take effect according to following assertion from JLS 18.4:<br class="">
          <blockquote class=""><tt class="">Otherwise, the result
                contains the bound <span class="emphasis"><em class="">false</em></span>,
                so a second attempt is made to instantiate { <span class="symbol">a</span><span class="type"><sub class="">1</sub></span>,
                ..., <span class="symbol">a</span><span class="type"><sub class="">n</sub></span>
                } by performing the step below</tt>.<br class="">
          </blockquote>
          4. Fresh type variable <tt class="">Y </tt>with upper bound <tt class="">B<Y>



          </tt>is introduced according to assertions from JLS 18.4
          presented below (<tt class="">Y</tt> upper bound is <tt class="">glb(Object,B<e>[e:=Y])


            = B<e>[e:=Y] = B<Y></tt>):<br class="">
          <blockquote class=""><tt class="">then let <span class="type">Y<sub class="">1</sub></span>, ..., <span class="type">Y<sub class="">n</sub></span> be fresh type
                variables whose bounds are as follows:</tt><tt class=""><br class="">
            </tt><font class="txtNOMATCH"><tt class="">* For all </tt><tt class=""><span class="emphasis"><em class="">i</em></span></tt><tt class=""> (1 ≤ </tt><tt class=""><span class="emphasis"><em class="">i</em></span></tt><tt class=""> ≤ </tt><tt class=""><span class="emphasis"><em class="">n</em></span></tt><tt class="">), where </tt><tt class=""><span class="symbol">a</span></tt><tt class=""><span class="type"><sub class="">i</sub></span></tt><tt class="">
                has upper bounds </tt><tt class=""><span class="type">U<sub class="">1</sub></span></tt><tt class="">,
                ..., </tt><tt class=""><span class="type">U<sub class="">k</sub></span></tt><tt class="">,
                let the upper bound of </tt><tt class=""><span class="type">Y<sub class="">i</sub></span></tt><tt class="">
                be glb(</tt><tt class=""><span class="type">U<sub class="">1</sub></span></tt><tt class="">
              </tt><tt class=""><span class="symbol">q</span></tt><tt class="">, ..., </tt><tt class=""><span class="type">U<sub class="">k</sub></span></tt><tt class=""> </tt><tt class=""><span class="symbol">q</span></tt><tt class="">), where </tt><tt class=""><span class="symbol">q</span></tt><tt class=""> is the substitution </tt><code class="literal">[</code><tt class=""><span class="symbol">a</span></tt><tt class=""><span class="type"><sub class="">1</sub></span></tt><tt class="">:=</tt><tt class=""><span class="type">Y<sub class="">1</sub></span></tt><tt class="">, ..., </tt><tt class=""><span class="symbol">a</span></tt><tt class=""><span class="type"><sub class="">n</sub></span></tt><tt class="">:=</tt><tt class=""><span class="type">Y<sub class="">n</sub></span></tt><code class="literal">]</code><tt class="">. </tt></font><br class="">
          </blockquote>
          5. Finally e is instantiated as a fresh type variable<tt class=""> Y </tt>with



          the upper bound<tt class=""> B<Y></tt> according to the following
          assertion from JLS 18.4:<br class="">
          <blockquote class=""><tt class=""><font class="txtNOMATCH">Otherwise, for all <span class="emphasis"><em class="">i</em></span> (1 ≤ <span class="emphasis"><em class="">i</em></span> ≤ <span class="emphasis"><em class="">n</em></span>), all bounds of the
                form <span class="type">G</span><code class="literal"><</code>...,


                <span class="symbol">a</span><span class="type"><sub class="">i</sub></span>,
                ...<code class="literal">></code> = capture(<span class="type">G</span><code class="literal"><</code>...<code class="literal">></code>) are removed from the
                current bound set, <i class=""><u class=""><b class="">and the bounds </b></u></i><i class=""><u class=""><b class=""><span class="symbol">a</span></b></u></i><i class=""><u class=""><b class=""><span class="type"><sub class="">1</sub></span></b></u></i><i class=""><u class=""><b class="">
                      = </b></u></i><i class=""><u class=""><b class=""><span class="type">Y<sub class="">1</sub></span></b></u></i><i class=""><u class=""><b class="">,
                      ..., </b></u></i><i class=""><u class=""><b class=""><span class="symbol">a</span></b></u></i><i class=""><u class=""><b class=""><span class="type"><sub class="">n</sub></span></b></u></i><i class=""><u class=""><b class="">
                      = </b></u></i><i class=""><u class=""><b class=""><span class="type">Y<sub class="">n</sub></span></b></u></i><i class=""><u class=""><b class="">
                      are incorporated.<br class="">
                      <br class="">
                    </b></u></i></font></tt></blockquote>
          Thanks,<br class="">
          Georgiy.<tt class=""><br class="">
          </tt> </div>
      </div>
    </blockquote>
    <br class="">
  </div>

</div></blockquote></div><br class=""></div></body></html>