<div dir="ltr">Actually, I have realized that there are realistic methods that would fall into this problem. In fact, with pattern matching, it is also a question how the JEP will plan to retain source compatibility, because a method might this could realistically exist:<div><br></div><div>```</div><div><T> boolean contains(Iterable<T> itr, T element) {</div><div>  return itr instanceof Collection<T> c </div><div>    ? c.contains(element) </div><div>    : iterableContains(itr, element); // impl of iterableContains omitted</div><div>}</div><div>```</div><div><br></div><div>One could argue that the implementor should have used `? extends T` here, but (as even the JEP admits) people are often lazy (or just lack knowledge) and will not write `? extends`.</div><div><br></div><div>If it was on me, I would allow the above unsafe construct in the JEP, but would issue some kind of unsafe cast warning.</div><div><br></div></div><br><div class="gmail_quote gmail_quote_container"><div dir="ltr" class="gmail_attr">Attila Kelemen <<a href="mailto:attila.kelemen85@gmail.com">attila.kelemen85@gmail.com</a>> ezt írta (időpont: 2025. márc. 4., K, 20:51):<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 dir="ltr">Hi,<div><br></div><div>I have read JEP 300, and it seems it is not defining what it intends to do with casting these adjusted types to a subtype. For example consider the following method:</div><div><br></div><div>```</div><div><T> void method1(Iterable<T> itr) {</div><div>  if (itr instanceof List) {</div><div>    var list = (List<T>) itr;</div><div>    list.add(null);</div><div>  }</div><div>}</div><div>```</div><div><br></div><div>The cast in the above example is safe (it doesn't emit any unsafe cast warning). However, if `Iterable` becomes covariant at the declaration site, then the above code is now unsafe.</div><div><br></div><div>What is the plan of the JEP with such casting? Will it make the above cast unsafe? If so, then there will be no way to safely cast from `Iterable<T>` to `List<T>`. Admittedly, I can't recall any code I have ever seen where this would be a problem (and so I wouldn't worry about it too much), but it would be nice if the JEP would explicitly address this question.</div><div><br></div><div>In Kotlin, they allow such unsafe casts without a warning (in fact, you don't even need a cast in Kotlin for it). For example, the following code compiles without warning in Kotlin:</div><div><br></div><div>```</div><div>fun evilMethod(list: List<Any>) {<br>  if (list is MutableList) {<br>    list.add("hello")<br>  }<br>}</div><div><br></div><div>fun naiveMethod() {<br>  val list = mutableListOf<Int>()<br>  evilMethod(list)<br>  println(list.sum())<br>}</div><div>```</div><div><br></div><div>Of course, calling `naiveMethod` fails with an exception when trying to call `sum`. (Note: `List` in Kotlin is a "read-only" variant of Java's List, and MutableList is the equivalent of Java's List interface).</div><div><br></div><div>I personally don't like the behavior of Kotlin, and would rather choose that only `Iterable<T>` to `List<? extends T>` is safe from here onwards.</div><div><br></div><div>Attila</div><div><br></div></div>
</blockquote></div>