Skip to content

Support unbounded struct fields and nested sequence elements (follow-up to #4856 and #5240) #5247

Description

@AlbertoCentonze

Version information

  • Vyper: 0.5.0b2+commit.5764199a, master at 5764199a9ab64e13bc64d8f41371378db4fa6ab0 (checked September 5, 2026).
  • Also observed at the port's pinned compiler, 8af5e83c10af4f065cc660fe20293dac11fdff83. The intervening commit changes only .github/workflows/codeql.yml.
  • Python 3.13.14; macOS 26.6.2, arm64.
  • Venom (--experimental-codegen), Cancun; bytecode metadata disabled.

Summary and relation to existing work

This is a focused follow-up to #4856 for recursive runtime-sized types, motivated by full input/output-domain compatibility in the Aave V4 Vyper port.

The open PR #5240 already addresses ABI-dynamic bounded elements in an unbounded outer array and explicitly references the Aave port. It also explicitly leaves DynArray[Bytes[INF], INF] rejected. This request concerns that remaining inner unbounded case and structs containing unbounded fields, rather than duplicating its bounded-element work.

Current limitations

These two separate minimal sources are rejected on the master commit above.

Unbounded bytes elements inside an unbounded array:

# pragma version 0.5.0b2
@external
@pure
def echo(values: DynArray[Bytes[INF], INF]) -> DynArray[Bytes[INF], INF]:
    return values
vyper.exceptions.StructureException: DynArray element types cannot contain unbounded sequence types

An unbounded array field inside a struct:

# pragma version 0.5.0b2
struct Batch:
    owner: address
    values: DynArray[uint256, INF]
@external
@pure
def count(batch: Batch) -> uint256:
    return len(batch.values)
vyper.exceptions.StructureException: Structs cannot contain unbounded sequence types

Compile each file separately with:

vyper --evm-version cancun --experimental-codegen -O 2 -f bytecode example.vy

Array probe, struct probe, pinned diagnostics. Both rejections were rechecked on current master.

Motivation

A bounded Bytes[N] element can have the same external bytes[] ABI encoding as Solidity while accepting only elements up to N bytes. An unbounded outer count alone therefore does not provide the full domain of a Solidity multicall.

Likewise, signed batch requests and configuration structs contain dynamic arrays. Imposing a fixed count inside those fields changes which otherwise valid ABI values can be accepted. This is language capability feedback, not a request to hide those restrictions behind larger constants or custom raw ABI decoders.

Requested scope

  • Allow unbounded sequence fields inside non-storage structs and unbounded elements inside sequences, including combinations of the two.
  • Support the corresponding runtime ABI decoding and encoding for parameters and return values, with allocation based on actual runtime sizes.
  • Carry the supported types through internal calls, interface declarations, and exported module interfaces.
  • Preserve existing bounded-type behavior; cover empty and nonempty nested values and exact round trips.

This request is about calldata/memory/return values. Runtime-sized persistent storage is a separate design topic. Capturing complete successful external-call returndata is also a separate prerequisite for a fully generic multicall.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

No labels
No labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions