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.
This commit is contained in:
Felix Lange 2026-02-11 14:50:24 +01:00 committed by GitHub
parent 30656d714e
commit 341907cdb8
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 8 additions and 8 deletions

View file

@ -25,20 +25,20 @@ type Iterator struct {
} }
// NewListIterator creates an iterator for the (list) represented by data. // 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) k, t, c, err := readKind(data)
if err != nil { if err != nil {
return nil, err return Iterator{}, err
} }
if k != List { 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 return it, nil
} }
func newIterator(data []byte) *Iterator { func newIterator(data []byte, initialOffset int) Iterator {
return &Iterator{data: data} return Iterator{data: data, offset: initialOffset}
} }
// Next forwards the iterator one step. // Next forwards the iterator one step.

View file

@ -122,8 +122,8 @@ func (r *RawList[T]) Empty() bool {
// ContentIterator returns an iterator over the content of the list. // ContentIterator returns an iterator over the content of the list.
// Note the offsets returned by iterator.Offset are relative to the // Note the offsets returned by iterator.Offset are relative to the
// Content bytes of the list. // Content bytes of the list.
func (r *RawList[T]) ContentIterator() *Iterator { func (r *RawList[T]) ContentIterator() Iterator {
return newIterator(r.Content()) return newIterator(r.Content(), 0)
} }
// Append adds an item to the end of the list. // Append adds an item to the end of the list.