Skip to content

fix[lang]: reject type names passed as builtin varargs - #5195

Open
beardthelion wants to merge 1 commit into
vyperlang:masterfrom
beardthelion:fix/vararg-type-name-panic
Open

beardthelion wants to merge 1 commit into
vyperlang:masterfrom
beardthelion:fix/vararg-type-name-panic

Conversation

@beardthelion

@beardthelion beardthelion commented Jul 21, 2026

Copy link
Copy Markdown
Contributor

What I did

Builtins that take variable arguments never semantically checked them, so a bare type name passed as a vararg reached codegen and crashed the compiler with an internal panic. This rejects that case during semantic analysis. Part of #4609

How I did it

BuiltinFunctionT._validate_arg_types inferred each vararg's type only for its side effects and discarded the result. A bare type name like uint256 infers to TYPE_T, which is exactly inferable, so it passed the check and slipped through to codegen, where TYPE_T has no abi_type/typ/location and the compiler panicked. The vararg loop now inspects the inferred type and rejects TYPE_T with InvalidReference, the same "not a variable or literal" error the language already raises for a type name in value position (x: uint256 = uint256).

How to verify it

On master both of these panic:

@external
def foo():
    x: Bytes[32] = abi_encode(uint256)   # CompilerPanic: TYPE_T does not implement abi_type

@external
def bar():
    print(uint256)                       # CodegenPanic: 'IntegerT' object has no attribute 'typ'

After this change both raise InvalidReference: not a variable or literal: 'uint256' at compile time. Regression tests are in tests/functional/syntax/test_abi_encode.py and tests/functional/syntax/test_print.py.

Commit message

Builtins with variable arguments (abi_encode, print, raw_create,
create_from_blueprint) inferred each vararg's type for its side effects
but never checked the argument was a runtime value. A bare type name
infers to TYPE_T, which passed the vararg check and slipped through to
codegen, where it panicked (`TYPE_T does not implement abi_type`,
`'IntegerT' object has no attribute 'typ'`).

Reject a TYPE_T vararg during semantic analysis with the same "not a
variable or literal" error the language already raises for a type name
in value position (e.g. `x: uint256 = uint256`).

Part of GH 4609

Description for the changelog

Reject a bare type name passed as a builtin vararg (e.g. abi_encode(uint256)) with a clear error instead of an internal compiler panic.

Cute Animal Picture

Put a link to a cute animal picture inside the parenthesis-->

@Sporarum Sporarum left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks very good !

One small potential nitpick below

Comment thread tests/functional/syntax/test_abi_encode.py Outdated
Builtins with variable arguments (abi_encode, print, raw_create,
create_from_blueprint) inferred each vararg's type for its side effects
but never checked the argument was a runtime value. A bare type name
infers to TYPE_T, which passed the vararg check and slipped through to
codegen, where it panicked (`TYPE_T does not implement abi_type`,
`'IntegerT' object has no attribute 'typ'`).

Reject a TYPE_T vararg during semantic analysis with the same
"not a variable or literal" error the language already raises for a
type name in value position (e.g. `x: uint256 = uint256`).

Part of vyperlang#4609
@beardthelion
beardthelion force-pushed the fix/vararg-type-name-panic branch from 7e30e47 to 7781981 Compare September 9, 2026 13:05
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants