1616
1717import java .util .*;
1818import java .util .Map .Entry ;
19+ import java .util .stream .Collectors ;
1920import org .eclipse .jdt .core .compiler .CharOperation ;
2021import org .eclipse .jdt .internal .compiler .ast .*;
2122import org .eclipse .jdt .internal .compiler .lookup .TypeConstants .BoundCheckStatus ;
@@ -1169,19 +1170,14 @@ public boolean reduceAndIncorporate(ConstraintFormula constraint) throws Inferen
11691170 // find a minimal set of dependent variables:
11701171 Set <InferenceVariable > variableSet ;
11711172 boolean [] hasSkippedSuperBound = { false };
1172- while ((variableSet = getSmallestVariableSet (tmpBoundSet , toResolveSet , maySkipSuperBound , hasSkippedSuperBound )) != null ) {
1173+ while ((variableSet = getSmallestVariableSet (tmpBoundSet , toResolveSet , false , hasSkippedSuperBound )) != null ) {
11731174 int oldNumUninstantiated = tmpBoundSet .numUninstantiatedVariables (this .inferenceVariables );
1174- final int numVars = variableSet .size ();
1175- if (numVars > 0 ) {
1176- final InferenceVariable [] variables = variableSet .toArray (new InferenceVariable [numVars ]);
1177- // NON-JLS: prioritize ivars in 'inThrows' as those may pull in new information by extra rule below (=RuntimeException)
1178- BoundSet tSet = tmpBoundSet ;
1179- Arrays .sort (variables , (v1 , v2 ) -> {
1180- int r1 = tSet .inThrows .contains (v1 ) ? -1 : 0 ;
1181- int r2 = tSet .inThrows .contains (v2 ) ? -1 : 0 ;
1182- return r1 - r2 ;
1183- });
1184- //
1175+ List <InferenceVariable > ofRank ;
1176+ while ((ofRank = pickIvarsByRank (variableSet , tmpBoundSet )) != null ) {
1177+ final int numVars = ofRank .size ();
1178+ if (numVars == 0 )
1179+ continue ;
1180+ final InferenceVariable [] variables = ofRank .toArray (new InferenceVariable [numVars ]);
11851181 variables : if (!isRecordPatternTypeInference && !tmpBoundSet .hasCaptureBound (variableSet )) {
11861182 // try to instantiate this set of variables in a fresh copy of the bound set:
11871183 BoundSet prevBoundSet = tmpBoundSet ;
@@ -1190,6 +1186,7 @@ public boolean reduceAndIncorporate(ConstraintFormula constraint) throws Inferen
11901186 InferenceVariable variable = variables [j ];
11911187 if (tmpBoundSet .isInstantiated (variable )) { // NON-JLS: may happen when exception bound has been incorporated
11921188 toResolveSet .remove (variable );
1189+ variableSet .remove (variable );
11931190 continue ;
11941191 }
11951192 // try lower bounds:
@@ -1236,11 +1233,13 @@ public boolean reduceAndIncorporate(ConstraintFormula constraint) throws Inferen
12361233 }
12371234 }
12381235 toResolveSet .remove (variable );
1236+ variableSet .remove (variable );
12391237 }
12401238 if (tmpBoundSet .incorporate (this ))
12411239 continue ;
12421240 tmpBoundSet = prevBoundSet ;// clean-up for second attempt
12431241 }
1242+
12441243 if (maySkipSuperBound && hasSkippedSuperBound [0 ])
12451244 return resolve (toResolve , isRecordPatternTypeInference , false );
12461245 // Otherwise, a second attempt is made...
@@ -1348,6 +1347,7 @@ public TypeBinding substitute(TypeVariableBinding typeVariable) {
13481347 if (!typeboundCreated )
13491348 tmpBoundSet .addBound (new TypeBound (variable , zsj , ReductionResult .SAME ), this .environment );
13501349 toResolveSet .remove (variable );
1350+ variableSet .remove (variable );
13511351 }
13521352 if (tmpBoundSet .incorporate (this )) {
13531353 if (tmpBoundSet .numUninstantiatedVariables (this .inferenceVariables ) == oldNumUninstantiated )
@@ -1458,7 +1458,9 @@ public Set<InferenceVariable> getSmallestVariableSet(BoundSet bounds, Set<Infere
14581458 // "... and ii) there exists no non-empty proper subset of { α1, ..., αn } with this property."
14591459 // -> find a smallest among candidate sets:
14601460 if (set == null ) {
1461- return Collections .singleton (currentVariable );
1461+ set = new HashSet <>();
1462+ set .add (currentVariable );
1463+ return set ;
14621464 }
14631465 for (Iterator <InferenceVariable > iter = set .iterator (); iter .hasNext ();) {
14641466 InferenceVariable iv = iter .next ();
@@ -1476,6 +1478,22 @@ public Set<InferenceVariable> getSmallestVariableSet(BoundSet bounds, Set<Infere
14761478 return result ;
14771479 }
14781480
1481+ static List <InferenceVariable > pickIvarsByRank (Set <InferenceVariable > variableSet , BoundSet tmpBoundSet ) {
1482+ // apply the ranking of ivars according to their bounds as explained in
1483+ // https://mail.openjdk.org/archives/list/compiler-dev@openjdk.org/message/GN6RTCGMME6I5JVLSFZRIR32XY6QKOI2/
1484+ Map <Integer , List <InferenceVariable >> byRank = variableSet .stream ().collect (Collectors .groupingBy (tmpBoundSet ::rankIVar ));
1485+ for (int rank = 0 ; rank < 4 ; rank ++) {
1486+ List <InferenceVariable > ofRank = byRank .get (rank );
1487+ if (ofRank == null )
1488+ continue ;
1489+ final int numVars = ofRank .size ();
1490+ if (numVars == 0 )
1491+ continue ;
1492+ return ofRank ;
1493+ }
1494+ return null ;
1495+ }
1496+
14791497 /**
14801498 * Collect dependencies of all our ivars based on TypeBounds of 'bounds'
14811499 * @param bounds consider all its TypeBounds
0 commit comments