Reduce b2 when reducing ConstraintExpressionFormula#4315
Reduce b2 when reducing ConstraintExpressionFormula#4315stephan-herrmann merged 2 commits intoeclipse-jdt:masterfrom
Conversation
|
@coehlrich I found this by chance only since I chose not to be informed about every activity in github. In the future feel free to ping (mention) me in issues / PRs that relate to generics / type inference and all that. Sometimes the good folks in India pick up and redirect such issues, but they may miss a few. That said, now we're late in the cycle of 4.37. Do you mind postponing this issue to right when 4.38 re-opens, or is anybody currently blocked by this bug? |
|
I'm fine with waiting until 4.38. |
|
@coehlrich thanks for your sharp analysis and fix. Still let me play the pedantic guardian of JLS :) We are coming from § 18.2.1
So let's have a look also at §18.5.2.1:
I read this like so:
So rather than doing too much and then reverting part of that, I tried to add only this: if (!inferenceContext.reduce())
return FALSE;which also passes tests and seems more in line with JLS. Incorporation can happen at any point later, it's only the reduction from constraint to bound which was "forgotten". What do you think? |
Also javac does not report an error on line 15 of that test, so that change looks good to me. |
|
the public static void main(String[] args) {
m(
i -> new A<>((C<B<?>>) null),
b -> b.intValue());
}
private static <T, R> void m(Function<B<Integer>, A<T>> f1, Function<T, R> f2) {}
private static class A<T> {
public A(C<? extends C<T>> t) {}
}
private record B<T extends Integer>(T t) implements C<T> {
}
private interface C<T> {
T t();
}which does compile when using |
c98b96f to
8fa14fc
Compare
Given that both compilers agree, should we add that as a negative test? Other than that the PR looks good to go. |
At a second look I see the conflict: the variant with |
|
Something suspicious: I modified the example to be otherwise warning free and to use unique names for type variables: import java.util.function.Function;
public class Test {
public static void main(String[] args) {
C<B<?>> c = null;
m(
_ -> new A<>(c),
b -> b.intValue());
}
static <T, R> void m(Function<B<Number>, A<T>> f1, Function<T, R> f2) {}
static class A<U> {
public A(C<? extends C<U>> t) {}
}
record B<V extends Number>(V t) implements C<V> {
}
interface C<W> {
W t();
}
}Now with the pending fix inference gives: Wait a minute: two different inference variables are instantiated to the same capture? Is this legal? 2 Experiments:
I asked for clarification: https://mail.openjdk.org/pipermail/compiler-dev/2025-October/031848.html |
public static void main(String[] args) {
C<B<?>> c = null;
m(
a -> new A<>(c),
b -> b.intValue());
}
static <T, R> void m(Function<B<Number>, A<T>> f1, Function<T, R> f2) {}
static class A<U> {
public A(C<? extends C<? extends U>> t) {}
}
record B<V extends Number>(V t) implements C<V> {
}
interface C<W> {
W t();
}Changing I think javac is trying to avoid having |
Interesting. With the initial answer in https://mail.openjdk.org/pipermail/compiler-dev/2025-October/031850.html and your latest variant of the test case I'm leaning towards the following conclusion:
I'll wait if Vicente has some additional news for us. Otherwise I'll just add the two mentioned variants of the test and merge the change. |
8fa14fc to
c0ca54b
Compare
f9a8027 to
7c5754a
Compare
|
I believe we have achieved the best feasible solution here. |
What it does
Fixes #4314 by solving the b2 bound set prior to using it for the b3 bound set when the class of the method isn't
ParameterizedGenericMethodBindingThe removed error from the existing test seems to be originally caused by the b3 bound set (which succeeded without solving the b2 bound set)
How to test
Attempt to compile the test case
Author checklist