Skip to content

Commit 1e41295

Browse files
ClassCastException with array as wildcard generic parameter (eclipse-jdt#2832)
avoid the bogus cast fixes eclipse-jdt#2817
1 parent e743aee commit 1e41295

File tree

5 files changed

+40
-13
lines changed

5 files changed

+40
-13
lines changed

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

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -284,15 +284,15 @@ public void initializeBounds(Scope scope, ParameterizedTypeBinding capturedParam
284284
}
285285
}
286286
@Override
287-
public ReferenceBinding upwardsProjection(Scope scope, TypeBinding[] mentionedTypeVariables) {
287+
public TypeBinding upwardsProjection(Scope scope, TypeBinding[] mentionedTypeVariables) {
288288
if (enterRecursiveProjectionFunction()) {
289289
try {
290290
for (TypeBinding mentionedTypeVariable : mentionedTypeVariables) {
291291
if (TypeBinding.equalsEquals(this, mentionedTypeVariable)) {
292292
TypeBinding upperBoundForProjection = this.upperBoundForProjection();
293293
if (upperBoundForProjection == null)
294294
upperBoundForProjection = scope.getJavaLangObject();
295-
return ((ReferenceBinding)upperBoundForProjection).upwardsProjection(scope, mentionedTypeVariables);
295+
return upperBoundForProjection.upwardsProjection(scope, mentionedTypeVariables);
296296
}
297297
}
298298
return this;
@@ -535,13 +535,13 @@ public TypeBinding uncapture(Scope scope) {
535535
}
536536

537537
@Override
538-
public ReferenceBinding downwardsProjection(Scope scope, TypeBinding[] mentionedTypeVariables) {
539-
ReferenceBinding result = null;
538+
public TypeBinding downwardsProjection(Scope scope, TypeBinding[] mentionedTypeVariables) {
539+
TypeBinding result = null;
540540
if (enterRecursiveProjectionFunction()) {
541541
for (TypeBinding mentionedTypeVariable : mentionedTypeVariables) {
542542
if (TypeBinding.equalsEquals(this, mentionedTypeVariable)) {
543543
if (this.lowerBound != null) {
544-
result = (ReferenceBinding) this.lowerBound.downwardsProjection(scope, mentionedTypeVariables);
544+
result = this.lowerBound.downwardsProjection(scope, mentionedTypeVariables);
545545
}
546546
break;
547547
}

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

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -348,7 +348,11 @@ void collectInferenceVariables(Set<InferenceVariable> variables) {
348348
public ReferenceBinding upwardsProjection(Scope scope, TypeBinding[] mentionedTypeVariables) {
349349
ReferenceBinding[] projectedTypes = new ReferenceBinding[this.intersectingTypes.length];
350350
for (int i = 0; i < this.intersectingTypes.length; ++i) {
351-
projectedTypes[i] = this.intersectingTypes[i].upwardsProjection(scope, mentionedTypeVariables);
351+
TypeBinding projected = this.intersectingTypes[i].upwardsProjection(scope, mentionedTypeVariables);
352+
if (projected instanceof ReferenceBinding refBinding)
353+
projectedTypes[i] = refBinding;
354+
else
355+
return null;
352356
}
353357
return (ReferenceBinding) scope.environment().createIntersectionType18(projectedTypes);
354358
}
@@ -357,10 +361,11 @@ public ReferenceBinding upwardsProjection(Scope scope, TypeBinding[] mentionedTy
357361
public ReferenceBinding downwardsProjection(Scope scope, TypeBinding[] mentionedTypeVariables) {
358362
ReferenceBinding[] projectedTypes = new ReferenceBinding[this.intersectingTypes.length];
359363
for (int i = 0; i < this.intersectingTypes.length; ++i) {
360-
ReferenceBinding projected = this.intersectingTypes[i].downwardsProjection(scope, mentionedTypeVariables);
361-
if (projected == null)
364+
TypeBinding projected = this.intersectingTypes[i].downwardsProjection(scope, mentionedTypeVariables);
365+
if (projected instanceof ReferenceBinding refBind)
366+
projectedTypes[i] = refBind;
367+
else
362368
return null;
363-
projectedTypes[i] = projected;
364369
}
365370
return (ReferenceBinding) scope.environment().createIntersectionType18(projectedTypes);
366371
}

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

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2050,7 +2050,8 @@ public char[] sourceName() {
20502050
* @return Upwards type projection of 'this', or null if downwards projection is undefined
20512051
*/
20522052
@Override
2053-
public ReferenceBinding upwardsProjection(Scope scope, TypeBinding[] mentionedTypeVariables) {
2053+
public TypeBinding upwardsProjection(Scope scope, TypeBinding[] mentionedTypeVariables) {
2054+
// Note: return type remains as TypeBinding, because subclass CaptureBinding may return an ArrayBinding :(
20542055
return this;
20552056
}
20562057

@@ -2061,7 +2062,8 @@ public ReferenceBinding upwardsProjection(Scope scope, TypeBinding[] mentionedTy
20612062
* @return Downwards type projection of 'this', or null if downwards projection is undefined
20622063
*/
20632064
@Override
2064-
public ReferenceBinding downwardsProjection(Scope scope, TypeBinding[] mentionedTypeVariables) {
2065+
public TypeBinding downwardsProjection(Scope scope, TypeBinding[] mentionedTypeVariables) {
2066+
// Note: return type remains as TypeBinding, because subclass CaptureBinding may return an ArrayBinding :(
20652067
return this;
20662068
}
20672069

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1205,12 +1205,12 @@ public boolean isFreeTypeVariable() {
12051205
}
12061206

12071207
@Override
1208-
public ReferenceBinding upwardsProjection(Scope scope, TypeBinding[] mentionedTypeVariables) {
1208+
public TypeBinding upwardsProjection(Scope scope, TypeBinding[] mentionedTypeVariables) {
12091209
return this;
12101210
}
12111211

12121212
@Override
1213-
public ReferenceBinding downwardsProjection(Scope scope, TypeBinding[] mentionedTypeVariables) {
1213+
public TypeBinding downwardsProjection(Scope scope, TypeBinding[] mentionedTypeVariables) {
12141214
return this;
12151215
}
12161216

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

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1007,6 +1007,26 @@ public void foo() {
10071007
+ "----------\n",
10081008
null, true, options);
10091009
}
1010+
public void testGH2817() {
1011+
Runner runner = new Runner();
1012+
runner.testFiles = new String[] {
1013+
"Test.java",
1014+
"""
1015+
class A<T> {}
1016+
class B<T> {}
1017+
1018+
public interface Test {
1019+
<T> void use(T t, B<? super T> b);
1020+
<T> B<A<? super T>> create();
1021+
1022+
default void test() {
1023+
use(new A<Object[]>(), create());
1024+
}
1025+
}
1026+
"""
1027+
};
1028+
runner.runConformTest();
1029+
}
10101030
public static Class<GenericsRegressionTest_9> testClass() {
10111031
return GenericsRegressionTest_9.class;
10121032
}

0 commit comments

Comments
 (0)