From 341907cdb8c30e85dcb6458d3fdbd9445ce8a8a4 Mon Sep 17 00:00:00 2001 From: Felix Lange Date: Wed, 11 Feb 2026 14:50:24 +0100 Subject: [PATCH] rlp: return Iterator as non-pointer (#33818) Most uses of the iterator are like this: it, _ := rlp.NewListIterator(data) for it.Next() { do(it.Value()) } This doesn't require the iterator to be a pointer and it's better to have it stack-allocated. AFAIK the compiler cannot prove it is OK to stack-allocate when it is returned as a pointer because the methods of `Iterator` use pointer receiver and also mutate the object. The iterator type was not exported until very recently, so I think it is still OK to change this API. --- rlp/iterator.go | 12 ++++++------ rlp/raw.go | 4 ++-- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/rlp/iterator.go b/rlp/iterator.go index a67e6651f5..f1f214c4bc 100644 --- a/rlp/iterator.go +++ b/rlp/iterator.go @@ -25,20 +25,20 @@ type Iterator struct { } // NewListIterator creates an iterator for the (list) represented by data. -func NewListIterator(data RawValue) (*Iterator, error) { +func NewListIterator(data RawValue) (Iterator, error) { k, t, c, err := readKind(data) if err != nil { - return nil, err + return Iterator{}, err } if k != List { - return nil, ErrExpectedList + return Iterator{}, ErrExpectedList } - it := &Iterator{data: data[t : t+c], offset: int(t)} + it := newIterator(data[t:t+c], int(t)) return it, nil } -func newIterator(data []byte) *Iterator { - return &Iterator{data: data} +func newIterator(data []byte, initialOffset int) Iterator { + return Iterator{data: data, offset: initialOffset} } // Next forwards the iterator one step. diff --git a/rlp/raw.go b/rlp/raw.go index 876a503d70..8d171ce0f6 100644 --- a/rlp/raw.go +++ b/rlp/raw.go @@ -122,8 +122,8 @@ func (r *RawList[T]) Empty() bool { // ContentIterator returns an iterator over the content of the list. // Note the offsets returned by iterator.Offset are relative to the // Content bytes of the list. -func (r *RawList[T]) ContentIterator() *Iterator { - return newIterator(r.Content()) +func (r *RawList[T]) ContentIterator() Iterator { + return newIterator(r.Content(), 0) } // Append adds an item to the end of the list.