Skip to content

Commit

Permalink
Bring back a simpler (cheaper) approach to BoundSet::incorporate ecli…
Browse files Browse the repository at this point in the history
…pse-jdt#3227

This simple approach was faster than the new one but it didn't cover
some very specific use cases, which is why the newer and more complex
(slower) approach was introduced. This commit brings back the older,
simpler, approach and falls back to the newer, more expensive, approach
only when necessary.

Reduce the visibility of BoundSet::allSuperPairsWithCommonGenericType
from protected to private too.

Fixes eclipse-jdt#3327
  • Loading branch information
fedejeanne committed Nov 21, 2024
1 parent 6b53bf4 commit e6ad65c
Showing 1 changed file with 52 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -615,12 +615,23 @@ boolean incorporate(InferenceContext18 context, TypeBound [] first, TypeBound []
}
}
}

if (deriveTypeArgumentConstraints) {
for (ConstraintTypeFormula typeArgumentConstraint : deriveTypeArgumentConstraints(bound1, bound2, context)) {
if (!reduceOneConstraint(context, typeArgumentConstraint))
return false;
// Try with a simpler (cheaper) approach first
for (ConstraintFormula cf : deriveTypeArgumentConstraintsSimple(bound1, bound2)) {
if (reduceOneConstraint(context, cf)) {
// No need to keep searching, the simple strategy worked
continue;
}

// If the simple search failed, try with a more complex (and expensive) search
for (ConstraintTypeFormula cf2 : deriveTypeArgumentConstraints(bound1, bound2, context)) {
if (!reduceOneConstraint(context, cf2))
return false;
}
}
}

if (iteration == 2) {
TypeBound boundX = bound1;
bound1 = bound2;
Expand Down Expand Up @@ -939,6 +950,43 @@ private ConstraintTypeFormula combineWithProperTypes(Collection<TypeBound> prope
return ConstraintTypeFormula.create(left, right, boundRight.relation, isAnyLeftSoft||boundRight.isSoft);
}

private List<ConstraintTypeFormula> deriveTypeArgumentConstraintsSimple(TypeBound boundS, TypeBound boundT) {
/* From 18.4:
* If two bounds have the form α <: S and α <: T, and if for some generic class or interface, G,
* there exists a supertype (4.10) of S of the form G<S1, ..., Sn> and a supertype of T of the form G<T1, ..., Tn>,
* then for all i, 1 ≤ i ≤ n, if Si and Ti are types (not wildcards), the constraint ⟨Si = Ti⟩ is implied.
*/
// callers must ensure both relations are <: and both lefts are equal
TypeBinding[] supers = superTypesWithCommonGenericType(boundS.right, boundT.right);
if (supers != null)
return typeArgumentEqualityConstraints(supers[0], supers[1], boundS.isSoft || boundT.isSoft);
return Collections.emptyList();
}

private TypeBinding[] superTypesWithCommonGenericType(TypeBinding s, TypeBinding t) {
if (s == null || s.id == TypeIds.T_JavaLangObject || t == null || t.id == TypeIds.T_JavaLangObject)
return null;
if (TypeBinding.equalsEquals(s.original(), t.original())) {
return new TypeBinding[] { s, t };
}
TypeBinding tSuper = t.findSuperTypeOriginatingFrom(s);
if (tSuper != null) {
return new TypeBinding[] {s, tSuper};
}
TypeBinding[] result = superTypesWithCommonGenericType(s.superclass(), t);
if (result != null)
return result;
ReferenceBinding[] superInterfaces = s.superInterfaces();
if (superInterfaces != null) {
for (ReferenceBinding superInterface : superInterfaces) {
result = superTypesWithCommonGenericType(superInterface, t);
if (result != null)
return result;
}
}
return null;
}

private List<ConstraintTypeFormula> deriveTypeArgumentConstraints(TypeBound boundS, TypeBound boundT, InferenceContext18 context) {
/* From 18.4:
* If two bounds have the form α <: S and α <: T, and if for some generic class or interface, G,
Expand Down Expand Up @@ -1263,7 +1311,7 @@ private boolean superOnlyRaw(TypeBinding g, TypeBinding s, LookupEnvironment env
return false;
}

protected List<Pair<TypeBinding>> allSuperPairsWithCommonGenericType(TypeBinding s, TypeBinding t) {
private List<Pair<TypeBinding>> allSuperPairsWithCommonGenericType(TypeBinding s, TypeBinding t) {
if (s == null || s.id == TypeIds.T_JavaLangObject || t == null || t.id == TypeIds.T_JavaLangObject)
return Collections.emptyList();
List<Pair<TypeBinding>> result = new ArrayList<>();
Expand Down

0 comments on commit e6ad65c

Please sign in to comment.