fix(iter): ArrayIter:last returns nil when filtered to empty #34697

Problem: After filtering out all elements, ArrayIter:last still returns a stale element.
Solution: Add check for self._head == self._tail and return nil early.

Fix #34696
This commit is contained in:
glepnir
2025-07-23 08:40:24 +08:00
committed by GitHub
parent 1685c44dd4
commit 4fe51dfdae
2 changed files with 12 additions and 0 deletions

View File

@@ -1010,6 +1010,9 @@ end
---@private ---@private
function ArrayIter:last() function ArrayIter:last()
if self._head >= self._tail then
return nil
end
local inc = self._head < self._tail and 1 or -1 local inc = self._head < self._tail and 1 or -1
local v = self._table[self._tail - inc] local v = self._table[self._tail - inc]
self._head = self._tail self._head = self._tail

View File

@@ -405,6 +405,15 @@ describe('vim.iter', function()
local s = 'abcdefghijklmnopqrstuvwxyz' local s = 'abcdefghijklmnopqrstuvwxyz'
eq('z', vim.iter(vim.split(s, '')):last()) eq('z', vim.iter(vim.split(s, '')):last())
eq('z', vim.iter(vim.gsplit(s, '')):last()) eq('z', vim.iter(vim.gsplit(s, '')):last())
eq(
nil,
vim
.iter({ 1, 2, 3, 4, 5 })
:filter(function()
return false
end)
:last()
)
end) end)
it('enumerate()', function() it('enumerate()', function()