@@ -773,15 +773,16 @@ private boolean exhausts(JCExpression selector, List<JCCase> cases) {
773773 patternSet .add (new BindingPattern (e .getKey ().type ));
774774 }
775775 }
776- List <PatternDescription > patterns = List . from ( patternSet ) ;
776+ Set <PatternDescription > patterns = patternSet ;
777777 try {
778778 boolean repeat = true ;
779779 while (repeat ) {
780- List <PatternDescription > updatedPatterns ;
780+ Set <PatternDescription > updatedPatterns ;
781781 updatedPatterns = reduceBindingPatterns (selector .type , patterns );
782782 updatedPatterns = reduceNestedPatterns (updatedPatterns );
783783 updatedPatterns = reduceRecordPatterns (updatedPatterns );
784- repeat = updatedPatterns != patterns ;
784+ updatedPatterns = removeCoveredRecordPatterns (updatedPatterns );
785+ repeat = !updatedPatterns .equals (patterns );
785786 patterns = updatedPatterns ;
786787 if (checkCovered (selector .type , patterns )) {
787788 return true ;
@@ -794,7 +795,7 @@ private boolean exhausts(JCExpression selector, List<JCCase> cases) {
794795 }
795796 }
796797
797- private boolean checkCovered (Type seltype , List <PatternDescription > patterns ) {
798+ private boolean checkCovered (Type seltype , Iterable <PatternDescription > patterns ) {
798799 for (Type seltypeComponent : components (seltype )) {
799800 for (PatternDescription pd : patterns ) {
800801 if (pd instanceof BindingPattern bp &&
@@ -830,15 +831,14 @@ private List<Type> components(Type seltype) {
830831 * is found, it is removed, and replaced with a binding pattern
831832 * for the sealed supertype.
832833 */
833- private List <PatternDescription > reduceBindingPatterns (Type selectorType , List <PatternDescription > patterns ) {
834+ private Set <PatternDescription > reduceBindingPatterns (Type selectorType , Set <PatternDescription > patterns ) {
834835 Set <Symbol > existingBindings = patterns .stream ()
835836 .filter (pd -> pd instanceof BindingPattern )
836837 .map (pd -> ((BindingPattern ) pd ).type .tsym )
837838 .collect (Collectors .toSet ());
838839
839840 for (PatternDescription pdOne : patterns ) {
840841 if (pdOne instanceof BindingPattern bpOne ) {
841- Set <PatternDescription > toRemove = new HashSet <>();
842842 Set <PatternDescription > toAdd = new HashSet <>();
843843
844844 for (Type sup : types .directSupertypes (bpOne .type )) {
@@ -871,7 +871,6 @@ private List<PatternDescription> reduceBindingPatterns(Type selectorType, List<P
871871
872872 for (PatternDescription pdOther : patterns ) {
873873 if (pdOther instanceof BindingPattern bpOther ) {
874- boolean reduces = false ;
875874 Set <Symbol > currentPermittedSubTypes =
876875 allPermittedSubTypes ((ClassSymbol ) bpOther .type .tsym , s -> true );
877876
@@ -888,33 +887,21 @@ private List<PatternDescription> reduceBindingPatterns(Type selectorType, List<P
888887 if (types .isSubtype (types .erasure (perm .type ),
889888 types .erasure (bpOther .type ))) {
890889 it .remove ();
891- reduces = true ;
892- }
893- }
894-
895- if (reduces ) {
896- if (!types .isSubtype (types .erasure (clazz .type ), types .erasure (bpOther .type ))) {
897- bindings .append (pdOther );
898890 }
899891 }
900892 }
901893 }
902894
903895 if (permitted .isEmpty ()) {
904- toRemove .addAll (bindings );
905896 toAdd .add (new BindingPattern (clazz .type ));
906897 }
907898 }
908899 }
909900
910- if (!toAdd .isEmpty () || !toRemove .isEmpty ()) {
911- for (PatternDescription pd : toRemove ) {
912- patterns = List .filter (patterns , pd );
913- }
914- for (PatternDescription pd : toAdd ) {
915- patterns = patterns .prepend (pd );
916- }
917- return patterns ;
901+ if (!toAdd .isEmpty ()) {
902+ Set <PatternDescription > newPatterns = new HashSet <>(patterns );
903+ newPatterns .addAll (toAdd );
904+ return newPatterns ;
918905 }
919906 }
920907 }
@@ -958,7 +945,7 @@ private Set<Symbol> allPermittedSubTypes(ClassSymbol root, Predicate<ClassSymbol
958945 * of patterns is replaced with a new set of patterns of the form:
959946 * $record($prefix$, $resultOfReduction, $suffix$)
960947 */
961- private List <PatternDescription > reduceNestedPatterns (List <PatternDescription > patterns ) {
948+ private Set <PatternDescription > reduceNestedPatterns (Set <PatternDescription > patterns ) {
962949 /* implementation note:
963950 * finding a sub-set of patterns that only differ in a single
964951 * column is time-consuming task, so this method speeds it up by:
@@ -977,13 +964,14 @@ private List<PatternDescription> reduceNestedPatterns(List<PatternDescription> p
977964
978965 for (var e : groupByRecordClass .entrySet ()) {
979966 int nestedPatternsCount = e .getKey ().getRecordComponents ().size ();
967+ Set <RecordPattern > current = new HashSet <>(e .getValue ());
980968
981969 for (int mismatchingCandidate = 0 ;
982970 mismatchingCandidate < nestedPatternsCount ;
983971 mismatchingCandidate ++) {
984972 int mismatchingCandidateFin = mismatchingCandidate ;
985973 var groupByHashes =
986- e . getValue ()
974+ current
987975 .stream ()
988976 //error recovery, ignore patterns with incorrect number of nested patterns:
989977 .filter (pd -> pd .nested .length == nestedPatternsCount )
@@ -1018,37 +1006,35 @@ private List<PatternDescription> reduceNestedPatterns(List<PatternDescription> p
10181006 }
10191007 }
10201008
1021- var nestedPatterns = join .stream ().map (rp -> rp .nested [mismatchingCandidateFin ]).collect (List . collector ());
1009+ var nestedPatterns = join .stream ().map (rp -> rp .nested [mismatchingCandidateFin ]).collect (Collectors . toSet ());
10221010 var updatedPatterns = reduceNestedPatterns (nestedPatterns );
10231011
10241012 updatedPatterns = reduceRecordPatterns (updatedPatterns );
1013+ updatedPatterns = removeCoveredRecordPatterns (updatedPatterns );
10251014 updatedPatterns = reduceBindingPatterns (rpOne .fullComponentTypes ()[mismatchingCandidateFin ], updatedPatterns );
10261015
1027- if (nestedPatterns != updatedPatterns ) {
1028- ListBuffer <PatternDescription > result = new ListBuffer <>();
1029- Set <PatternDescription > toRemove = Collections .newSetFromMap (new IdentityHashMap <>());
1030-
1031- toRemove .addAll (join );
1032-
1033- for (PatternDescription p : patterns ) {
1034- if (!toRemove .contains (p )) {
1035- result .append (p );
1036- }
1037- }
1016+ if (!nestedPatterns .equals (updatedPatterns )) {
1017+ current .removeAll (join );
10381018
10391019 for (PatternDescription nested : updatedPatterns ) {
10401020 PatternDescription [] newNested =
10411021 Arrays .copyOf (rpOne .nested , rpOne .nested .length );
10421022 newNested [mismatchingCandidateFin ] = nested ;
1043- result . append (new RecordPattern (rpOne .recordType (),
1023+ current . add (new RecordPattern (rpOne .recordType (),
10441024 rpOne .fullComponentTypes (),
10451025 newNested ));
10461026 }
1047- return result .toList ();
10481027 }
10491028 }
10501029 }
10511030 }
1031+
1032+ if (!current .equals (new HashSet <>(e .getValue ()))) {
1033+ Set <PatternDescription > result = new HashSet <>(patterns );
1034+ result .removeAll (e .getValue ());
1035+ result .addAll (current );
1036+ return result ;
1037+ }
10521038 }
10531039 return patterns ;
10541040 }
@@ -1058,22 +1044,22 @@ private List<PatternDescription> reduceNestedPatterns(List<PatternDescription> p
10581044 * all the $nestedX pattern cover the given record component,
10591045 * and replace those with a simple binding pattern over $record.
10601046 */
1061- private List <PatternDescription > reduceRecordPatterns (List <PatternDescription > patterns ) {
1062- var newPatterns = new ListBuffer <PatternDescription >();
1047+ private Set <PatternDescription > reduceRecordPatterns (Set <PatternDescription > patterns ) {
1048+ var newPatterns = new HashSet <PatternDescription >();
10631049 boolean modified = false ;
10641050 for (PatternDescription pd : patterns ) {
10651051 if (pd instanceof RecordPattern rpOne ) {
10661052 PatternDescription reducedPattern = reduceRecordPattern (rpOne );
10671053 if (reducedPattern != rpOne ) {
1068- newPatterns .append (reducedPattern );
1054+ newPatterns .add (reducedPattern );
10691055 modified = true ;
10701056 continue ;
10711057 }
10721058 }
1073- newPatterns .append (pd );
1059+ newPatterns .add (pd );
10741060 }
1075- return modified ? newPatterns . toList () : patterns ;
1076- }
1061+ return modified ? newPatterns : patterns ;
1062+ }
10771063
10781064 private PatternDescription reduceRecordPattern (PatternDescription pattern ) {
10791065 if (pattern instanceof RecordPattern rpOne ) {
@@ -1105,6 +1091,23 @@ private PatternDescription reduceRecordPattern(PatternDescription pattern) {
11051091 return pattern ;
11061092 }
11071093
1094+ private Set <PatternDescription > removeCoveredRecordPatterns (Set <PatternDescription > patterns ) {
1095+ Set <Symbol > existingBindings = patterns .stream ()
1096+ .filter (pd -> pd instanceof BindingPattern )
1097+ .map (pd -> ((BindingPattern ) pd ).type .tsym )
1098+ .collect (Collectors .toSet ());
1099+ Set <PatternDescription > result = new HashSet <>(patterns );
1100+
1101+ for (Iterator <PatternDescription > it = result .iterator (); it .hasNext ();) {
1102+ PatternDescription pd = it .next ();
1103+ if (pd instanceof RecordPattern rp && existingBindings .contains (rp .recordType .tsym )) {
1104+ it .remove ();
1105+ }
1106+ }
1107+
1108+ return result ;
1109+ }
1110+
11081111 public void visitTry (JCTry tree ) {
11091112 ListBuffer <PendingExit > prevPendingExits = pendingExits ;
11101113 pendingExits = new ListBuffer <>();
0 commit comments