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

(cherry picked from commit 4fe51dfdae)
This commit is contained in:
glepnir
2025-07-23 08:40:24 +08:00
committed by github-actions[bot]
parent 62aae1084f
commit 359d65c902
2 changed files with 12 additions and 0 deletions

View File

@@ -957,6 +957,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

@@ -339,6 +339,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()