Skip to content

Commit

Permalink
ClassCastException with array as wildcard generic parameter
Browse files Browse the repository at this point in the history
avoid the bogus cast

fixes eclipse-jdt#2817
  • Loading branch information
stephan-herrmann committed Sep 24, 2024
1 parent 59bc0be commit 35f6996
Show file tree
Hide file tree
Showing 5 changed files with 40 additions and 13 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -284,15 +284,15 @@ public void initializeBounds(Scope scope, ParameterizedTypeBinding capturedParam
}
}
@Override
public ReferenceBinding upwardsProjection(Scope scope, TypeBinding[] mentionedTypeVariables) {
public TypeBinding upwardsProjection(Scope scope, TypeBinding[] mentionedTypeVariables) {
if (enterRecursiveProjectionFunction()) {
try {
for (TypeBinding mentionedTypeVariable : mentionedTypeVariables) {
if (TypeBinding.equalsEquals(this, mentionedTypeVariable)) {
TypeBinding upperBoundForProjection = this.upperBoundForProjection();
if (upperBoundForProjection == null)
upperBoundForProjection = scope.getJavaLangObject();
return ((ReferenceBinding)upperBoundForProjection).upwardsProjection(scope, mentionedTypeVariables);
return upperBoundForProjection.upwardsProjection(scope, mentionedTypeVariables);
}
}
return this;
Expand Down Expand Up @@ -535,13 +535,13 @@ public TypeBinding uncapture(Scope scope) {
}

@Override
public ReferenceBinding downwardsProjection(Scope scope, TypeBinding[] mentionedTypeVariables) {
ReferenceBinding result = null;
public TypeBinding downwardsProjection(Scope scope, TypeBinding[] mentionedTypeVariables) {
TypeBinding result = null;
if (enterRecursiveProjectionFunction()) {
for (TypeBinding mentionedTypeVariable : mentionedTypeVariables) {
if (TypeBinding.equalsEquals(this, mentionedTypeVariable)) {
if (this.lowerBound != null) {
result = (ReferenceBinding) this.lowerBound.downwardsProjection(scope, mentionedTypeVariables);
result = this.lowerBound.downwardsProjection(scope, mentionedTypeVariables);
}
break;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -348,7 +348,11 @@ void collectInferenceVariables(Set<InferenceVariable> variables) {
public ReferenceBinding upwardsProjection(Scope scope, TypeBinding[] mentionedTypeVariables) {
ReferenceBinding[] projectedTypes = new ReferenceBinding[this.intersectingTypes.length];
for (int i = 0; i < this.intersectingTypes.length; ++i) {
projectedTypes[i] = this.intersectingTypes[i].upwardsProjection(scope, mentionedTypeVariables);
TypeBinding projected = this.intersectingTypes[i].upwardsProjection(scope, mentionedTypeVariables);
if (projected instanceof ReferenceBinding refBinding)
projectedTypes[i] = refBinding;
else
return null;
}
return (ReferenceBinding) scope.environment().createIntersectionType18(projectedTypes);
}
Expand All @@ -357,10 +361,11 @@ public ReferenceBinding upwardsProjection(Scope scope, TypeBinding[] mentionedTy
public ReferenceBinding downwardsProjection(Scope scope, TypeBinding[] mentionedTypeVariables) {
ReferenceBinding[] projectedTypes = new ReferenceBinding[this.intersectingTypes.length];
for (int i = 0; i < this.intersectingTypes.length; ++i) {
ReferenceBinding projected = this.intersectingTypes[i].downwardsProjection(scope, mentionedTypeVariables);
if (projected == null)
TypeBinding projected = this.intersectingTypes[i].downwardsProjection(scope, mentionedTypeVariables);
if (projected instanceof ReferenceBinding refBind)
projectedTypes[i] = refBind;
else
return null;
projectedTypes[i] = projected;
}
return (ReferenceBinding) scope.environment().createIntersectionType18(projectedTypes);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2050,7 +2050,8 @@ public char[] sourceName() {
* @return Upwards type projection of 'this', or null if downwards projection is undefined
*/
@Override
public ReferenceBinding upwardsProjection(Scope scope, TypeBinding[] mentionedTypeVariables) {
public TypeBinding upwardsProjection(Scope scope, TypeBinding[] mentionedTypeVariables) {
// Note: return type remains as TypeBinding, because subclass CaptureBinding may return an ArrayBinding :(
return this;
}

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

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1205,12 +1205,12 @@ public boolean isFreeTypeVariable() {
}

@Override
public ReferenceBinding upwardsProjection(Scope scope, TypeBinding[] mentionedTypeVariables) {
public TypeBinding upwardsProjection(Scope scope, TypeBinding[] mentionedTypeVariables) {
return this;
}

@Override
public ReferenceBinding downwardsProjection(Scope scope, TypeBinding[] mentionedTypeVariables) {
public TypeBinding downwardsProjection(Scope scope, TypeBinding[] mentionedTypeVariables) {
return this;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1007,6 +1007,26 @@ public void foo() {
+ "----------\n",
null, true, options);
}
public void testGH2817() {
Runner runner = new Runner();
runner.testFiles = new String[] {
"Test.java",
"""
class A<T> {}
class B<T> {}
public interface Test {
<T> void use(T t, B<? super T> b);
<T> B<A<? super T>> create();
default void test() {
use(new A<Object[]>(), create());
}
}
"""
};
runner.runConformTest();
}
public static Class<GenericsRegressionTest_9> testClass() {
return GenericsRegressionTest_9.class;
}
Expand Down

0 comments on commit 35f6996

Please sign in to comment.