Skip to content

Commit 7f34a62

Browse files
Compilation error with generics in 2025-09
don't persist captured PTB.superInterfaces eclipse-jdt#4402
1 parent 331f142 commit 7f34a62

3 files changed

Lines changed: 78 additions & 1 deletion

File tree

org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/lookup/CapturingContext.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,4 +64,8 @@ public static ReferenceBinding maybeCapture(ReferenceBinding type) {
6464
}
6565
return type;
6666
}
67+
68+
public static boolean isActive() {
69+
return activeContexts.get() != null;
70+
}
6771
}

org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/lookup/ParameterizedTypeBinding.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1552,12 +1552,18 @@ public ReferenceBinding[] superInterfaces() {
15521552
this.superInterfaces = Scope.substitute(this, this.type.superInterfaces());
15531553
if (this.superInterfaces != null) {
15541554
for (int i = this.superInterfaces.length; --i >= 0;) {
1555-
this.superInterfaces[i] = CapturingContext.maybeCapture(this.superInterfaces[i]);
15561555
this.typeBits |= (this.superInterfaces[i].typeBits & TypeIds.InheritableBits);
15571556
if ((this.typeBits & (TypeIds.BitAutoCloseable|TypeIds.BitCloseable)) != 0) // avoid the side-effects of hasTypeBit()!
15581557
this.typeBits |= applyCloseableWhitelists(this.environment.globalOptions);
15591558
}
15601559
}
1560+
}
1561+
if (CapturingContext.isActive()) {
1562+
ReferenceBinding[] captured = new ReferenceBinding[this.superInterfaces.length];
1563+
for (int i = 0; i < captured.length; i++) {
1564+
captured[i] = CapturingContext.maybeCapture(this.superInterfaces[i]);
1565+
}
1566+
return captured;
15611567
}
15621568
return this.superInterfaces;
15631569
}

org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/GenericsRegressionTest_9.java

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1492,6 +1492,73 @@ public <U extends T> U getProcess(Object object) {
14921492
}
14931493
"""});
14941494
}
1495+
public void testGH4402() {
1496+
runConformTest(new String[] {
1497+
"Main.java",
1498+
"""
1499+
import java.util.Collection;
1500+
1501+
public class Main {
1502+
1503+
void test() {
1504+
ArrayNode results = new ArrayNode();
1505+
1506+
// those first two compile fine
1507+
assertThat(results, jsonArray(empty()));
1508+
assertThat(results, jsonArray(contains(jsonObject().where("Id", jsonText("dataset-a")),
1509+
jsonObject().where("Id", jsonText("dataset-b")))));
1510+
/*
1511+
* this one fails compilation:
1512+
* The method jsonArray(Main.Matcher<? super Collection<? extends Main.JsonNode>>) in the type Main is not applicable for the arguments (Main.Matcher<Iterable<? extends capture#3-of ? extends Main.JsonNode>>)
1513+
*
1514+
* However it will compile fine if I comment out lines 12-13
1515+
*/
1516+
assertThat(results, jsonArray(contains(jsonObject().where("Id", jsonText("dataset-c")))));
1517+
/*
1518+
* this one fails compilation:
1519+
* The method jsonArray(Main.Matcher<? super Collection<? extends Main.JsonNode>>) in the type Main is not applicable for the arguments (Main.Matcher<Iterable<? extends capture#3-of ? extends Main.JsonNode>>)
1520+
*
1521+
* However it will compile fine if I comment out lines 12-13 AND 20
1522+
*/
1523+
assertThat(results, jsonArray(contains(jsonObject().where("Id", jsonText("dataset-@1")),
1524+
jsonObject().where("Id", jsonText("dataset-@2")))));
1525+
}
1526+
1527+
public static abstract class JsonNode { }
1528+
public static class ArrayNode extends ContainerNode<ArrayNode> { }
1529+
public static abstract class ContainerNode<T extends ContainerNode<T>> extends JsonNode { }
1530+
public class ObjectNode extends ContainerNode<ObjectNode> { }
1531+
public class TextNode extends JsonNode { }
1532+
public interface Matcher<T> { }
1533+
1534+
public static <E> Matcher<java.util.Collection<? extends E>> empty() { return null; }
1535+
1536+
public static <T> void assertThat(T actual, Matcher<? super T> matcher) { }
1537+
1538+
@SafeVarargs
1539+
public static <E> Matcher<java.lang.Iterable<? extends E>> contains(Matcher<? super E>... itemMatchers) { return null; }
1540+
1541+
public static Matcher<JsonNode> jsonArray(Matcher<? super Collection<? extends JsonNode>> elementsMatcher) { return null; }
1542+
1543+
public static IsJsonObject jsonObject() { return null; }
1544+
1545+
public static Matcher<JsonNode> jsonText(String text) { return null; }
1546+
1547+
public static class IsJsonArray extends AbstractJsonNodeMatcher<ArrayNode> { }
1548+
1549+
public static class IsJsonObject extends AbstractJsonNodeMatcher<ObjectNode> {
1550+
public IsJsonObject where(String key, Matcher<? super JsonNode> valueMatcher) {
1551+
return null;
1552+
}
1553+
}
1554+
1555+
public static class IsJsonText extends AbstractJsonNodeMatcher<TextNode> { }
1556+
public static abstract class AbstractJsonNodeMatcher<A extends JsonNode> implements Matcher<JsonNode> { }
1557+
}
1558+
"""
1559+
},
1560+
"");
1561+
}
14951562
public static Class<GenericsRegressionTest_9> testClass() {
14961563
return GenericsRegressionTest_9.class;
14971564
}

0 commit comments

Comments
 (0)