Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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