<!DOCTYPE html><html><head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  </head>
  <body>
    <p>Hi Tagir!</p>
    <p>Nice cacth.</p>
    <p>Here's a slightly different example which reveals a bit more of
      what's happening:</p>
    <p>```<br>
      interface Main {<br>
          interface X<T> {<br>
              X<T> self();<br>
          }<br>
      <br>
          static X<?> makeX() {return null;}<br>
      <br>
          static <R> X<R> create(Supplier<? extends R>
      supplier) {return null;}<br>
      <br>
          static X<X<?>> methodRef() {<br>
              var s = (String)create(Main::makeX);<br>
          }<br>
      <br>
          static X<X<?>> lambda() {<br>
              var s = (String)create(() -> makeX());<br>
          }<br>
      }<br>
      ```</p>
    <p>This prints:</p>
    <p>```<br>
      error: incompatible types: X<X<?>> cannot be converted
      to String<br>
              var s = (String)create(Main::makeX);<br>
                                    ^<br>
      error: incompatible types: X<X<CAP#1>> cannot be
      converted to String<br>
              var s = (String)create(() -> makeX());<br>
                                    ^<br>
        where CAP#1 is a fresh type-variable:<br>
          CAP#1 extends Object from capture of ?<br>
      ```</p>
    <p>So, the main difference between the two examples is that in the
      lambda case, the return type of the makeX call is captured. But in
      the method refreene case no capture occurs.</p>
    <p>I believe the lambda case works as expected, but the method
      reference case does not.</p>
    <p>The JLS mandates a capture of the resolved method return type
      (JLS 15.13.2, emphasis mine):</p>
    <p>
      <blockquote type="cite">A method reference expression is <span class="emphasis"><em>congruent</em></span> with a function
        type if both of the following are true:
        <div class="norm">
          <ul class="norm" style="list-style-type: disc; ">
            <li class="listitem">
              <p class="norm-static">The function type identifies a
                single compile-time declaration corresponding to the
                reference. </p>
            </li>
            <li class="listitem">
              <p class="norm-static"> One of the following is true: </p>
              <div class="norm">
                <ul class="norm" style="list-style-type: circle; ">
                  <li class="listitem">
                    <p class="norm-static">The result of the function
                      type is <code class="literal">void</code>. </p>
                  </li>
                  <li class="listitem">
                    <p class="norm-static"> The result of the function
                      type is <span class="type">R</span>, <b>and the
                        result of applying capture conversion (<a class="xref" href="https://docs.oracle.com/javase/specs/jls/se25/html/jls-5.html#jls-5.1.10" title="5.1.10. Capture Conversion">§5.1.10</a>)
                        to the return type of the invocation type (<a class="xref" href="https://docs.oracle.com/javase/specs/jls/se25/html/jls-15.html#jls-15.12.2.6" title="15.12.2.6. Method Invocation Type">§15.12.2.6</a>)
                        of the chosen compile-time declaration is <span class="type">R</span>'</b> (where <span class="type">R</span> is the target type that
                      may be used to infer <span class="type">R</span>'),
                      and neither <span class="type">R</span> nor <span class="type">R</span>' is <code class="literal">void</code>,
                      and <span class="type">R</span>' is compatible
                      with <span class="type">R</span> in an assignment
                      context. </p>
                  </li>
                </ul>
              </div>
            </li>
          </ul>
        </div>
      </blockquote>
    </p>
    <p>It seems like javac is missing this capture conversion and,
      because of that, the behavior of the two examples diverge.</p>
    <p>Cheers<br>
      Maurizio<br>
    </p>
    <p><br>
    </p>
    <p><br>
    </p>
    <p><br>
    </p>
    <p><br>
    </p>
    <div class="moz-cite-prefix">On 07/10/2025 17:12, Tagir Valeev
      wrote:<br>
    </div>
    <blockquote type="cite" cite="mid:CAE+3fjb4EM9=TstxTO1_4dHJ6Gc=bt6qw=r_9QRkmsC6AraXzQ@mail.gmail.com">
      
      <div dir="ltr">Hello!
        <div><br>
        </div>
        <div>I'm investigating a seemingly weird compilation case.
          Consider the following Java interface:</div>
        <div><br>
        </div>
        <div>import java.util.function.Supplier;<br>
          <br>
          interface Main {<br>
              interface X<T> {<br>
                  X<T> self();<br>
              }<br>
          <br>
              static X<?> makeX() {return null;}<br>
          <br>
              static <R> X<R> create(Supplier<? extends
          R> supplier) {return null;}<br>
           <br>
              static X<X<?>> methodRef() {<br>
                  return create(Main::makeX).self();<br>
              }<br>
          <br>
              static X<X<?>> lambda() {<br>
                  return create(() -> makeX()).self();<br>
              }<br>
          }</div>
        <div><br>
        </div>
        <div>I expect that either both methods 'methodRef' and 'lambda'
          should be compilable or both should be non-compilable.
          However, while 'methodRef' compiles, 'lambda' is rejected by
          compiler (using javac build 25+36-3489):</div>
        <div><br>
          Main.java:17: error: incompatible types:
          X<X<CAP#1>> cannot be converted to
          X<X<?>><br>
                  return create(() -> makeX()).self();<br>
                                                   ^<br>
            where CAP#1 is a fresh type-variable:<br>
              CAP#1 extends Object from capture of ?<br>
          1 error<br>
          error: compilation failed</div>
        <div><br>
        </div>
        <div>Could you please help me and clarify whether this is an
          expected behavior or not?</div>
        <div><br>
        </div>
        <div>With best regards,</div>
        <div>Tagir Valeev</div>
      </div>
    </blockquote>
  </body>
</html>