<html><head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  </head>
  <body>
    <p>The introduction of Sequenced Collections in JDK 21+20 did make a
      difference in this specific case. One can compile Rémi's example
      on JDK 21+19 successfully, but it will fail on JDK 21+20.</p>
    <p>Here's Rémi's example:</p>
    <p><font face="monospace">    public static void
        m(List<Supplier<? extends Map<String,
        String>>> factories) {<br>
            }<br>
        <br>
            public static void main(String[] args) {<br>
                Supplier<LinkedHashMap<String,String>>
        supplier1 = LinkedHashMap::new;<br>
                Supplier<SortedMap<String,String>> supplier2
        = TreeMap::new;<br>
                var factories = List.of(supplier1, supplier2);<br>
                m(factories);<br>
            }</font><br>
    </p>
    <p>The type of 'factories' is inferred to be a List of the <i>something</i>
      which is the common supertype (least upper bound, or LUB) of the
      arguments. It's pretty easy to see this in an IDE or in jshell. In
      JDK 21+19 factories is inferred to have this type:</p>
    <p><font face="monospace">    List<Supplier<? extends
        Map<String,String>>></font><br>
    </p>
    <p>whereas in JDK 21+20 it's inferred to have this type:</p>
    <p><font face="monospace">    List<Supplier<? extends
        SequencedMap<String,String>>></font></p>
    <p>Rémi's example carefully defined the parameter of the m() method
      so that it matches the first (and compiles successfully) but does
      not match the second (and so fails with a compilation error).</p>
    <p>This isn't a bug in type inference or in Sequenced Collections.
      It's a consequence of a few phenomena: 1) the result of type
      inference depends on the exact inputs given; 2) the result of type
      inference depends on the current type hierarchy; 3) it's possible
      to write source code that implicitly depends on a specific result
      of type inference. Sequenced Collections changed the type
      hierarchy, so inference gave different results, and the example
      depended on getting a specific result under JDK 21+19.<br>
    </p>
    <p>When you changed the code to List.of(supplier1), this changed the
      inputs to type inference, so it got a different result:<br>
    </p>
    <p><font face="monospace">   
        List<Supplier<LinkedHashMap<String,String>>></font><br>
    </p>
    <p>This doesn't match the parameter of the m() method, so this gives
      a compilation error on all versions of the system.</p>
    <p>As you observed, changing the declaration of m() to be:</p>
    <p><font face="monospace">    public static void m(List<? extends
        Supplier<? extends Map<String, String>>>
        factories)</font><br>
    </p>
    <p>This lets the examples compile on JDK 21+19 and JDK 21+20,
      whether List.of() is given one or both arguments. This change
      broadens the set of types accepted by m(), reducing its specific
      dependency on a specific arrangement of the type hierarchy. It's
      also probably a good idea in general, as we recommend using
      wildcard variance (? extends T) consistently in order to increase
      the flexibility of methods. For example, I might have a MySupplier
      functional interface that adds some features to the built-in
      Supplier interface:</p>
    <p><font face="monospace">    interface MySupplier<T> extends
        Supplier<T> {<br>
                // more features<br>
            }</font><br>
    </p>
    <p>If the suppliers were declared as instances of MySupplier
      instead, Rémi's example would fail even on JDK 21+19. So yes, in a
      sense, this doesn't have much to do with the introduction of
      Sequenced Collections.<br>
    </p>
    <p>s'marks<br>
    </p>
    <p><br>
    </p>
    <p><br>
    </p>
    <div class="moz-cite-prefix">On 5/2/23 5:09 AM, Blaise B. wrote:<br>
    </div>
    <blockquote type="cite" cite="mid:CAEK75Eqq36wRodc=_n-6jsxAMJ2GTF-uPX-6DB2cVVWBTkPwSA@mail.gmail.com">
      
      <div dir="ltr">
        <div><br>
        </div>
        <div>Hello,<br>
          <br>
          I've tested the example provided by Rémi, and it looks like
          the compile-time error has little to do with the integration
          of Sequenced Collections into mainline.<br>
          By changing the "factories" list to contain only one element
          instead of two, the code does not compile even in previous jdk
          versions (tested on jdk 17, 18, 19, 20, 21):<br>
          <br>
                 import java.util.*;<br>
                 import java.util.function.Supplier;<br>
          <br>
                 public class SequencedCollectionsTest {<br>
          <br>
                       public static void m(List<Supplier<?
          extends Map<String, String>>> factories) {<br>
                       }<br>
          <br>
                       public static void main(String[] args) {<br>
                               
           Supplier<LinkedHashMap<String,String>> supplier1
          = LinkedHashMap::new;<br>
                               
           Supplier<SortedMap<String,String>> supplier2 =
          TreeMap::new;<br>
          <br>
                                 //var factories = List.of(supplier1,
          supplier2);<br>
                                 var factories = List.of(supplier1);<br>
          <br>
                                 m(factories);<br>
                       }<br>
                }<br>
          <br>
          It all only compiles on all versions when I change the
          signature of the method m() to:<br>
          <br>
                    public static void m(List<? extends Supplier<?
          extends Map<String, String>>> factories) {<br>
                    }<br>
          <br>
          So unless there are more other cases of failing compiles, it
          seems to me like something was actually fixed in the latest
          jdk21 build, and that the integration of Sequenced Collections
          was just coincidence.<br>
          <br>
          Hope this helps.<br>
        </div>
      </div>
    </blockquote>
  </body>
</html>