Skip to content

Commit 14e8d7b

Browse files
committed
fixes #2139 by catching the IndexOutOfBoundsException and searching for a reflexive element that may have caused it. Tests for this error case are very hard to write to the randomized shuffling in the sort algorithm
1 parent a4d16d9 commit 14e8d7b

1 file changed

Lines changed: 27 additions & 12 deletions

File tree

src/org/rascalmpl/library/Prelude.java

Lines changed: 27 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1578,7 +1578,7 @@ public Sorting sort() {
15781578
}
15791579
if (less.less(array[0], array[0])) {
15801580
throw RuntimeExceptionFactory.illegalArgument(less.less,
1581-
"Bad comparator: Did you use less-or-equals instead of less-than?");
1581+
"A reflexive comparator can not be used for sorting. At least one element is less than itself: " + less);
15821582
}
15831583
sort(0, size - 1);
15841584

@@ -1597,16 +1597,33 @@ private void sort(int low, int high) {
15971597
int oldLow = low;
15981598
int oldHigh = high;
15991599

1600-
while (low < high) {
1601-
for (; less.less(array[low], pivot); low++);
1602-
for (; less.less(pivot, array[high]); high--);
1603-
1604-
if (low <= high) {
1605-
swap(low, high);
1606-
low++;
1607-
high--;
1600+
try {
1601+
while (low < high) {
1602+
for (; less.less(array[low], pivot); low++);
1603+
for (; less.less(pivot, array[high]); high--);
1604+
1605+
if (low <= high) {
1606+
swap(low, high);
1607+
low++;
1608+
high--;
1609+
}
16081610
}
16091611
}
1612+
catch (IndexOutOfBoundsException e) {
1613+
// now that we are crashing anyway, we can do some diagnostics.
1614+
// the hypothesis is that at least one element was not irreflexive, making
1615+
// one of the bounds pointers (low or high) shift beyond the edge of the array
1616+
1617+
for (IValue elem : array) {
1618+
if (less.less(elem, elem)) {
1619+
throw RuntimeExceptionFactory.illegalArgument(less.less,
1620+
"A reflexive comparator can not be used for sorting. At least one element is less than itself with the given comparator: " + elem);
1621+
}
1622+
}
1623+
1624+
// another cause for the same exception?
1625+
throw e;
1626+
}
16101627

16111628
if (oldLow < high)
16121629
sort(oldLow, high);
@@ -1665,9 +1682,7 @@ public IList sort(ISet l, IFunction cmpv) {
16651682
new Sorting(tmpArr, new Less(cmpv)).sort();
16661683

16671684
IListWriter writer = values.listWriter();
1668-
for(IValue v : tmpArr){
1669-
writer.append(v);
1670-
}
1685+
writer.append(tmpArr);
16711686

16721687
return writer.done();
16731688
}

0 commit comments

Comments
 (0)