Skip to content

Commit 9ee5bfa

Browse files
Align inference resolution with javac by applying hints from Maurizio
remove our own tweak from commit ad3653e
1 parent 6f7152f commit 9ee5bfa

2 files changed

Lines changed: 29 additions & 49 deletions

File tree

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -315,7 +315,7 @@ else if (type.hasNullTypeAnnotations())
315315
* <dl>
316316
* <dt>captures<dd>IC18.resumeSuspendedInference() will reset these to avoid captures from nested
317317
* inference spilling blindly into the current inference.<br>
318-
* {@link InferenceContext18#collectDependencies(BoundSet, boolean, boolean[])} considers only "local" {@link #captures}.
318+
* {@link InferenceContext18#collectDependencies(BoundSet)} considers only "local" {@link #captures}.
319319
* <dt>allCaptures<dd>Still {@link #hasCaptureBound(Set)} and {@link #incorporate(InferenceContext18)} will
320320
* operate on {@link #allCaptures}.
321321
*/

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

Lines changed: 28 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -430,7 +430,7 @@ public BoundSet inferInvocationType(TypeBinding expectedType, InvocationSite inv
430430
return null;
431431
// 5. bullet: determine B4 from C
432432
while (!c.isEmpty()) {
433-
Map<InferenceVariable,Set<InferenceVariable>> dependencies = collectDependencies(this.currentBounds, false, new boolean[1]);
433+
Map<InferenceVariable,Set<InferenceVariable>> dependencies = collectDependencies(this.currentBounds);
434434
List<Set<InferenceVariable>> components = new ArrayList<>(dependencies.values());
435435
// *
436436
Set<ConstraintFormula> bottomSet = findBottomSet(c, allOutputVariables(c), components);
@@ -1152,13 +1152,6 @@ public boolean reduceAndIncorporate(ConstraintFormula constraint) throws Inferen
11521152
private /*@Nullable*/ BoundSet resolve(
11531153
InferenceVariable[] toResolve,
11541154
boolean isRecordPatternTypeInference) throws InferenceFailureException {
1155-
return resolve(toResolve, isRecordPatternTypeInference, true);
1156-
}
1157-
private /*@Nullable*/ BoundSet resolve(
1158-
InferenceVariable[] toResolve,
1159-
boolean isRecordPatternTypeInference,
1160-
boolean maySkipSuperBound) throws InferenceFailureException {
1161-
11621155
this.captureId = 0;
11631156
// NOTE: 18.5.2 ...
11641157
// "(While it was necessary to demonstrate that the inference variables in B1 could be resolved
@@ -1169,8 +1162,7 @@ public boolean reduceAndIncorporate(ConstraintFormula constraint) throws Inferen
11691162
Set<InferenceVariable> toResolveSet = new LinkedHashSet<>(Arrays.asList(toResolve));
11701163
// find a minimal set of dependent variables:
11711164
Set<InferenceVariable> variableSet;
1172-
boolean[] hasSkippedSuperBound = { false };
1173-
while ((variableSet = getSmallestVariableSet(tmpBoundSet, toResolveSet, false, hasSkippedSuperBound)) != null) {
1165+
while ((variableSet = getSmallestVariableSet(tmpBoundSet, toResolveSet)) != null) {
11741166
int oldNumUninstantiated = tmpBoundSet.numUninstantiatedVariables(this.inferenceVariables);
11751167
List<InferenceVariable> ofRank;
11761168
while ((ofRank = pickIvarsByRank(variableSet, tmpBoundSet)) != null) {
@@ -1239,9 +1231,6 @@ public boolean reduceAndIncorporate(ConstraintFormula constraint) throws Inferen
12391231
continue;
12401232
tmpBoundSet = prevBoundSet;// clean-up for second attempt
12411233
}
1242-
1243-
if (maySkipSuperBound && hasSkippedSuperBound[0])
1244-
return resolve(toResolve, isRecordPatternTypeInference, false);
12451234
// Otherwise, a second attempt is made...
12461235
Sorting.sortInferenceVariables(variables); // ensure stability of capture IDs
12471236
final CaptureBinding18[] zs = new CaptureBinding18[numVars];
@@ -1432,11 +1421,11 @@ public int compare(TypeBinding o1, TypeBinding o2) {
14321421
* Find the smallest set of uninstantiated inference variables not depending
14331422
* on any uninstantiated variable outside the set.
14341423
*/
1435-
public Set<InferenceVariable> getSmallestVariableSet(BoundSet bounds, Set<InferenceVariable> subSet, boolean maySkipSuperBound, boolean[] hasSkippedSuperBound) {
1424+
public Set<InferenceVariable> getSmallestVariableSet(BoundSet bounds, Set<InferenceVariable> subSet) {
14361425
// "Given a set of inference variables to resolve, let V be the union of this set and
14371426
// all variables upon which the resolution of at least one variable in this set depends."
14381427
Set<InferenceVariable> v = new LinkedHashSet<>(subSet);
1439-
Map<InferenceVariable,Set<InferenceVariable>> dependencies = collectDependencies(bounds, maySkipSuperBound, hasSkippedSuperBound);
1428+
Map<InferenceVariable,Set<InferenceVariable>> dependencies = collectDependencies(bounds);
14401429
for (InferenceVariable iv : subSet) {
14411430
Set<InferenceVariable> tmp = dependencies.get(iv);
14421431
if (tmp != null)
@@ -1497,11 +1486,9 @@ static List<InferenceVariable> pickIvarsByRank(Set<InferenceVariable> variableSe
14971486
/**
14981487
* Collect dependencies of all our ivars based on TypeBounds of 'bounds'
14991488
* @param bounds consider all its TypeBounds
1500-
* @param maySkipSuperBound if true, then α :> β bounds will not be treated as a dependency from α to β (only the inverse)
1501-
* @param hasSkippedSuperBound output parameter to signal to the caller if maySkipSuperBound has been used
15021489
* @return a map from an ivar to the set of all its dependencies including itself.
15031490
*/
1504-
Map<InferenceVariable,Set<InferenceVariable>> collectDependencies(BoundSet bounds, boolean maySkipSuperBound, boolean[] hasSkippedSuperBound) {
1491+
Map<InferenceVariable,Set<InferenceVariable>> collectDependencies(BoundSet bounds) {
15051492
// Implements the definition of dependencies from JLS §18.4:
15061493
Map<InferenceVariable,Set<InferenceVariable>> dependsOn = new LinkedHashMap<>();
15071494
// "An inference variable α depends on the resolution of itself."
@@ -1517,38 +1504,31 @@ Map<InferenceVariable,Set<InferenceVariable>> collectDependencies(BoundSet bound
15171504
// T = α -- encoded as α = T
15181505
// T <: α -- encoded as α :> T
15191506
for (int i=0; i<2; i++) { // 2 attempts, reading the bound left-to-right, then right-to-left
1520-
if (maySkipSuperBound && typeBound.relation == ReductionResult.SUPERTYPE && typeBound.right instanceof InferenceVariable) {
1521-
// NON-JLS: first try to ignore any dependencies resulting from a supertype bound,
1522-
// i.e., given α :> β do not consider α to depend on β
1523-
hasSkippedSuperBound[0] = true; // signal the application of this tweak to upstream,
1524-
// so they can retry with the tweak disabled (maySkip=false)
1525-
} else {
1526-
Set<InferenceVariable> betas = new LinkedHashSet<>();
1527-
typeBound.right.collectInferenceVariables(betas);
1528-
if (!betas.isEmpty()) {
1529-
InferenceVariable alpha = typeBound.left;
1530-
// Determine the direction of dependencies to add:
1531-
// "If α appears on the left-hand side of another bound of the form G<..., α, ...> = capture(G<...>),
1532-
// then β depends on the resolution of α. Otherwise, α depends on the resolution of β."
1533-
boolean alphaDependsOnBeta = true;
1534-
captureTest: for (ParameterizedTypeBinding gCap : bounds.captures.keySet()) {
1535-
for (TypeBinding arg : gCap.arguments) {
1536-
if (TypeBinding.equalsEquals(arg, alpha)) {
1537-
alphaDependsOnBeta = false;
1538-
break captureTest;
1539-
}
1507+
Set<InferenceVariable> betas = new LinkedHashSet<>();
1508+
typeBound.right.collectInferenceVariables(betas);
1509+
if (!betas.isEmpty()) {
1510+
InferenceVariable alpha = typeBound.left;
1511+
// Determine the direction of dependencies to add:
1512+
// "If α appears on the left-hand side of another bound of the form G<..., α, ...> = capture(G<...>),
1513+
// then β depends on the resolution of α. Otherwise, α depends on the resolution of β."
1514+
boolean alphaDependsOnBeta = true;
1515+
captureTest: for (ParameterizedTypeBinding gCap : bounds.captures.keySet()) {
1516+
for (TypeBinding arg : gCap.arguments) {
1517+
if (TypeBinding.equalsEquals(arg, alpha)) {
1518+
alphaDependsOnBeta = false;
1519+
break captureTest;
15401520
}
15411521
}
1542-
if (alphaDependsOnBeta) {
1543-
Set<InferenceVariable> deps = dependsOn.computeIfAbsent(alpha, iv -> new LinkedHashSet<>());
1544-
deps.addAll(betas);
1545-
deps.add(alpha); // add self-dependency, alpha might not yet be recorded if its from inner inference
1546-
} else {
1547-
for (InferenceVariable beta : betas) {
1548-
Set<InferenceVariable> deps = dependsOn.computeIfAbsent(beta, iv -> new LinkedHashSet<>());
1549-
deps.add(alpha);
1550-
deps.add(beta); // add self-dependency, beta might not yet be recorded if its from inner inference
1551-
}
1522+
}
1523+
if (alphaDependsOnBeta) {
1524+
Set<InferenceVariable> deps = dependsOn.computeIfAbsent(alpha, iv -> new LinkedHashSet<>());
1525+
deps.addAll(betas);
1526+
deps.add(alpha); // add self-dependency, alpha might not yet be recorded if its from inner inference
1527+
} else {
1528+
for (InferenceVariable beta : betas) {
1529+
Set<InferenceVariable> deps = dependsOn.computeIfAbsent(beta, iv -> new LinkedHashSet<>());
1530+
deps.add(alpha);
1531+
deps.add(beta); // add self-dependency, beta might not yet be recorded if its from inner inference
15521532
}
15531533
}
15541534
}

0 commit comments

Comments
 (0)