<div dir="ltr"><div dir="ltr">On Thu, Feb 2, 2023 at 4:18 AM Maurizio Cimadamore <<a href="mailto:maurizio.cimadamore@oracle.com">maurizio.cimadamore@oracle.com</a>> wrote:</div><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">

  
  <div>On 02/02/2023 02:04, Archie Cobbs
      wrote:<br>
    
    <blockquote type="cite">In other words the type itself is not a problem. There's no
        mention of types at all in the above two reasons.<br>
      
    </blockquote>
    Exactly - I came up with the same conclusion in my long-winded reply
    to myself :-)<br></div></blockquote><div><br></div><div>Hah, glad we think alike. At least that makes two of us.</div><div> <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>
    <blockquote type="cite">
      <div>So one thought experiment is: What would happen if we
        eliminated all restrictions on generic type parameters in static
        contexts? What would actually go wrong?</div>
    </blockquote>In other words, my angle is the opposite: if javac blindly
      followed the "static context" rule, what would happen to existing
      code? What could go wrong? And my answer there was: quite a bit,
      actually. Which leads me to think that the "static" rule, while
      fine in a pre-generics world (and in a world where super calls are
      the first statement in a constructor) is a good and concise way to
      say what we mean. But, in a post-generics world, conflating types
      with expressions (and initializaton only cares about the latter)
      leads to problems - at least if restrictions are to be interpreted
      literally.<br></div></blockquote><div><br></div><div>I agree that something definitely needs to be improved here... <br></div><div><br></div><div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">I do not think the bug has to do with "static context" being
      ill-defined. There is a big difference between using a T in a
      constructor, and using T in a static method:<p>* when a constructor is called, you are already initializing a
      _specific_ instance, so T is _bound_;<br>
      * when a static method is called, there is no instance, so T is
      _not bound_, and has no real meaning.</p></blockquote><div>Good point, these are definitely two different cases.</div><div><br></div><div>So it sounds like we both agree the use of <span style="font-family:monospace">T</span> in a constructor (case #1), even prior to <span style="font-family:monospace">super()</span>, should be allowed. Of course the 'this' instance, which happens to have a type involving <span style="font-family:monospace">T</span>, is unavailable, but that's really an entirely separate issue.<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><p>Allowing access to T from static method as if it was a "real
      thing"  seems like a recipe for disaster:</p></blockquote><div><div>Well in my twisted way of looking at it, a static method is just an 
instance method with one less parameter, and yes, it so happens that the particular parameter that's 
missing happens to have a type involving <span style="font-family:monospace">T</span>, but so what? That doesn't 
affect how we should treat <span style="font-family:monospace">T</span> itself. As in constructors (case #1), these are two separate issues.<br></div></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><p>how do we validate that
      a call to `toFloat` is correct? And, if `toFloat` returned a T,
      how do we validate that the return type is also used correctly at
      the callsite? And which synthetic cast should be generated (given
      that T not known?).</p></blockquote>
    
    
    
    </div></div><div>I think the answer would be "T is always not known". So you fall into the same behavior as you would with a <span style="font-family:monospace">Foo<?></span>.</div><div><br></div><div>Referring to the example (btw, I forgot to include the return type of the method which obviously is <span style="font-family:monospace">float</span>):</div><div><br></div><div>- Any call to <span style="font-family:monospace">toFloat()</span> is correct, because <span style="font-family:monospace">T</span> has <span style="font-family:monospace">Number</span> as upper bound. Same as if the method were not static and you invoked it on a <span style="font-family:monospace">Foo<?></span>.</div><div>- If a static method returns T, then the compiler treats this as if it returned <span style="font-family:monospace">? extends Number</span>.</div><div>- The synthetic cast for <span style="font-family:monospace">T</span> would always be to <span style="font-family:monospace">Number</span></div><div><br></div><div>I'm NOT saying that allowing static methods would be an intuitive and obviously beneficial addition to the language. I'm just saying that it could be done in a reasonably coherent way. The point of that is just to provide more evidence that it's NOT automatically true that type parameters should be forbidden from static contexts.<br></div><div><div><div><br></div><div>-Archie</div><div><br></div><div>-- <br><div dir="ltr" class="gmail_signature">Archie L. Cobbs<br></div></div></div></div></div>