Community
Participate
Working Groups
I've installed the JDT Patch with Java 16 support for 2021-03: - Eclipse JDT (Java Development Tools) Patch with Java 16 support for 2021-03 release 1.2.100.v20210317-0429_JAVA16 org.eclipse.jdt.java16patch.feature.group Eclipse.org - Eclipse JDT (Java Development Tools) Source Patch with Java 16 support for 2021-03 release 1.2.100.v20210317-0429_JAVA16 org.eclipse.jdt.java16patch.source.feature.group Eclipse.org From: https://download.eclipse.org/eclipse/updates/4.19-P-builds/ I'm now experiencing a significant compiler regression in a class like this: // -------------------------------------------------- package test; import java.util.Iterator; public class Test { static <T> Iterable<T> iterable() { // Error here: return () -> new Iterator<T>() { @Override public boolean hasNext() { return false; } @Override // Problem here: public T next() { return null; } }; } } // -------------------------------------------------- Two errors are reported, the second one being the cause of the first one: 1. The type new Iterator<T>(){} must implement the inherited abstract method Iterator<T>.next() 2. Cannot make a static reference to the non-static type T A workaround is to avoid the lambda expression. This works: // -------------------------------------------------- package test; import java.util.Iterator; public class Test { static <T> Iterable<T> iterable() { return new Iterable<T>() { @Override public Iterator<T> iterator() { return new Iterator<T>() { @Override public boolean hasNext() { return false; } @Override public T next() { return null; } }; } }; } } // -------------------------------------------------- Removing static also helps, but is obviously not viable in many cases: // -------------------------------------------------- package test; import java.util.Iterator; public class Test { <T> Iterable<T> iterable() { return () -> new Iterator<T>() { @Override public boolean hasNext() { return false; } @Override public T next() { return null; } }; } } // --------------------------------------------------
Another workaround is to assign the iterator to a local variable: // -------------------------------------------------- package test; import java.util.Iterator; public class Test { static <T> Iterable<T> iterable() { Iterator<T> iterator = new Iterator<T>() { @Override public boolean hasNext() { return false; } @Override public T next() { return null; } }; return () -> iterator; } } // --------------------------------------------------
Also get this error in 2021-03 + Java 16 patch. If the static generic method includes a lambda class and uses the same generic inside the lambda class, it will report this error. import java.util.function.Consumer; public class HelloWorld { public static <T> void build(T element) { new Thread(() -> { new Consumer<T>() { @Override public void accept(T t) { // report error at this line } }; }); } } This error doesn't exist in 2020-12.
This is a regression introduced by this change. https://git.eclipse.org/r/c/jdt/eclipse.jdt.core/+/176377 When JDT news a MethodScope for a lambda expression, its isStatic property is inherited from its enclosing method. See https://github.com/eclipse/eclipse.jdt.core/blob/33f60d3da79a0ae0b5266c2c7f357a3f7fdb6519/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/LambdaExpression.java#L270 In this issue case, the external method 'iterable()' is a static method, so JDT treats the method scope of lambda expression as static as well. The method 'public T next()' in the lambda body is considered to be inside a static context and report the error. See https://github.com/eclipse/eclipse.jdt.core/blob/33f60d3da79a0ae0b5266c2c7f357a3f7fdb6519/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/Scope.java#L3325
Manoy, Jay, Kalyan: this affects not only Java 16 code, probability is high this will affect many people. Any chance to fix it in 4.20?
(In reply to Andrey Loskutov from comment #4) > Manoy, Jay, Kalyan: this affects not only Java 16 code, probability is high > this will affect many people. Any chance to fix it in 4.20? Kalyan and I was thinking about going beyond the scope of class if it is anonymous since the inheritance comes from the methodscope for anon classes. Kalyan will implement this and test I will work with him to see whether we can push a solution in RC2 itself..
New Gerrit change created: https://git.eclipse.org/r/c/jdt/eclipse.jdt.core/+/181266
New Gerrit change created: https://git.eclipse.org/r/c/jdt/eclipse.jdt.core/+/181289
+1 for RC2
(In reply to Eclipse Genie from comment #6) > New Gerrit change created: > https://git.eclipse.org/r/c/jdt/eclipse.jdt.core/+/181266 There is a failure in the test. However, I am taking a decision to commit based on all the following observations: 1)This is a regression that needs to be fixed. 2a) The failure due to the tests is via time-out and individual local runs passed. 2b) Multiple cumulative Local runs have passed taking only just around an hour each. 3) There is nothing in the code change that is going to cause such an increase in time based on the following code observations: (a) The code change just replaces the rhs of a boolean variabe(insideClassContext) assignment with a single line with a function call (!sourceType.isAnonymousType()) (b) The boolean variable insideClassContext is not participating in decision making for loop continuation (c) The function sourceType.isAnonymousType() implementations do not contain loop but just a bitwise operation. With the reasons cited in 2 and 3 (subsections) concluding this timeout due to an infrastructure issue and given that this is a regression, giving this case an exception by taking the decision to commit within the RC2 time-frame.
Gerrit change https://git.eclipse.org/r/c/jdt/eclipse.jdt.core/+/181266 was merged to [master]. Commit: http://git.eclipse.org/c/jdt/eclipse.jdt.core.git/commit/?id=0fc92c07cc21c7828eda0293e01fda98392e50b8
Verified for 4.20 RC2 with build I20210603-0040.