Skip to content
Original file line number Diff line number Diff line change
Expand Up @@ -315,7 +315,7 @@ else if (type.hasNullTypeAnnotations())
* <dl>
* <dt>captures<dd>IC18.resumeSuspendedInference() will reset these to avoid captures from nested
* inference spilling blindly into the current inference.<br>
* {@link InferenceContext18#collectDependencies(BoundSet, boolean, boolean[])} considers only "local" {@link #captures}.
* {@link InferenceContext18#collectDependencies(BoundSet)} considers only "local" {@link #captures}.
* <dt>allCaptures<dd>Still {@link #hasCaptureBound(Set)} and {@link #incorporate(InferenceContext18)} will
* operate on {@link #allCaptures}.
*/
Expand All @@ -327,6 +327,7 @@ else if (type.hasNullTypeAnnotations())
private TypeBound[] unincorporatedBounds = new TypeBound[8];
private int unincorporatedBoundsCount = 0;
private final TypeBound[] mostRecentBounds = new TypeBound[4]; // for quick & dirty duplicate elimination
public boolean isRecordPatternInference;

public BoundSet() {}

Expand Down Expand Up @@ -428,12 +429,17 @@ else if (boundNullBits != 0) // combine bits from both sources, even if this cre
three.setInstantiation(typeBinding, variable, environment);
if (bound.right instanceof InferenceVariable) {
// for a dependency between two IVs make a note about the inverse bound.
// this should be needed to determine IV dependencies independent of direction.
// TODO: so far no test could be identified which actually needs it ...
InferenceVariable rightIV = (InferenceVariable) bound.right.prototype();
three = this.boundsPerVariable.get(rightIV);
if (three == null)
this.boundsPerVariable.put(rightIV, (three = new ThreeSets()));
int relation = switch (bound.relation) {
case ReductionResult.SUBTYPE -> ReductionResult.SUPERTYPE;
case ReductionResult.SUPERTYPE -> ReductionResult.SUBTYPE;
case ReductionResult.SAME -> this.isRecordPatternInference ? -1 : ReductionResult.SAME;
default -> -1;
};
if (relation != -1) {
InferenceVariable rightIV = (InferenceVariable) bound.right.prototype();
three = this.boundsPerVariable.computeIfAbsent(rightIV, k -> new ThreeSets());
three.addBound(new TypeBound(rightIV, bound.left, relation, bound.isSoft));
}
}
}
}
Expand Down Expand Up @@ -600,8 +606,11 @@ boolean incorporate(InferenceContext18 context, TypeBound [] first, TypeBound []
mostRecentFormulas[1] = mostRecentFormulas[0];
mostRecentFormulas[0] = newConstraint;

if (!reduceOneConstraint(context, newConstraint))
if (!reduceOneConstraint(context, newConstraint)) {
if (InferenceContext18.DEBUG)
System.out.println("Incorporation failed to reduce new constraint "+newConstraint); //$NON-NLS-1$
return false;
}

if (analyzeNull) {
// not per JLS: if the new constraint relates types where at least one has a null annotations,
Expand All @@ -619,8 +628,11 @@ boolean incorporate(InferenceContext18 context, TypeBound [] first, TypeBound []
}
if (deriveTypeArgumentConstraints) {
for (ConstraintTypeFormula typeArgumentConstraint : deriveTypeArgumentConstraints(bound1, bound2, context)) {
if (!reduceOneConstraint(context, typeArgumentConstraint))
if (!reduceOneConstraint(context, typeArgumentConstraint)) {
if (InferenceContext18.DEBUG)
System.out.println("Incorporation failed to reduce new constraint "+newConstraint); //$NON-NLS-1$
return false;
}
}
}
if (iteration == 2) {
Expand Down Expand Up @@ -722,7 +734,8 @@ protected TypeBinding getP(int i) {
if (InferenceContext18.DEBUG) {
if (!capturesToRemove.isEmpty()) {
for (ParameterizedTypeBinding toRemove : capturesToRemove) {
System.out.println("Removing capture bound " + //$NON-NLS-1$
if (this.captures.containsKey(toRemove))
System.out.println("Removing capture bound " + //$NON-NLS-1$
String.valueOf(toRemove.shortReadableName()) +
"=capture("+String.valueOf(this.captures.get(toRemove).shortReadableName())+")"); //$NON-NLS-1$ //$NON-NLS-2$
}
Expand All @@ -739,11 +752,11 @@ boolean addTypeBoundsFromWildcardBound(InferenceContext18 context, InferenceSubs
ConstraintFormula formula = null;
if (boundKind == Wildcard.EXTENDS) {
if (bi.id == TypeIds.T_JavaLangObject)
formula = ConstraintTypeFormula.create(t, r, ReductionResult.SUBTYPE);
formula = ConstraintTypeFormula.create(t, r, ReductionResult.SUBTYPE, true);
if (t.id == TypeIds.T_JavaLangObject)
formula = ConstraintTypeFormula.create(theta.substitute(theta, bi), r, ReductionResult.SUBTYPE);
formula = ConstraintTypeFormula.create(theta.substitute(theta, bi), r, ReductionResult.SUBTYPE, true);
} else {
formula = ConstraintTypeFormula.create(theta.substitute(theta, bi), r, ReductionResult.SUBTYPE);
formula = ConstraintTypeFormula.create(theta.substitute(theta, bi), r, ReductionResult.SUBTYPE, true);
}
if (formula != null) {
reduceOneConstraint(context, formula);
Expand Down Expand Up @@ -875,7 +888,7 @@ private ConstraintTypeFormula combineEqualSupers(TypeBound boundS, TypeBound bou
innerSame = true; // came in as: S REL α and α REL T imply ⟨S REL T⟩
if (outerSame) {
if (innerSame) // NON-JLS bidirectional subtyping implies equality:
return ConstraintTypeFormula.create(boundS.left, boundS.right, ReductionResult.SAME, false);
return ConstraintTypeFormula.create(boundS.left, boundS.right, ReductionResult.SAME, boundT.isSoft||boundS.isSoft);
return ConstraintTypeFormula.create(boundT.left, boundS.right, boundS.relation, boundT.isSoft||boundS.isSoft);
} else if (innerSame) {
return ConstraintTypeFormula.create(boundS.left, boundT.right, boundS.relation, boundT.isSoft||boundS.isSoft);
Expand Down Expand Up @@ -1070,6 +1083,32 @@ public boolean hasOnlyTrivialExceptionBounds(InferenceVariable variable, TypeBin
return true;
}

public int rankIVar(InferenceVariable ivar) {
// implements the ranking of ivars according to their bounds as explained in
// https://mail.openjdk.org/archives/list/compiler-dev@openjdk.org/message/GN6RTCGMME6I5JVLSFZRIR32XY6QKOI2/
ThreeSets three = this.boundsPerVariable.get(ivar.prototype());
if (three != null) {
if (three.sameBounds != null)
if (!three.sameBounds.isEmpty())
return 1;
if (this.isRecordPatternInference) {
// workaround for not having inverse bounds of type SAME (see addBound(TypeBound, LookupEnvironment)):
for (ThreeSets dep3 : this.boundsPerVariable.values()) {
if (dep3 != null && dep3.sameBounds != null) {
for (TypeBound depBound : dep3.sameBounds) {
if (depBound.right.equals(ivar))
return 1;
}
}
}
}
if (three.superBounds != null)
if (!three.superBounds.isEmpty())
return 2;
}
return 3;
}

/**
* JLS 18.1.3:
* Answer all upper bounds for the given inference variable as defined by any bounds in this set.
Expand Down
Loading
Loading