Fix slicing last n elements using count (#6838)

This commit is contained in:
Philipp Niedermayer 2025-09-01 11:16:19 +02:00 committed by GitHub
parent 45ad06453b
commit 1f41a9f2a1
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 27 additions and 11 deletions

View File

@ -286,11 +286,8 @@ impl Array {
#[named] #[named]
count: Option<i64>, count: Option<i64>,
) -> StrResult<Array> { ) -> StrResult<Array> {
let mut end = end;
if end.is_none() {
end = count.map(|c: i64| start + c);
}
let start = self.locate(start, true)?; let start = self.locate(start, true)?;
let end = end.or(count.map(|c| start as i64 + c));
let end = self.locate(end.unwrap_or(self.len() as i64), true)?.max(start); let end = self.locate(end.unwrap_or(self.len() as i64), true)?.max(start);
Ok(self.0[start..end].into()) Ok(self.0[start..end].into())
} }

View File

@ -197,12 +197,8 @@ impl Bytes {
#[named] #[named]
count: Option<i64>, count: Option<i64>,
) -> StrResult<Bytes> { ) -> StrResult<Bytes> {
let mut end = end;
if end.is_none() {
end = count.map(|c: i64| start + c);
}
let start = self.locate(start)?; let start = self.locate(start)?;
let end = end.or(count.map(|c| start as i64 + c));
let end = self.locate(end.unwrap_or(self.len() as i64))?.max(start); let end = self.locate(end.unwrap_or(self.len() as i64))?.max(start);
let slice = &self.as_slice()[start..end]; let slice = &self.as_slice()[start..end];

View File

@ -254,9 +254,9 @@ impl Str {
#[named] #[named]
count: Option<i64>, count: Option<i64>,
) -> StrResult<Str> { ) -> StrResult<Str> {
let end = end.or(count.map(|c| start + c)).unwrap_or(self.len() as i64);
let start = self.locate(start)?; let start = self.locate(start)?;
let end = self.locate(end)?.max(start); let end = end.or(count.map(|c| start as i64 + c));
let end = self.locate(end.unwrap_or(self.len() as i64))?.max(start);
Ok(self.0[start..end].into()) Ok(self.0[start..end].into())
} }

View File

@ -223,6 +223,8 @@
#test(range(10).slice(2, 6), (2, 3, 4, 5)) #test(range(10).slice(2, 6), (2, 3, 4, 5))
#test(range(10).slice(4, count: 3), (4, 5, 6)) #test(range(10).slice(4, count: 3), (4, 5, 6))
#test(range(10).slice(-5, count: 2), (5, 6)) #test(range(10).slice(-5, count: 2), (5, 6))
#test((1, 2, 3).slice(-3, count: 3), (1, 2, 3))
#test((1, 2, 3).slice(-1, count: 1), (3,))
#test((1, 2, 3).slice(2, -2), ()) #test((1, 2, 3).slice(2, -2), ())
#test((1, 2, 3).slice(-2, 2), (2,)) #test((1, 2, 3).slice(-2, 2), (2,))
#test((1, 2, 3).slice(-3, 2), (1, 2)) #test((1, 2, 3).slice(-3, 2), (1, 2))
@ -232,6 +234,10 @@
// Error: 2-30 array index out of bounds (index: 12, len: 10) // Error: 2-30 array index out of bounds (index: 12, len: 10)
#range(10).slice(9, count: 3) #range(10).slice(9, count: 3)
--- array-slice-out-of-bounds-from-back ---
// Error: 2-31 array index out of bounds (index: 12, len: 10)
#range(10).slice(-2, count: 4)
--- array-slice-out-of-bounds-negative --- --- array-slice-out-of-bounds-negative ---
// Error: 2-24 array index out of bounds (index: -4, len: 3) // Error: 2-24 array index out of bounds (index: -4, len: 3)
#(1, 2, 3).slice(0, -4) #(1, 2, 3).slice(0, -4)

View File

@ -29,3 +29,18 @@
--- bytes-bad-conversion-from-dict --- --- bytes-bad-conversion-from-dict ---
// Error: 8-14 expected string, array, or bytes, found dictionary // Error: 8-14 expected string, array, or bytes, found dictionary
#bytes((a: 1)) #bytes((a: 1))
--- bytes-slice ---
// Test the `slice` method.
#test(bytes("abcd").slice(2), bytes("cd"))
#test(bytes("abcd").slice(0, 3), bytes("abc"))
#test(bytes("abcd").slice(1, -1), bytes("bc"))
#test(bytes("abcd").slice(3, 3), bytes(""))
#test(bytes("abcd").slice(3, 0), bytes(""))
#test(bytes("abcd").slice(-2), bytes("cd"))
#test(bytes("abcd").slice(-3, 2), bytes("b"))
#test(bytes("abcd").slice(-3, -1), bytes("bc"))
#test(bytes("abcd").slice(-2, -2), bytes(""))
#test(bytes("abcd").slice(1, count: 3), bytes("bcd"))
#test(bytes("abcd").slice(-3, count: 3), bytes("bcd"))
#test(bytes("abcd").slice(2, count: 0), bytes(""))

View File

@ -145,6 +145,8 @@
#test("abc🏡def".slice(2, 7), "c🏡") #test("abc🏡def".slice(2, 7), "c🏡")
#test("abc🏡def".slice(2, -2), "c🏡d") #test("abc🏡def".slice(2, -2), "c🏡d")
#test("abc🏡def".slice(-3, -1), "de") #test("abc🏡def".slice(-3, -1), "de")
#test("x🏡yz".slice(-2, count: 2), "yz")
#test("x🏡yz".slice(-7, count: 7), "x🏡yz")
--- string-slice-not-a-char-boundary --- --- string-slice-not-a-char-boundary ---
// Error: 2-21 string index -1 is not a character boundary // Error: 2-21 string index -1 is not a character boundary