<!DOCTYPE html><html><head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  </head>
  <body>
    <p>Hi Tagir,<br>
      I agree with all Kevin said. I'm also with you re. things being
      inconsistent.</p>
    <p>The reason as to why javac allows what it allows is that it
      implements a more lax version of "unboxing" (mostly because of old
      issues that were "fixed" in Java 6, see end of this email). E.g.
      anything whose supertype is a boxed type can be unboxed, and so
      type variables get caught in the mix.</p>
    <p>But since String doesn't use unboxing conversion, there's no
      special behavior there.</p>
    <p>There's also other oddities and anomalies -- for instance:</p>
    <p>```<br>
      <X extends Integer> void m(Integer i, X x) {<br>
           x++; // ok<br>
           x = (Integer)x; // error<br>
      }<br>
      ```<br>
      <br>
      The first statement being ok means that basically we know that X
      can only be instantiated with Integer (as Integer is final). But
      then why does the cast fail?</p>
    <p>I think more work needs to be done on both sides (spec _and_
      compiler) to flesh out this story in full.</p>
    <p>Maurizio<br>
      <br>
      [1] - <a class="moz-txt-link-freetext" href="https://bugs.openjdk.org/browse/JDK-5043021">https://bugs.openjdk.org/browse/JDK-5043021</a><br>
      [2] - <a class="moz-txt-link-freetext" href="https://bugs.openjdk.org/browse/JDK-6240565">https://bugs.openjdk.org/browse/JDK-6240565</a><br>
    </p>
    <div class="moz-cite-prefix">On 16/12/2025 08:04, Tagir Valeev
      wrote:<br>
    </div>
    <blockquote type="cite" cite="mid:CAE+3fjbGY+H5vSzL5vg3PPmcyiiv=d2kK7ywLcet0J3AwY4_uw@mail.gmail.com">
      
      <div dir="ltr">Hello, Kevin!
        <div><br>
        </div>
        <div>Indeed, this is helpful, thank you. It looks like, we
          should support this case in IntelliJ IDEA as well. Here's
          another sample that might be related:</div>
        <div><br>
        </div>
        <div>private static <X extends String> void concat(X x) {<br>
              System.out.println(x+1);<br>
          }<br>
          <br>
          void main() {<br>
              concat("hello");<br>
          }<br>
        </div>
        <div><br>
        </div>
        <div>This code is not compilable, we have a compilation error:</div>
        <div><br>
        </div>
        <div>java: bad operand types for binary operator '+'<br>
            first type:  X<br>
            second type: int</div>
        <div><br>
        </div>
        <div>It looks inconsistent to me that 'X extends Integer' is
          being treated as Integer, but 'X extends String' is not being
          treated as String. But probably it's a different case, as
          unboxing is not involved here.</div>
        <div><br>
        </div>
        <div>With best regards,</div>
        <div>Tagir Valeev.</div>
      </div>
      <br>
      <div class="gmail_quote gmail_quote_container">
        <div dir="ltr" class="gmail_attr">On Tue, Dec 16, 2025 at
          12:01 AM Kevin Bourrillion <<a href="mailto:kevin.bourrillion@oracle.com" moz-do-not-send="true" class="moz-txt-link-freetext">kevin.bourrillion@oracle.com</a>>
          wrote:<br>
        </div>
        <blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
          <div>
            <div dir="ltr" style="font-family:Aptos,Arial,Helvetica,sans-serif;font-size:12pt;color:rgb(0,0,0)">
              Hey Tagir, we were discussing this internally a couple
              months ago, and I felt there was a general consensus that
              this is indeed a spec bug. Javac's permissiveness
              seems totally reasonable here.</div>
            <div dir="ltr" style="font-family:Aptos,Arial,Helvetica,sans-serif;font-size:12pt;color:rgb(0,0,0)">
              <br>
            </div>
            <div dir="ltr" style="font-family:Aptos,Arial,Helvetica,sans-serif;font-size:12pt;color:rgb(0,0,0)">
              We either need to insert more WRCs before unbox
              conversions (like the one you found), or (a
              seemingly-simpler approach that I hope will work) just
              tweak the specification of unboxing conversion itself so
              it applies to any
              <i>subtype</i> of Integer-etc., instead of only the exact
              type. (Of course this also affects intersection types and
              capture types as well as the case in your example.)</div>
            <div dir="ltr" style="font-family:Aptos,Arial,Helvetica,sans-serif;font-size:12pt;color:rgb(0,0,0)">
              <br>
            </div>
            <div dir="ltr" style="font-family:Aptos,Arial,Helvetica,sans-serif;font-size:12pt;color:rgb(0,0,0)">
              We didn't jump on fixing it yet but it's slated to happen
              sooner or later as part of a series of type-conversion
              cleanups we're working on. Hopefully just getting this
              answer unblocks you for now?</div>
            <div dir="ltr" style="font-family:Aptos,Arial,Helvetica,sans-serif;font-size:12pt;color:rgb(0,0,0)">
              <br>
            </div>
            <div dir="ltr" style="font-family:Aptos,Arial,Helvetica,sans-serif;font-size:12pt;color:rgb(0,0,0)">
              <br>
            </div>
            <div dir="ltr" style="font-family:Aptos,Arial,Helvetica,sans-serif;font-size:12pt;color:rgb(0,0,0)">
              <br>
            </div>
            <div dir="ltr" style="font-family:Aptos,Arial,Helvetica,sans-serif;font-size:12pt;color:rgb(0,0,0)">
              <br>
            </div>
            <div id="m_-2918854146287893194mail-editor-reference-message-container">
              <div style="text-align:left;padding:3pt 0in 0in;border-width:1pt medium medium;border-style:solid none none;border-color:rgb(181,196,223) currentcolor currentcolor;font-family:Aptos;font-size:12pt;color:black">
                <b><br>
                  <p style="font-family:Calibri;font-size:10pt;color:rgb(0,0,0);margin:5pt;font-style:normal;font-weight:normal;text-decoration:none" align="Left">
                    Confidential- Oracle Internal<br>
                  </p>
                  From: </b>compiler-dev <<a href="mailto:compiler-dev-retn@openjdk.org" target="_blank" moz-do-not-send="true" class="moz-txt-link-freetext">compiler-dev-retn@openjdk.org</a>>
                on behalf of Tagir Valeev <<a href="mailto:amaembo@gmail.com" target="_blank" moz-do-not-send="true" class="moz-txt-link-freetext">amaembo@gmail.com</a>><br>
                <b>Date: </b>Monday, December 15, 2025 at 9:21 AM<br>
                <b>To: </b><a href="mailto:compiler-dev@openjdk.org" target="_blank" moz-do-not-send="true" class="moz-txt-link-freetext">compiler-dev@openjdk.org</a>
                <<a href="mailto:compiler-dev@openjdk.org" target="_blank" moz-do-not-send="true" class="moz-txt-link-freetext">compiler-dev@openjdk.org</a>><br>
                <b>Subject: </b>Unboxing conversion of generic types
                with box as a bound<br>
                <br>
              </div>
              <div dir="ltr">Hello!</div>
              <div dir="ltr"><br>
              </div>
              <div dir="ltr">I noticed that the following program is
                compilable without errors using OpenJDK 25 javac:</div>
              <div dir="ltr"><br>
              </div>
              <div dir="ltr">private static <X extends Integer>
                void add(X x) {<br>
                    System.out.println(+x);<br>
                }<br>
                <br>
                void main() {<br>
                    add(10);<br>
                }</div>
              <div dir="ltr"><br>
              </div>
              <div dir="ltr">I wonder if it's correct. The JLS 15.15.3
                says [1]:</div>
              <div dir="ltr"><br>
                The type of the operand expression of the unary +
                operator must be a type that is convertible (§5.1.8) to
                a primitive numeric type, or a compile-time error
                occurs.<br>
                <br>
              </div>
              <div dir="ltr">The JLS 5.1.8, in turn, says [2]:</div>
              <div dir="ltr"><br>
              </div>
              <div dir="ltr">Unboxing conversion treats expressions of a
                reference type as expressions of a corresponding
                primitive type. Specifically, the following eight
                conversions are called the unboxing conversions:<br>
                ...</div>
              <div dir="ltr">From type Integer to type int<br>
                ...</div>
              <div dir="ltr">At run time, unboxing conversion proceeds
                as follows:</div>
              <div dir="ltr">...</div>
              <div dir="ltr">If r is a reference of type Integer, then
                unboxing conversion converts r into r.intValue()<br>
                <br>
              </div>
              <div dir="ltr">In my case, the type of reference is X,
                rather than Integer. So my question, should I read 'type
                Integer' here as 'type Integer, or any generic type
                whose upper bound is type Integer'? In other words,
                should we assume that the X type declared as `X extends
                Integer` is convertible to a primitive numeric type? It
                looks like, here a widening reference conversion (5.1.5)
                happens before an unboxing conversion, but 15.15.3 does
                not say about widening reference conversion. I've also
                checked 5.6 "Numeric contexts", but it also does not
                mention that before unboxing conversion, a widening
                reference conversion might occur. </div>
              <div dir="ltr"><br>
              </div>
              <div dir="ltr">Could anybody please clarify whether the
                compiler is wrong or I read the specification
                incorrectly? Thank you in advance!</div>
              <div dir="ltr"><br>
              </div>
              <div dir="ltr">With best regards,</div>
              <div dir="ltr">Tagir Valeev</div>
              <div dir="ltr"><br>
              </div>
              <div dir="ltr">[1] <a href="https://docs.oracle.com/javase/specs/jls/se25/html/jls-15.html#jls-15.15.3" target="_blank" moz-do-not-send="true" class="moz-txt-link-freetext">
https://docs.oracle.com/javase/specs/jls/se25/html/jls-15.html#jls-15.15.3</a></div>
              <div dir="ltr">[2] <a href="https://docs.oracle.com/javase/specs/jls/se25/html/jls-5.html#jls-5.1.8" target="_blank" moz-do-not-send="true" class="moz-txt-link-freetext">
https://docs.oracle.com/javase/specs/jls/se25/html/jls-5.html#jls-5.1.8</a></div>
            </div>
          </div>
        </blockquote>
      </div>
    </blockquote>
  </body>
</html>