Skip to content

Commit bcdba5d

Browse files
Valid java code with multiple upper bounded type parameter with wildcards gives "cannot be implemented more than once with different arguments" (#4554)
weaken this particular check, to admit pairs of equivalent wildcards at the same rank (at any nesting level) #4463
1 parent 1baf91d commit bcdba5d

File tree

2 files changed

+75
-3
lines changed
  • org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/lookup
  • org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression

2 files changed

+75
-3
lines changed

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

Lines changed: 38 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3731,15 +3731,50 @@ public boolean hasErasedCandidatesCollisions(TypeBinding one, TypeBinding two, M
37313731
Object value = invocations.get(mec);
37323732
if (value instanceof TypeBinding[]) {
37333733
TypeBinding[] invalidInvocations = (TypeBinding[]) value;
3734-
problemReporter().superinterfacesCollide(invalidInvocations[0].erasure(), typeRef, invalidInvocations[0], invalidInvocations[1]);
3735-
type.tagBits |= TagBits.HierarchyHasProblems;
3736-
return true;
3734+
if (areSignificantlyDifferent(invalidInvocations[0], invalidInvocations[1])) {
3735+
problemReporter().superinterfacesCollide(invalidInvocations[0].erasure(), typeRef, invalidInvocations[0], invalidInvocations[1]);
3736+
type.tagBits |= TagBits.HierarchyHasProblems;
3737+
return true;
3738+
}
37373739
}
37383740
}
37393741
}
37403742
return false;
37413743
}
37423744

3745+
private boolean areSignificantlyDifferent(TypeBinding one, TypeBinding two) {
3746+
if (!one.enterRecursiveFunction())
3747+
return true;
3748+
try {
3749+
if (one instanceof ParameterizedTypeBinding ptb1 && two instanceof ParameterizedTypeBinding ptb2) {
3750+
if (TypeBinding.notEquals(ptb1.erasure(), ptb2.erasure()))
3751+
return true;
3752+
return areSignificantlyDifferent(ptb1.arguments, ptb2.arguments);
3753+
} else if (one instanceof WildcardBinding wb1 && two instanceof WildcardBinding wb2) {
3754+
if (wb1.boundKind() != wb2.boundKind())
3755+
return true;
3756+
if (TypeBinding.notEquals(wb1.bound, wb2.bound))
3757+
return true;
3758+
return areSignificantlyDifferent(wb1.otherBounds, wb2.otherBounds);
3759+
}
3760+
return TypeBinding.notEquals(one, two);
3761+
} finally {
3762+
one.exitRecursiveFunction();
3763+
}
3764+
}
3765+
3766+
private boolean areSignificantlyDifferent(TypeBinding[] ones, TypeBinding[] twos) {
3767+
if (ones == null || twos == null)
3768+
return ones != twos;
3769+
if (ones.length != twos.length)
3770+
return true;
3771+
for (int i = 0; i < ones.length; i++) {
3772+
if (areSignificantlyDifferent(ones[i], twos[i]))
3773+
return true;
3774+
}
3775+
return false; // no significant difference found
3776+
}
3777+
37433778
/**
37443779
* Returns the immediately enclosing case statement (carried by closest blockScope),
37453780
*/

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

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1781,6 +1781,43 @@ String getValue() {
17811781
----------
17821782
""");
17831783
}
1784+
public void testGH4463() {
1785+
runConformTest(new String[] {
1786+
"A.java",
1787+
"""
1788+
interface A<T> {}
1789+
interface B<T> extends A<T> {}
1790+
interface C<T> extends A<T> {}
1791+
1792+
class BC1 implements B<String>, C<String> {}
1793+
class BC2 implements B<Integer>, C<Integer> {}
1794+
1795+
// Eclipse Compile error "The interface A cannot be implemented more than once with different arguments: A<?> and A<?>"
1796+
interface IHelperBC<T extends B<?> & C<?>> {}
1797+
1798+
class HelperBC1 implements IHelperBC<BC1> {}
1799+
class HelperBC2 implements IHelperBC<BC2> {}
1800+
"""
1801+
});
1802+
}
1803+
public void testGH4463b() {
1804+
runConformTest(new String[] {
1805+
"A.java",
1806+
"""
1807+
interface A<T> {}
1808+
interface B<T> extends A<T> {}
1809+
interface C<T> extends A<T> {}
1810+
1811+
class BC1 implements B<String>, C<String> {}
1812+
class BC2 implements B<Integer>, C<Integer> {}
1813+
1814+
// eclipse compile error "The interface A cannot be implemented more than once with different arguments: A<? super T> and A<? super T>"
1815+
interface IHelperBCSuper<T, BC extends B<? super T> & C<? super T>> {}
1816+
// eclipse compile error "The interface A cannot be implemented more than once with different arguments: A<? extends T> and A<? extends T>"
1817+
interface IHelperBCExtends<T, BC extends B<? extends T> & C<? extends T>> {}
1818+
"""
1819+
});
1820+
}
17841821
public static Class<GenericsRegressionTest_9> testClass() {
17851822
return GenericsRegressionTest_9.class;
17861823
}

0 commit comments

Comments
 (0)