-
-
Notifications
You must be signed in to change notification settings - Fork 21.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix range error for Array.slice
#79103
Fix range error for Array.slice
#79103
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think this is a proper fix. In #56668 slice
was changed to work similarily to e.g. Python. With this PR e.g.:
[0].slice(1)
would return[0]
instead of an empty array,[].slice(anything, anything2)
would crash (as it would result inbegin = -1
,end = 0
because of howCLAMP
works).
Good points will investigate further |
Doing it conditionally only when |
dc5a8fe
to
8fe32ec
Compare
There, I believe it works correctly now, tested with the examples you gave and added some new unit tests, should be correct now I think |
Here's a comparison of the current state of this PR with the Python's slicing notation ( Generating `slice_gdscript.txt`
@tool
extends EditorScript
func _run() -> void:
var s := 3
var a := range(s)
var f := FileAccess.open("res://slice_gdscript.txt", FileAccess.WRITE)
for begin in range(-2 * s, 2 * s + 1):
for end in range(-2 * s, 2 * s + 1):
for step in range(-2 * s, 2 * s + 1):
if step == 0:
continue
var slice := a.slice(begin, end, step)
var line := "%s.slice(%2s, %2s, %2s) = %s" % [a, begin, end, step, slice]
f.store_line(line) Generating `slice_python.txt`
a = list(range(3))
s = len(a)
text = ""
for begin in range(-2 * s, 2 * s + 1):
for end in range(-2 * s, 2 * s + 1):
for step in range(-2 * s, 2 * s + 1):
if step == 0:
continue
slice = a[begin:end:step]
text += f"{a}.slice({begin:2}, {end:2}, {step:2}) = {slice}\n"
from pathlib import Path
p = Path(__file__).with_name('slice_python.txt')
p.write_text(text) git diff -U0 slice_gdscript.txt slice_python.txt
diff --git a/slice_gdscript.txt b/slice_python.txt
index a33c575..778628a 100644
--- a/slice_gdscript.txt
+++ b/slice_python.txt
@@ -469,6 +469,6 @@
-[0, 1, 2].slice(-3, -6, -6) = []
-[0, 1, 2].slice(-3, -6, -5) = []
-[0, 1, 2].slice(-3, -6, -4) = []
-[0, 1, 2].slice(-3, -6, -3) = []
-[0, 1, 2].slice(-3, -6, -2) = []
-[0, 1, 2].slice(-3, -6, -1) = []
+[0, 1, 2].slice(-3, -6, -6) = [0]
+[0, 1, 2].slice(-3, -6, -5) = [0]
+[0, 1, 2].slice(-3, -6, -4) = [0]
+[0, 1, 2].slice(-3, -6, -3) = [0]
+[0, 1, 2].slice(-3, -6, -2) = [0]
+[0, 1, 2].slice(-3, -6, -1) = [0]
@@ -481,6 +481,6 @@
-[0, 1, 2].slice(-3, -5, -6) = []
-[0, 1, 2].slice(-3, -5, -5) = []
-[0, 1, 2].slice(-3, -5, -4) = []
-[0, 1, 2].slice(-3, -5, -3) = []
-[0, 1, 2].slice(-3, -5, -2) = []
-[0, 1, 2].slice(-3, -5, -1) = []
+[0, 1, 2].slice(-3, -5, -6) = [0]
+[0, 1, 2].slice(-3, -5, -5) = [0]
+[0, 1, 2].slice(-3, -5, -4) = [0]
+[0, 1, 2].slice(-3, -5, -3) = [0]
+[0, 1, 2].slice(-3, -5, -2) = [0]
+[0, 1, 2].slice(-3, -5, -1) = [0]
@@ -493,6 +493,6 @@
-[0, 1, 2].slice(-3, -4, -6) = []
-[0, 1, 2].slice(-3, -4, -5) = []
-[0, 1, 2].slice(-3, -4, -4) = []
-[0, 1, 2].slice(-3, -4, -3) = []
-[0, 1, 2].slice(-3, -4, -2) = []
-[0, 1, 2].slice(-3, -4, -1) = []
+[0, 1, 2].slice(-3, -4, -6) = [0]
+[0, 1, 2].slice(-3, -4, -5) = [0]
+[0, 1, 2].slice(-3, -4, -4) = [0]
+[0, 1, 2].slice(-3, -4, -3) = [0]
+[0, 1, 2].slice(-3, -4, -2) = [0]
+[0, 1, 2].slice(-3, -4, -1) = [0]
@@ -630 +630 @@
-[0, 1, 2].slice(-2, -6, -1) = [1]
+[0, 1, 2].slice(-2, -6, -1) = [1, 0]
@@ -642 +642 @@
-[0, 1, 2].slice(-2, -5, -1) = [1]
+[0, 1, 2].slice(-2, -5, -1) = [1, 0]
@@ -654 +654 @@
-[0, 1, 2].slice(-2, -4, -1) = [1]
+[0, 1, 2].slice(-2, -4, -1) = [1, 0]
@@ -785,2 +785,2 @@
-[0, 1, 2].slice(-1, -6, -2) = [2]
-[0, 1, 2].slice(-1, -6, -1) = [2, 1]
+[0, 1, 2].slice(-1, -6, -2) = [2, 0]
+[0, 1, 2].slice(-1, -6, -1) = [2, 1, 0]
@@ -797,2 +797,2 @@
-[0, 1, 2].slice(-1, -5, -2) = [2]
-[0, 1, 2].slice(-1, -5, -1) = [2, 1]
+[0, 1, 2].slice(-1, -5, -2) = [2, 0]
+[0, 1, 2].slice(-1, -5, -1) = [2, 1, 0]
@@ -809,2 +809,2 @@
-[0, 1, 2].slice(-1, -4, -2) = [2]
-[0, 1, 2].slice(-1, -4, -1) = [2, 1]
+[0, 1, 2].slice(-1, -4, -2) = [2, 0]
+[0, 1, 2].slice(-1, -4, -1) = [2, 1, 0]
@@ -937,6 +937,6 @@
-[0, 1, 2].slice( 0, -6, -6) = []
-[0, 1, 2].slice( 0, -6, -5) = []
-[0, 1, 2].slice( 0, -6, -4) = []
-[0, 1, 2].slice( 0, -6, -3) = []
-[0, 1, 2].slice( 0, -6, -2) = []
-[0, 1, 2].slice( 0, -6, -1) = []
+[0, 1, 2].slice( 0, -6, -6) = [0]
+[0, 1, 2].slice( 0, -6, -5) = [0]
+[0, 1, 2].slice( 0, -6, -4) = [0]
+[0, 1, 2].slice( 0, -6, -3) = [0]
+[0, 1, 2].slice( 0, -6, -2) = [0]
+[0, 1, 2].slice( 0, -6, -1) = [0]
@@ -949,6 +949,6 @@
-[0, 1, 2].slice( 0, -5, -6) = []
-[0, 1, 2].slice( 0, -5, -5) = []
-[0, 1, 2].slice( 0, -5, -4) = []
-[0, 1, 2].slice( 0, -5, -3) = []
-[0, 1, 2].slice( 0, -5, -2) = []
-[0, 1, 2].slice( 0, -5, -1) = []
+[0, 1, 2].slice( 0, -5, -6) = [0]
+[0, 1, 2].slice( 0, -5, -5) = [0]
+[0, 1, 2].slice( 0, -5, -4) = [0]
+[0, 1, 2].slice( 0, -5, -3) = [0]
+[0, 1, 2].slice( 0, -5, -2) = [0]
+[0, 1, 2].slice( 0, -5, -1) = [0]
@@ -961,6 +961,6 @@
-[0, 1, 2].slice( 0, -4, -6) = []
-[0, 1, 2].slice( 0, -4, -5) = []
-[0, 1, 2].slice( 0, -4, -4) = []
-[0, 1, 2].slice( 0, -4, -3) = []
-[0, 1, 2].slice( 0, -4, -2) = []
-[0, 1, 2].slice( 0, -4, -1) = []
+[0, 1, 2].slice( 0, -4, -6) = [0]
+[0, 1, 2].slice( 0, -4, -5) = [0]
+[0, 1, 2].slice( 0, -4, -4) = [0]
+[0, 1, 2].slice( 0, -4, -3) = [0]
+[0, 1, 2].slice( 0, -4, -2) = [0]
+[0, 1, 2].slice( 0, -4, -1) = [0]
@@ -1098 +1098 @@
-[0, 1, 2].slice( 1, -6, -1) = [1]
+[0, 1, 2].slice( 1, -6, -1) = [1, 0]
@@ -1110 +1110 @@
-[0, 1, 2].slice( 1, -5, -1) = [1]
+[0, 1, 2].slice( 1, -5, -1) = [1, 0]
@@ -1122 +1122 @@
-[0, 1, 2].slice( 1, -4, -1) = [1]
+[0, 1, 2].slice( 1, -4, -1) = [1, 0]
@@ -1253,2 +1253,2 @@
-[0, 1, 2].slice( 2, -6, -2) = [2]
-[0, 1, 2].slice( 2, -6, -1) = [2, 1]
+[0, 1, 2].slice( 2, -6, -2) = [2, 0]
+[0, 1, 2].slice( 2, -6, -1) = [2, 1, 0]
@@ -1265,2 +1265,2 @@
-[0, 1, 2].slice( 2, -5, -2) = [2]
-[0, 1, 2].slice( 2, -5, -1) = [2, 1]
+[0, 1, 2].slice( 2, -5, -2) = [2, 0]
+[0, 1, 2].slice( 2, -5, -1) = [2, 1, 0]
@@ -1277,2 +1277,2 @@
-[0, 1, 2].slice( 2, -4, -2) = [2]
-[0, 1, 2].slice( 2, -4, -1) = [2, 1]
+[0, 1, 2].slice( 2, -4, -2) = [2, 0]
+[0, 1, 2].slice( 2, -4, -1) = [2, 1, 0]
@@ -1409,2 +1409,2 @@
-[0, 1, 2].slice( 3, -6, -2) = [2]
-[0, 1, 2].slice( 3, -6, -1) = [2, 1]
+[0, 1, 2].slice( 3, -6, -2) = [2, 0]
+[0, 1, 2].slice( 3, -6, -1) = [2, 1, 0]
@@ -1421,2 +1421,2 @@
-[0, 1, 2].slice( 3, -5, -2) = [2]
-[0, 1, 2].slice( 3, -5, -1) = [2, 1]
+[0, 1, 2].slice( 3, -5, -2) = [2, 0]
+[0, 1, 2].slice( 3, -5, -1) = [2, 1, 0]
@@ -1433,2 +1433,2 @@
-[0, 1, 2].slice( 3, -4, -2) = [2]
-[0, 1, 2].slice( 3, -4, -1) = [2, 1]
+[0, 1, 2].slice( 3, -4, -2) = [2, 0]
+[0, 1, 2].slice( 3, -4, -1) = [2, 1, 0]
@@ -1565,2 +1565,2 @@
-[0, 1, 2].slice( 4, -6, -2) = [2]
-[0, 1, 2].slice( 4, -6, -1) = [2, 1]
+[0, 1, 2].slice( 4, -6, -2) = [2, 0]
+[0, 1, 2].slice( 4, -6, -1) = [2, 1, 0]
@@ -1577,2 +1577,2 @@
-[0, 1, 2].slice( 4, -5, -2) = [2]
-[0, 1, 2].slice( 4, -5, -1) = [2, 1]
+[0, 1, 2].slice( 4, -5, -2) = [2, 0]
+[0, 1, 2].slice( 4, -5, -1) = [2, 1, 0]
@@ -1589,2 +1589,2 @@
-[0, 1, 2].slice( 4, -4, -2) = [2]
-[0, 1, 2].slice( 4, -4, -1) = [2, 1]
+[0, 1, 2].slice( 4, -4, -2) = [2, 0]
+[0, 1, 2].slice( 4, -4, -1) = [2, 1, 0]
@@ -1721,2 +1721,2 @@
-[0, 1, 2].slice( 5, -6, -2) = [2]
-[0, 1, 2].slice( 5, -6, -1) = [2, 1]
+[0, 1, 2].slice( 5, -6, -2) = [2, 0]
+[0, 1, 2].slice( 5, -6, -1) = [2, 1, 0]
@@ -1733,2 +1733,2 @@
-[0, 1, 2].slice( 5, -5, -2) = [2]
-[0, 1, 2].slice( 5, -5, -1) = [2, 1]
+[0, 1, 2].slice( 5, -5, -2) = [2, 0]
+[0, 1, 2].slice( 5, -5, -1) = [2, 1, 0]
@@ -1745,2 +1745,2 @@
-[0, 1, 2].slice( 5, -4, -2) = [2]
-[0, 1, 2].slice( 5, -4, -1) = [2, 1]
+[0, 1, 2].slice( 5, -4, -2) = [2, 0]
+[0, 1, 2].slice( 5, -4, -1) = [2, 1, 0]
@@ -1877,2 +1877,2 @@
-[0, 1, 2].slice( 6, -6, -2) = [2]
-[0, 1, 2].slice( 6, -6, -1) = [2, 1]
+[0, 1, 2].slice( 6, -6, -2) = [2, 0]
+[0, 1, 2].slice( 6, -6, -1) = [2, 1, 0]
@@ -1889,2 +1889,2 @@
-[0, 1, 2].slice( 6, -5, -2) = [2]
-[0, 1, 2].slice( 6, -5, -1) = [2, 1]
+[0, 1, 2].slice( 6, -5, -2) = [2, 0]
+[0, 1, 2].slice( 6, -5, -1) = [2, 1, 0]
@@ -1901,2 +1901,2 @@
-[0, 1, 2].slice( 6, -4, -2) = [2]
-[0, 1, 2].slice( 6, -4, -1) = [2, 1]
+[0, 1, 2].slice( 6, -4, -2) = [2, 0]
+[0, 1, 2].slice( 6, -4, -1) = [2, 1, 0] So while crashes are gone the above diff shows the problem with the current implementation (existing before this PR): for a negative step it's impossible to make the resulting slice include the first element of the array. Probably a good idea to fix it in this PR. Also some cases result in unneeded errors, e.g. |
Will see what I can do, that's tracked in #61530 |
Oh, I even already commented in there. 😆 But haven't noticed the problem with negative step back then though... |
Got a basic idea going, will test it when I'm able to be by my computer properly |
8fe32ec
to
42a6cdf
Compare
I believe this should do it, will add to the documentation as well later Currently unable to be by my computer for more than a few minutes at a time so can't test it myself properly rn |
With the recent changes the same diff as in #79103 (comment) is: git diff -U0 slice_gdscript.txt slice_python.txt
diff --git a/slice_gdscript.txt b/slice_python.txt
index 0e21a82..778628a 100644
--- a/slice_gdscript.txt
+++ b/slice_python.txt
@@ -1,6 +1,6 @@
-[0, 1, 2].slice(-6, -6, -6) = [0]
-[0, 1, 2].slice(-6, -6, -5) = [0]
-[0, 1, 2].slice(-6, -6, -4) = [0]
-[0, 1, 2].slice(-6, -6, -3) = [0]
-[0, 1, 2].slice(-6, -6, -2) = [0]
-[0, 1, 2].slice(-6, -6, -1) = [0]
+[0, 1, 2].slice(-6, -6, -6) = []
+[0, 1, 2].slice(-6, -6, -5) = []
+[0, 1, 2].slice(-6, -6, -4) = []
+[0, 1, 2].slice(-6, -6, -3) = []
+[0, 1, 2].slice(-6, -6, -2) = []
+[0, 1, 2].slice(-6, -6, -1) = []
@@ -13,6 +13,6 @@
-[0, 1, 2].slice(-6, -5, -6) = [0]
-[0, 1, 2].slice(-6, -5, -5) = [0]
-[0, 1, 2].slice(-6, -5, -4) = [0]
-[0, 1, 2].slice(-6, -5, -3) = [0]
-[0, 1, 2].slice(-6, -5, -2) = [0]
-[0, 1, 2].slice(-6, -5, -1) = [0]
+[0, 1, 2].slice(-6, -5, -6) = []
+[0, 1, 2].slice(-6, -5, -5) = []
+[0, 1, 2].slice(-6, -5, -4) = []
+[0, 1, 2].slice(-6, -5, -3) = []
+[0, 1, 2].slice(-6, -5, -2) = []
+[0, 1, 2].slice(-6, -5, -1) = []
@@ -25,6 +25,6 @@
-[0, 1, 2].slice(-6, -4, -6) = [0]
-[0, 1, 2].slice(-6, -4, -5) = [0]
-[0, 1, 2].slice(-6, -4, -4) = [0]
-[0, 1, 2].slice(-6, -4, -3) = [0]
-[0, 1, 2].slice(-6, -4, -2) = [0]
-[0, 1, 2].slice(-6, -4, -1) = [0]
+[0, 1, 2].slice(-6, -4, -6) = []
+[0, 1, 2].slice(-6, -4, -5) = []
+[0, 1, 2].slice(-6, -4, -4) = []
+[0, 1, 2].slice(-6, -4, -3) = []
+[0, 1, 2].slice(-6, -4, -2) = []
+[0, 1, 2].slice(-6, -4, -1) = []
@@ -157,6 +157,6 @@
-[0, 1, 2].slice(-5, -6, -6) = [0]
-[0, 1, 2].slice(-5, -6, -5) = [0]
-[0, 1, 2].slice(-5, -6, -4) = [0]
-[0, 1, 2].slice(-5, -6, -3) = [0]
-[0, 1, 2].slice(-5, -6, -2) = [0]
-[0, 1, 2].slice(-5, -6, -1) = [0]
+[0, 1, 2].slice(-5, -6, -6) = []
+[0, 1, 2].slice(-5, -6, -5) = []
+[0, 1, 2].slice(-5, -6, -4) = []
+[0, 1, 2].slice(-5, -6, -3) = []
+[0, 1, 2].slice(-5, -6, -2) = []
+[0, 1, 2].slice(-5, -6, -1) = []
@@ -169,6 +169,6 @@
-[0, 1, 2].slice(-5, -5, -6) = [0]
-[0, 1, 2].slice(-5, -5, -5) = [0]
-[0, 1, 2].slice(-5, -5, -4) = [0]
-[0, 1, 2].slice(-5, -5, -3) = [0]
-[0, 1, 2].slice(-5, -5, -2) = [0]
-[0, 1, 2].slice(-5, -5, -1) = [0]
+[0, 1, 2].slice(-5, -5, -6) = []
+[0, 1, 2].slice(-5, -5, -5) = []
+[0, 1, 2].slice(-5, -5, -4) = []
+[0, 1, 2].slice(-5, -5, -3) = []
+[0, 1, 2].slice(-5, -5, -2) = []
+[0, 1, 2].slice(-5, -5, -1) = []
@@ -181,6 +181,6 @@
-[0, 1, 2].slice(-5, -4, -6) = [0]
-[0, 1, 2].slice(-5, -4, -5) = [0]
-[0, 1, 2].slice(-5, -4, -4) = [0]
-[0, 1, 2].slice(-5, -4, -3) = [0]
-[0, 1, 2].slice(-5, -4, -2) = [0]
-[0, 1, 2].slice(-5, -4, -1) = [0]
+[0, 1, 2].slice(-5, -4, -6) = []
+[0, 1, 2].slice(-5, -4, -5) = []
+[0, 1, 2].slice(-5, -4, -4) = []
+[0, 1, 2].slice(-5, -4, -3) = []
+[0, 1, 2].slice(-5, -4, -2) = []
+[0, 1, 2].slice(-5, -4, -1) = []
@@ -313,6 +313,6 @@
-[0, 1, 2].slice(-4, -6, -6) = [0]
-[0, 1, 2].slice(-4, -6, -5) = [0]
-[0, 1, 2].slice(-4, -6, -4) = [0]
-[0, 1, 2].slice(-4, -6, -3) = [0]
-[0, 1, 2].slice(-4, -6, -2) = [0]
-[0, 1, 2].slice(-4, -6, -1) = [0]
+[0, 1, 2].slice(-4, -6, -6) = []
+[0, 1, 2].slice(-4, -6, -5) = []
+[0, 1, 2].slice(-4, -6, -4) = []
+[0, 1, 2].slice(-4, -6, -3) = []
+[0, 1, 2].slice(-4, -6, -2) = []
+[0, 1, 2].slice(-4, -6, -1) = []
@@ -325,6 +325,6 @@
-[0, 1, 2].slice(-4, -5, -6) = [0]
-[0, 1, 2].slice(-4, -5, -5) = [0]
-[0, 1, 2].slice(-4, -5, -4) = [0]
-[0, 1, 2].slice(-4, -5, -3) = [0]
-[0, 1, 2].slice(-4, -5, -2) = [0]
-[0, 1, 2].slice(-4, -5, -1) = [0]
+[0, 1, 2].slice(-4, -5, -6) = []
+[0, 1, 2].slice(-4, -5, -5) = []
+[0, 1, 2].slice(-4, -5, -4) = []
+[0, 1, 2].slice(-4, -5, -3) = []
+[0, 1, 2].slice(-4, -5, -2) = []
+[0, 1, 2].slice(-4, -5, -1) = []
@@ -337,6 +337,6 @@
-[0, 1, 2].slice(-4, -4, -6) = [0]
-[0, 1, 2].slice(-4, -4, -5) = [0]
-[0, 1, 2].slice(-4, -4, -4) = [0]
-[0, 1, 2].slice(-4, -4, -3) = [0]
-[0, 1, 2].slice(-4, -4, -2) = [0]
-[0, 1, 2].slice(-4, -4, -1) = [0]
+[0, 1, 2].slice(-4, -4, -6) = []
+[0, 1, 2].slice(-4, -4, -5) = []
+[0, 1, 2].slice(-4, -4, -4) = []
+[0, 1, 2].slice(-4, -4, -3) = []
+[0, 1, 2].slice(-4, -4, -2) = []
+[0, 1, 2].slice(-4, -4, -1) = [] So there are still discrepancies but less than before. I'm not sure if it's even possible to make the behavior be in par with the Python because of the clamping premise which is needed for the current default arg for It might be a matter of leaving it as is and documenting it in detail. |
Will take a look as well, might be some solution |
After rethinking the solution could be to treat |
Tested and that seems to work, will do some more structured testing when I'm able and add this change Will also document how to get the last value, as it's not entirely intuitive, and some other details |
42a6cdf
to
65df218
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems like we're settled on the behavior, now the diff compared to Python is empty (so hopefully the behavior is more intuitive now). 👍
Now just a matter of updating the docs accordingly (+maybe some additional tests could be added).
For the documentation I'm thinking something on the lines of:
Or something along those lines, exact formatting and wording to be worked out Edit: Alternatively
|
Regarding the docs I'd firstly get rid of mentioning any clamping: Line 583 in c3b0a92
Conceptually it doesn't do any clamping now, the indexes which would end up out of bounds are just skipped / not included (fact it uses clamping is implementation detail). So it should be sufficient to explain that:
Also indeed should be worth explicitly pointing out that (for non-empty array) because of (1) and (2):
I guess the quest is to write this in a clear and simple manner. 🙂 Some code examples could clarify things too.
BTW if |
Forgot to update my example here with |
65df218
to
e7628f6
Compare
Will add more to the documentation and see what additional tests to add tomorrow probably |
e7628f6
to
7752a0d
Compare
@AThousandShips What's the status on this? 🙃 |
The documentation needs a tweak, but uncertain how to word it, otherwise I believe it's ready Been unable to work on it the last few days |
You mentioned adding tests too? |
Added some, unsure what other cases need covering @kleonc any thoughts? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree that the documentation can be significantly improved, but let's leave it to a follow-up. Fixes that improve the implementation are good as is.
Thanks! |
Thank you! And feel free to provide any feedback on the documentation, or add if yourself |
I mostly agree with @kleonc's assessment which points we need to hit, so it's a matter of presenting them in a readable format. I think the description as is can be hard to comprehend as it uses a very robotic, technical voice to describe the logic. Like, the second sentence is
And it deals with many non-intuitive things (such as "absolute value", "clamping") when all the user wants to do is get a portion of an array. And the same happens with every sentence that follows.
Upon reading it I'm hard pressed to imagine what being relative to the end means.
Step may be a relative index if you had to define it scientifically, but who talks like that? 🙃 Even changing that to talk about "every Nth element" would be better, though still not ideal. I don't have a particular suggestion how to phrase it all better at the moment, though. |
Cherry-picked for 4.1.2. |
Start of the range is included so the upper end of the range should be clamped or it will try to access the element beyond the end, the same error shouldn't occur in 3.x as it does the correct clamping there
Added a unit test to catch the crash or behavior, could replace the previous one just to simplify as well
I also have no idea how I didn't notice this one when I did my previous PR for slice