Community
Participate
Working Groups
Xtend code: val HashSet<String> values = newHashSet values += null The assignment should be ambiguous while there are 2 candidates which match: 1. org.eclipse.xtext.xbase.lib.CollectionExtensions.operator_add(Collection<? super E>, E) 2. org.eclipse.xtext.xbase.lib.CollectionExtensions.operator_add(Collection<E>, Iterable<? extends E>) Currently the second variant wins and it leads to NPE at the runtime. It can be unexpected since HashSet permits null as a value.
Extension methods are not necessary to reproduce this: import java.util.Set; class C { def <T> void m(Set<? super T> target, T element) {} def <T> void m(Set<? super T> target, Iterable<? extends T> elements) {} def void m2(Set<String> strings) { m(strings, null); } } Java fags the equivalent code with an error, even though the error message is not really helpful, since 'null' is not necessarily a String: The method m(Set<? super String>, String) is ambiguous for the type C Stricter type bounds do not help in Xtend either: import java.util.Set; class C { def <T> void m(Set<T> target, T element) {} def <T> void m(Set<T> target, Iterable<T> elements) {} def void m2(Set<String> strings) { m(strings, null); } } Reason for the problem in Xtend: On their own, both overloads of m are valid, so to figure the best match, the declared parameter types are taken into account. Since we use a type parameter T, its upper bound is used, which is Object. If the method signatures are compared, we see m(Set, Object) and m(Set, Iterable). Since both overloads are valid for the arguments (Set, null), the most special declared type is used, which is (Set, Iterable).